diff options
Diffstat (limited to 'contrib/googletest/googlemock')
117 files changed, 20230 insertions, 38982 deletions
diff --git a/contrib/googletest/googlemock/CHANGES b/contrib/googletest/googlemock/CHANGES deleted file mode 100644 index 4328ece3d3af..000000000000 --- a/contrib/googletest/googlemock/CHANGES +++ /dev/null @@ -1,126 +0,0 @@ -Changes for 1.7.0: - -* All new improvements in Google Test 1.7.0. -* New feature: matchers DoubleNear(), FloatNear(), - NanSensitiveDoubleNear(), NanSensitiveFloatNear(), - UnorderedElementsAre(), UnorderedElementsAreArray(), WhenSorted(), - WhenSortedBy(), IsEmpty(), and SizeIs(). -* Improvement: Google Mock can now be built as a DLL. -* Improvement: when compiled by a C++11 compiler, matchers AllOf() - and AnyOf() can accept an arbitrary number of matchers. -* Improvement: when compiled by a C++11 compiler, matchers - ElementsAreArray() can accept an initializer list. -* Improvement: when exceptions are enabled, a mock method with no - default action now throws instead crashing the test. -* Improvement: added class testing::StringMatchResultListener to aid - definition of composite matchers. -* Improvement: function return types used in MOCK_METHOD*() macros can - now contain unprotected commas. -* Improvement (potentially breaking): EXPECT_THAT() and ASSERT_THAT() - are now more strict in ensuring that the value type and the matcher - type are compatible, catching potential bugs in tests. -* Improvement: Pointee() now works on an optional<T>. -* Improvement: the ElementsAreArray() matcher can now take a vector or - iterator range as input, and makes a copy of its input elements - before the conversion to a Matcher. -* Improvement: the Google Mock Generator can now generate mocks for - some class templates. -* Bug fix: mock object destruction triggerred by another mock object's - destruction no longer hangs. -* Improvement: Google Mock Doctor works better with newer Clang and - GCC now. -* Compatibility fixes. -* Bug/warning fixes. - -Changes for 1.6.0: - -* Compilation is much faster and uses much less memory, especially - when the constructor and destructor of a mock class are moved out of - the class body. -* New matchers: Pointwise(), Each(). -* New actions: ReturnPointee() and ReturnRefOfCopy(). -* CMake support. -* Project files for Visual Studio 2010. -* AllOf() and AnyOf() can handle up-to 10 arguments now. -* Google Mock doctor understands Clang error messages now. -* SetArgPointee<> now accepts string literals. -* gmock_gen.py handles storage specifier macros and template return - types now. -* Compatibility fixes. -* Bug fixes and implementation clean-ups. -* Potentially incompatible changes: disables the harmful 'make install' - command in autotools. - -Potentially breaking changes: - -* The description string for MATCHER*() changes from Python-style - interpolation to an ordinary C++ string expression. -* SetArgumentPointee is deprecated in favor of SetArgPointee. -* Some non-essential project files for Visual Studio 2005 are removed. - -Changes for 1.5.0: - - * New feature: Google Mock can be safely used in multi-threaded tests - on platforms having pthreads. - * New feature: function for printing a value of arbitrary type. - * New feature: function ExplainMatchResult() for easy definition of - composite matchers. - * The new matcher API lets user-defined matchers generate custom - explanations more directly and efficiently. - * Better failure messages all around. - * NotNull() and IsNull() now work with smart pointers. - * Field() and Property() now work when the matcher argument is a pointer - passed by reference. - * Regular expression matchers on all platforms. - * Added GCC 4.0 support for Google Mock Doctor. - * Added gmock_all_test.cc for compiling most Google Mock tests - in a single file. - * Significantly cleaned up compiler warnings. - * Bug fixes, better test coverage, and implementation clean-ups. - - Potentially breaking changes: - - * Custom matchers defined using MatcherInterface or MakePolymorphicMatcher() - need to be updated after upgrading to Google Mock 1.5.0; matchers defined - using MATCHER or MATCHER_P* aren't affected. - * Dropped support for 'make install'. - -Changes for 1.4.0 (we skipped 1.2.* and 1.3.* to match the version of -Google Test): - - * Works in more environments: Symbian and minGW, Visual C++ 7.1. - * Lighter weight: comes with our own implementation of TR1 tuple (no - more dependency on Boost!). - * New feature: --gmock_catch_leaked_mocks for detecting leaked mocks. - * New feature: ACTION_TEMPLATE for defining templatized actions. - * New feature: the .After() clause for specifying expectation order. - * New feature: the .With() clause for specifying inter-argument - constraints. - * New feature: actions ReturnArg<k>(), ReturnNew<T>(...), and - DeleteArg<k>(). - * New feature: matchers Key(), Pair(), Args<...>(), AllArgs(), IsNull(), - and Contains(). - * New feature: utility class MockFunction<F>, useful for checkpoints, etc. - * New feature: functions Value(x, m) and SafeMatcherCast<T>(m). - * New feature: copying a mock object is rejected at compile time. - * New feature: a script for fusing all Google Mock and Google Test - source files for easy deployment. - * Improved the Google Mock doctor to diagnose more diseases. - * Improved the Google Mock generator script. - * Compatibility fixes for Mac OS X and gcc. - * Bug fixes and implementation clean-ups. - -Changes for 1.1.0: - - * New feature: ability to use Google Mock with any testing framework. - * New feature: macros for easily defining new matchers - * New feature: macros for easily defining new actions. - * New feature: more container matchers. - * New feature: actions for accessing function arguments and throwing - exceptions. - * Improved the Google Mock doctor script for diagnosing compiler errors. - * Bug fixes and implementation clean-ups. - -Changes for 1.0.0: - - * Initial Open Source release of Google Mock diff --git a/contrib/googletest/googlemock/CMakeLists.txt b/contrib/googletest/googlemock/CMakeLists.txt index 8a8de1f64119..a9aa0723fbf1 100644 --- a/contrib/googletest/googlemock/CMakeLists.txt +++ b/contrib/googletest/googlemock/CMakeLists.txt @@ -1,4 +1,7 @@ ######################################################################## +# 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 @@ -33,13 +36,8 @@ endif() # 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.6.4) +cmake_minimum_required(VERSION 3.13) +project(gmock VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C) if (COMMAND set_up_hermetic_build) set_up_hermetic_build() @@ -49,7 +47,7 @@ endif() # 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") +add_subdirectory("${gtest_dir}" "${gmock_BINARY_DIR}/${gtest_dir}") # These commands only run if this is the main project @@ -75,18 +73,6 @@ set(gmock_build_include_dirs "${gtest_SOURCE_DIR}") include_directories(${gmock_build_include_dirs}) -# Summary of tuple support for Microsoft Visual Studio: -# Compiler version(MS) version(cmake) Support -# ---------- ----------- -------------- ----------------------------- -# <= VS 2010 <= 10 <= 1600 Use Google Tests's own tuple. -# VS 2012 11 1700 std::tr1::tuple + _VARIADIC_MAX=10 -# VS 2013 12 1800 std::tr1::tuple -# VS 2015 14 1900 std::tuple -# VS 2017 15 >= 1910 std::tuple -if (MSVC AND MSVC_VERSION EQUAL 1700) - add_definitions(/D _VARIADIC_MAX=10) -endif() - ######################################################################## # # Defines the gmock & gmock_main libraries. User tests should link @@ -109,21 +95,20 @@ if (MSVC) 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) -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}>") + set_target_properties(gmock_main PROPERTIES VERSION ${GOOGLETEST_VERSION}) endif() +string(REPLACE ";" "$<SEMICOLON>" dirs "${gmock_build_include_dirs}") +target_include_directories(gmock SYSTEM INTERFACE + "$<BUILD_INTERFACE:${dirs}>" + "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>") +target_include_directories(gmock_main SYSTEM INTERFACE + "$<BUILD_INTERFACE:${dirs}>" + "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>") + ######################################################################## # # Install rules @@ -145,18 +130,22 @@ if (gmock_build_tests) # 'make test' or ctest. enable_testing() + if (MINGW OR CYGWIN) + add_compile_options("-Wa,-mbig-obj") + 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-generated-actions_test gmock_main) - cxx_test(gmock-generated-function-mockers_test gmock_main) - cxx_test(gmock-generated-internal-utils_test gmock_main) - cxx_test(gmock-generated-matchers_test gmock_main) + cxx_test(gmock-function-mocker_test gmock_main) cxx_test(gmock-internal-utils_test gmock_main) - cxx_test(gmock-matchers_test gmock_main) + cxx_test(gmock-matchers-arithmetic_test gmock_main) + cxx_test(gmock-matchers-comparisons_test gmock_main) + cxx_test(gmock-matchers-containers_test gmock_main) + cxx_test(gmock-matchers-misc_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) @@ -182,25 +171,12 @@ if (gmock_build_tests) cxx_library(gmock_main_no_rtti "${cxx_no_rtti}" "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc) - if (MSVC_VERSION LESS 1600) # 1600 is Visual Studio 2010. - # Visual Studio 2010, 2012, and 2013 define symbols in std::tr1 that - # conflict with our own definitions. Therefore using our own tuple does not - # work on those compilers. - cxx_library(gmock_main_use_own_tuple "${cxx_use_own_tuple}" - "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc) - - cxx_test_with_flags(gmock_use_own_tuple_test "${cxx_use_own_tuple}" - gmock_main_use_own_tuple test/gmock-spec-builders_test.cc) - endif() 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) - - cxx_library(gmock_main_use_own_tuple "${cxx_use_own_tuple}" src/gmock_main.cc) - target_link_libraries(gmock_main_use_own_tuple 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) diff --git a/contrib/googletest/googlemock/CONTRIBUTORS b/contrib/googletest/googlemock/CONTRIBUTORS deleted file mode 100644 index 6e9ae362b60c..000000000000 --- a/contrib/googletest/googlemock/CONTRIBUTORS +++ /dev/null @@ -1,40 +0,0 @@ -# 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/contrib/googletest/googlemock/LICENSE b/contrib/googletest/googlemock/LICENSE deleted file mode 100644 index 1941a11f8ce9..000000000000 --- a/contrib/googletest/googlemock/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -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/contrib/googletest/googlemock/Makefile.am b/contrib/googletest/googlemock/Makefile.am deleted file mode 100644 index 9adbc5163dd7..000000000000 --- a/contrib/googletest/googlemock/Makefile.am +++ /dev/null @@ -1,224 +0,0 @@ -# Automake file - -# Nonstandard package files for distribution. -EXTRA_DIST = LICENSE - -# We may need to build our internally packaged gtest. If so, it will be -# included in the 'subdirs' variable. -SUBDIRS = $(subdirs) - -# This is generated by the configure script, so clean it for distribution. -DISTCLEANFILES = scripts/gmock-config - -# We define the global AM_CPPFLAGS as everything we compile includes from these -# directories. -AM_CPPFLAGS = $(GTEST_CPPFLAGS) -I$(srcdir)/include - -# Modifies compiler and linker flags for pthreads compatibility. -if HAVE_PTHREADS - AM_CXXFLAGS = @PTHREAD_CFLAGS@ -DGTEST_HAS_PTHREAD=1 - AM_LIBS = @PTHREAD_LIBS@ -endif - -# Build rules for libraries. -lib_LTLIBRARIES = lib/libgmock.la lib/libgmock_main.la - -lib_libgmock_la_SOURCES = src/gmock-all.cc - -pkginclude_HEADERS = \ - include/gmock/gmock-actions.h \ - include/gmock/gmock-cardinalities.h \ - include/gmock/gmock-generated-actions.h \ - include/gmock/gmock-generated-function-mockers.h \ - include/gmock/gmock-generated-matchers.h \ - include/gmock/gmock-generated-nice-strict.h \ - include/gmock/gmock-matchers.h \ - include/gmock/gmock-more-actions.h \ - include/gmock/gmock-more-matchers.h \ - include/gmock/gmock-spec-builders.h \ - include/gmock/gmock.h - -pkginclude_internaldir = $(pkgincludedir)/internal -pkginclude_internal_HEADERS = \ - include/gmock/internal/gmock-generated-internal-utils.h \ - include/gmock/internal/gmock-internal-utils.h \ - include/gmock/internal/gmock-port.h \ - include/gmock/internal/custom/gmock-generated-actions.h \ - include/gmock/internal/custom/gmock-matchers.h \ - include/gmock/internal/custom/gmock-port.h - -lib_libgmock_main_la_SOURCES = src/gmock_main.cc -lib_libgmock_main_la_LIBADD = lib/libgmock.la - -# Build rules for tests. Automake's naming for some of these variables isn't -# terribly obvious, so this is a brief reference: -# -# TESTS -- Programs run automatically by "make check" -# check_PROGRAMS -- Programs built by "make check" but not necessarily run - -TESTS= -check_PROGRAMS= -AM_LDFLAGS = $(GTEST_LDFLAGS) - -# This exercises all major components of Google Mock. It also -# verifies that libgmock works. -TESTS += test/gmock-spec-builders_test -check_PROGRAMS += test/gmock-spec-builders_test -test_gmock_spec_builders_test_SOURCES = test/gmock-spec-builders_test.cc -test_gmock_spec_builders_test_LDADD = $(GTEST_LIBS) lib/libgmock.la - -# This tests using Google Mock in multiple translation units. It also -# verifies that libgmock_main and libgmock work. -TESTS += test/gmock_link_test -check_PROGRAMS += test/gmock_link_test -test_gmock_link_test_SOURCES = \ - test/gmock_link2_test.cc \ - test/gmock_link_test.cc \ - test/gmock_link_test.h -test_gmock_link_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la lib/libgmock.la - -if HAVE_PYTHON - # Tests that fused gmock files compile and work. - TESTS += test/gmock_fused_test - check_PROGRAMS += test/gmock_fused_test - test_gmock_fused_test_SOURCES = \ - fused-src/gmock-gtest-all.cc \ - fused-src/gmock/gmock.h \ - fused-src/gmock_main.cc \ - fused-src/gtest/gtest.h \ - test/gmock_test.cc - test_gmock_fused_test_CPPFLAGS = -I"$(srcdir)/fused-src" -endif - -# Google Mock source files that we don't compile directly. -GMOCK_SOURCE_INGLUDES = \ - src/gmock-cardinalities.cc \ - src/gmock-internal-utils.cc \ - src/gmock-matchers.cc \ - src/gmock-spec-builders.cc \ - src/gmock.cc - -EXTRA_DIST += $(GMOCK_SOURCE_INGLUDES) - -# C++ tests that we don't compile using autotools. -EXTRA_DIST += \ - test/gmock-actions_test.cc \ - test/gmock_all_test.cc \ - test/gmock-cardinalities_test.cc \ - test/gmock_ex_test.cc \ - test/gmock-generated-actions_test.cc \ - test/gmock-generated-function-mockers_test.cc \ - test/gmock-generated-internal-utils_test.cc \ - test/gmock-generated-matchers_test.cc \ - test/gmock-internal-utils_test.cc \ - test/gmock-matchers_test.cc \ - test/gmock-more-actions_test.cc \ - test/gmock-nice-strict_test.cc \ - test/gmock-port_test.cc \ - test/gmock_stress_test.cc - -# Python tests, which we don't run using autotools. -EXTRA_DIST += \ - test/gmock_leak_test.py \ - test/gmock_leak_test_.cc \ - test/gmock_output_test.py \ - test/gmock_output_test_.cc \ - test/gmock_output_test_golden.txt \ - test/gmock_test_utils.py - -# Nonstandard package files for distribution. -EXTRA_DIST += \ - CHANGES \ - CONTRIBUTORS \ - make/Makefile - -# Pump scripts for generating Google Mock headers. -# TODO(chandlerc@google.com): automate the generation of *.h from *.h.pump. -EXTRA_DIST += \ - include/gmock/gmock-generated-actions.h.pump \ - include/gmock/gmock-generated-function-mockers.h.pump \ - include/gmock/gmock-generated-matchers.h.pump \ - include/gmock/gmock-generated-nice-strict.h.pump \ - include/gmock/internal/gmock-generated-internal-utils.h.pump \ - include/gmock/internal/custom/gmock-generated-actions.h.pump - -# Script for fusing Google Mock and Google Test source files. -EXTRA_DIST += scripts/fuse_gmock_files.py - -# The Google Mock Generator tool from the cppclean project. -EXTRA_DIST += \ - scripts/generator/LICENSE \ - scripts/generator/README \ - scripts/generator/README.cppclean \ - scripts/generator/cpp/__init__.py \ - scripts/generator/cpp/ast.py \ - scripts/generator/cpp/gmock_class.py \ - scripts/generator/cpp/keywords.py \ - scripts/generator/cpp/tokenize.py \ - scripts/generator/cpp/utils.py \ - scripts/generator/gmock_gen.py - -# Script for diagnosing compiler errors in programs that use Google -# Mock. -EXTRA_DIST += scripts/gmock_doctor.py - -# CMake scripts. -EXTRA_DIST += \ - CMakeLists.txt - -# Microsoft Visual Studio 2005 projects. -EXTRA_DIST += \ - msvc/2005/gmock.sln \ - msvc/2005/gmock.vcproj \ - msvc/2005/gmock_config.vsprops \ - msvc/2005/gmock_main.vcproj \ - msvc/2005/gmock_test.vcproj - -# Microsoft Visual Studio 2010 projects. -EXTRA_DIST += \ - msvc/2010/gmock.sln \ - msvc/2010/gmock.vcxproj \ - msvc/2010/gmock_config.props \ - msvc/2010/gmock_main.vcxproj \ - msvc/2010/gmock_test.vcxproj - -if HAVE_PYTHON -# gmock_test.cc does not really depend on files generated by the -# fused-gmock-internal rule. However, gmock_test.o does, and it is -# important to include test/gmock_test.cc as part of this rule in order to -# prevent compiling gmock_test.o until all dependent files have been -# generated. -$(test_gmock_fused_test_SOURCES): fused-gmock-internal - -# TODO(vladl@google.com): Find a way to add Google Tests's sources here. -fused-gmock-internal: $(pkginclude_HEADERS) $(pkginclude_internal_HEADERS) \ - $(lib_libgmock_la_SOURCES) $(GMOCK_SOURCE_INGLUDES) \ - $(lib_libgmock_main_la_SOURCES) \ - scripts/fuse_gmock_files.py - mkdir -p "$(srcdir)/fused-src" - chmod -R u+w "$(srcdir)/fused-src" - rm -f "$(srcdir)/fused-src/gtest/gtest.h" - rm -f "$(srcdir)/fused-src/gmock/gmock.h" - rm -f "$(srcdir)/fused-src/gmock-gtest-all.cc" - "$(srcdir)/scripts/fuse_gmock_files.py" "$(srcdir)/fused-src" - cp -f "$(srcdir)/src/gmock_main.cc" "$(srcdir)/fused-src" - -maintainer-clean-local: - rm -rf "$(srcdir)/fused-src" -endif - -# Death tests may produce core dumps in the build directory. In case -# this happens, clean them to keep distcleancheck happy. -CLEANFILES = core - -# Disables 'make install' as installing a compiled version of Google -# Mock can lead to undefined behavior due to violation of the -# One-Definition Rule. - -install-exec-local: - echo "'make install' is dangerous and not supported. Instead, see README for how to integrate Google Mock into your build system." - false - -install-data-local: - echo "'make install' is dangerous and not supported. Instead, see README for how to integrate Google Mock into your build system." - false diff --git a/contrib/googletest/googlemock/README.md b/contrib/googletest/googlemock/README.md index be4758aedb5b..7da60655dba8 100644 --- a/contrib/googletest/googlemock/README.md +++ b/contrib/googletest/googlemock/README.md @@ -1,323 +1,40 @@ -## Google Mock ## +# Googletest Mocking (gMock) Framework -The Google C++ mocking framework. +### Overview -### 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. +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/), and - * [Hamcrest](http://code.google.com/p/hamcrest/), - -and designed with C++'s specifics in mind. - -Google mock: - - * lets you create mock classes trivially using simple macros. - * supports a rich set of matchers and actions. - * handles unordered, partially ordered, or completely ordered expectations. - * is extensible by users. - -We hope you find it useful! - -### Features ### - - * Provides a declarative syntax for defining mocks. - * Can easily 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 an user extend it by defining new matchers and actions. - * Does not use exceptions. - * Is easy to learn and use. - -Please see the project page above for more information as well as the -mailing list for questions, discussions, and development. There is -also an IRC channel on OFTC (irc.oftc.net) #gtest available. Please -join us! - -Please note that code under [scripts/generator](scripts/generator/) is -from [cppclean](http://code.google.com/p/cppclean/) and released under -the Apache License, which is different from Google Mock's license. - -## Getting Started ## - -If you are new to the project, we suggest that you read the user -documentation in the following order: - - * Learn the [basics](../../master/googletest/docs/primer.md) of - Google Test, if you choose to use Google Mock with it (recommended). - * Read [Google Mock for Dummies](../../master/googlemock/docs/ForDummies.md). - * Read the instructions below on how to build Google Mock. - -You can also watch Zhanyong's [talk](http://www.youtube.com/watch?v=sYpCyLI47rM) on Google Mock's usage and implementation. - -Once you understand the basics, check out the rest of the docs: - - * [CheatSheet](../../master/googlemock/docs/CheatSheet.md) - all the commonly used stuff - at a glance. - * [CookBook](../../master/googlemock/docs/CookBook.md) - recipes for getting things done, - including advanced techniques. - -If you need help, please check the -[KnownIssues](docs/KnownIssues.md) and -[FrequentlyAskedQuestions](docs/FrequentlyAskedQuestions.md) before -posting a question on the -[discussion group](http://groups.google.com/group/googlemock). - - -### Using Google Mock Without Google Test ### - -Google Mock is not a testing framework itself. Instead, it needs a -testing framework for writing tests. Google Mock works seamlessly -with [Google Test](https://github.com/google/googletest), but -you can also use it with [any C++ testing framework](../../master/googlemock/docs/ForDummies.md#using-google-mock-with-any-testing-framework). - -### Requirements for End Users ### - -Google Mock is implemented on top of [Google Test]( -http://github.com/google/googletest/), and depends on it. -You must use the bundled version of Google Test when using Google Mock. - -You can also easily configure Google Mock to work with another testing -framework, although it will still need Google Test. Please read -["Using_Google_Mock_with_Any_Testing_Framework"]( - ../../master/googlemock/docs/ForDummies.md#using-google-mock-with-any-testing-framework) -for instructions. - -Google Mock depends on advanced C++ features and thus requires a more -modern compiler. The following are needed to use Google Mock: - -#### Linux Requirements #### - - * GNU-compatible Make or "gmake" - * POSIX-standard shell - * POSIX(-2) Regular Expressions (regex.h) - * C++98-standard-compliant compiler (e.g. GCC 3.4 or newer) - -#### Windows Requirements #### - - * Microsoft Visual C++ 8.0 SP1 or newer - -#### Mac OS X Requirements #### - - * Mac OS X 10.4 Tiger or newer - * Developer Tools Installed - -### Requirements for Contributors ### - -We welcome patches. If you plan to contribute a patch, you need to -build Google Mock and its tests, which has further requirements: - - * Automake version 1.9 or newer - * Autoconf version 2.59 or newer - * Libtool / Libtoolize - * Python version 2.3 or newer (for running some of the tests and - re-generating certain source files from templates) - -### Building Google Mock ### - -#### Using CMake #### - -If you have CMake available, it is recommended that you follow the -[build instructions][gtest_cmakebuild] -as described for Google Test. - -If are using Google Mock with an -existing CMake project, the section -[Incorporating Into An Existing CMake Project][gtest_incorpcmake] -may be of particular interest. -To make it work for Google Mock you will need to change - - target_link_libraries(example gtest_main) - -to - - target_link_libraries(example gmock_main) - -This works because `gmock_main` library is compiled with Google Test. - -#### Preparing to Build (Unix only) #### - -If you are using a Unix system and plan to use the GNU Autotools build -system to build Google Mock (described below), you'll need to -configure it now. - -To prepare the Autotools build system: - - cd googlemock - autoreconf -fvi - -To build Google Mock and your tests that use it, you need to tell your -build system where to find its headers and source files. The exact -way to do it depends on which build system you use, and is usually -straightforward. - -This section shows how you can integrate Google Mock into your -existing build system. - -Suppose you put Google Mock in directory `${GMOCK_DIR}` and Google Test -in `${GTEST_DIR}` (the latter is `${GMOCK_DIR}/gtest` by default). To -build Google Mock, create a library build target (or a project as -called by Visual Studio and Xcode) to compile - - ${GTEST_DIR}/src/gtest-all.cc and ${GMOCK_DIR}/src/gmock-all.cc - -with - - ${GTEST_DIR}/include and ${GMOCK_DIR}/include - -in the system header search path, and - - ${GTEST_DIR} and ${GMOCK_DIR} - -in the normal header search path. Assuming a Linux-like system and gcc, -something like the following will do: - - g++ -isystem ${GTEST_DIR}/include -I${GTEST_DIR} \ - -isystem ${GMOCK_DIR}/include -I${GMOCK_DIR} \ - -pthread -c ${GTEST_DIR}/src/gtest-all.cc - g++ -isystem ${GTEST_DIR}/include -I${GTEST_DIR} \ - -isystem ${GMOCK_DIR}/include -I${GMOCK_DIR} \ - -pthread -c ${GMOCK_DIR}/src/gmock-all.cc - ar -rv libgmock.a gtest-all.o gmock-all.o - -(We need -pthread as Google Test and Google Mock use threads.) - -Next, you should compile your test source file with -${GTEST\_DIR}/include and ${GMOCK\_DIR}/include in the header search -path, and link it with gmock and any other necessary libraries: - - g++ -isystem ${GTEST_DIR}/include -isystem ${GMOCK_DIR}/include \ - -pthread path/to/your_test.cc libgmock.a -o your_test - -As an example, the make/ directory contains a Makefile that you can -use to build Google Mock on systems where GNU make is available -(e.g. Linux, Mac OS X, and Cygwin). It doesn't try to build Google -Mock's own tests. Instead, it just builds the Google Mock library and -a sample test. You can use it as a starting point for your own build -script. - -If the default settings are correct for your environment, the -following commands should succeed: - - cd ${GMOCK_DIR}/make - make - ./gmock_test - -If you see errors, try to tweak the contents of -[make/Makefile](make/Makefile) to make them go away. - -### Windows ### - -The msvc/2005 directory contains VC++ 2005 projects and the msvc/2010 -directory contains VC++ 2010 projects for building Google Mock and -selected tests. - -Change to the appropriate directory and run "msbuild gmock.sln" to -build the library and tests (or open the gmock.sln in the MSVC IDE). -If you want to create your own project to use with Google Mock, you'll -have to configure it to use the `gmock_config` propety sheet. For that: - - * Open the Property Manager window (View | Other Windows | Property Manager) - * Right-click on your project and select "Add Existing Property Sheet..." - * Navigate to `gmock_config.vsprops` or `gmock_config.props` and select it. - * In Project Properties | Configuration Properties | General | Additional - Include Directories, type <path to Google Mock>/include. - -### Tweaking Google Mock ### - -Google Mock can be used in diverse environments. The default -configuration may not work (or may not work well) out of the box in -some environments. However, you can easily tweak Google Mock by -defining control macros on the compiler command line. Generally, -these macros are named like `GTEST_XYZ` and you define them to either 1 -or 0 to enable or disable a certain feature. - -We list the most frequently used macros below. For a complete list, -see file [${GTEST\_DIR}/include/gtest/internal/gtest-port.h]( -../googletest/include/gtest/internal/gtest-port.h). - -### Choosing a TR1 Tuple Library ### - -Google Mock uses the C++ Technical Report 1 (TR1) tuple library -heavily. Unfortunately TR1 tuple is not yet widely available with all -compilers. The good news is that Google Test 1.4.0+ implements a -subset of TR1 tuple that's enough for Google Mock's need. Google Mock -will automatically use that implementation when the compiler doesn't -provide TR1 tuple. - -Usually you don't need to care about which tuple library Google Test -and Google Mock use. However, if your project already uses TR1 tuple, -you need to tell Google Test and Google Mock to use the same TR1 tuple -library the rest of your project uses, or the two tuple -implementations will clash. To do that, add - - -DGTEST_USE_OWN_TR1_TUPLE=0 - -to the compiler flags while compiling Google Test, Google Mock, and -your tests. If you want to force Google Test and Google Mock to use -their own tuple library, just add - - -DGTEST_USE_OWN_TR1_TUPLE=1 - -to the compiler flags instead. - -If you want to use Boost's TR1 tuple library with Google Mock, please -refer to the Boost website (http://www.boost.org/) for how to obtain -it and set it up. - -### As a Shared Library (DLL) ### - -Google Mock is compact, so most users can build and link it as a static -library for the simplicity. Google Mock can be used as a DLL, but the -same DLL must contain Google Test as well. See -[Google Test's README][gtest_readme] -for instructions on how to set up necessary compiler settings. - -### Tweaking Google Mock ### - -Most of Google Test's control macros apply to Google Mock as well. -Please see [Google Test's README][gtest_readme] for how to tweak them. - -### Upgrading from an Earlier Version ### - -We strive to keep Google Mock releases backward compatible. -Sometimes, though, we have to make some breaking changes for the -users' long-term benefits. This section describes what you'll need to -do if you are upgrading from an earlier version of Google Mock. - -#### Upgrading from 1.1.0 or Earlier #### - -You may need to explicitly enable or disable Google Test's own TR1 -tuple library. See the instructions in section "[Choosing a TR1 Tuple -Library](../googletest/#choosing-a-tr1-tuple-library)". - -#### Upgrading from 1.4.0 or Earlier #### - -On platforms where the pthread library is available, Google Test and -Google Mock use it in order to be thread-safe. For this to work, you -may need to tweak your compiler and/or linker flags. Please see the -"[Multi-threaded Tests](../googletest#multi-threaded-tests -)" section in file Google Test's README for what you may need to do. - -If you have custom matchers defined using `MatcherInterface` or -`MakePolymorphicMatcher()`, you'll need to update their definitions to -use the new matcher API ( -[monomorphic](./docs/CookBook.md#writing-new-monomorphic-matchers), -[polymorphic](./docs/CookBook.md#writing-new-polymorphic-matchers)). -Matchers defined using `MATCHER()` or `MATCHER_P*()` aren't affected. - -Happy testing! - -[gtest_readme]: ../googletest/README.md "googletest" -[gtest_cmakebuild]: ../googletest/README.md#using-cmake "Using CMake" -[gtest_incorpcmake]: ../googletest/README.md#incorporating-into-an-existing-cmake-project "Incorporating Into An Existing CMake Project" +* [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](https://google.github.io/googletest/gmock_for_dummies.html) +* [Legacy gMock FAQ](https://google.github.io/googletest/gmock_faq.html) +* [gMock Cookbook](https://google.github.io/googletest/gmock_cook_book.html) +* [gMock Cheat Sheet](https://google.github.io/googletest/gmock_cheat_sheet.html) + +GoogleMock is a part of +[GoogleTest C++ testing framework](http://github.com/google/googletest/) and a +subject to the same requirements. diff --git a/contrib/googletest/googlemock/build-aux/.keep b/contrib/googletest/googlemock/build-aux/.keep deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/contrib/googletest/googlemock/build-aux/.keep +++ /dev/null diff --git a/contrib/googletest/googlemock/cmake/gmock.pc.in b/contrib/googletest/googlemock/cmake/gmock.pc.in index c44164264acf..23c67b5c88db 100644 --- a/contrib/googletest/googlemock/cmake/gmock.pc.in +++ b/contrib/googletest/googlemock/cmake/gmock.pc.in @@ -5,5 +5,6 @@ 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@ @CMAKE_THREAD_LIBS_INIT@ +Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ diff --git a/contrib/googletest/googlemock/cmake/gmock_main.pc.in b/contrib/googletest/googlemock/cmake/gmock_main.pc.in index c377dba1e57d..66ffea7f4431 100644 --- a/contrib/googletest/googlemock/cmake/gmock_main.pc.in +++ b/contrib/googletest/googlemock/cmake/gmock_main.pc.in @@ -5,5 +5,6 @@ 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@ @CMAKE_THREAD_LIBS_INIT@ +Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ diff --git a/contrib/googletest/googlemock/configure.ac b/contrib/googletest/googlemock/configure.ac deleted file mode 100644 index cb5e1a6a8cae..000000000000 --- a/contrib/googletest/googlemock/configure.ac +++ /dev/null @@ -1,146 +0,0 @@ -m4_include(../googletest/m4/acx_pthread.m4) - -AC_INIT([Google C++ Mocking Framework], - [1.8.0], - [googlemock@googlegroups.com], - [gmock]) - -# Provide various options to initialize the Autoconf and configure processes. -AC_PREREQ([2.59]) -AC_CONFIG_SRCDIR([./LICENSE]) -AC_CONFIG_AUX_DIR([build-aux]) -AC_CONFIG_HEADERS([build-aux/config.h]) -AC_CONFIG_FILES([Makefile]) -AC_CONFIG_FILES([scripts/gmock-config], [chmod +x scripts/gmock-config]) - -# Initialize Automake with various options. We require at least v1.9, prevent -# pedantic complaints about package files, and enable various distribution -# targets. -AM_INIT_AUTOMAKE([1.9 dist-bzip2 dist-zip foreign subdir-objects]) - -# Check for programs used in building Google Test. -AC_PROG_CC -AC_PROG_CXX -AC_LANG([C++]) -AC_PROG_LIBTOOL - -# TODO(chandlerc@google.com): Currently we aren't running the Python tests -# against the interpreter detected by AM_PATH_PYTHON, and so we condition -# HAVE_PYTHON by requiring "python" to be in the PATH, and that interpreter's -# version to be >= 2.3. This will allow the scripts to use a "/usr/bin/env" -# hashbang. -PYTHON= # We *do not* allow the user to specify a python interpreter -AC_PATH_PROG([PYTHON],[python],[:]) -AS_IF([test "$PYTHON" != ":"], - [AM_PYTHON_CHECK_VERSION([$PYTHON],[2.3],[:],[PYTHON=":"])]) -AM_CONDITIONAL([HAVE_PYTHON],[test "$PYTHON" != ":"]) - -# TODO(chandlerc@google.com) Check for the necessary system headers. - -# Configure pthreads. -AC_ARG_WITH([pthreads], - [AS_HELP_STRING([--with-pthreads], - [use pthreads (default is yes)])], - [with_pthreads=$withval], - [with_pthreads=check]) - -have_pthreads=no -AS_IF([test "x$with_pthreads" != "xno"], - [ACX_PTHREAD( - [], - [AS_IF([test "x$with_pthreads" != "xcheck"], - [AC_MSG_FAILURE( - [--with-pthreads was specified, but unable to be used])])]) - have_pthreads="$acx_pthread_ok"]) -AM_CONDITIONAL([HAVE_PTHREADS],[test "x$have_pthreads" == "xyes"]) -AC_SUBST(PTHREAD_CFLAGS) -AC_SUBST(PTHREAD_LIBS) - -# GoogleMock currently has hard dependencies upon GoogleTest above and beyond -# running its own test suite, so we both provide our own version in -# a subdirectory and provide some logic to use a custom version or a system -# installed version. -AC_ARG_WITH([gtest], - [AS_HELP_STRING([--with-gtest], - [Specifies how to find the gtest package. If no - arguments are given, the default behavior, a - system installed gtest will be used if present, - and an internal version built otherwise. If a - path is provided, the gtest built or installed at - that prefix will be used.])], - [], - [with_gtest=yes]) -AC_ARG_ENABLE([external-gtest], - [AS_HELP_STRING([--disable-external-gtest], - [Disables any detection or use of a system - installed or user provided gtest. Any option to - '--with-gtest' is ignored. (Default is enabled.)]) - ], [], [enable_external_gtest=yes]) -AS_IF([test "x$with_gtest" == "xno"], - [AC_MSG_ERROR([dnl -Support for GoogleTest was explicitly disabled. Currently GoogleMock has a hard -dependency upon GoogleTest to build, please provide a version, or allow -GoogleMock to use any installed version and fall back upon its internal -version.])]) - -# Setup various GTEST variables. TODO(chandlerc@google.com): When these are -# used below, they should be used such that any pre-existing values always -# trump values we set them to, so that they can be used to selectively override -# details of the detection process. -AC_ARG_VAR([GTEST_CONFIG], - [The exact path of Google Test's 'gtest-config' script.]) -AC_ARG_VAR([GTEST_CPPFLAGS], - [C-like preprocessor flags for Google Test.]) -AC_ARG_VAR([GTEST_CXXFLAGS], - [C++ compile flags for Google Test.]) -AC_ARG_VAR([GTEST_LDFLAGS], - [Linker path and option flags for Google Test.]) -AC_ARG_VAR([GTEST_LIBS], - [Library linking flags for Google Test.]) -AC_ARG_VAR([GTEST_VERSION], - [The version of Google Test available.]) -HAVE_BUILT_GTEST="no" - -GTEST_MIN_VERSION="1.8.0" - -AS_IF([test "x${enable_external_gtest}" = "xyes"], - [# Begin filling in variables as we are able. - AS_IF([test "x${with_gtest}" != "xyes"], - [AS_IF([test -x "${with_gtest}/scripts/gtest-config"], - [GTEST_CONFIG="${with_gtest}/scripts/gtest-config"], - [GTEST_CONFIG="${with_gtest}/bin/gtest-config"]) - AS_IF([test -x "${GTEST_CONFIG}"], [], - [AC_MSG_ERROR([dnl -Unable to locate either a built or installed Google Test at '${with_gtest}'.]) - ])]) - - AS_IF([test -x "${GTEST_CONFIG}"], [], - [AC_PATH_PROG([GTEST_CONFIG], [gtest-config])]) - AS_IF([test -x "${GTEST_CONFIG}"], - [AC_MSG_CHECKING([for Google Test version >= ${GTEST_MIN_VERSION}]) - AS_IF([${GTEST_CONFIG} --min-version=${GTEST_MIN_VERSION}], - [AC_MSG_RESULT([yes]) - HAVE_BUILT_GTEST="yes"], - [AC_MSG_RESULT([no])])])]) - -AS_IF([test "x${HAVE_BUILT_GTEST}" = "xyes"], - [GTEST_CPPFLAGS=`${GTEST_CONFIG} --cppflags` - GTEST_CXXFLAGS=`${GTEST_CONFIG} --cxxflags` - GTEST_LDFLAGS=`${GTEST_CONFIG} --ldflags` - GTEST_LIBS=`${GTEST_CONFIG} --libs` - GTEST_VERSION=`${GTEST_CONFIG} --version`], - [ - # GTEST_CONFIG needs to be executable both in a Makefile environment and - # in a shell script environment, so resolve an absolute path for it here. - GTEST_CONFIG="`pwd -P`/../googletest/scripts/gtest-config" - GTEST_CPPFLAGS='-I$(top_srcdir)/../googletest/include' - GTEST_CXXFLAGS='-g' - GTEST_LDFLAGS='' - GTEST_LIBS='$(top_builddir)/../googletest/lib/libgtest.la' - GTEST_VERSION="${GTEST_MIN_VERSION}"]) - -# TODO(chandlerc@google.com) Check the types, structures, and other compiler -# and architecture characteristics. - -# Output the generated files. No further autoconf macros may be used. -AC_OUTPUT diff --git a/contrib/googletest/googlemock/docs/CheatSheet.md b/contrib/googletest/googlemock/docs/CheatSheet.md deleted file mode 100644 index d54dd16ae24d..000000000000 --- a/contrib/googletest/googlemock/docs/CheatSheet.md +++ /dev/null @@ -1,564 +0,0 @@ - - -# Defining a Mock Class # - -## Mocking a Normal Class ## - -Given -``` -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 -``` -#include "gmock/gmock.h" - -class MockFoo : public Foo { - MOCK_CONST_METHOD0(GetSize, int()); - MOCK_METHOD1(Describe, string(const char* name)); - MOCK_METHOD1(Describe, string(int type)); - MOCK_METHOD2(Process, bool(Bar elem, int count)); -}; -``` - -To create a "nice" mock object which ignores all uninteresting calls, -or a "strict" mock object, which treats them as failures: -``` -NiceMock<MockFoo> nice_foo; // The type is a subclass of MockFoo. -StrictMock<MockFoo> strict_foo; // The type is a subclass of MockFoo. -``` - -## Mocking a Class Template ## - -To mock -``` -template <typename Elem> -class StackInterface { - public: - ... - virtual ~StackInterface(); - virtual int GetSize() const = 0; - virtual void Push(const Elem& x) = 0; -}; -``` -(note that `~StackInterface()` **must** be virtual) just append `_T` to the `MOCK_*` macros: -``` -template <typename Elem> -class MockStack : public StackInterface<Elem> { - public: - ... - MOCK_CONST_METHOD0_T(GetSize, int()); - MOCK_METHOD1_T(Push, void(const Elem& x)); -}; -``` - -## Specifying Calling Conventions for Mock Functions ## - -If your mock function doesn't use the default calling convention, you -can specify it by appending `_WITH_CALLTYPE` to any of the macros -described in the previous two sections and supplying the calling -convention as the first argument to the macro. For example, -``` - MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, Foo, bool(int n)); - MOCK_CONST_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, Bar, int(double x, double y)); -``` -where `STDMETHODCALLTYPE` is defined by `<objbase.h>` on Windows. - -# Using Mocks in Tests # - -The typical flow is: - 1. Import the Google Mock names you need to use. All Google Mock names are in the `testing` namespace unless they are macros or otherwise noted. - 1. Create the mock objects. - 1. Optionally, set the default actions of the mock objects. - 1. Set your expectations on the mock objects (How will they be called? What wil they do?). - 1. Exercise code that uses the mock objects; if necessary, check the result using [Google Test](../../googletest/) assertions. - 1. When a mock objects is destructed, Google Mock automatically verifies that all expectations on it have been satisfied. - -Here is an example: -``` -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 # - -Google Mock has a **built-in default action** for any function that -returns `void`, `bool`, a numeric value, or a pointer. - -To customize the default action for functions with return type `T` globally: -``` -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(); -``` - -To customize the default action for a particular method, use `ON_CALL()`: -``` -ON_CALL(mock_object, method(matchers)) - .With(multi_argument_matcher) ? - .WillByDefault(action); -``` - -# Setting Expectations # - -`EXPECT_CALL()` sets **expectations** on a mock method (How will it be -called? What will it do?): -``` -EXPECT_CALL(mock_object, method(matchers)) - .With(multi_argument_matcher) ? - .Times(cardinality) ? - .InSequence(sequences) * - .After(expectations) * - .WillOnce(action) * - .WillRepeatedly(action) ? - .RetiresOnSaturation(); ? -``` - -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 # - -A **matcher** matches a _single_ argument. You can use it inside -`ON_CALL()` or `EXPECT_CALL()`, or use it to validate a value -directly: - -| `EXPECT_THAT(value, matcher)` | Asserts that `value` matches `matcher`. | -|:------------------------------|:----------------------------------------| -| `ASSERT_THAT(value, matcher)` | The same as `EXPECT_THAT(value, matcher)`, except that it generates a **fatal** failure. | - -Built-in matchers (where `argument` is the function argument) are -divided into several categories: - -## Wildcard ## -|`_`|`argument` can be any value of the correct type.| -|:--|:-----------------------------------------------| -|`A<type>()` or `An<type>()`|`argument` can be any value of type `type`. | - -## Generic Comparison ## - -|`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`| -|`IsNull()` |`argument` is a `NULL` pointer (raw or smart).| -|`NotNull()` |`argument` is a non-null pointer (raw or smart).| -|`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.| - -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 `ByRef()`, -e.g. `Eq(ByRef(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. - -## Floating-Point Matchers ## - -|`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. | - -The above matchers use ULP-based comparison (the same as used in -[Google Test](../../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. - -|`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. | - -## String Matchers ## - -The `argument` can be either a C string or a C++ string object: - -|`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`. | - -`ContainsRegex()` and `MatchesRegex()` use the regular expression -syntax defined -[here](../../googletest/docs/advanced.md#regular-expression-syntax). -`StrCaseEq()`, `StrCaseNe()`, `StrEq()`, and `StrNe()` work for wide -strings as well. - -## 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: - -| `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. 0 to 10 arguments are allowed. | -| `ElementsAreArray({ e0, e1, ..., en })`, `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, or C-style array. | -| `IsEmpty()` | `argument` is an empty container (`container.empty()`). | -| `Pointwise(m, container)` | `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 each element matches an `ei` (for a different `i`), which can be a value or a matcher. 0 to 10 arguments are allowed. | -| `UnorderedElementsAreArray({ e0, e1, ..., en })`, `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, or C-style array. | -| `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<int>(), ElementsAre(3, 2, 1))`. | - -Notes: - - * These matchers can also match: - 1. a native array passed by reference (e.g. in `Foo(const int (&a)[5])`), and - 1. an array passed as a pointer and a count (e.g. in `Bar(const T* buffer, int len)` -- see [Multi-argument Matchers](#Multiargument_Matchers.md)). - * The array being matched may be multi-dimensional (i.e. its elements can be arrays). - * `m` in `Pointwise(m, ...)` should be a matcher for `::testing::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==` but has an `Equals()` method, one might write: - -``` -using ::testing::get; -MATCHER(FooEq, "") { - return get<0>(arg).Equals(get<1>(arg)); -} -... -EXPECT_THAT(actual_foos, Pointwise(FooEq(), expected_foos)); -``` - -## Member Matchers ## - -|`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`. | -|`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_.| - -## Matching the Result of a Function or Functor ## - -|`ResultOf(f, m)`|`f(argument)` matches matcher `m`, where `f` is a function or functor.| -|:---------------|:---------------------------------------------------------------------| - -## Pointer Matchers ## - -|`Pointee(m)`|`argument` (either a smart pointer or a raw pointer) points to a value that matches matcher `m`.| -|:-----------|:-----------------------------------------------------------------------------------------------| -|`WhenDynamicCastTo<T>(m)`| when `argument` is passed through `dynamic_cast<T>()`, it matches matcher `m`. | - -## Multiargument Matchers ## - -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)`: - -|`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: - -|`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())`.| - -## Composite Matchers ## - -You can make a matcher from one or more other matchers: - -|`AllOf(m1, m2, ..., mn)`|`argument` matches all of the matchers `m1` to `mn`.| -|:-----------------------|:---------------------------------------------------| -|`AnyOf(m1, m2, ..., mn)`|`argument` matches at least one of the matchers `m1` to `mn`.| -|`Not(m)` |`argument` doesn't match matcher `m`. | - -## Adapters for Matchers ## - -|`MatcherCast<T>(m)`|casts matcher `m` to type `Matcher<T>`.| -|:------------------|:--------------------------------------| -|`SafeMatcherCast<T>(m)`| [safely casts](CookBook.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.| - -## Matchers as Predicates ## - -|`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`. | - -## Defining Matchers ## - -| `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 macher `IsDivisibleBy(n)` to match a number divisible by `n`. | -| `MATCHER_P2(IsBetween, a, b, std::string(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`]. | - -**Notes:** - - 1. The `MATCHER*` macros cannot be used inside a function or class. - 1. 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). - 1. You can use `PrintToString(x)` to convert a value `x` of any type to a string. - -## Matchers as Test Assertions ## - -|`ASSERT_THAT(expression, m)`|Generates a [fatal failure](../../googletest/docs/primer.md#assertions) if the value of `expression` doesn't match matcher `m`.| -|:---------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------| -|`EXPECT_THAT(expression, m)`|Generates a non-fatal failure if the value of `expression` doesn't match matcher `m`. | - -# Actions # - -**Actions** specify what a mock function should do when invoked. - -## Returning a Value ## - -|`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.| - -## Side Effects ## - -|`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.| - -## Using a Function or a Functor as an Action ## - -|`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.| - -The return value of the invoked function is used as the return value -of the action. - -When defining a function or functor to be used with `Invoke*()`, you can declare any unused parameters as `Unused`: -``` - double Distance(Unused, double x, double y) { return sqrt(x*x + y*y); } - ... - EXPECT_CALL(mock, Foo("Hi", _, _)).WillOnce(Invoke(Distance)); -``` - -In `InvokeArgument<N>(...)`, if an argument needs to be passed by reference, wrap it inside `ByRef()`. For example, -``` - InvokeArgument<2>(5, string("Hi"), ByRef(foo)) -``` -calls the mock function's #2 argument, passing to it `5` and `string("Hi")` by value, and `foo` by reference. - -## Default Action ## - -|`DoDefault()`|Do the default action (specified by `ON_CALL()` or the built-in one).| -|:------------|:--------------------------------------------------------------------| - -**Note:** due to technical reasons, `DoDefault()` cannot be used inside a composite action - trying to do so will result in a run-time error. - -## Composite Actions ## - -|`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. | -|:-----------------------|:-----------------------------------------------------------------------------------------------------------------------------| -|`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. | - -## Defining Actions ## - -| `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`. | - -The `ACTION*` macros cannot be used inside a function or class. - -# Cardinalities # - -These are used in `Times()` to specify how many times a mock function will be called: - -|`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.| - -# 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 ## - -``` -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: - -``` -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 ## - -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. <i>All expected<br> -calls</i> in the same sequence must occur in the order they are -specified. - -``` -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: -``` -using ::testing::InSequence; -{ - InSequence dummy; - - EXPECT_CALL(...)...; - EXPECT_CALL(...)...; - ... - EXPECT_CALL(...)...; -} -``` -says that all expected calls in the scope of `dummy` must occur in -strict order. The name `dummy` is irrelevant.) - -# Verifying and Resetting a Mock # - -Google Mock will verify the expectations on a mock object when it is destructed, or you can do it earlier: -``` -using ::testing::Mock; -... -// Verifies and removes the expectations on mock_obj; -// returns true iff successful. -Mock::VerifyAndClearExpectations(&mock_obj); -... -// Verifies and removes the expectations on mock_obj; -// also removes the default actions set by ON_CALL(); -// returns true iff successful. -Mock::VerifyAndClear(&mock_obj); -``` - -You can also tell Google Mock that a mock object can be leaked and doesn't -need to be verified: -``` -Mock::AllowLeak(&mock_obj); -``` - -# Mock Classes # - -Google Mock defines a convenient mock class template -``` -class MockFunction<R(A1, ..., An)> { - public: - MOCK_METHODn(Call, R(A1, ..., An)); -}; -``` -See this [recipe](CookBook.md#using-check-points) for one application of it. - -# Flags # - -| `--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. | diff --git a/contrib/googletest/googlemock/docs/CookBook.md b/contrib/googletest/googlemock/docs/CookBook.md deleted file mode 100644 index 8809b0e7e480..000000000000 --- a/contrib/googletest/googlemock/docs/CookBook.md +++ /dev/null @@ -1,3660 +0,0 @@ - - -You can find recipes for using Google Mock here. If you haven't yet, -please read the [ForDummies](ForDummies.md) document first to make sure you understand -the basics. - -**Note:** Google Mock 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 Google Mock. We omit -such `using` statements in this page for brevity, but you should do it -in your own code. - -# Creating Mock Classes # - -## 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 specify -a different access level than the base class on a virtual function.) -Example: - -``` -class Foo { - public: - ... - virtual bool Transform(Gadget* g) = 0; - - protected: - virtual void Resume(); - - private: - virtual int GetTimeOut(); -}; - -class MockFoo : public Foo { - public: - ... - MOCK_METHOD1(Transform, bool(Gadget* g)); - - // The following must be in the public section, even though the - // methods are protected or private in the base class. - MOCK_METHOD0(Resume, void()); - MOCK_METHOD0(GetTimeOut, int()); -}; -``` - -## Mocking Overloaded Methods ## - -You can mock overloaded functions as usual. No special attention is required: - -``` -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_METHOD1(Add, int(Element x)); - MOCK_METHOD2(Add, int(int times, Element x); - - MOCK_METHOD0(GetBar, Bar&()); - MOCK_CONST_METHOD0(GetBar, const Bar&()); -}; -``` - -**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: - -``` -class MockFoo : public Foo { - ... - using Foo::Add; - MOCK_METHOD1(Add, int(Element x)); - // We don't want to mock int Add(int times, Element x); - ... -}; -``` - -## Mocking Class Templates ## - -To mock a class template, append `_T` to the `MOCK_*` macros: - -``` -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_CONST_METHOD0_T(GetSize, int()); - MOCK_METHOD1_T(Push, void(const Elem& x)); -}; -``` - -## Mocking Nonvirtual Methods ## - -Google Mock can mock non-virtual functions to be used in what we call _hi-perf -dependency injection_. - -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: - -``` -// 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_CONST_METHOD1(GetPacket, const Packet*(size_t packet_number)); - MOCK_CONST_METHOD0(NumberOfPackets, size_t()); - ... -}; -``` - -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 to 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: - -``` -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. - -``` - 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 Google Mock 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: - -``` -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 much 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](#mocking-nonvirtual-methods). - -## The Nice, the Strict, and the Naggy ## - -If a mock method has no `EXPECT_CALL` spec but is called, Google Mock -will print a warning about the "uninteresting call". The rationale is: - - * New methods may be added to an interface after a test is written. We shouldn't fail a test just because a method it doesn't know about is called. - * However, this may also mean there's a bug in the test, so Google Mock shouldn't be silent either. If the user believes these calls are harmless, they can add an `EXPECT_CALL()` to suppress the warning. - -However, sometimes you may want to suppress all "uninteresting call" -warnings, while sometimes you may want the opposite, i.e. to treat all -of them as errors. Google Mock lets you make the decision on a -per-mock-object basis. - -Suppose your test uses a mock class `MockFoo`: - -``` -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, it will be -reported by Google Mock as a warning. However, if you rewrite your -test to use `NiceMock<MockFoo>` instead, the warning will be gone, -resulting in a cleaner test output: - -``` -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: - -``` -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: - -``` -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. -} -``` - -There are some caveats though (I don't like them just as much as the -next guy, but 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*` 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` and `StrictMock` (e.g. `NiceMock<StrictMock<MockFoo> >`) is **not** supported. - 1. The constructors of the base mock (`MockFoo`) cannot have arguments passed by non-const reference, which happens to be banned by the [Google C++ style guide](https://google.github.io/styleguide/cppguide.html). - 1. During the constructor or destructor of `MockFoo`, the mock object is _not_ nice or strict. This may cause surprises if the constructor or destructor calls a mock method on `this` object. (This behavior, however, is consistent with C++'s general rule: if a constructor or destructor calls a virtual method of `this` object, that method is treated as non-virtual. In other words, to the base class's constructor or destructor, `this` object behaves like an instance of the base class, not the derived class. This rule is required for safety. Otherwise a base constructor may use members of a derived class before they are initialized, or a base destructor may use members of a derived class after they have been destroyed.) - -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 should'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 ## - -Sometimes a method has a long list of arguments that is mostly -uninteresting. For example, - -``` -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 (let's -say that 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 re-dispatch the method in the mock class: - -``` -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_METHOD3(Log, void(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 much more user-friendly. - -## 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 ## - -Some times you have a non-trivial fake implementation of an -interface. For example: - -``` -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: - virtual char DoThis(int n) { - return (n > 0) ? '+' : - (n < 0) ? '-' : '0'; - } - - virtual void DoThat(const char* s, int* p) { - *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 Google Mock, you can have it -delegate its default action to a fake class you already have, using -this pattern: - -``` -using ::testing::_; -using ::testing::Invoke; - -class MockFoo : public Foo { - public: - // Normal mock method definitions using Google Mock. - MOCK_METHOD1(DoThis, char(int n)); - MOCK_METHOD2(DoThat, void(const char* s, int* p)); - - // 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(Invoke(&fake_, &FakeFoo::DoThis)); - ON_CALL(*this, DoThat(_, _)) - .WillByDefault(Invoke(&fake_, &FakeFoo::DoThat)); - } - 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: - -``` -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()`), see the "Selecting Between Overloaded Functions" section on this page; 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 technique, the difference being that we use a real -object instead of a fake. Here's an example: - -``` -using ::testing::_; -using ::testing::AtLeast; -using ::testing::Invoke; - -class MockFoo : public Foo { - public: - MockFoo() { - // By default, all calls are delegated to the real object. - ON_CALL(*this, DoThis()) - .WillByDefault(Invoke(&real_, &Foo::DoThis)); - ON_CALL(*this, DoThat(_)) - .WillByDefault(Invoke(&real_, &Foo::DoThat)); - ... - } - MOCK_METHOD0(DoThis, ...); - MOCK_METHOD1(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, Google Mock 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: - -``` -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_METHOD1(Pure, void(int n)); - // Mocking a concrete method. Foo::Concrete() is shadowed. - MOCK_METHOD1(Concrete, int(const char* str)); -}; -``` - -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). - -The trick is to leave a back door in your mock class for accessing the -real methods in the base class: - -``` -class MockFoo : public Foo { - public: - // Mocking a pure method. - MOCK_METHOD1(Pure, void(int n)); - // Mocking a concrete method. Foo::Concrete() is shadowed. - MOCK_METHOD1(Concrete, int(const char* str)); - - // Use this to call Concrete() defined in Foo. - int FooConcrete(const char* str) { return Foo::Concrete(str); } -}; -``` - -Now, you can call `Foo::Concrete()` inside an action by: - -``` -using ::testing::_; -using ::testing::Invoke; -... - EXPECT_CALL(foo, Concrete(_)) - .WillOnce(Invoke(&foo, &MockFoo::FooConcrete)); -``` - -or tell the mock object that you don't want to mock `Concrete()`: - -``` -using ::testing::Invoke; -... - ON_CALL(foo, Concrete(_)) - .WillByDefault(Invoke(&foo, &MockFoo::FooConcrete)); -``` - -(Why don't we just write `Invoke(&foo, &Foo::Concrete)`? 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: - -``` -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: - -``` -using ::testing::Ge; -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: - -``` -using ::testing::_; -using ::testing::NotNull; -... - EXPECT_CALL(foo, DoThat(_, NotNull())); -``` - -## Combining Matchers ## - -You can build complex matchers from existing ones using `AllOf()`, -`AnyOf()`, and `Not()`: - -``` -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)); -``` - -## Casting Matchers ## - -Google Mock 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` before giving it to the -matcher. - -To support this need, Google Mock gives you the -`SafeMatcherCast<T>(m)` function. It casts a matcher `m` to type -`Matcher<T>`. To ensure safety, Google Mock checks that (let `U` be the -type `m` accepts): - - 1. Type `T` can be implicitly cast to type `U`; - 1. 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 - 1. 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 aren't met. - -Here's one example: - -``` -using ::testing::SafeMatcherCast; - -// A base class and a child class. -class Base { ... }; -class Derived : public Base { ... }; - -class MockFoo : public Foo { - public: - MOCK_METHOD1(DoThis, void(Derived* derived)); -}; -... - - 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 ## - -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. - -``` -using ::testing::ReturnRef; - -class MockFoo : public Foo { - ... - MOCK_METHOD0(GetBar, Bar&()); - MOCK_CONST_METHOD0(GetBar, const Bar&()); -}; -... - - 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 Google Mock 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): - -``` -using ::testing::An; -using ::testing::Lt; -using ::testing::Matcher; -using ::testing::TypedEq; - -class MockPrinter : public Printer { - public: - MOCK_METHOD1(Print, void(int n)); - MOCK_METHOD1(Print, void(char c)); -}; - -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: - -``` -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, - -``` -using ::testing::_; -using ::testing::Lt; -using ::testing::Ne; -... - 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< ::testing::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, - -``` -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`. - -As a convenience and example, Google Mock provides some matchers for -2-tuples, including the `Lt()` matcher above. See the [CheatSheet](CheatSheet.md) 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 `::testing::tuple` as its argument; Google Mock 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 Google Mock matchers are 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, - -``` -#include <algorithm> -#include <vector> - -std::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 -Google Mock, 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: - -``` -Matches(AllOf(Ge(0), Le(100), Ne(50))) -``` - -## Using Matchers in Google Test Assertions ## - -Since matchers are basically predicates that also know how to describe -themselves, there is a way to take advantage of them in -[Google Test](../../googletest/) assertions. It's -called `ASSERT_THAT` and `EXPECT_THAT`: - -``` - ASSERT_THAT(value, matcher); // Asserts that value matches matcher. - EXPECT_THAT(value, matcher); // The non-fatal version. -``` - -For example, in a Google Test test you can write: - -``` -#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: - -``` -Value of: Foo() - Actual: "Hi, world!" -Expected: starts with "Hello" -``` - -**Credit:** The idea of `(ASSERT|EXPECT)_THAT` was stolen from the -[Hamcrest](https://github.com/hamcrest/) project, which adds -`assertThat()` to JUnit. - -## Using Predicates as Matchers ## - -Google Mock provides a built-in set of matchers. In case you find them -lacking, you can use an arbitray 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: - -``` -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 statement `if (condition) ...`. - -## Matching Arguments that Are Not Copyable ## - -When you do an `EXPECT_CALL(mock_obj, Foo(bar))`, Google Mock saves -away a copy of `bar`. When `Foo()` is called later, Google Mock -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 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 Google Mock that it should -save a reference to `bar`, instead of a copy of it. Here's how: - -``` -using ::testing::Eq; -using ::testing::ByRef; -using ::testing::Lt; -... - // Expects that Foo()'s argument == bar. - EXPECT_CALL(mock_obj, Foo(Eq(ByRef(bar)))); - - // Expects that Foo()'s argument < bar. - EXPECT_CALL(mock_obj, Foo(Lt(ByRef(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, - -``` -Field(&Foo::bar, m) -``` - -is a matcher that matches a `Foo` object whose `bar` member variable -satisfies matcher `m`. - -``` -Property(&Foo::baz, m) -``` - -is a matcher that matches a `Foo` object whose `baz()` method returns -a value that satisfies matcher `m`. - -For example: - -| 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 "`. | - -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, - -``` -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 is `AllOf()`. - -## 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 iff `m` matches the value the pointer -points to. For example: - -``` -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 - -``` - 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 (`linked_ptr`, `shared_ptr`, `scoped_ptr`, and -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. 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: - -``` -using ::testing::MatcherInterface; -using ::testing::MatchResultListener; - -class BarPlusBazEqMatcher : public MatcherInterface<const Foo&> { - public: - explicit BarPlusBazEqMatcher(int expected_sum) - : expected_sum_(expected_sum) {} - - virtual bool MatchAndExplain(const Foo& foo, - MatchResultListener* listener) const { - return (foo.bar() + foo.baz()) == expected_sum_; - } - - virtual void DescribeTo(::std::ostream* os) const { - *os << "bar() + baz() equals " << expected_sum_; - } - - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "bar() + baz() does not equal " << expected_sum_; - } - private: - const int expected_sum_; -}; - -inline 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: - -``` -using ::testing::_; -using ::testing::ElementsAre; -using ::testing::Gt; -... - - MOCK_METHOD1(Foo, void(const vector<int>& numbers)); -... - - 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: - -``` -using ::testing::_; -using ::testing::Gt; -using ::testing::UnorderedElementsAre; -... - - MOCK_METHOD1(Foo, void(const vector<int>& numbers)); -... - - 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. - -`ElementsAre()` and `UnorderedElementsAre()` are overloaded to take 0 -to 10 arguments. If more are needed, you can place them in a C-style -array and use `ElementsAreArray()` or `UnorderedElementsAreArray()` -instead: - -``` -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: - -``` -using ::testing::ElementsAreArray; -... - int* const expected_vector3 = new int[count]; - ... fill expected_vector3 with values ... - EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector3, count))); -``` - -**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*()`. Therefore don't use it with containers whose element order is undefined (e.g. `hash_map`). - -## Sharing Matchers ## - -Under the hood, a Google Mock 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 every time. Just assign it to a -matcher variable and use that variable repeatedly! For example, - -``` - Matcher<int> in_range = AllOf(Gt(5), Le(10)); - ... use in_range as a matcher in multiple EXPECT_CALLs ... -``` - -# Setting Expectations # - -## Knowing When to Expect ## - -`ON_CALL` is likely the single most under-utilized construct in Google Mock. - -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 _doesn't imply any expectation on the method being called._ `EXPECT_CALL` not only defines the behavior, but also sets an expectation that _the method will be called with the given arguments, for the given number of times_ (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, -Google Mock will perform its default action to allow the test program -to continue. If you are not happy with the default action taken by -Google Mock, you can override it using `DefaultValue<T>::Set()` -(described later in this document) 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: - -``` -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: - -``` -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_ calls and _unexpected_ calls are different concepts in Google Mock. _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. (Google Mock'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 Google Mock, `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: - -``` -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 Google Mock that `GetDomainOwner()` can be called with some other arguments as well? The standard technique is to add a "catch all" `EXPECT_CALL`: - -``` - 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_CALLs` 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"](#the-nice-the-strict-and-the-naggy). - -## Expecting Ordered Calls ## - -Although an `EXPECT_CALL()` statement defined earlier takes precedence -when Google Mock 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 third `EXPECT_CALL()`, but not those in the first two, -then the third 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`: - -``` - 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, Google Mock will report an error. - -## Expecting Partially Ordered Calls ## - -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. - -Google Mock allows you to impose an arbitrary DAG (directed acyclic -graph) on the calls. One way to express the DAG is to use the -[After](CheatSheet.md#the-after-clause) 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, - -``` - 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`): - -``` - +---> 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, Google Mock only consider 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 - -``` - 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, - -``` -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: - -``` -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: - -``` -using ::testing::ReturnRef; - -class MockFoo : public Foo { - public: - MOCK_METHOD0(GetBar, Bar&()); -}; -... - - 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_.). - -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, Google Mock 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? - -You may be tempted to try `ByRef()`: - -``` -using testing::ByRef; -using testing::Return; - -class MockFoo : public Foo { - public: - MOCK_METHOD0(GetValue, int()); -}; -... - int x = 0; - MockFoo foo; - EXPECT_CALL(foo, GetValue()) - .WillRepeatedly(Return(ByRef(x))); - x = 42; - EXPECT_EQ(42, foo.GetValue()); -``` - -Unfortunately, it doesn't work here. The above code will fail with error: - -``` -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, `ByRef(x)` is converted to an -`int` value (instead of a `const int&`) when the expectation is set, -and `Return(ByRef(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_: - -``` -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. - -``` -using ::testing::DoAll; - -class MockFoo : public Foo { - public: - MOCK_METHOD1(Bar, bool(int n)); -}; -... - - EXPECT_CALL(foo, Bar(_)) - .WillOnce(DoAll(action_1, - action_2, - ... - action_n)); -``` - -## Mocking Side Effects ## - -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: - -``` -using ::testing::SetArgPointee; - -class MockMutator : public Mutator { - public: - MOCK_METHOD2(Mutate, void(bool mutate, int* value)); - ... -}; -... - - 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()`: - -``` -using ::testing::_; -using ::testing::Return; -using ::testing::SetArgPointee; - -class MockMutator : public Mutator { - public: - ... - MOCK_METHOD1(MutateInt, bool(int* value)); -}; -... - - MockMutator mutator; - EXPECT_CALL(mutator, MutateInt(_)) - .WillOnce(DoAll(SetArgPointee<0>(5), - Return(true))); -``` - -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: - -``` -using ::testing::NotNull; -using ::testing::SetArrayArgument; - -class MockArrayMutator : public ArrayMutator { - public: - MOCK_METHOD2(Mutate, void(int* values, int num_values)); - ... -}; -... - - 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: - -``` -using ::testing::_; -using ::testing::SetArrayArgument; - -class MockRolodex : public Rolodex { - public: - MOCK_METHOD1(GetNames, void(std::back_insert_iterator<vector<string> >)); - ... -}; -... - - 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: - -``` -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: - -``` -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 ## - -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 Google Mock doesn't know -about. You can do this using the `::testing::DefaultValue` class -template: - -``` -class MockFoo : public Foo { - public: - MOCK_METHOD0(CalculateBar, Bar()); -}; -... - - 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 you -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: - -``` -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 news 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. - -## Using Functions/Methods/Functors as Actions ## - -If the built-in actions don't suit you, you can easily use an existing -function, method, or functor as an action: - -``` -using ::testing::_; -using ::testing::Invoke; - -class MockFoo : public Foo { - public: - MOCK_METHOD2(Sum, int(int x, int y)); - MOCK_METHOD1(ComplexJob, bool(int x)); -}; - -int CalculateSum(int x, int y) { return x + y; } - -class Helper { - public: - bool ComplexJob(int x); -}; -... - - MockFoo foo; - Helper helper; - EXPECT_CALL(foo, Sum(_, _)) - .WillOnce(Invoke(CalculateSum)); - EXPECT_CALL(foo, ComplexJob(_)) - .WillOnce(Invoke(&helper, &Helper::ComplexJob)); - - foo.Sum(5, 6); // Invokes CalculateSum(5, 6). - foo.ComplexJob(10); // Invokes helper.ComplexJob(10); -``` - -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 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? - -## Invoking a Function/Method/Functor Without Arguments ## - -`Invoke()` is very useful for doing actions that are more complex. It -passes the mock function's arguments to the function or functor 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. `Invoke()` allows her to -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. - -`InvokeWithoutArgs()` solves this problem. It's like `Invoke()` except -that it doesn't pass the mock function's arguments to the -callee. Here's an example: - -``` -using ::testing::_; -using ::testing::InvokeWithoutArgs; - -class MockFoo : public Foo { - public: - MOCK_METHOD1(ComplexJob, bool(int n)); -}; - -bool Job1() { ... } -... - - MockFoo foo; - EXPECT_CALL(foo, ComplexJob(_)) - .WillOnce(InvokeWithoutArgs(Job1)); - - foo.ComplexJob(10); // Invokes Job1(). -``` - -## Invoking an Argument of the Mock Function ## - -Sometimes a mock function will receive a function pointer or a functor -(in other words, a "callable") as an argument, e.g. - -``` -class MockFoo : public Foo { - public: - MOCK_METHOD2(DoThis, bool(int n, bool (*fp)(int))); -}; -``` - -and you may want to invoke this callable argument: - -``` -using ::testing::_; -... - MockFoo foo; - EXPECT_CALL(foo, DoThis(_, _)) - .WillOnce(...); - // Will execute (*fp)(5), where fp is the - // second argument DoThis() receives. -``` - -Arghh, you need to refer to a mock function argument but your version -of C++ has no lambdas, so you have to define your own action. :-( -Or do you really? - -Well, Google Mock has an action to solve _exactly_ this problem: - -``` - 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 or a functor, Google Mock handles them both. - -With that, you could write: - -``` -using ::testing::_; -using ::testing::InvokeArgument; -... - EXPECT_CALL(foo, DoThis(_, _)) - .WillOnce(InvokeArgument<1>(5)); - // Will execute (*fp)(5), where fp is the - // second argument DoThis() receives. -``` - -What if the callable takes an argument by reference? No problem - just -wrap it inside `ByRef()`: - -``` -... - MOCK_METHOD1(Bar, bool(bool (*fp)(int, const Helper&))); -... -using ::testing::_; -using ::testing::ByRef; -using ::testing::InvokeArgument; -... - - MockFoo foo; - Helper helper; - ... - EXPECT_CALL(foo, Bar(_)) - .WillOnce(InvokeArgument<0>(5, ByRef(helper))); - // ByRef(helper) guarantees that a reference to helper, not a copy of it, - // will be passed to the callable. -``` - -What if the callable takes an argument by reference and we do **not** -wrap the argument in `ByRef()`? 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: - -``` -... - MOCK_METHOD1(DoThat, bool(bool (*f)(const double& x, const string& s))); -... -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: - -``` -using ::testing::_; -using ::testing::Invoke; -using ::testing::Return; - -int Process(const MyData& data); -string DoSomething(); - -class MockFoo : public Foo { - public: - MOCK_METHOD1(Abc, void(const MyData& data)); - MOCK_METHOD0(Xyz, bool()); -}; -... - - 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(Invoke(Process))); - - EXPECT_CALL(foo, Xyz()) - .WillOnce(DoAll(IgnoreResult(Invoke(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 ## - -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: - -``` -using ::testing::_; -using ::testing::Invoke; -... - MOCK_METHOD7(Foo, bool(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 can to define an "adaptor" that has -the same signature as `Foo()` and calls the custom action with the -right arguments: - -``` -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? - -Google Mock provides a generic _action adaptor_, so you can spend your -time minding more important business than writing your own -adaptors. Here's the syntax: - -``` - 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: - -``` -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, Google Mock 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 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, method, or functor 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 - -``` - MOCK_METHOD3(Foo, double(const string& label, double x, double y)); - MOCK_METHOD3(Bar, double(int index, double x, double y)); -``` - -instead of - -``` -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); -} -... - - EXEPCT_CALL(mock, Foo("abc", _, _)) - .WillOnce(Invoke(DistanceToOriginWithLabel)); - EXEPCT_CALL(mock, Bar(5, _, _)) - .WillOnce(Invoke(DistanceToOriginWithIndex)); -``` - -you could write - -``` -using ::testing::_; -using ::testing::Invoke; -using ::testing::Unused; - -double DistanceToOrigin(Unused, double x, double y) { - return sqrt(x*x + y*y); -} -... - - EXEPCT_CALL(mock, Foo("abc", _, _)) - .WillOnce(Invoke(DistanceToOrigin)); - EXEPCT_CALL(mock, Bar(5, _, _)) - .WillOnce(Invoke(DistanceToOrigin)); -``` - -## Sharing Actions ## - -Just like matchers, a Google Mock 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 every time. 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: - -``` - 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 -exihibit different behaviors. Example: - -``` - 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 - -``` - 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. -``` - -# Misc Recipes on Using Google Mock # - -## 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_METHOD1(MakeBuzz, std::unique_ptr<Buzz>(StringPiece text)); - MOCK_METHOD2(ShareBuzz, bool(std::unique_ptr<Buzz> buzz, int64_t timestamp)); -}; -``` - -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 -`.WillRepeated()` 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_METHOD2(DoShareBuzz, bool(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 `.cpp` 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: - -``` -// 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_METHOD0(DoThis, int()); - MOCK_METHOD1(DoThat, bool(const char* str)); - ... more mock methods ... -}; -``` - -After the change, it would look like: - -``` -// File mock_foo.h. -... -class MockFoo : public Foo { - public: - // The constructor and destructor are declared, but not defined, here. - MockFoo(); - virtual ~MockFoo(); - - MOCK_METHOD0(DoThis, int()); - MOCK_METHOD1(DoThat, bool(const char* str)); - ... more mock methods ... -}; -``` -and -``` -// File mock_foo.cpp. -#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 [Google Test](../../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 may not be 100% reliable. So, sometimes you do want -to _force_ Google Mock to verify a mock object before it is -(hopefully) destructed. You can do this with -`Mock::VerifyAndClearExpectations(&mock_object)`: - -``` -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 ## - -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: - -``` -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: - -``` -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 -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_METHOD0` macro doesn't work for it: - -``` - MOCK_METHOD0(~MockFoo, void()); // 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: - -``` -class MockFoo : public Foo { - ... - // Add the following two lines to the mock class. - MOCK_METHOD0(Die, void()); - virtual ~MockFoo() { 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: - -``` - 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 Google Mock and Threads ## - -**IMPORTANT NOTE:** What we describe in this recipe is **ONLY** true on -platforms where Google Mock is thread-safe. Currently these are only -platforms that support the pthreads library (this includes Linux and Mac). -To make it thread-safe on other platforms we only need to implement -some synchronization operations in `"gtest/internal/gtest-port.h"`. - -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 many programs are multi-threaded, and sometimes to test something -we need to pound on it from more than one thread. Google Mock works -for this purpose too. - -Remember the steps for using a mock: - - 1. Create a mock object `foo`. - 1. Set its default actions and expectations using `ON_CALL()` and `EXPECT_CALL()`. - 1. The code under test calls methods of `foo`. - 1. Optionally, verify and reset the mock. - 1. 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. Google Mock 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. - -Google Mock guarantees that the action for a mock function is done in -the same thread that called the mock function. For example, in - -``` - 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, -Google Mock will execute `action1` in thread 1 and `action2` in thread -2. - -Google Mock 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 Google Mock Prints ## - -When Google Mock 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 and the return value. 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 and the return value). Clearly, one size doesn't fit -all. - -You can control how much Google Mock tells you using the -`--gmock_verbose=LEVEL` command-line flag, where `LEVEL` is a string -with three possible values: - - * `info`: Google Mock will print all informational messages, warnings, and errors (most verbose). At this setting, Google Mock will also log any calls to the `ON_CALL/EXPECT_CALL` macros. - * `warning`: Google Mock will print both warnings and errors (less verbose). This is the default. - * `error`: Google Mock will print errors only (least verbose). - -Alternatively, you can adjust the value of that flag from within your -tests like so: - -``` - ::testing::FLAGS_gmock_verbose = "error"; -``` - -Now, judiciously use the right flag to enable Google Mock serve you better! - -## Gaining Super Vision into Mock Calls ## - -You have a test using Google Mock. It fails: Google Mock tells you -that 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` Google Mock thinks it matches? - -You can unlock this power by running your test with the -`--gmock_verbose=info` flag. For example, given the test program: - -``` -using testing::_; -using testing::HasSubstr; -using testing::Return; - -class MockFoo { - public: - MOCK_METHOD2(F, void(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: - -``` -[ RUN ] Foo.Bar - -foo_test.cc:14: EXPECT_CALL(mock, F(_, _)) invoked -foo_test.cc:15: EXPECT_CALL(mock, F("a", "b")) invoked -foo_test.cc:16: EXPECT_CALL(mock, F("c", HasSubstr("d"))) invoked -foo_test.cc:14: Mock function call matches EXPECT_CALL(mock, F(_, _))... - Function call: F(@0x7fff7c8dad40"a", @0x7fff7c8dad10"good") -foo_test.cc:15: Mock function call matches EXPECT_CALL(mock, F("a", "b"))... - Function call: F(@0x7fff7c8dada0"a", @0x7fff7c8dad70"b") -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. - -## Running Tests in Emacs ## - -If you build and run your tests in Emacs, the source file locations of -Google Mock and [Google Test](../../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: - -``` -(global-set-key "\M-m" '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, or `M-up`/`M-down` to move -back and forth between errors. - -## Fusing Google Mock Source Files ## - -Google Mock's implementation consists of dozens of files (excluding -its own tests). Sometimes you may want them to be packaged up in -fewer files instead, such that you can easily copy them to a new -machine and start hacking there. For this we provide an experimental -Python script `fuse_gmock_files.py` in the `scripts/` directory -(starting with release 1.2.0). Assuming you have Python 2.4 or above -installed on your machine, just go to that directory and run -``` -python fuse_gmock_files.py OUTPUT_DIR -``` - -and you should see an `OUTPUT_DIR` directory being created with files -`gtest/gtest.h`, `gmock/gmock.h`, and `gmock-gtest-all.cc` in it. -These three files contain everything you need to use Google Mock (and -Google Test). Just copy them to anywhere you want and you are ready -to write tests and use mocks. You can use the -[scrpts/test/Makefile](../scripts/test/Makefile) file as an example on how to compile your tests -against them. - -# Extending Google Mock # - -## Writing New Matchers Quickly ## - -The `MATCHER*` family of macros can be used to define custom matchers -easily. The syntax: - -``` -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 Google Mock will use the sequence of words in the -matcher name as the description. - -For example: -``` -MATCHER(IsDivisibleBy7, "") { return (arg % 7) == 0; } -``` -allows you to write -``` - // Expects mock_foo.Bar(n) to be called where n is divisible by 7. - EXPECT_CALL(mock_foo, Bar(IsDivisibleBy7())); -``` -or, -``` -using ::testing::Not; -... - EXPECT_THAT(some_expression, IsDivisibleBy7()); - EXPECT_THAT(some_other_expression, Not(IsDivisibleBy7())); -``` -If the above assertions fail, they will print something like: -``` - 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: -``` -MATCHER(IsDivisibleBy7, std::string(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: -``` -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: -``` - 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 -Google Mock already prints it for you. - -**Notes:** - - 1. 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. - 1. Google Mock doesn't guarantee when or how many times a matcher will be invoked. Therefore the matcher logic 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). This requirement must be satisfied no matter how you define the matcher (e.g. using one of the methods described in the following recipes). In particular, a matcher can never call a mock function, as that will affect the state of the mock object and Google Mock. - -## Writing New Parameterized Matchers Quickly ## - -Sometimes you'll want to define a matcher that has parameters. For that you -can use the macro: -``` -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: -``` -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`. - -Google Mock also provides `MATCHER_P2`, `MATCHER_P3`, ..., up to -`MATCHER_P10` to support multi-parameter matchers: -``` -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. Google Mock lets you do that by -referencing the matcher parameters in the description string -expression. - -For example, -``` - using ::testing::PrintToString; - MATCHER_P2(InClosedRange, low, hi, - std::string(negation ? "isn't" : "is") + " in range [" + - PrintToString(low) + ", " + PrintToString(hi) + "]") { - return low <= arg && arg <= hi; - } - ... - EXPECT_THAT(3, InClosedRange(4, 6)); -``` -would generate a failure that contains the message: -``` - 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, -``` - MATCHER_P2(InClosedRange, low, hi, "") { ... } - ... - EXPECT_THAT(3, InClosedRange(4, 6)); -``` -would generate a failure that contains the text: -``` - Expected: in closed range (4, 6) -``` - -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. 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: -``` -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: - -``` -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 iff 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: -``` -using ::testing::MakeMatcher; -using ::testing::Matcher; -using ::testing::MatcherInterface; -using ::testing::MatchResultListener; - -class DivisibleBy7Matcher : public MatcherInterface<int> { - public: - virtual bool MatchAndExplain(int n, MatchResultListener* listener) const { - return (n % 7) == 0; - } - - virtual void DescribeTo(::std::ostream* os) const { - *os << "is divisible by 7"; - } - - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "is not divisible by 7"; - } -}; - -inline 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()`: - -``` -class DivisibleBy7Matcher : public MatcherInterface<int> { - public: - virtual bool MatchAndExplain(int n, - MatchResultListener* listener) const { - const int remainder = n % 7; - if (remainder != 0) { - *listener << "the remainder is " << remainder; - } - return remainder == 0; - } - ... -}; -``` - -Then, `EXPECT_THAT(x, DivisibleBy7());` may general a message like this: -``` -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 `"gmock/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: - -``` -using ::testing::MakePolymorphicMatcher; -using ::testing::MatchResultListener; -using ::testing::NotNull; -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. -inline 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 Google Mock 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 of cardinalities doesn't suit you, you are free to -define your own by implementing the following interface (in namespace -`testing`): - -``` -class CardinalityInterface { - public: - virtual ~CardinalityInterface(); - - // Returns true iff call_count calls will satisfy this cardinality. - virtual bool IsSatisfiedByCallCount(int call_count) const = 0; - - // Returns true iff 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 - -``` -using ::testing::Cardinality; -using ::testing::CardinalityInterface; -using ::testing::MakeCardinality; - -class EvenNumberCardinality : public CardinalityInterface { - public: - virtual bool IsSatisfiedByCallCount(int call_count) const { - return (call_count % 2) == 0; - } - - virtual bool IsSaturatedByCallCount(int call_count) const { - return false; - } - - virtual 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 ## - -If the built-in actions don't work for you, and you find it -inconvenient to use `Invoke()`, you can use a macro from the `ACTION*` -family to quickly define a new action that can be used in your code as -if it's a built-in action. - -By writing -``` -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: -``` -ACTION(IncrementArg1) { return ++(*arg1); } -``` -allows you to write -``` -... 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: -``` -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: -``` -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 `::testing::tuple<bool, int*>` | -| `return_type` | the type `int` | -| `function_type` | the type `int(bool, int*)` | - -## Writing New Parameterized Actions Quickly ## - -Sometimes you'll want to parameterize an action you define. For that -we have another macro -``` -ACTION_P(name, param) { statements; } -``` - -For example, -``` -ACTION_P(Add, n) { return arg0 + n; } -``` -will allow you to write -``` -// 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 -Google-Mock-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`. - -Google Mock also provides `ACTION_P2`, `ACTION_P3`, and etc to support -multi-parameter actions. For example, -``` -ACTION_P2(ReturnDistanceTo, x, y) { - double dx = arg0 - x; - double dy = arg1 - y; - return sqrt(dx*dx + dy*dy); -} -``` -lets you write -``` -... 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: -``` -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: -``` -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 Google Test -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: -``` -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 between 1 and 10, and _n_ is -between 0 and 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: -``` -// 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(::testing::get<k>(args)); -} -``` - -To create an instance of an action template, write: -``` - 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: -``` -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: -``` - 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 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, HAS_m_TEMPLATE_PARAMS(...), AND_0_VALUE_PARAMS())` | `Foo<t1, ..., t_m>()` | `FooAction<t1, ..., t_m>` | -| `ACTION_P(Bar, param)` | `Bar(int_value)` | `BarActionP<int>` | -| `ACTION_TEMPLATE(Bar, HAS_m_TEMPLATE_PARAMS(...), AND_1_VALUE_PARAMS(p1))` | `Bar<t1, ..., t_m>(int_value)` | `FooActionP<t1, ..., t_m, int>` | -| `ACTION_P2(Baz, p1, p2)` | `Baz(bool_value, int_value)` | `BazActionP2<bool, int>` | -| `ACTION_TEMPLATE(Baz, HAS_m_TEMPLATE_PARAMS(...), AND_2_VALUE_PARAMS(p1, p2))`| `Baz<t1, ..., t_m>(bool_value, int_value)` | `FooActionP2<t1, ..., t_m, bool, int>` | -| ... | ... | ... | - -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 ## - -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: - -``` -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 ::testing::tuple<bool, const string&>. - virtual Result Perform(const ArgumentTuple& args) = 0; -}; - -using ::testing::_; -using ::testing::Action; -using ::testing::ActionInterface; -using ::testing::MakeAction; - -typedef int IncrementMethod(int*); - -class IncrementArgumentAction : public ActionInterface<IncrementMethod> { - public: - virtual int Perform(const ::testing::tuple<int*>& args) { - int* p = ::testing::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 ## - -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: - -``` -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: - -``` -class ReturnSecondArgumentAction { - public: - template <typename Result, typename ArgumentTuple> - Result Perform(const ArgumentTuple& args) const { - // To get the i-th (0-based) argument, use ::testing::get<i>(args). - return ::testing::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: - -``` -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: - -``` -using ::testing::_; - -class MockFoo : public Foo { - public: - MOCK_METHOD2(DoThis, int(bool flag, int n)); - MOCK_METHOD3(DoThat, string(int x, const char* str1, const char* str2)); -}; -... - - 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 Google Mock How to Print Your Values ## - -When an uninteresting or unexpected call occurs, Google Mock 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. Google Mock and Google Test do this using -Google Test'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. -[Google Test's advanced guide](../../googletest/docs/advanced.md#teaching-google-test-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. diff --git a/contrib/googletest/googlemock/docs/DesignDoc.md b/contrib/googletest/googlemock/docs/DesignDoc.md deleted file mode 100644 index 3f515c3b6dd6..000000000000 --- a/contrib/googletest/googlemock/docs/DesignDoc.md +++ /dev/null @@ -1,280 +0,0 @@ -This page discusses the design of new Google Mock features. - - - -# Macros for Defining Actions # - -## Problem ## - -Due to the lack of closures in C++, it currently requires some -non-trivial effort to define a custom action in Google Mock. For -example, suppose you want to "increment the value pointed to by the -second argument of the mock function and return it", you could write: - -``` -int IncrementArg1(Unused, int* p, Unused) { - return ++(*p); -} - -... WillOnce(Invoke(IncrementArg1)); -``` - -There are several things unsatisfactory about this approach: - - * Even though the action only cares about the second argument of the mock function, its definition needs to list other arguments as dummies. This is tedious. - * The defined action is usable only in mock functions that takes exactly 3 arguments - an unnecessary restriction. - * To use the action, one has to say `Invoke(IncrementArg1)`, which isn't as nice as `IncrementArg1()`. - -The latter two problems can be overcome using `MakePolymorphicAction()`, -but it requires much more boilerplate code: - -``` -class IncrementArg1Action { - public: - template <typename Result, typename ArgumentTuple> - Result Perform(const ArgumentTuple& args) const { - return ++(*tr1::get<1>(args)); - } -}; - -PolymorphicAction<IncrementArg1Action> IncrementArg1() { - return MakePolymorphicAction(IncrementArg1Action()); -} - -... WillOnce(IncrementArg1()); -``` - -Our goal is to allow defining custom actions with the least amount of -boiler-plate C++ requires. - -## Solution ## - -We propose to introduce a new macro: -``` -ACTION(name) { statements; } -``` - -Using this in a namespace scope will define an action with the given -name that executes the statements. Inside the statements, you can -refer to the K-th (0-based) argument of the mock function as `argK`. -For example: -``` -ACTION(IncrementArg1) { return ++(*arg1); } -``` -allows you to write -``` -... WillOnce(IncrementArg1()); -``` - -Note that you don't need to specify the types of the mock function -arguments, as brevity is a top design goal here. Rest assured that -your code is still 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: -``` -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: -``` -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::tr1::tuple<bool, int*>` | -| `return_type` | the type `int` | -| `function_type` | the type `int(bool, int*)` | - -## Parameterized actions ## - -Sometimes you'll want to parameterize the action. For that we propose -another macro -``` -ACTION_P(name, param) { statements; } -``` - -For example, -``` -ACTION_P(Add, n) { return arg0 + n; } -``` -will allow you to write -``` -// 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 -Google-Mock-defined symbol `param_type` to refer to the type of the -parameter as inferred by the compiler. - -We will also provide `ACTION_P2`, `ACTION_P3`, and etc to support -multi-parameter actions. For example, -``` -ACTION_P2(ReturnDistanceTo, x, y) { - double dx = arg0 - x; - double dy = arg1 - y; - return sqrt(dx*dx + dy*dy); -} -``` -lets you write -``` -... WillOnce(ReturnDistanceTo(5.0, 26.5)); -``` - -You can view `ACTION` as a degenerated parameterized action where the -number of parameters is 0. - -## Advanced Usages ## - -### Overloading Actions ### - -You can easily define actions overloaded on the number of parameters: -``` -ACTION_P(Plus, a) { ... } -ACTION_P2(Plus, a, b) { ... } -``` - -### Restricting the Type of an Argument or Parameter ### - -For maximum brevity and reusability, the `ACTION*` macros don't let -you specify 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: -``` -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 we plan to add to -Google Test (the name is chosen to match `static_assert` in C++0x). - -### 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_P(Bar, param)` | `Bar(int_value)` | `BarActionP<int>` | -| `ACTION_P2(Baz, p1, p2)` | `Baz(bool_value, int_value)` | `BazActionP2<bool, int>` | -| ... | ... | ... | - -Note that we have to pick different suffixes (`Action`, `ActionP`, -`ActionP2`, and etc) for actions with different numbers of parameters, -or the action definitions cannot be overloaded on the number of -parameters. - -## When to Use ## - -While the new macros are very convenient, please also consider other -means of implementing actions (e.g. via `ActionInterface` or -`MakePolymorphicAction()`), especially if you need to use the defined -action a lot. While the other 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 the number of -parameters. - -## Related Work ## - -As you may have realized, the `ACTION*` macros resemble closures (also -known as lambda expressions or anonymous functions). Indeed, both of -them seek to lower the syntactic overhead for defining a function. - -C++0x will support lambdas, but they are not part of C++ right now. -Some non-standard libraries (most notably BLL or Boost Lambda Library) -try to alleviate this problem. However, they are not a good choice -for defining actions as: - - * They are non-standard and not widely installed. Google Mock only depends on standard libraries and `tr1::tuple`, which is part of the new C++ standard and comes with gcc 4+. We want to keep it that way. - * They are not trivial to learn. - * They will become obsolete when C++0x's lambda feature is widely supported. We don't want to make our users use a dying library. - * Since they are based on operators, they are rather ad hoc: you cannot use statements, and you cannot pass the lambda arguments to a function, for example. - * They have subtle semantics that easily confuses new users. For example, in expression `_1++ + foo++`, `foo` will be incremented only once where the expression is evaluated, while `_1` will be incremented every time the unnamed function is invoked. This is far from intuitive. - -`ACTION*` avoid all these problems. - -## Future Improvements ## - -There may be a need for composing `ACTION*` definitions (i.e. invoking -another `ACTION` inside the definition of one `ACTION*`). We are not -sure we want it yet, as one can get a similar effect by putting -`ACTION` definitions in function templates and composing the function -templates. We'll revisit this based on user feedback. - -The reason we don't allow `ACTION*()` inside a function body is that -the current C++ standard doesn't allow function-local types to be used -to instantiate templates. The upcoming C++0x standard will lift this -restriction. Once this feature is widely supported by compilers, we -can revisit the implementation and add support for using `ACTION*()` -inside a function. - -C++0x will also support lambda expressions. When they become -available, we may want to support using lambdas as actions. - -# Macros for Defining Matchers # - -Once the macros for defining actions are implemented, we plan to do -the same for matchers: - -``` -MATCHER(name) { statements; } -``` - -where you can refer to the value being matched as `arg`. For example, -given: - -``` -MATCHER(IsPositive) { return arg > 0; } -``` - -you can use `IsPositive()` as a matcher that matches a value iff it is -greater than 0. - -We will also add `MATCHER_P`, `MATCHER_P2`, and etc for parameterized -matchers.
\ No newline at end of file diff --git a/contrib/googletest/googlemock/docs/Documentation.md b/contrib/googletest/googlemock/docs/Documentation.md deleted file mode 100644 index 16083e7047a8..000000000000 --- a/contrib/googletest/googlemock/docs/Documentation.md +++ /dev/null @@ -1,15 +0,0 @@ -This page lists all documentation markdown files for Google Mock **(the -current git version)** --- **if you use a former version of Google Mock, please read the -documentation for that specific version instead (e.g. by checking out -the respective git branch/tag).** - - * [ForDummies](ForDummies.md) -- start here if you are new to Google Mock. - * [CheatSheet](CheatSheet.md) -- a quick reference. - * [CookBook](CookBook.md) -- recipes for doing various tasks using Google Mock. - * [FrequentlyAskedQuestions](FrequentlyAskedQuestions.md) -- check here before asking a question on the mailing list. - -To contribute code to Google Mock, read: - - * [CONTRIBUTING](../CONTRIBUTING.md) -- read this _before_ writing your first patch. - * [Pump Manual](../../googletest/docs/PumpManual.md) -- how we generate some of Google Mock's source files. diff --git a/contrib/googletest/googlemock/docs/ForDummies.md b/contrib/googletest/googlemock/docs/ForDummies.md deleted file mode 100644 index 566a34e5b940..000000000000 --- a/contrib/googletest/googlemock/docs/ForDummies.md +++ /dev/null @@ -1,447 +0,0 @@ - - -(**Note:** If you get compiler errors that you don't understand, be sure to consult [Google Mock Doctor](FrequentlyAskedQuestions.md#how-am-i-supposed-to-make-sense-of-these-horrible-template-errors).) - -# What Is Google C++ Mocking Framework? # -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 will become much clearer once you start to use mocks. - -**Google C++ Mocking Framework** (or **Google Mock** for short) 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](http://www.jmock.org/) and [EasyMock](http://www.easymock.org/) do to Java. - -Using Google Mock involves three basic steps: - - 1. Use some simple macros to describe the interface you want to mock, and they will expand to the implementation of your mock class; - 1. Create some mock objects and specify its expectations and behavior using an intuitive syntax; - 1. Exercise code that uses the mock objects. Google Mock will catch any violation of the expectations as soon as it arises. - -# Why Google Mock? # -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 distances 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. - -In contrast, Java and Python programmers have some fine mock frameworks, 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. - -Google Mock was built to help C++ programmers. It was inspired by [jMock](http://www.jmock.org/) and [EasyMock](http://www.easymock.org/), 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, which is 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 Google Mock 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 # -Using Google Mock is easy! Inside your C++ source file, just `#include` `"gtest/gtest.h"` and `"gmock/gmock.h"`, and you are ready to go. - -# A Case for Mock Turtles # -Let's look at an example. Suppose you are developing a graphics program that relies on a LOGO-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 and know the right thing to do: instead of having your application talk to the drawing API directly, wrap the API in an interface (say, `Turtle`) and code to that interface: - -``` -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 - Google Mock 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: - - 1. Derive a class `MockTurtle` from `Turtle`. - 1. Take a _virtual_ function of `Turtle` (while it's possible to [mock non-virtual methods using templates](CookBook.md#mocking-nonvirtual-methods), it's much more involved). Count how many arguments it has. - 1. In the `public:` section of the child class, write `MOCK_METHODn();` (or `MOCK_CONST_METHODn();` if you are mocking a `const` method), where `n` is the number of the arguments; if you counted wrong, shame on you, and a compiler error will tell you so. - 1. Now comes the fun part: you take the function signature, cut-and-paste the _function name_ as the _first_ argument to the macro, and leave what's left as the _second_ argument (in case you're curious, this is the _type of the function_). - 1. Repeat until all virtual functions you want to mock are done. - -After the process, you should have something like: - -``` -#include "gmock/gmock.h" // Brings in Google Mock. -class MockTurtle : public Turtle { - public: - ... - MOCK_METHOD0(PenUp, void()); - MOCK_METHOD0(PenDown, void()); - MOCK_METHOD1(Forward, void(int distance)); - MOCK_METHOD1(Turn, void(int degrees)); - MOCK_METHOD2(GoTo, void(int x, int y)); - MOCK_CONST_METHOD0(GetX, int()); - MOCK_CONST_METHOD0(GetY, int()); -}; -``` - -You don't need to define these mock methods somewhere else - the `MOCK_METHOD*` macros will generate the definitions for you. It's that simple! Once you get the hang of it, you can pump out mock classes faster than your source-control system can handle your check-ins. - -**Tip:** If even this is too much work for you, you'll find the -`gmock_gen.py` tool in Google Mock's `scripts/generator/` directory (courtesy of the [cppclean](http://code.google.com/p/cppclean/) project) useful. This command-line -tool requires that you have Python 2.4 installed. You give it a C++ file and the name of an abstract class defined in it, -and it will print the definition of the mock class for you. Due to the -complexity of the C++ language, this script may not always work, but -it can be quite handy when it does. For more details, read the [user documentation](../scripts/generator/README). - -## 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), and put it in a `mock_foo.h`. Then everyone can reference `mock_foo.h` 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. - -# Using Mocks in Tests # -Once you have a mock class, using it is easy. The typical work flow is: - - 1. Import the Google Mock 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 and good for your health.). - 1. Create some mock objects. - 1. Specify your expectations on them (How many times will a method be called? With what arguments? What should it do? etc.). - 1. Exercise some code that uses the mocks; optionally, check the result using Google Test assertions. If a mock method is called more than expected or with wrong arguments, you'll get an error immediately. - 1. When a mock is destructed, Google Mock will automatically check whether all expectations on it have been satisfied. - -Here's an example: - -``` -#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 - -int main(int argc, char** argv) { - // The following line must be executed to initialize Google Mock - // (and Google Test) before running the tests. - ::testing::InitGoogleMock(&argc, argv); - return RUN_ALL_TESTS(); -} -``` - -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: - -``` -path/to/my_test.cc:119: Failure -Actual function call count doesn't match this expectation: -Actually: never called; -Expected: called at least once. -``` - -**Tip 1:** If you run the test from an Emacs buffer, you can hit `<Enter>` on the line number displayed in the error message 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 use a heap leak checker in your tests when you allocate mocks on the heap. - -**Important note:** Google Mock 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 Google Mock work like that? Well, specifying the expectation beforehand allows Google Mock to report a violation as soon as it arises, 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 Google Mock. However, as we shall reveal soon, Google Mock allows you to do _much more_ with the mocks. - -## Using Google Mock with Any Testing Framework ## -If you want to use something other than Google Test (e.g. [CppUnit](http://sourceforge.net/projects/cppunit/) or -[CxxTest](https://cxxtest.com/)) as your testing framework, just change the `main()` function in the previous section to: -``` -int main(int argc, char** argv) { - // The following line causes Google Mock to throw an exception on failure, - // which will be interpreted by your testing framework as a test failure. - ::testing::GTEST_FLAG(throw_on_failure) = true; - ::testing::InitGoogleMock(&argc, argv); - ... whatever your testing framework requires ... -} -``` - -This approach has a catch: it makes Google Mock throw an exception -from a mock object's destructor sometimes. With some compilers, this -sometimes causes the test program to crash. You'll still be able to -notice that the test has failed, but it's not a graceful failure. - -A better solution is to use Google Test's -[event listener API](../../googletest/docs/advanced.md#extending-google-test-by-handling-test-events) -to report a test failure to your testing framework properly. You'll need to -implement the `OnTestPartResult()` method of the event listener interface, but it -should be straightforward. - -If this turns out to be too much work, we suggest that you stick with -Google Test, which works with Google Mock seamlessly (in fact, it is -technically part of Google Mock.). If there is a reason that you -cannot use Google Test, please let us know. - -# 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. Google Mock provides the necessary means for you to do it "just right." - -## General Syntax ## -In Google Mock we use the `EXPECT_CALL()` macro to set an expectation on a mock method. The general syntax is: - -``` -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.) - -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 - -``` -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? It serves two purposes: first it makes expectations easily identifiable (either by `grep` or by a human reader), and second it allows Google Mock 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 must specify what arguments we are expecting; for example: - -``` -// Expects the turtle to move forward by 100 units. -EXPECT_CALL(turtle, Forward(100)); -``` - -Sometimes you may 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 care to check that `Forward()` will be called but aren't interested in its actual argument, write `_` as the argument, which means "anything goes": - -``` -using ::testing::_; -... -// Expects the turtle to move forward. -EXPECT_CALL(turtle, Forward(_)); -``` - -`_` 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. - -A list of built-in matchers can be found in the [CheatSheet](CheatSheet.md). For example, here's the `Ge` (greater than or equal) matcher: - -``` -using ::testing::Ge; -... -EXPECT_CALL(turtle, Forward(Ge(100))); -``` - -This checks that the turtle will be told to go forward by at least 100 units. - -## 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 Google Mock will report a Google Test 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 the [CheatSheet](CheatSheet.md). - -The `Times()` clause can be omitted. **If you omit `Times()`, Google Mock 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 Google Mock. - -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, - -``` -using ::testing::Return; -... -EXPECT_CALL(turtle, GetX()) - .WillOnce(Return(100)) - .WillOnce(Return(200)) - .WillOnce(Return(300)); -``` - -This says that `turtle.GetX()` will be called _exactly three times_ (Google Mock 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. - -``` -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_ (Google Mock knows this as we've written two `WillOnce()` clauses and a `WillRepeatedly()` while having no explicit `Times()`), will return 100 the first time, 200 the second time, and 300 from the third time on. - -Of course, if you explicitly write a `Times()`, Google Mock 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, Google Mock 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](CheatSheet.md#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: - -``` -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 [CookBook](CookBook.md). - -Time for another quiz! What do you think the following means? - -``` -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 ## -So far we've only shown examples where you have a single expectation. More realistically, you're going to specify expectations on multiple mock methods, which may be from multiple mock objects. - -By default, when a mock method is invoked, Google Mock 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: - -``` -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. - -**Side note:** Why does Google Mock 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. - -## Ordered vs Unordered Calls ## -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 Google Mock is easy: - -``` -using ::testing::InSequence; -... -TEST(FooTest, DrawsLineSegment) { - ... - { - InSequence dummy; - - 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! If you are impatient, the details can be found in the [CookBook](CookBook.md#expecting-partially-ordered-calls).) - -## All Expectations Are Sticky (Unless Said Otherwise) ## -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!): - -``` -using ::testing::_; -... -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, Google Mock 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, Google Mock will report an error immediately. This is basically what we've told you in the "Using Multiple Expectations" section above. - -This example shows that **expectations in Google Mock 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? - -``` -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 exceeded" 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: - -``` -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: - -``` -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 Google Mock, 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. - -# What Now? # -Congratulations! You've learned enough about Google Mock to start using it. Now, you might want to join the [googlemock](http://groups.google.com/group/googlemock) discussion group and actually write some tests using Google Mock - it will be fun. Hey, it may even be addictive - you've been warned. - -Then, if you feel like increasing your mock quotient, you should move on to the [CookBook](CookBook.md). You can learn many advanced features of Google Mock there -- and advance your level of enjoyment and testing bliss. diff --git a/contrib/googletest/googlemock/docs/FrequentlyAskedQuestions.md b/contrib/googletest/googlemock/docs/FrequentlyAskedQuestions.md deleted file mode 100644 index 9008c63718f9..000000000000 --- a/contrib/googletest/googlemock/docs/FrequentlyAskedQuestions.md +++ /dev/null @@ -1,627 +0,0 @@ - - -Please send your questions to the -[googlemock](http://groups.google.com/group/googlemock) discussion -group. If you need help with compiler errors, make sure you have -tried [Google Mock Doctor](#How_am_I_supposed_to_make_sense_of_these_horrible_template_error.md) first. - -## 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](CookBook.md#mocking-nonvirtual-methods). - -## I wrote some matchers. After I upgraded to a new version of Google Mock, they no longer compile. What's going on? ## - -After version 1.4.0 of Google Mock was released, we had an idea on how -to make it easier to write matchers that can generate informative -messages efficiently. We experimented with this idea and liked what -we saw. Therefore we decided to implement it. - -Unfortunately, this means that if you have defined your own matchers -by implementing `MatcherInterface` or using `MakePolymorphicMatcher()`, -your definitions will no longer compile. Matchers defined using the -`MATCHER*` family of macros are not affected. - -Sorry for the hassle if your matchers are affected. We believe it's -in everyone's long-term interest to make this change sooner than -later. Fortunately, it's usually not hard to migrate an existing -matcher to the new API. Here's what you need to do: - -If you wrote your matcher like this: -``` -// Old matcher definition that doesn't work with the latest -// Google Mock. -using ::testing::MatcherInterface; -... -class MyWonderfulMatcher : public MatcherInterface<MyType> { - public: - ... - virtual bool Matches(MyType value) const { - // Returns true if value matches. - return value.GetFoo() > 5; - } - ... -}; -``` - -you'll need to change it to: -``` -// New matcher definition that works with the latest Google Mock. -using ::testing::MatcherInterface; -using ::testing::MatchResultListener; -... -class MyWonderfulMatcher : public MatcherInterface<MyType> { - public: - ... - virtual bool MatchAndExplain(MyType value, - MatchResultListener* listener) const { - // Returns true if value matches. - return value.GetFoo() > 5; - } - ... -}; -``` -(i.e. rename `Matches()` to `MatchAndExplain()` and give it a second -argument of type `MatchResultListener*`.) - -If you were also using `ExplainMatchResultTo()` to improve the matcher -message: -``` -// Old matcher definition that doesn't work with the lastest -// Google Mock. -using ::testing::MatcherInterface; -... -class MyWonderfulMatcher : public MatcherInterface<MyType> { - public: - ... - virtual bool Matches(MyType value) const { - // Returns true if value matches. - return value.GetFoo() > 5; - } - - virtual void ExplainMatchResultTo(MyType value, - ::std::ostream* os) const { - // Prints some helpful information to os to help - // a user understand why value matches (or doesn't match). - *os << "the Foo property is " << value.GetFoo(); - } - ... -}; -``` - -you should move the logic of `ExplainMatchResultTo()` into -`MatchAndExplain()`, using the `MatchResultListener` argument where -the `::std::ostream` was used: -``` -// New matcher definition that works with the latest Google Mock. -using ::testing::MatcherInterface; -using ::testing::MatchResultListener; -... -class MyWonderfulMatcher : public MatcherInterface<MyType> { - public: - ... - virtual bool MatchAndExplain(MyType value, - MatchResultListener* listener) const { - // Returns true if value matches. - *listener << "the Foo property is " << value.GetFoo(); - return value.GetFoo() > 5; - } - ... -}; -``` - -If your matcher is defined using `MakePolymorphicMatcher()`: -``` -// Old matcher definition that doesn't work with the latest -// Google Mock. -using ::testing::MakePolymorphicMatcher; -... -class MyGreatMatcher { - public: - ... - bool Matches(MyType value) const { - // Returns true if value matches. - return value.GetBar() < 42; - } - ... -}; -... MakePolymorphicMatcher(MyGreatMatcher()) ... -``` - -you should rename the `Matches()` method to `MatchAndExplain()` and -add a `MatchResultListener*` argument (the same as what you need to do -for matchers defined by implementing `MatcherInterface`): -``` -// New matcher definition that works with the latest Google Mock. -using ::testing::MakePolymorphicMatcher; -using ::testing::MatchResultListener; -... -class MyGreatMatcher { - public: - ... - bool MatchAndExplain(MyType value, - MatchResultListener* listener) const { - // Returns true if value matches. - return value.GetBar() < 42; - } - ... -}; -... MakePolymorphicMatcher(MyGreatMatcher()) ... -``` - -If your polymorphic matcher uses `ExplainMatchResultTo()` for better -failure messages: -``` -// Old matcher definition that doesn't work with the latest -// Google Mock. -using ::testing::MakePolymorphicMatcher; -... -class MyGreatMatcher { - public: - ... - bool Matches(MyType value) const { - // Returns true if value matches. - return value.GetBar() < 42; - } - ... -}; -void ExplainMatchResultTo(const MyGreatMatcher& matcher, - MyType value, - ::std::ostream* os) { - // Prints some helpful information to os to help - // a user understand why value matches (or doesn't match). - *os << "the Bar property is " << value.GetBar(); -} -... MakePolymorphicMatcher(MyGreatMatcher()) ... -``` - -you'll need to move the logic inside `ExplainMatchResultTo()` to -`MatchAndExplain()`: -``` -// New matcher definition that works with the latest Google Mock. -using ::testing::MakePolymorphicMatcher; -using ::testing::MatchResultListener; -... -class MyGreatMatcher { - public: - ... - bool MatchAndExplain(MyType value, - MatchResultListener* listener) const { - // Returns true if value matches. - *listener << "the Bar property is " << value.GetBar(); - return value.GetBar() < 42; - } - ... -}; -... MakePolymorphicMatcher(MyGreatMatcher()) ... -``` - -For more information, you can read these -[two](CookBook.md#writing-new-monomorphic-matchers) -[recipes](CookBook.md#writing-new-polymorphic-matchers) -from the cookbook. As always, you -are welcome to post questions on `googlemock@googlegroups.com` if you -need any help. - -## When using Google Mock, do I have to use Google Test as the testing framework? I have my favorite testing framework and don't want to switch. ## - -Google Mock works out of the box with Google Test. However, it's easy -to configure it to work with any testing framework of your choice. -[Here](ForDummies.md#using-google-mock-with-any-testing-framework) is how. - -## How am I supposed to make sense of these horrible template errors? ## - -If you are confused by the compiler errors gcc threw at you, -try consulting the _Google Mock Doctor_ tool first. What it does is to -scan stdin for gcc error messages, and spit out diagnoses on the -problems (we call them diseases) your code has. - -To "install", run command: -``` -alias gmd='<path to googlemock>/scripts/gmock_doctor.py' -``` - -To use it, do: -``` -<your-favorite-build-command> <your-test> 2>&1 | gmd -``` - -For example: -``` -make my_test 2>&1 | gmd -``` - -Or you can run `gmd` and copy-n-paste gcc's error messages to it. - -## Can I mock a variadic function? ## - -You cannot mock a variadic function (i.e. a function taking ellipsis -(`...`) arguments) directly in Google Mock. - -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 their 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: -``` -class Foo { - ... - virtual void Bar(const int i) = 0; -}; - -class MockFoo : public Foo { - ... - MOCK_METHOD1(Bar, void(const int i)); -}; -``` -You may get the following warning: -``` -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: -``` -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: -``` -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: -``` -void Bar(int* p); // Neither p nor *p is const. -void Bar(const int* p); // p is not const, but *p is. -``` - -## 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. - -## I can't figure out why Google Mock thinks my expectations are not satisfied. What should I do? ## - -You might want to run your test with -`--gmock_verbose=info`. This flag lets Google Mock 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. - -## How can I assert that a function is NEVER called? ## - -``` -EXPECT_CALL(foo, Bar(_)) - .Times(0); -``` - -## I have a failed test where Google Mock tells me TWICE that a particular expectation is not satisfied. Isn't this redundant? ## - -When Google Mock 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, Google -Mock 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 heap check 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: - -``` -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 Google Mock do that? ## - -When people complain about this, often they are referring to code like: - -``` -// 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 Google Mock'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: - -``` -// 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: - -``` -// 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 Google Mock 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 Google Mock -searches from front to back, this very useful pattern won't be -possible. - -## Google Mock 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 - -``` -EXPECT_CALL(foo, Bar(_)) - .WillRepeatedly(...); -``` - -instead of - -``` -ON_CALL(foo, Bar(_)) - .WillByDefault(...); -``` - -This tells Google Mock that you do expect the calls and no warning should be -printed. - -Also, you can control the verbosity using the `--gmock_verbose` flag. -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 you find yourself needing to perform some action that's not -supported by Google Mock directly, remember that you can define your own -actions using -[MakeAction()](CookBook.md#writing-new-actions) or -[MakePolymorphicAction()](CookBook.md#writing_new_polymorphic_actions), -or you can write a stub function and invoke it using -[Invoke()](CookBook.md#using-functions_methods_functors). - -## MOCK\_METHODn()'s second argument looks funny. Why don't you use the MOCK\_METHODn(Method, return\_type, arg\_1, ..., arg\_n) syntax? ## - -What?! I think it's beautiful. :-) - -While which syntax looks more natural is a subjective matter to some -extent, Google Mock's syntax was chosen for several practical advantages it -has. - -Try to mock a function that takes a map as an argument: -``` -virtual int GetSize(const map<int, std::string>& m); -``` - -Using the proposed syntax, it would be: -``` -MOCK_METHOD1(GetSize, int, const map<int, std::string>& m); -``` - -Guess what? You'll get a compiler error as the compiler thinks that -`const map<int, std::string>& m` are **two**, not one, arguments. To work -around this you can use `typedef` to give the map type a name, but -that gets in the way of your work. Google Mock's syntax avoids this -problem as the function's argument types are protected inside a pair -of parentheses: -``` -// This compiles fine. -MOCK_METHOD1(GetSize, int(const map<int, std::string>& m)); -``` - -You still need a `typedef` if the return type contains an unprotected -comma, but that's much rarer. - -Other advantages include: - 1. `MOCK_METHOD1(Foo, int, bool)` can leave a reader wonder whether the method returns `int` or `bool`, while there won't be such confusion using Google Mock's syntax. - 1. The way Google Mock describes a function type is nothing new, although many people may not be familiar with it. The same syntax was used in C, and the `function` library in `tr1` uses this syntax extensively. Since `tr1` will become a part of the new version of STL, we feel very comfortable to be consistent with it. - 1. The function type syntax is also used in other parts of Google Mock's API (e.g. the action interface) in order to make the implementation tractable. A user needs to learn it anyway in order to utilize Google Mock's more advanced features. We'd as well stick to the same syntax in `MOCK_METHOD*`! - -## 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. Google Mock sucks! ## - -I know it's not a question, but you get an answer for free any way. :-) - -With Google Mock, 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 Google Mock'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, Google Mock 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, Google Mock prints the function name and arguments -when an uninteresting call is encountered. - -## I want to define a custom action. Should I use Invoke() or implement the action 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 `include/gmock/gmock-actions.h` for an example. - -## I'm using the set-argument-pointee action, and the compiler complains about "conflicting return type specified". What does it mean? ## - -You got this error as Google Mock 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()`. - -See this [recipe](CookBook.md#mocking_side_effects) for more details and an example. - - -## My question is not in your FAQ! ## - -If you cannot find the answer to your question in this FAQ, there are -some other resources you can use: - - 1. search the mailing list [archive](http://groups.google.com/group/googlemock/topics), - 1. ask it on [googlemock@googlegroups.com](mailto:googlemock@googlegroups.com) and someone will answer it (to prevent spam, we require you to join the [discussion group](http://groups.google.com/group/googlemock) before you can post.). - -Please note that creating an issue in the -[issue tracker](https://github.com/google/googletest/issues) is _not_ -a good way to get your answer, as it is monitored infrequently by a -very small number of people. - -When asking a question, it's helpful to provide as much of the -following information as possible (people cannot help you if there's -not enough information in your question): - - * the version (or the revision number if you check out from SVN directly) of Google Mock you use (Google Mock is under active development, so it's possible that your problem has been solved in a later version), - * your operating system, - * the name and version of your compiler, - * the complete command line flags you give to your compiler, - * the complete compiler error messages (if the question is about compilation), - * the _actual_ code (ideally, a minimal but complete program) that has the problem you encounter. diff --git a/contrib/googletest/googlemock/docs/KnownIssues.md b/contrib/googletest/googlemock/docs/KnownIssues.md deleted file mode 100644 index adadf5144b1b..000000000000 --- a/contrib/googletest/googlemock/docs/KnownIssues.md +++ /dev/null @@ -1,19 +0,0 @@ -As any non-trivial software system, Google Mock has some known limitations and problems. We are working on improving it, and welcome your help! The follow is a list of issues we know about. - - - -## README contains outdated information on Google Mock's compatibility with other testing frameworks ## - -The `README` file in release 1.1.0 still says that Google Mock only works with Google Test. Actually, you can configure Google Mock to work with any testing framework you choose. - -## Tests failing on machines using Power PC CPUs (e.g. some Macs) ## - -`gmock_output_test` and `gmock-printers_test` are known to fail with Power PC CPUs. This is due to portability issues with these tests, and is not an indication of problems in Google Mock itself. You can safely ignore them. - -## Failed to resolve libgtest.so.0 in tests when built against installed Google Test ## - -This only applies if you manually built and installed Google Test, and then built a Google Mock against it (either explicitly, or because gtest-config was in your path post-install). In this situation, Libtool has a known issue with certain systems' ldconfig setup: - -http://article.gmane.org/gmane.comp.sysutils.automake.general/9025 - -This requires a manual run of "sudo ldconfig" after the "sudo make install" for Google Test before any binaries which link against it can be executed. This isn't a bug in our install, but we should at least have documented it or hacked a work-around into our install. We should have one of these solutions in our next release.
\ No newline at end of file diff --git a/contrib/googletest/googlemock/docs/README.md b/contrib/googletest/googlemock/docs/README.md new file mode 100644 index 000000000000..1bc57b799cce --- /dev/null +++ b/contrib/googletest/googlemock/docs/README.md @@ -0,0 +1,4 @@ +# Content Moved + +We are working on updates to the GoogleTest documentation, which has moved to +the top-level [docs](../../docs) directory. diff --git a/contrib/googletest/googlemock/include/gmock/gmock-actions.h b/contrib/googletest/googlemock/include/gmock/gmock-actions.h index b82313d5b05c..bd9ba73ee634 100644 --- a/contrib/googletest/googlemock/include/gmock/gmock-actions.h +++ b/contrib/googletest/googlemock/include/gmock/gmock-actions.h @@ -27,30 +27,126 @@ // (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 actions. +// 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/main/docs/gmock_cook_book.md -// GOOGLETEST_CM0002 DO NOT DELETE +// IWYU pragma: private, include "gmock/gmock.h" +// IWYU pragma: friend gmock/.* -#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ #ifndef _WIN32_WCE -# include <errno.h> +#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" -#if GTEST_LANG_CXX11 // Defined by gtest-port.h via gmock-port.h. -#include <functional> -#include <type_traits> -#endif // GTEST_LANG_CXX11 +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100) namespace testing { @@ -65,9 +161,6 @@ namespace testing { namespace internal { -template <typename F1, typename F2> -class ActionAdaptor; - // BuiltInDefaultValueGetter<T, true>::Get() returns a // default-constructed T value. BuiltInDefaultValueGetter<T, // false>::Get() crashes with an error. @@ -98,28 +191,14 @@ struct BuiltInDefaultValueGetter<T, false> { template <typename T> class BuiltInDefaultValue { public: -#if GTEST_LANG_CXX11 - // This function returns true iff type T has a built-in default value. - static bool Exists() { - return ::std::is_default_constructible<T>::value; - } + // 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(); } - -#else // GTEST_LANG_CXX11 - // This function returns true iff type T has a built-in default value. - static bool Exists() { - return false; - } - - static T Get() { - return BuiltInDefaultValueGetter<T, false>::Get(); - } - -#endif // GTEST_LANG_CXX11 }; // This partial specialization says that we use the same built-in @@ -137,23 +216,20 @@ template <typename T> class BuiltInDefaultValue<T*> { public: static bool Exists() { return true; } - static T* Get() { return NULL; } + 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; } \ + template <> \ + class BuiltInDefaultValue<type> { \ + public: \ + static bool Exists() { return true; } \ + static type Get() { return value; } \ } GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(void, ); // NOLINT -#if GTEST_HAS_GLOBAL_STRING -GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(::string, ""); -#endif // GTEST_HAS_GLOBAL_STRING 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'); @@ -174,17 +250,309 @@ 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_(UInt64, 0); -GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(Int64, 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_ +// Partial implementations of metaprogramming types from the standard library +// not available in C++11. + +template <typename P> +struct negation + // NOLINTNEXTLINE + : std::integral_constant<bool, bool(!P::value)> {}; + +// Base case: with zero predicates the answer is always true. +template <typename...> +struct conjunction : std::true_type {}; + +// With a single predicate, the answer is that predicate. +template <typename P1> +struct conjunction<P1> : P1 {}; + +// With multiple predicates the answer is the first predicate if that is false, +// and we recurse otherwise. +template <typename P1, typename... Ps> +struct conjunction<P1, Ps...> + : std::conditional<bool(P1::value), conjunction<Ps...>, P1>::type {}; + +template <typename...> +struct disjunction : std::false_type {}; + +template <typename P1> +struct disjunction<P1> : P1 {}; + +template <typename P1, typename... Ps> +struct disjunction<P1, Ps...> + // NOLINTNEXTLINE + : std::conditional<!bool(P1::value), disjunction<Ps...>, P1>::type {}; + +template <typename...> +using void_t = void; + +// Detects whether an expression of type `From` can be implicitly converted to +// `To` according to [conv]. In C++17, [conv]/3 defines this as follows: +// +// An expression e can be implicitly converted to a type T if and only if +// the declaration T t=e; is well-formed, for some invented temporary +// variable t ([dcl.init]). +// +// [conv]/2 implies we can use function argument passing to detect whether this +// initialization is valid. +// +// Note that this is distinct from is_convertible, which requires this be valid: +// +// To test() { +// return declval<From>(); +// } +// +// In particular, is_convertible doesn't give the correct answer when `To` and +// `From` are the same non-moveable type since `declval<From>` will be an rvalue +// reference, defeating the guaranteed copy elision that would otherwise make +// this function work. +// +// REQUIRES: `From` is not cv void. +template <typename From, typename To> +struct is_implicitly_convertible { + private: + // A function that accepts a parameter of type T. This can be called with type + // U successfully only if U is implicitly convertible to T. + template <typename T> + static void Accept(T); + + // A function that creates a value of type T. + template <typename T> + static T Make(); + + // An overload be selected when implicit conversion from T to To is possible. + template <typename T, typename = decltype(Accept<To>(Make<T>()))> + static std::true_type TestImplicitConversion(int); + + // A fallback overload selected in all other cases. + template <typename T> + static std::false_type TestImplicitConversion(...); + + public: + using type = decltype(TestImplicitConversion<From>(0)); + static constexpr bool value = type::value; +}; + +// Like std::invoke_result_t from C++17, but works only for objects with call +// operators (not e.g. member function pointers, which we don't need specific +// support for in OnceAction because std::function deals with them). +template <typename F, typename... Args> +using call_result_t = decltype(std::declval<F>()(std::declval<Args>()...)); + +template <typename Void, typename R, typename F, typename... Args> +struct is_callable_r_impl : std::false_type {}; + +// Specialize the struct for those template arguments where call_result_t is +// well-formed. When it's not, the generic template above is chosen, resulting +// in std::false_type. +template <typename R, typename F, typename... Args> +struct is_callable_r_impl<void_t<call_result_t<F, Args...>>, R, F, Args...> + : std::conditional< + std::is_void<R>::value, // + std::true_type, // + is_implicitly_convertible<call_result_t<F, Args...>, R>>::type {}; + +// Like std::is_invocable_r from C++17, but works only for objects with call +// operators. See the note on call_result_t. +template <typename R, typename F, typename... Args> +using is_callable_r = is_callable_r_impl<void, R, F, Args...>; + +// Like std::as_const from C++17. +template <typename T> +typename std::add_const<T>::type& as_const(T& t) { + return t; +} + } // namespace internal +// Specialized for function types below. +template <typename F> +class OnceAction; + +// An action that can only be used once. +// +// This is accepted by WillOnce, which doesn't require the underlying action to +// be copy-constructible (only move-constructible), and promises to invoke it as +// an rvalue reference. This allows the action to work with move-only types like +// std::move_only_function in a type-safe manner. +// +// For example: +// +// // Assume we have some API that needs to accept a unique pointer to some +// // non-copyable object Foo. +// void AcceptUniquePointer(std::unique_ptr<Foo> foo); +// +// // We can define an action that provides a Foo to that API. Because It +// // has to give away its unique pointer, it must not be called more than +// // once, so its call operator is &&-qualified. +// struct ProvideFoo { +// std::unique_ptr<Foo> foo; +// +// void operator()() && { +// AcceptUniquePointer(std::move(Foo)); +// } +// }; +// +// // This action can be used with WillOnce. +// EXPECT_CALL(mock, Call) +// .WillOnce(ProvideFoo{std::make_unique<Foo>(...)}); +// +// // But a call to WillRepeatedly will fail to compile. This is correct, +// // since the action cannot correctly be used repeatedly. +// EXPECT_CALL(mock, Call) +// .WillRepeatedly(ProvideFoo{std::make_unique<Foo>(...)}); +// +// A less-contrived example would be an action that returns an arbitrary type, +// whose &&-qualified call operator is capable of dealing with move-only types. +template <typename Result, typename... Args> +class OnceAction<Result(Args...)> final { + private: + // True iff we can use the given callable type (or lvalue reference) directly + // via StdFunctionAdaptor. + template <typename Callable> + using IsDirectlyCompatible = internal::conjunction< + // It must be possible to capture the callable in StdFunctionAdaptor. + std::is_constructible<typename std::decay<Callable>::type, Callable>, + // The callable must be compatible with our signature. + internal::is_callable_r<Result, typename std::decay<Callable>::type, + Args...>>; + + // True iff we can use the given callable type via StdFunctionAdaptor once we + // ignore incoming arguments. + template <typename Callable> + using IsCompatibleAfterIgnoringArguments = internal::conjunction< + // It must be possible to capture the callable in a lambda. + std::is_constructible<typename std::decay<Callable>::type, Callable>, + // The callable must be invocable with zero arguments, returning something + // convertible to Result. + internal::is_callable_r<Result, typename std::decay<Callable>::type>>; + + public: + // Construct from a callable that is directly compatible with our mocked + // signature: it accepts our function type's arguments and returns something + // convertible to our result type. + template <typename Callable, + typename std::enable_if< + internal::conjunction< + // Teach clang on macOS that we're not talking about a + // copy/move constructor here. Otherwise it gets confused + // when checking the is_constructible requirement of our + // traits above. + internal::negation<std::is_same< + OnceAction, typename std::decay<Callable>::type>>, + IsDirectlyCompatible<Callable>> // + ::value, + int>::type = 0> + OnceAction(Callable&& callable) // NOLINT + : function_(StdFunctionAdaptor<typename std::decay<Callable>::type>( + {}, std::forward<Callable>(callable))) {} + + // As above, but for a callable that ignores the mocked function's arguments. + template <typename Callable, + typename std::enable_if< + internal::conjunction< + // Teach clang on macOS that we're not talking about a + // copy/move constructor here. Otherwise it gets confused + // when checking the is_constructible requirement of our + // traits above. + internal::negation<std::is_same< + OnceAction, typename std::decay<Callable>::type>>, + // Exclude callables for which the overload above works. + // We'd rather provide the arguments if possible. + internal::negation<IsDirectlyCompatible<Callable>>, + IsCompatibleAfterIgnoringArguments<Callable>>::value, + int>::type = 0> + OnceAction(Callable&& callable) // NOLINT + // Call the constructor above with a callable + // that ignores the input arguments. + : OnceAction(IgnoreIncomingArguments<typename std::decay<Callable>::type>{ + std::forward<Callable>(callable)}) {} + + // We are naturally copyable because we store only an std::function, but + // semantically we should not be copyable. + OnceAction(const OnceAction&) = delete; + OnceAction& operator=(const OnceAction&) = delete; + OnceAction(OnceAction&&) = default; + + // Invoke the underlying action callable with which we were constructed, + // handing it the supplied arguments. + Result Call(Args... args) && { + return function_(std::forward<Args>(args)...); + } + + private: + // An adaptor that wraps a callable that is compatible with our signature and + // being invoked as an rvalue reference so that it can be used as an + // StdFunctionAdaptor. This throws away type safety, but that's fine because + // this is only used by WillOnce, which we know calls at most once. + // + // Once we have something like std::move_only_function from C++23, we can do + // away with this. + template <typename Callable> + class StdFunctionAdaptor final { + public: + // A tag indicating that the (otherwise universal) constructor is accepting + // the callable itself, instead of e.g. stealing calls for the move + // constructor. + struct CallableTag final {}; + + template <typename F> + explicit StdFunctionAdaptor(CallableTag, F&& callable) + : callable_(std::make_shared<Callable>(std::forward<F>(callable))) {} + + // Rather than explicitly returning Result, we return whatever the wrapped + // callable returns. This allows for compatibility with existing uses like + // the following, when the mocked function returns void: + // + // EXPECT_CALL(mock_fn_, Call) + // .WillOnce([&] { + // [...] + // return 0; + // }); + // + // Such a callable can be turned into std::function<void()>. If we use an + // explicit return type of Result here then it *doesn't* work with + // std::function, because we'll get a "void function should not return a + // value" error. + // + // We need not worry about incompatible result types because the SFINAE on + // OnceAction already checks this for us. std::is_invocable_r_v itself makes + // the same allowance for void result types. + template <typename... ArgRefs> + internal::call_result_t<Callable, ArgRefs...> operator()( + ArgRefs&&... args) const { + return std::move(*callable_)(std::forward<ArgRefs>(args)...); + } + + private: + // We must put the callable on the heap so that we are copyable, which + // std::function needs. + std::shared_ptr<Callable> callable_; + }; + + // An adaptor that makes a callable that accepts zero arguments callable with + // our mocked arguments. + template <typename Callable> + struct IgnoreIncomingArguments { + internal::call_result_t<Callable> operator()(Args&&...) { + return std::move(callable)(); + } + + Callable callable; + }; + + std::function<Result(Args...)> function_; +}; + // 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; @@ -220,11 +588,11 @@ class DefaultValue { // Unsets the default value for type T. static void Clear() { delete producer_; - producer_ = NULL; + producer_ = nullptr; } - // Returns true iff the user has set the default value for type T. - static bool IsSet() { return producer_ != NULL; } + // 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. @@ -236,36 +604,38 @@ class DefaultValue { // 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_ == NULL ? - internal::BuiltInDefaultValue<T>::Get() : producer_->Produce(); + return producer_ == nullptr ? internal::BuiltInDefaultValue<T>::Get() + : producer_->Produce(); } private: class ValueProducer { public: - virtual ~ValueProducer() {} + virtual ~ValueProducer() = default; virtual T Produce() = 0; }; class FixedValueProducer : public ValueProducer { public: explicit FixedValueProducer(T value) : value_(value) {} - virtual T Produce() { return value_; } + T Produce() override { return value_; } private: const T value_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(FixedValueProducer); + FixedValueProducer(const FixedValueProducer&) = delete; + FixedValueProducer& operator=(const FixedValueProducer&) = delete; }; class FactoryValueProducer : public ValueProducer { public: explicit FactoryValueProducer(FactoryFunction factory) : factory_(factory) {} - virtual T Produce() { return factory_(); } + T Produce() override { return factory_(); } private: const FactoryFunction factory_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(FactoryValueProducer); + FactoryValueProducer(const FactoryValueProducer&) = delete; + FactoryValueProducer& operator=(const FactoryValueProducer&) = delete; }; static ValueProducer* producer_; @@ -282,12 +652,10 @@ class DefaultValue<T&> { } // Unsets the default value for type T&. - static void Clear() { - address_ = NULL; - } + static void Clear() { address_ = nullptr; } - // Returns true iff the user has set the default value for type T&. - static bool IsSet() { return address_ != NULL; } + // 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. @@ -299,8 +667,8 @@ class DefaultValue<T&> { // otherwise returns the built-in default value if there is one; // otherwise aborts the process. static T& Get() { - return address_ == NULL ? - internal::BuiltInDefaultValue<T&>::Get() : *address_; + return address_ == nullptr ? internal::BuiltInDefaultValue<T&>::Get() + : *address_; } private: @@ -318,11 +686,11 @@ class DefaultValue<void> { // Points to the user-set default value for type T. template <typename T> -typename DefaultValue<T>::ValueProducer* DefaultValue<T>::producer_ = NULL; +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_ = NULL; +T* DefaultValue<T&>::address_ = nullptr; // Implement this interface to define an action for function type F. template <typename F> @@ -331,8 +699,8 @@ class ActionInterface { typedef typename internal::Function<F>::Result Result; typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - ActionInterface() {} - virtual ~ActionInterface() {} + ActionInterface() = default; + virtual ~ActionInterface() = default; // Performs the action. This method is not const, as in general an // action can have side effects and be stateful. For example, a @@ -341,56 +709,73 @@ class ActionInterface { virtual Result Perform(const ArgumentTuple& args) = 0; private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionInterface); + ActionInterface(const ActionInterface&) = delete; + ActionInterface& operator=(const ActionInterface&) = delete; }; -// 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 -// linked_ptr to const ActionInterface<T>, so copying is fairly cheap. -// 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 { +class Action; + +// An Action<R(Args...)> is a copyable and IMMUTABLE (except by assignment) +// object that represents an action to be taken when a mock function of type +// R(Args...) 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 R, typename... Args> +class Action<R(Args...)> { + private: + using F = R(Args...); + + // 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... InArgs> + typename internal::Function<F>::Result operator()(InArgs&&... args) { + return impl_->Perform( + ::std::forward_as_tuple(::std::forward<InArgs>(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() {} + Action() = default; -#if GTEST_LANG_CXX11 // 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< - ::std::is_constructible<::std::function<F>, G>::value>::type> - Action(G&& fun) : fun_(::std::forward<G>(fun)) {} // NOLINT -#endif + 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) : impl_(impl) {} + 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. + // to Func's and Func's return type can be implicitly converted to F's. template <typename Func> - explicit Action(const Action<Func>& action); - - // Returns true iff this is the DoDefault() action. - bool IsDoDefault() const { -#if GTEST_LANG_CXX11 - return impl_ == nullptr && fun_ == nullptr; -#else - return impl_ == NULL; -#endif - } + Action(const Action<Func>& action) // NOLINT + : 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 @@ -402,31 +787,53 @@ class Action { if (IsDoDefault()) { internal::IllegalDoDefault(__FILE__, __LINE__); } -#if GTEST_LANG_CXX11 - if (fun_ != nullptr) { - return internal::Apply(fun_, ::std::move(args)); - } -#endif - return impl_->Perform(args); + return internal::Apply(fun_, ::std::move(args)); } - private: - template <typename F1, typename F2> - friend class internal::ActionAdaptor; + // An action can be used as a OnceAction, since it's obviously safe to call it + // once. + operator OnceAction<F>() const { // NOLINT + // Return a OnceAction-compatible callable that calls Perform with the + // arguments it is provided. We could instead just return fun_, but then + // we'd need to handle the IsDoDefault() case separately. + struct OA { + Action<F> action; + + R operator()(Args... args) && { + return action.Perform( + std::forward_as_tuple(std::forward<Args>(args)...)); + } + }; + + return OA{*this}; + } + private: template <typename G> friend class Action; - // In C++11, Action can be implemented either as a generic functor (through - // std::function), or legacy ActionInterface. In C++98, only ActionInterface - // is available. The invariants are as follows: - // * in C++98, impl_ is null iff this is the default action - // * in C++11, at most one of fun_ & impl_ may be nonnull; both are null iff - // this is the default action -#if GTEST_LANG_CXX11 + 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... InArgs> + Result operator()(const InArgs&...) 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_; -#endif - internal::linked_ptr<ActionInterface<F> > impl_; }; // The PolymorphicAction class template makes it easy to implement a @@ -441,7 +848,7 @@ class Action { // template <typename Result, typename ArgumentTuple> // Result Perform(const ArgumentTuple& args) const { // // Processes the arguments and returns a result, using -// // tr1::get<N>(args) to get the N-th (0-based) argument in the tuple. +// // std::get<N>(args) to get the N-th (0-based) argument in the tuple. // } // ... // }; @@ -469,19 +876,15 @@ class PolymorphicAction { explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {} - virtual Result Perform(const ArgumentTuple& args) { + Result Perform(const ArgumentTuple& args) override { return impl_.template Perform<Result>(args); } private: Impl impl_; - - GTEST_DISALLOW_ASSIGN_(MonomorphicImpl); }; Impl impl_; - - GTEST_DISALLOW_ASSIGN_(PolymorphicAction); }; // Creates an Action from its implementation and returns it. The @@ -505,148 +908,206 @@ inline PolymorphicAction<Impl> MakePolymorphicAction(const Impl& impl) { namespace internal { -// Allows an Action<F2> object to pose as an Action<F1>, as long as F2 -// and F1 are compatible. -template <typename F1, typename F2> -class ActionAdaptor : public ActionInterface<F1> { - public: - typedef typename internal::Function<F1>::Result Result; - typedef typename internal::Function<F1>::ArgumentTuple ArgumentTuple; - - explicit ActionAdaptor(const Action<F2>& from) : impl_(from.impl_) {} - - virtual Result Perform(const ArgumentTuple& args) { - return impl_->Perform(args); - } - - private: - const internal::linked_ptr<ActionInterface<F2> > impl_; - - GTEST_DISALLOW_ASSIGN_(ActionAdaptor); -}; - // 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(internal::move(value)) {} + 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. -// +// The general implementation of Return(R). Specializations follow below. template <typename R> -class ReturnAction { +class ReturnAction final { 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(internal::move(value))) {} + explicit ReturnAction(R value) : value_(std::move(value)) {} + + template <typename U, typename... Args, + typename = typename std::enable_if<conjunction< + // See the requirements documented on Return. + negation<std::is_same<void, U>>, // + negation<std::is_reference<U>>, // + std::is_convertible<R, U>, // + std::is_move_constructible<U>>::value>::type> + operator OnceAction<U(Args...)>() && { // NOLINT + return Impl<U>(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 { - // 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_( - !is_reference<Result>::value, - use_ReturnRef_instead_of_Return_to_return_a_reference); - return Action<F>(new Impl<R, F>(value_)); + template <typename U, typename... Args, + typename = typename std::enable_if<conjunction< + // See the requirements documented on Return. + negation<std::is_same<void, U>>, // + negation<std::is_reference<U>>, // + std::is_convertible<const R&, U>, // + std::is_copy_constructible<U>>::value>::type> + operator Action<U(Args...)>() const { // NOLINT + return Impl<U>(value_); } private: - // Implements the Return(x) action for a particular function type F. - template <typename R_, typename F> - class Impl : public ActionInterface<F> { + // Implements the Return(x) action for a mock function that returns type U. + template <typename U> + class Impl final { public: - typedef typename Function<F>::Result Result; - typedef typename Function<F>::ArgumentTuple ArgumentTuple; + // The constructor used when the return value is allowed to move from the + // input value (i.e. we are converting to OnceAction). + explicit Impl(R&& input_value) + : state_(new State(std::move(input_value))) {} - // 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 linked_ptr<R>& value) - : value_before_cast_(*value), - value_(ImplicitCast_<Result>(value_before_cast_)) {} + // The constructor used when the return value is not allowed to move from + // the input value (i.e. we are converting to Action). + explicit Impl(const R& input_value) : state_(new State(input_value)) {} - virtual Result Perform(const ArgumentTuple&) { return value_; } + U operator()() && { return std::move(state_->value); } + U operator()() const& { return state_->value; } private: - GTEST_COMPILE_ASSERT_(!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); + // We put our state on the heap so that the compiler-generated copy/move + // constructors work correctly even when U is a reference-like type. This is + // necessary only because we eagerly create State::value (see the note on + // that symbol for details). If we instead had only the input value as a + // member then the default constructors would work fine. + // + // For example, when R is std::string and U is std::string_view, value is a + // reference to the string backed by input_value. The copy constructor would + // copy both, so that we wind up with a new input_value object (with the + // same contents) and a reference to the *old* input_value object rather + // than the new one. + struct State { + explicit State(const R& input_value_in) + : input_value(input_value_in), + // Make an implicit conversion to Result before initializing the U + // object we store, avoiding calling any explicit constructor of U + // from R. + // + // This simulates the language rules: a function with return type U + // that does `return R()` requires R to be implicitly convertible to + // U, and uses that path for the conversion, even U Result has an + // explicit constructor from R. + value(ImplicitCast_<U>(internal::as_const(input_value))) {} + + // As above, but for the case where we're moving from the ReturnAction + // object because it's being used as a OnceAction. + explicit State(R&& input_value_in) + : input_value(std::move(input_value_in)), + // For the same reason as above we make an implicit conversion to U + // before initializing the value. + // + // Unlike above we provide the input value as an rvalue to the + // implicit conversion because this is a OnceAction: it's fine if it + // wants to consume the input value. + value(ImplicitCast_<U>(std::move(input_value))) {} + + // A copy of the value originally provided by the user. We retain this in + // addition to the value of the mock function's result type below in case + // the latter is a reference-like type. See the std::string_view example + // in the documentation on Return. + R input_value; + + // The value we actually return, as the type returned by the mock function + // itself. + // + // We eagerly initialize this here, rather than lazily doing the implicit + // conversion automatically each time Perform is called, for historical + // reasons: in 2009-11, commit a070cbd91c (Google changelist 13540126) + // made the Action<U()> conversion operator eagerly convert the R value to + // U, but without keeping the R alive. This broke the use case discussed + // in the documentation for Return, making reference-like types such as + // std::string_view not safe to use as U where the input type R is a + // value-like type such as std::string. + // + // The example the commit gave was not very clear, nor was the issue + // thread (https://github.com/google/googlemock/issues/86), but it seems + // the worry was about reference-like input types R that flatten to a + // value-like type U when being implicitly converted. An example of this + // is std::vector<bool>::reference, which is often a proxy type with an + // reference to the underlying vector: + // + // // Helper method: have the mock function return bools according + // // to the supplied script. + // void SetActions(MockFunction<bool(size_t)>& mock, + // const std::vector<bool>& script) { + // for (size_t i = 0; i < script.size(); ++i) { + // EXPECT_CALL(mock, Call(i)).WillOnce(Return(script[i])); + // } + // } + // + // TEST(Foo, Bar) { + // // Set actions using a temporary vector, whose operator[] + // // returns proxy objects that references that will be + // // dangling once the call to SetActions finishes and the + // // vector is destroyed. + // MockFunction<bool(size_t)> mock; + // SetActions(mock, {false, true}); + // + // EXPECT_FALSE(mock.AsStdFunction()(0)); + // EXPECT_TRUE(mock.AsStdFunction()(1)); + // } + // + // This eager conversion helps with a simple case like this, but doesn't + // fully make these types work in general. For example the following still + // uses a dangling reference: + // + // TEST(Foo, Baz) { + // MockFunction<std::vector<std::string>()> mock; + // + // // Return the same vector twice, and then the empty vector + // // thereafter. + // auto action = Return(std::initializer_list<std::string>{ + // "taco", "burrito", + // }); + // + // EXPECT_CALL(mock, Call) + // .WillOnce(action) + // .WillOnce(action) + // .WillRepeatedly(Return(std::vector<std::string>{})); + // + // EXPECT_THAT(mock.AsStdFunction()(), + // ElementsAre("taco", "burrito")); + // EXPECT_THAT(mock.AsStdFunction()(), + // ElementsAre("taco", "burrito")); + // EXPECT_THAT(mock.AsStdFunction()(), IsEmpty()); + // } + // + U value; + }; + + const std::shared_ptr<State> state_; }; - // 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; + R value_; +}; - explicit Impl(const linked_ptr<R>& wrapper) - : performed_(false), wrapper_(wrapper) {} +// A specialization of ReturnAction<R> when R is ByMoveWrapper<T> for some T. +// +// This version applies the type system-defeating hack of moving from T even in +// the const call operator, checking at runtime that it isn't called more than +// once, since the user has declared their intent to do so by using ByMove. +template <typename T> +class ReturnAction<ByMoveWrapper<T>> final { + public: + explicit ReturnAction(ByMoveWrapper<T> wrapper) + : state_(new State(std::move(wrapper.payload))) {} - virtual Result Perform(const ArgumentTuple&) { - GTEST_CHECK_(!performed_) - << "A ByMove() action should only be performed once."; - performed_ = true; - return internal::move(wrapper_->payload); - } + T operator()() const { + GTEST_CHECK_(!state_->called) + << "A ByMove() action must be performed at most once."; - private: - bool performed_; - const linked_ptr<R> wrapper_; + state_->called = true; + return std::move(state_->value); + } - GTEST_DISALLOW_ASSIGN_(Impl); - }; + private: + // We store our state on the heap so that we are copyable as required by + // Action, despite the fact that we are stateful and T may not be copyable. + struct State { + explicit State(T&& value_in) : value(std::move(value_in)) {} - const linked_ptr<R> value_; + T value; + bool called = false; + }; - GTEST_DISALLOW_ASSIGN_(ReturnAction); + const std::shared_ptr<State> state_; }; // Implements the ReturnNull() action. @@ -657,13 +1118,7 @@ class ReturnNullAction { // pointer type on compile time. template <typename Result, typename ArgumentTuple> static Result Perform(const ArgumentTuple&) { -#if GTEST_LANG_CXX11 return nullptr; -#else - GTEST_COMPILE_ASSERT_(internal::is_pointer<Result>::value, - ReturnNull_can_be_used_to_return_a_pointer_only); - return NULL; -#endif // GTEST_LANG_CXX11 } }; @@ -673,7 +1128,7 @@ class ReturnVoidAction { // Allows Return() to be used in any void-returning function. template <typename Result, typename ArgumentTuple> static void Perform(const ArgumentTuple&) { - CompileAssertTypesEqual<void, Result>(); + static_assert(std::is_void<Result>::value, "Result should be void."); } }; @@ -694,8 +1149,8 @@ class ReturnRefAction { // 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_(internal::is_reference<Result>::value, - use_Return_instead_of_ReturnRef_to_return_a_value); + static_assert(std::is_reference<Result>::value, + "use Return instead of ReturnRef to return a value"); return Action<F>(new Impl<F>(ref_)); } @@ -709,19 +1164,13 @@ class ReturnRefAction { explicit Impl(T& ref) : ref_(ref) {} // NOLINT - virtual Result Perform(const ArgumentTuple&) { - return ref_; - } + Result Perform(const ArgumentTuple&) override { return ref_; } private: T& ref_; - - GTEST_DISALLOW_ASSIGN_(Impl); }; T& ref_; - - GTEST_DISALLOW_ASSIGN_(ReturnRefAction); }; // Implements the polymorphic ReturnRefOfCopy(x) action, which can be @@ -742,9 +1191,8 @@ class ReturnRefOfCopyAction { // 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_( - internal::is_reference<Result>::value, - use_Return_instead_of_ReturnRefOfCopy_to_return_a_value); + static_assert(std::is_reference<Result>::value, + "use Return instead of ReturnRefOfCopy to return a value"); return Action<F>(new Impl<F>(value_)); } @@ -758,19 +1206,43 @@ class ReturnRefOfCopyAction { explicit Impl(const T& value) : value_(value) {} // NOLINT - virtual Result Perform(const ArgumentTuple&) { - return value_; - } + Result Perform(const ArgumentTuple&) override { return value_; } private: T value_; - - GTEST_DISALLOW_ASSIGN_(Impl); }; 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); + } - GTEST_DISALLOW_ASSIGN_(ReturnRefOfCopyAction); + 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. @@ -779,7 +1251,9 @@ class DoDefaultAction { // This template type conversion operator allows DoDefault() to be // used in any function. template <typename F> - operator Action<F>() const { return Action<F>(); } // NOLINT + operator Action<F>() const { + return Action<F>(); + } // NOLINT }; // Implements the Assign action to set a given pointer referent to a @@ -797,11 +1271,9 @@ class AssignAction { private: T1* const ptr_; const T2 value_; - - GTEST_DISALLOW_ASSIGN_(AssignAction); }; -#if !GTEST_OS_WINDOWS_MOBILE +#ifndef GTEST_OS_WINDOWS_MOBILE // Implements the SetErrnoAndReturn action to simulate return from // various system calls and libc functions. @@ -809,8 +1281,7 @@ template <typename T> class SetErrnoAndReturnAction { public: SetErrnoAndReturnAction(int errno_value, T result) - : errno_(errno_value), - result_(result) {} + : errno_(errno_value), result_(result) {} template <typename Result, typename ArgumentTuple> Result Perform(const ArgumentTuple& /* args */) const { errno = errno_; @@ -820,121 +1291,64 @@ class SetErrnoAndReturnAction { private: const int errno_; const T result_; - - GTEST_DISALLOW_ASSIGN_(SetErrnoAndReturnAction); }; #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. The -// template parameter kIsProto is true iff type A is ProtocolMessage, -// proto2::Message, or a sub-class of those. -template <size_t N, typename A, bool kIsProto> -class SetArgumentPointeeAction { - public: - // Constructs an action that sets the variable pointed to by the - // N-th function argument to 'value'. - explicit SetArgumentPointeeAction(const A& value) : value_(value) {} - - template <typename Result, typename ArgumentTuple> - void Perform(const ArgumentTuple& args) const { - CompileAssertTypesEqual<void, Result>(); - *::testing::get<N>(args) = value_; +// 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; } - - private: - const A value_; - - GTEST_DISALLOW_ASSIGN_(SetArgumentPointeeAction); }; -template <size_t N, typename Proto> -class SetArgumentPointeeAction<N, Proto, true> { - public: - // Constructs an action that sets the variable pointed to by the - // N-th function argument to 'proto'. Both ProtocolMessage and - // proto2::Message have the CopyFrom() method, so the same - // implementation works for both. - explicit SetArgumentPointeeAction(const Proto& proto) : proto_(new Proto) { - proto_->CopyFrom(proto); - } - - template <typename Result, typename ArgumentTuple> - void Perform(const ArgumentTuple& args) const { - CompileAssertTypesEqual<void, Result>(); - ::testing::get<N>(args)->CopyFrom(*proto_); +// 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)...); } - - private: - const internal::linked_ptr<Proto> proto_; - - GTEST_DISALLOW_ASSIGN_(SetArgumentPointeeAction); }; // 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 (i.e. f can be -// assigned to a tr1::function<F>). +// Action<F> as long as f's type is compatible with F. template <typename FunctionImpl> -class InvokeWithoutArgsAction { - public: - // The c'tor makes a copy of function_impl (either a function - // pointer or a functor). - explicit InvokeWithoutArgsAction(FunctionImpl function_impl) - : function_impl_(function_impl) {} +struct InvokeWithoutArgsAction { + FunctionImpl function_impl; // Allows InvokeWithoutArgs(f) to be used as any action whose type is // compatible with f. - template <typename Result, typename ArgumentTuple> - Result Perform(const ArgumentTuple&) { return function_impl_(); } - - private: - FunctionImpl function_impl_; - - GTEST_DISALLOW_ASSIGN_(InvokeWithoutArgsAction); + 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> -class InvokeMethodWithoutArgsAction { - public: - InvokeMethodWithoutArgsAction(Class* obj_ptr, MethodPtr method_ptr) - : obj_ptr_(obj_ptr), method_ptr_(method_ptr) {} - - template <typename Result, typename ArgumentTuple> - Result Perform(const ArgumentTuple&) const { - return (obj_ptr_->*method_ptr_)(); - } +struct InvokeMethodWithoutArgsAction { + Class* const obj_ptr; + const MethodPtr method_ptr; - private: - Class* const obj_ptr_; - const MethodPtr method_ptr_; + using ReturnType = + decltype((std::declval<Class*>()->*std::declval<MethodPtr>())()); - GTEST_DISALLOW_ASSIGN_(InvokeMethodWithoutArgsAction); -}; - -// Implements the InvokeWithoutArgs(callback) action. -template <typename CallbackType> -class InvokeCallbackWithoutArgsAction { - public: - // The c'tor takes ownership of the callback. - explicit InvokeCallbackWithoutArgsAction(CallbackType* callback) - : callback_(callback) { - callback->CheckIsRepeatable(); // Makes sure the callback is permanent. + template <typename... Args> + ReturnType operator()(const Args&...) const { + return (obj_ptr->*method_ptr)(); } - - // This type conversion operator template allows Invoke(callback) to - // be used wherever the callback's return type can be implicitly - // converted to that of the mock function. - template <typename Result, typename ArgumentTuple> - Result Perform(const ArgumentTuple&) const { return callback_->Run(); } - - private: - const internal::linked_ptr<CallbackType> callback_; - - GTEST_DISALLOW_ASSIGN_(InvokeCallbackWithoutArgsAction); }; // Implements the IgnoreResult(action) action. @@ -956,7 +1370,7 @@ class IgnoreResultAction { typedef typename internal::Function<F>::Result Result; // Asserts at compile time that F returns void. - CompileAssertTypesEqual<void, Result>(); + static_assert(std::is_void<Result>::value, "Result type should be void."); return Action<F>(new Impl<F>(action_)); } @@ -970,7 +1384,7 @@ class IgnoreResultAction { explicit Impl(const A& action) : action_(action) {} - virtual void Perform(const ArgumentTuple& args) { + void Perform(const ArgumentTuple& args) override { // Performs the action and ignores its result. action_.Perform(args); } @@ -978,91 +1392,356 @@ class IgnoreResultAction { private: // Type OriginalFunction is the same as F except that its return // type is IgnoredValue. - typedef typename internal::Function<F>::MakeResultIgnoredValue - OriginalFunction; + typedef + typename internal::Function<F>::MakeResultIgnoredValue OriginalFunction; const Action<OriginalFunction> action_; - - GTEST_DISALLOW_ASSIGN_(Impl); }; const A action_; +}; - GTEST_DISALLOW_ASSIGN_(IgnoreResultAction); +template <typename InnerAction, size_t... I> +struct WithArgsAction { + InnerAction inner_action; + + // The signature of the function as seen by the inner action, given an out + // action with the given result and argument types. + template <typename R, typename... Args> + using InnerSignature = + R(typename std::tuple_element<I, std::tuple<Args...>>::type...); + + // Rather than a call operator, we must define conversion operators to + // particular action types. This is necessary for embedded actions like + // DoDefault(), which rely on an action conversion operators rather than + // providing a call operator because even with a particular set of arguments + // they don't have a fixed return type. + + template < + typename R, typename... Args, + typename std::enable_if< + std::is_convertible<InnerAction, + // Unfortunately we can't use the InnerSignature + // alias here; MSVC complains about the I + // parameter pack not being expanded (error C3520) + // despite it being expanded in the type alias. + // TupleElement is also an MSVC workaround. + // See its definition for details. + OnceAction<R(internal::TupleElement< + I, std::tuple<Args...>>...)>>::value, + int>::type = 0> + operator OnceAction<R(Args...)>() && { // NOLINT + struct OA { + OnceAction<InnerSignature<R, Args...>> inner_action; + + R operator()(Args&&... args) && { + return std::move(inner_action) + .Call(std::get<I>( + std::forward_as_tuple(std::forward<Args>(args)...))...); + } + }; + + return OA{std::move(inner_action)}; + } + + template < + typename R, typename... Args, + typename std::enable_if< + std::is_convertible<const InnerAction&, + // Unfortunately we can't use the InnerSignature + // alias here; MSVC complains about the I + // parameter pack not being expanded (error C3520) + // despite it being expanded in the type alias. + // TupleElement is also an MSVC workaround. + // See its definition for details. + Action<R(internal::TupleElement< + I, std::tuple<Args...>>...)>>::value, + int>::type = 0> + operator Action<R(Args...)>() const { // NOLINT + Action<InnerSignature<R, Args...>> converted(inner_action); + + return [converted](Args&&... args) -> R { + return converted.Perform(std::forward_as_tuple( + std::get<I>(std::forward_as_tuple(std::forward<Args>(args)...))...)); + }; + } }; -// A ReferenceWrapper<T> object represents a reference to type T, -// which can be either const or not. It can be explicitly converted -// from, and implicitly converted to, a T&. Unlike a reference, -// ReferenceWrapper<T> can be copied and can survive template type -// inference. This is used to support by-reference arguments in the -// InvokeArgument<N>(...) action. The idea was from "reference -// wrappers" in tr1, which we don't have in our source tree yet. -template <typename T> -class ReferenceWrapper { +template <typename... Actions> +class DoAllAction; + +// Base case: only a single action. +template <typename FinalAction> +class DoAllAction<FinalAction> { public: - // Constructs a ReferenceWrapper<T> object from a T&. - explicit ReferenceWrapper(T& l_value) : pointer_(&l_value) {} // NOLINT + struct UserConstructorTag {}; + + template <typename T> + explicit DoAllAction(UserConstructorTag, T&& action) + : final_action_(std::forward<T>(action)) {} + + // Rather than a call operator, we must define conversion operators to + // particular action types. This is necessary for embedded actions like + // DoDefault(), which rely on an action conversion operators rather than + // providing a call operator because even with a particular set of arguments + // they don't have a fixed return type. + + template <typename R, typename... Args, + typename std::enable_if< + std::is_convertible<FinalAction, OnceAction<R(Args...)>>::value, + int>::type = 0> + operator OnceAction<R(Args...)>() && { // NOLINT + return std::move(final_action_); + } + + template < + typename R, typename... Args, + typename std::enable_if< + std::is_convertible<const FinalAction&, Action<R(Args...)>>::value, + int>::type = 0> + operator Action<R(Args...)>() const { // NOLINT + return final_action_; + } - // Allows a ReferenceWrapper<T> object to be implicitly converted to - // a T&. - operator T&() const { return *pointer_; } private: - T* pointer_; + FinalAction final_action_; }; -// Allows the expression ByRef(x) to be printed as a reference to x. -template <typename T> -void PrintTo(const ReferenceWrapper<T>& ref, ::std::ostream* os) { - T& value = ref; - UniversalPrinter<T&>::Print(value, os); -} +// Recursive case: support N actions by calling the initial action and then +// calling through to the base class containing N-1 actions. +template <typename InitialAction, typename... OtherActions> +class DoAllAction<InitialAction, OtherActions...> + : private DoAllAction<OtherActions...> { + private: + using Base = DoAllAction<OtherActions...>; + + // The type of reference that should be provided to an initial action for a + // mocked function parameter of type T. + // + // There are two quirks here: + // + // * Unlike most forwarding functions, we pass scalars through by value. + // This isn't strictly necessary because an lvalue reference would work + // fine too and be consistent with other non-reference types, but it's + // perhaps less surprising. + // + // For example if the mocked function has signature void(int), then it + // might seem surprising for the user's initial action to need to be + // convertible to Action<void(const int&)>. This is perhaps less + // surprising for a non-scalar type where there may be a performance + // impact, or it might even be impossible, to pass by value. + // + // * More surprisingly, `const T&` is often not a const reference type. + // By the reference collapsing rules in C++17 [dcl.ref]/6, if T refers to + // U& or U&& for some non-scalar type U, then InitialActionArgType<T> is + // U&. In other words, we may hand over a non-const reference. + // + // So for example, given some non-scalar type Obj we have the following + // mappings: + // + // T InitialActionArgType<T> + // ------- ----------------------- + // Obj const Obj& + // Obj& Obj& + // Obj&& Obj& + // const Obj const Obj& + // const Obj& const Obj& + // const Obj&& const Obj& + // + // In other words, the initial actions get a mutable view of an non-scalar + // argument if and only if the mock function itself accepts a non-const + // reference type. They are never given an rvalue reference to an + // non-scalar type. + // + // This situation makes sense if you imagine use with a matcher that is + // designed to write through a reference. For example, if the caller wants + // to fill in a reference argument and then return a canned value: + // + // EXPECT_CALL(mock, Call) + // .WillOnce(DoAll(SetArgReferee<0>(17), Return(19))); + // + template <typename T> + using InitialActionArgType = + typename std::conditional<std::is_scalar<T>::value, T, const T&>::type; -// Does two actions sequentially. Used for implementing the DoAll(a1, -// a2, ...) action. -template <typename Action1, typename Action2> -class DoBothAction { public: - DoBothAction(Action1 action1, Action2 action2) - : action1_(action1), action2_(action2) {} + struct UserConstructorTag {}; + + template <typename T, typename... U> + explicit DoAllAction(UserConstructorTag, T&& initial_action, + U&&... other_actions) + : Base({}, std::forward<U>(other_actions)...), + initial_action_(std::forward<T>(initial_action)) {} + + template <typename R, typename... Args, + typename std::enable_if< + conjunction< + // Both the initial action and the rest must support + // conversion to OnceAction. + std::is_convertible< + InitialAction, + OnceAction<void(InitialActionArgType<Args>...)>>, + std::is_convertible<Base, OnceAction<R(Args...)>>>::value, + int>::type = 0> + operator OnceAction<R(Args...)>() && { // NOLINT + // Return an action that first calls the initial action with arguments + // filtered through InitialActionArgType, then forwards arguments directly + // to the base class to deal with the remaining actions. + struct OA { + OnceAction<void(InitialActionArgType<Args>...)> initial_action; + OnceAction<R(Args...)> remaining_actions; + + R operator()(Args... args) && { + std::move(initial_action) + .Call(static_cast<InitialActionArgType<Args>>(args)...); + + return std::move(remaining_actions).Call(std::forward<Args>(args)...); + } + }; + + return OA{ + std::move(initial_action_), + std::move(static_cast<Base&>(*this)), + }; + } - // This template type conversion operator allows DoAll(a1, ..., a_n) - // to be used in ANY function of compatible type. - template <typename F> - operator Action<F>() const { - return Action<F>(new Impl<F>(action1_, action2_)); + template < + typename R, typename... Args, + typename std::enable_if< + conjunction< + // Both the initial action and the rest must support conversion to + // Action. + std::is_convertible<const InitialAction&, + Action<void(InitialActionArgType<Args>...)>>, + std::is_convertible<const Base&, Action<R(Args...)>>>::value, + int>::type = 0> + operator Action<R(Args...)>() const { // NOLINT + // Return an action that first calls the initial action with arguments + // filtered through InitialActionArgType, then forwards arguments directly + // to the base class to deal with the remaining actions. + struct OA { + Action<void(InitialActionArgType<Args>...)> initial_action; + Action<R(Args...)> remaining_actions; + + R operator()(Args... args) const { + initial_action.Perform(std::forward_as_tuple( + static_cast<InitialActionArgType<Args>>(args)...)); + + return remaining_actions.Perform( + std::forward_as_tuple(std::forward<Args>(args)...)); + } + }; + + return OA{ + initial_action_, + static_cast<const Base&>(*this), + }; } private: - // Implements the DoAll(...) 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; - typedef typename Function<F>::MakeResultVoid VoidResult; + InitialAction initial_action_; +}; - Impl(const Action<VoidResult>& action1, const Action<F>& action2) - : action1_(action1), action2_(action2) {} +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; +}; - virtual Result Perform(const ArgumentTuple& args) { - action1_.Perform(args); - return action2_.Perform(args); - } +template <size_t k> +struct ReturnArgAction { + template <typename... Args, + typename = typename std::enable_if<(k < sizeof...(Args))>::type> + auto operator()(Args&&... args) const -> decltype(std::get<k>( + std::forward_as_tuple(std::forward<Args>(args)...))) { + return std::get<k>(std::forward_as_tuple(std::forward<Args>(args)...)); + } +}; - private: - const Action<VoidResult> action1_; - const Action<F> action2_; +template <size_t k, typename Ptr> +struct SaveArgAction { + Ptr pointer; - GTEST_DISALLOW_ASSIGN_(Impl); - }; + 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; + } + } +}; - Action1 action1_; - Action2 action2_; +template <size_t k> +struct DeleteArgAction { + template <typename... Args> + void operator()(const Args&... args) const { + delete std::get<k>(std::tie(args...)); + } +}; - GTEST_DISALLOW_ASSIGN_(DoBothAction); +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. @@ -1097,27 +1776,74 @@ class DoBothAction { // EXPECT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin)); typedef internal::IgnoredValue Unused; -// This constructor allows us to turn an Action<From> object into an -// Action<To>, as long as To's arguments can be implicitly converted -// to From's and From's return type cann be implicitly converted to -// To's. -template <typename To> -template <typename From> -Action<To>::Action(const Action<From>& from) - : -#if GTEST_LANG_CXX11 - fun_(from.fun_), -#endif - impl_(from.impl_ == NULL ? NULL - : new internal::ActionAdaptor<To, From>(from)) { +// 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 internal::DoAllAction<typename std::decay<Action>::type...>( + {}, std::forward<Action>(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. +// 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 a value. +// +// The returned type can be used with a mock function returning a non-void, +// non-reference type U as follows: +// +// * If R is convertible to U and U is move-constructible, then the action can +// be used with WillOnce. +// +// * If const R& is convertible to U and U is copy-constructible, then the +// action can be used with both WillOnce and WillRepeatedly. +// +// The mock expectation contains the R value from which the U return value is +// constructed (a move/copy of the argument to Return). This means that the R +// value will survive at least until the mock object's expectations are cleared +// or the mock object is destroyed, meaning that U can safely be a +// reference-like type such as std::string_view: +// +// // The mock function returns a view of a copy of the string fed to +// // Return. The view is valid even after the action is performed. +// MockFunction<std::string_view()> mock; +// EXPECT_CALL(mock, Call).WillOnce(Return(std::string("taco"))); +// const std::string_view result = mock.AsStdFunction()(); +// EXPECT_EQ("taco", result); +// template <typename R> internal::ReturnAction<R> Return(R value) { - return internal::ReturnAction<R>(internal::move(value)); + return internal::ReturnAction<R>(std::move(value)); } // Creates an action that returns NULL. @@ -1136,6 +1862,10 @@ 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. @@ -1144,13 +1874,32 @@ inline internal::ReturnRefOfCopyAction<R> ReturnRefOfCopy(const R& x) { return internal::ReturnRefOfCopyAction<R>(x); } +// DEPRECATED: use Return(x) directly with WillOnce. +// // 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>(internal::move(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. @@ -1161,81 +1910,66 @@ inline internal::DoDefaultAction DoDefault() { // Creates an action that sets the variable pointed by the N-th // (0-based) function argument to 'value'. template <size_t N, typename T> -PolymorphicAction< - internal::SetArgumentPointeeAction< - N, T, internal::IsAProtocolMessage<T>::value> > -SetArgPointee(const T& x) { - return MakePolymorphicAction(internal::SetArgumentPointeeAction< - N, T, internal::IsAProtocolMessage<T>::value>(x)); -} - -#if !((GTEST_GCC_VER_ && GTEST_GCC_VER_ < 40000) || GTEST_OS_SYMBIAN) -// This overload allows SetArgPointee() to accept a string literal. -// GCC prior to the version 4.0 and Symbian C++ compiler cannot distinguish -// this overload from the templated version and emit a compile error. -template <size_t N> -PolymorphicAction< - internal::SetArgumentPointeeAction<N, const char*, false> > -SetArgPointee(const char* p) { - return MakePolymorphicAction(internal::SetArgumentPointeeAction< - N, const char*, false>(p)); +internal::SetArgumentPointeeAction<N, T> SetArgPointee(T value) { + return {std::move(value)}; } -template <size_t N> -PolymorphicAction< - internal::SetArgumentPointeeAction<N, const wchar_t*, false> > -SetArgPointee(const wchar_t* p) { - return MakePolymorphicAction(internal::SetArgumentPointeeAction< - N, const wchar_t*, false>(p)); -} -#endif - // The following version is DEPRECATED. template <size_t N, typename T> -PolymorphicAction< - internal::SetArgumentPointeeAction< - N, T, internal::IsAProtocolMessage<T>::value> > -SetArgumentPointee(const T& x) { - return MakePolymorphicAction(internal::SetArgumentPointeeAction< - N, T, internal::IsAProtocolMessage<T>::value>(x)); +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) { +PolymorphicAction<internal::AssignAction<T1, T2>> Assign(T1* ptr, T2 val) { return MakePolymorphicAction(internal::AssignAction<T1, T2>(ptr, val)); } -#if !GTEST_OS_WINDOWS_MOBILE +#ifndef 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) { +PolymorphicAction<internal::SetErrnoAndReturnAction<T>> SetErrnoAndReturn( + int errval, T result) { return MakePolymorphicAction( internal::SetErrnoAndReturnAction<T>(errval, result)); } #endif // !GTEST_OS_WINDOWS_MOBILE -// Various overloads for InvokeWithoutArgs(). +// 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> -PolymorphicAction<internal::InvokeWithoutArgsAction<FunctionImpl> > +internal::InvokeWithoutArgsAction<typename std::decay<FunctionImpl>::type> InvokeWithoutArgs(FunctionImpl function_impl) { - return MakePolymorphicAction( - internal::InvokeWithoutArgsAction<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> -PolymorphicAction<internal::InvokeMethodWithoutArgsAction<Class, MethodPtr> > -InvokeWithoutArgs(Class* obj_ptr, MethodPtr method_ptr) { - return MakePolymorphicAction( - internal::InvokeMethodWithoutArgsAction<Class, MethodPtr>( - obj_ptr, method_ptr)); +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 @@ -1253,11 +1987,311 @@ inline internal::IgnoreResultAction<A> IgnoreResult(const A& an_action) { // 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> -inline internal::ReferenceWrapper<T> ByRef(T& l_value) { // NOLINT - return internal::ReferenceWrapper<T>(l_value); +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 constexpr 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)) GTEST_MUST_USE_RESULT_; \ + 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 -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100 + +#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ diff --git a/contrib/googletest/googlemock/include/gmock/gmock-cardinalities.h b/contrib/googletest/googlemock/include/gmock/gmock-cardinalities.h index f9169315cbae..533e604f326c 100644 --- a/contrib/googletest/googlemock/include/gmock/gmock-cardinalities.h +++ b/contrib/googletest/googlemock/include/gmock/gmock-cardinalities.h @@ -27,20 +27,23 @@ // (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 +// IWYU pragma: private, include "gmock/gmock.h" +// IWYU pragma: friend gmock/.* -#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ #include <limits.h> + +#include <memory> #include <ostream> // NOLINT + #include "gmock/internal/gmock-port.h" #include "gtest/gtest.h" @@ -62,17 +65,19 @@ namespace testing { // The implementation of a cardinality. class CardinalityInterface { public: - virtual ~CardinalityInterface() {} + virtual ~CardinalityInterface() = default; // 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 iff call_count calls will satisfy this cardinality. + // Returns true if and only if call_count calls will satisfy this + // cardinality. virtual bool IsSatisfiedByCallCount(int call_count) const = 0; - // Returns true iff call_count calls will saturate this cardinality. + // 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. @@ -81,14 +86,13 @@ class CardinalityInterface { // 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 linked_ptr -// to const CardinalityInterface, so copying is fairly cheap. -// Don't inherit from Cardinality! +// 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() {} + Cardinality() = default; // Constructs a Cardinality from its implementation. explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {} @@ -98,21 +102,23 @@ class GTEST_API_ Cardinality { int ConservativeLowerBound() const { return impl_->ConservativeLowerBound(); } int ConservativeUpperBound() const { return impl_->ConservativeUpperBound(); } - // Returns true iff call_count calls will satisfy this cardinality. + // 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 iff call_count calls will saturate this cardinality. + // 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 iff call_count calls will over-saturate this + // 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); + !impl_->IsSatisfiedByCallCount(call_count); } // Describes self to an ostream @@ -123,7 +129,7 @@ class GTEST_API_ Cardinality { ::std::ostream* os); private: - internal::linked_ptr<const CardinalityInterface> impl_; + std::shared_ptr<const CardinalityInterface> impl_; }; // Creates a cardinality that allows at least n calls. @@ -150,4 +156,4 @@ inline Cardinality MakeCardinality(const CardinalityInterface* c) { GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ diff --git a/contrib/googletest/googlemock/include/gmock/gmock-function-mocker.h b/contrib/googletest/googlemock/include/gmock/gmock-function-mocker.h new file mode 100644 index 000000000000..1a1f126e492f --- /dev/null +++ b/contrib/googletest/googlemock/include/gmock/gmock-function-mocker.h @@ -0,0 +1,518 @@ +// 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. + +// IWYU pragma: private, include "gmock/gmock.h" +// IWYU pragma: friend gmock/.* + +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_ + +#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)); + } +}; + +constexpr bool PrefixOf(const char* a, const char* b) { + return *a == 0 || (*a == *b && internal::PrefixOf(a + 1, b + 1)); +} + +template <int N, int M> +constexpr bool StartsWith(const char (&prefix)[N], const char (&str)[M]) { + return N <= M && internal::PrefixOf(prefix, str); +} + +template <int N, int M> +constexpr bool EndsWith(const char (&suffix)[N], const char (&str)[M]) { + return N <= M && internal::PrefixOf(suffix, str + M - N); +} + +template <int N, int M> +constexpr bool Equals(const char (&a)[N], const char (&b)[M]) { + return N == M && internal::PrefixOf(a, b); +} + +template <int N> +constexpr bool ValidateSpec(const char (&spec)[N]) { + return internal::Equals("const", spec) || + internal::Equals("override", spec) || + internal::Equals("final", spec) || + internal::Equals("noexcept", spec) || + (internal::StartsWith("noexcept(", spec) && + internal::EndsWith(")", spec)) || + internal::Equals("ref(&)", spec) || + internal::Equals("ref(&&)", spec) || + (internal::StartsWith("Calltype(", spec) && + internal::EndsWith(")", spec)); +} + +} // 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_INTERNAL_WARNING_PUSH() \ + GMOCK_INTERNAL_WARNING_CLANG(ignored, "-Wunused-member-function") \ + GMOCK_PP_VARIADIC_CALL(GMOCK_INTERNAL_MOCK_METHOD_ARG_, __VA_ARGS__) \ + GMOCK_INTERNAL_WARNING_POP() + +#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(_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__ + +// 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_CALLTYPE_SPEC(_Tuple) \ + GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_CALLTYPE_SPEC_IF_CALLTYPE, ~, _Tuple) + +#define GMOCK_INTERNAL_CALLTYPE_SPEC_IF_CALLTYPE(_i, _, _elem) \ + GMOCK_PP_IF( \ + GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CALLTYPE(_i, _, _elem)), \ + GMOCK_PP_CAT(GMOCK_INTERNAL_UNPACK_, _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), ) + +#ifdef GMOCK_INTERNAL_STRICT_SPEC_ASSERT +#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem) \ + static_assert( \ + ::testing::internal::ValidateSpec(GMOCK_PP_STRINGIZE(_elem)), \ + "Token \'" GMOCK_PP_STRINGIZE( \ + _elem) "\' cannot be recognized as a valid specification " \ + "modifier. Is a ',' missing?"); +#else +#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_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CALLTYPE(_i, _, _elem))) == 1, \ + GMOCK_PP_STRINGIZE( \ + _elem) " cannot be recognized as a valid specification modifier."); +#endif // GMOCK_INTERNAL_STRICT_SPEC_ASSERT + +// 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_DETECT_CALLTYPE(_i, _, _elem) \ + GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_CALLTYPE_I_, _elem) + +#define GMOCK_INTERNAL_DETECT_CALLTYPE_I_Calltype , + +#define GMOCK_INTERNAL_UNPACK_Calltype(...) __VA_ARGS__ + +// Note: The use of `identity_t` here allows _Ret to represent return types that +// would normally need to be specified in a different way. For example, a method +// returning a function pointer must be written as +// +// fn_ptr_return_t (*method(method_args_t...))(fn_ptr_args_t...) +// +// But we only support placing the return type at the beginning. To handle this, +// we wrap all calls in identity_t, so that a declaration will be expanded to +// +// identity_t<fn_ptr_return_t (*)(fn_ptr_args_t...)> method(method_args_t...) +// +// This allows us to work around the syntactic oddities of function/method +// types. +#define GMOCK_INTERNAL_SIGNATURE(_Ret, _Args) \ + ::testing::internal::identity_t<GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_Ret), \ + GMOCK_PP_REMOVE_PARENS, \ + GMOCK_PP_IDENTITY)(_Ret)>( \ + GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_TYPE, _, _Args)) + +#define GMOCK_INTERNAL_GET_TYPE(_i, _, _elem) \ + GMOCK_PP_COMMA_IF(_i) \ + 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 // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_ diff --git a/contrib/googletest/googlemock/include/gmock/gmock-generated-actions.h b/contrib/googletest/googlemock/include/gmock/gmock-generated-actions.h deleted file mode 100644 index 260036da899f..000000000000 --- a/contrib/googletest/googlemock/include/gmock/gmock-generated-actions.h +++ /dev/null @@ -1,2567 +0,0 @@ -// 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 "gmock/gmock-actions.h" -#include "gmock/internal/gmock-port.h" - -namespace testing { -namespace internal { - -// InvokeHelper<F> knows how to unpack an N-tuple and invoke an N-ary -// function, method, or callback with the unpacked values, where F is -// a function type that takes N arguments. -template <typename Result, typename ArgumentTuple> -class InvokeHelper; - -template <typename R> -class InvokeHelper<R, ::testing::tuple<> > { - public: - template <typename Function> - static R Invoke(Function function, const ::testing::tuple<>&) { - return function(); - } - - template <class Class, typename MethodPtr> - static R InvokeMethod(Class* obj_ptr, - MethodPtr method_ptr, - const ::testing::tuple<>&) { - return (obj_ptr->*method_ptr)(); - } - - template <typename CallbackType> - static R InvokeCallback(CallbackType* callback, - const ::testing::tuple<>&) { - return callback->Run(); - } -}; - -template <typename R, typename A1> -class InvokeHelper<R, ::testing::tuple<A1> > { - public: - template <typename Function> - static R Invoke(Function function, const ::testing::tuple<A1>& args) { - return function(get<0>(args)); - } - - template <class Class, typename MethodPtr> - static R InvokeMethod(Class* obj_ptr, - MethodPtr method_ptr, - const ::testing::tuple<A1>& args) { - return (obj_ptr->*method_ptr)(get<0>(args)); - } - - template <typename CallbackType> - static R InvokeCallback(CallbackType* callback, - const ::testing::tuple<A1>& args) { - return callback->Run(get<0>(args)); - } -}; - -template <typename R, typename A1, typename A2> -class InvokeHelper<R, ::testing::tuple<A1, A2> > { - public: - template <typename Function> - static R Invoke(Function function, const ::testing::tuple<A1, A2>& args) { - return function(get<0>(args), get<1>(args)); - } - - template <class Class, typename MethodPtr> - static R InvokeMethod(Class* obj_ptr, - MethodPtr method_ptr, - const ::testing::tuple<A1, A2>& args) { - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args)); - } - - template <typename CallbackType> - static R InvokeCallback(CallbackType* callback, - const ::testing::tuple<A1, A2>& args) { - return callback->Run(get<0>(args), get<1>(args)); - } -}; - -template <typename R, typename A1, typename A2, typename A3> -class InvokeHelper<R, ::testing::tuple<A1, A2, A3> > { - public: - template <typename Function> - static R Invoke(Function function, const ::testing::tuple<A1, A2, A3>& args) { - return function(get<0>(args), get<1>(args), get<2>(args)); - } - - template <class Class, typename MethodPtr> - static R InvokeMethod(Class* obj_ptr, - MethodPtr method_ptr, - const ::testing::tuple<A1, A2, A3>& args) { - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), - get<2>(args)); - } - - template <typename CallbackType> - static R InvokeCallback(CallbackType* callback, - const ::testing::tuple<A1, A2, A3>& args) { - return callback->Run(get<0>(args), get<1>(args), get<2>(args)); - } -}; - -template <typename R, typename A1, typename A2, typename A3, typename A4> -class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4> > { - public: - template <typename Function> - static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, - A4>& args) { - return function(get<0>(args), get<1>(args), get<2>(args), - get<3>(args)); - } - - template <class Class, typename MethodPtr> - static R InvokeMethod(Class* obj_ptr, - MethodPtr method_ptr, - const ::testing::tuple<A1, A2, A3, A4>& args) { - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), - get<2>(args), get<3>(args)); - } - - template <typename CallbackType> - static R InvokeCallback(CallbackType* callback, - const ::testing::tuple<A1, A2, A3, A4>& args) { - return callback->Run(get<0>(args), get<1>(args), get<2>(args), - get<3>(args)); - } -}; - -template <typename R, typename A1, typename A2, typename A3, typename A4, - typename A5> -class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5> > { - public: - template <typename Function> - static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, - A5>& args) { - return function(get<0>(args), get<1>(args), get<2>(args), - get<3>(args), get<4>(args)); - } - - template <class Class, typename MethodPtr> - static R InvokeMethod(Class* obj_ptr, - MethodPtr method_ptr, - const ::testing::tuple<A1, A2, A3, A4, A5>& args) { - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), - get<2>(args), get<3>(args), get<4>(args)); - } - - template <typename CallbackType> - static R InvokeCallback(CallbackType* callback, - const ::testing::tuple<A1, A2, A3, A4, A5>& args) { - return callback->Run(get<0>(args), get<1>(args), get<2>(args), - get<3>(args), get<4>(args)); - } -}; - -template <typename R, typename A1, typename A2, typename A3, typename A4, - typename A5, typename A6> -class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6> > { - public: - template <typename Function> - static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5, - A6>& args) { - return function(get<0>(args), get<1>(args), get<2>(args), - get<3>(args), get<4>(args), get<5>(args)); - } - - template <class Class, typename MethodPtr> - static R InvokeMethod(Class* obj_ptr, - MethodPtr method_ptr, - const ::testing::tuple<A1, A2, A3, A4, A5, A6>& args) { - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), - get<2>(args), get<3>(args), get<4>(args), get<5>(args)); - } - - // There is no InvokeCallback() for 6-tuples -}; - -template <typename R, typename A1, typename A2, typename A3, typename A4, - typename A5, typename A6, typename A7> -class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6, A7> > { - public: - template <typename Function> - static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5, - A6, A7>& args) { - return function(get<0>(args), get<1>(args), get<2>(args), - get<3>(args), get<4>(args), get<5>(args), get<6>(args)); - } - - template <class Class, typename MethodPtr> - static R InvokeMethod(Class* obj_ptr, - MethodPtr method_ptr, - const ::testing::tuple<A1, A2, A3, A4, A5, A6, - A7>& args) { - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), - get<2>(args), get<3>(args), get<4>(args), get<5>(args), - get<6>(args)); - } - - // There is no InvokeCallback() for 7-tuples -}; - -template <typename R, typename A1, typename A2, typename A3, typename A4, - typename A5, typename A6, typename A7, typename A8> -class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8> > { - public: - template <typename Function> - static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5, - A6, A7, A8>& args) { - return function(get<0>(args), get<1>(args), get<2>(args), - get<3>(args), get<4>(args), get<5>(args), get<6>(args), - get<7>(args)); - } - - template <class Class, typename MethodPtr> - static R InvokeMethod(Class* obj_ptr, - MethodPtr method_ptr, - const ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, - A8>& args) { - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), - get<2>(args), get<3>(args), get<4>(args), get<5>(args), - get<6>(args), get<7>(args)); - } - - // There is no InvokeCallback() for 8-tuples -}; - -template <typename R, typename A1, typename A2, typename A3, typename A4, - typename A5, typename A6, typename A7, typename A8, typename A9> -class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> > { - public: - template <typename Function> - static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5, - A6, A7, A8, A9>& args) { - return function(get<0>(args), get<1>(args), get<2>(args), - get<3>(args), get<4>(args), get<5>(args), get<6>(args), - get<7>(args), get<8>(args)); - } - - template <class Class, typename MethodPtr> - static R InvokeMethod(Class* obj_ptr, - MethodPtr method_ptr, - const ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, - A9>& args) { - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), - get<2>(args), get<3>(args), get<4>(args), get<5>(args), - get<6>(args), get<7>(args), get<8>(args)); - } - - // There is no InvokeCallback() for 9-tuples -}; - -template <typename R, typename A1, typename A2, typename A3, typename A4, - typename A5, typename A6, typename A7, typename A8, typename A9, - typename A10> -class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9, - A10> > { - public: - template <typename Function> - static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5, - A6, A7, A8, A9, A10>& args) { - return function(get<0>(args), get<1>(args), get<2>(args), - get<3>(args), get<4>(args), get<5>(args), get<6>(args), - get<7>(args), get<8>(args), get<9>(args)); - } - - template <class Class, typename MethodPtr> - static R InvokeMethod(Class* obj_ptr, - MethodPtr method_ptr, - const ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, - A9, A10>& args) { - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), - get<2>(args), get<3>(args), get<4>(args), get<5>(args), - get<6>(args), get<7>(args), get<8>(args), get<9>(args)); - } - - // There is no InvokeCallback() for 10-tuples -}; - -// Implements the Invoke(callback) action. -template <typename CallbackType> -class InvokeCallbackAction { - public: - // The c'tor takes ownership of the callback. - explicit InvokeCallbackAction(CallbackType* callback) - : callback_(callback) { - callback->CheckIsRepeatable(); // Makes sure the callback is permanent. - } - - // This type conversion operator template allows Invoke(callback) to - // be used wherever the callback's type is compatible with that of - // the mock function, i.e. if the mock function's arguments can be - // implicitly converted to the callback's arguments and the - // callback's result can be implicitly converted to the mock - // function's result. - template <typename Result, typename ArgumentTuple> - Result Perform(const ArgumentTuple& args) const { - return InvokeHelper<Result, ArgumentTuple>::InvokeCallback( - callback_.get(), args); - } - private: - const linked_ptr<CallbackType> callback_; -}; - -// An INTERNAL macro for extracting the type of a tuple field. It's -// subject to change without notice - DO NOT USE IN USER CODE! -#define GMOCK_FIELD_(Tuple, N) \ - typename ::testing::tuple_element<N, Tuple>::type - -// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::type is the -// type of an n-ary function whose i-th (1-based) argument type is the -// k{i}-th (0-based) field of ArgumentTuple, which must be a tuple -// type, and whose return type is Result. For example, -// SelectArgs<int, ::testing::tuple<bool, char, double, long>, 0, 3>::type -// is int(bool, long). -// -// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::Select(args) -// returns the selected fields (k1, k2, ..., k_n) of args as a tuple. -// For example, -// SelectArgs<int, tuple<bool, char, double>, 2, 0>::Select( -// ::testing::make_tuple(true, 'a', 2.5)) -// returns tuple (2.5, true). -// -// The numbers in list k1, k2, ..., k_n must be >= 0, where n can be -// in the range [0, 10]. Duplicates are allowed and they don't have -// to be in an ascending or descending order. - -template <typename Result, typename ArgumentTuple, int k1, int k2, int k3, - int k4, int k5, int k6, int k7, int k8, int k9, int k10> -class SelectArgs { - public: - typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), - GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3), - GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5), - GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7), - GMOCK_FIELD_(ArgumentTuple, k8), GMOCK_FIELD_(ArgumentTuple, k9), - GMOCK_FIELD_(ArgumentTuple, k10)); - typedef typename Function<type>::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& args) { - return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args), - get<k4>(args), get<k5>(args), get<k6>(args), get<k7>(args), - get<k8>(args), get<k9>(args), get<k10>(args)); - } -}; - -template <typename Result, typename ArgumentTuple> -class SelectArgs<Result, ArgumentTuple, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1> { - public: - typedef Result type(); - typedef typename Function<type>::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& /* args */) { - return SelectedArgs(); - } -}; - -template <typename Result, typename ArgumentTuple, int k1> -class SelectArgs<Result, ArgumentTuple, - k1, -1, -1, -1, -1, -1, -1, -1, -1, -1> { - public: - typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1)); - typedef typename Function<type>::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& args) { - return SelectedArgs(get<k1>(args)); - } -}; - -template <typename Result, typename ArgumentTuple, int k1, int k2> -class SelectArgs<Result, ArgumentTuple, - k1, k2, -1, -1, -1, -1, -1, -1, -1, -1> { - public: - typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), - GMOCK_FIELD_(ArgumentTuple, k2)); - typedef typename Function<type>::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& args) { - return SelectedArgs(get<k1>(args), get<k2>(args)); - } -}; - -template <typename Result, typename ArgumentTuple, int k1, int k2, int k3> -class SelectArgs<Result, ArgumentTuple, - k1, k2, k3, -1, -1, -1, -1, -1, -1, -1> { - public: - typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), - GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3)); - typedef typename Function<type>::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& args) { - return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args)); - } -}; - -template <typename Result, typename ArgumentTuple, int k1, int k2, int k3, - int k4> -class SelectArgs<Result, ArgumentTuple, - k1, k2, k3, k4, -1, -1, -1, -1, -1, -1> { - public: - typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), - GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3), - GMOCK_FIELD_(ArgumentTuple, k4)); - typedef typename Function<type>::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& args) { - return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args), - get<k4>(args)); - } -}; - -template <typename Result, typename ArgumentTuple, int k1, int k2, int k3, - int k4, int k5> -class SelectArgs<Result, ArgumentTuple, - k1, k2, k3, k4, k5, -1, -1, -1, -1, -1> { - public: - typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), - GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3), - GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5)); - typedef typename Function<type>::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& args) { - return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args), - get<k4>(args), get<k5>(args)); - } -}; - -template <typename Result, typename ArgumentTuple, int k1, int k2, int k3, - int k4, int k5, int k6> -class SelectArgs<Result, ArgumentTuple, - k1, k2, k3, k4, k5, k6, -1, -1, -1, -1> { - public: - typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), - GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3), - GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5), - GMOCK_FIELD_(ArgumentTuple, k6)); - typedef typename Function<type>::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& args) { - return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args), - get<k4>(args), get<k5>(args), get<k6>(args)); - } -}; - -template <typename Result, typename ArgumentTuple, int k1, int k2, int k3, - int k4, int k5, int k6, int k7> -class SelectArgs<Result, ArgumentTuple, - k1, k2, k3, k4, k5, k6, k7, -1, -1, -1> { - public: - typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), - GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3), - GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5), - GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7)); - typedef typename Function<type>::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& args) { - return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args), - get<k4>(args), get<k5>(args), get<k6>(args), get<k7>(args)); - } -}; - -template <typename Result, typename ArgumentTuple, int k1, int k2, int k3, - int k4, int k5, int k6, int k7, int k8> -class SelectArgs<Result, ArgumentTuple, - k1, k2, k3, k4, k5, k6, k7, k8, -1, -1> { - public: - typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), - GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3), - GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5), - GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7), - GMOCK_FIELD_(ArgumentTuple, k8)); - typedef typename Function<type>::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& args) { - return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args), - get<k4>(args), get<k5>(args), get<k6>(args), get<k7>(args), - get<k8>(args)); - } -}; - -template <typename Result, typename ArgumentTuple, int k1, int k2, int k3, - int k4, int k5, int k6, int k7, int k8, int k9> -class SelectArgs<Result, ArgumentTuple, - k1, k2, k3, k4, k5, k6, k7, k8, k9, -1> { - public: - typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), - GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3), - GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5), - GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7), - GMOCK_FIELD_(ArgumentTuple, k8), GMOCK_FIELD_(ArgumentTuple, k9)); - typedef typename Function<type>::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& args) { - return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args), - get<k4>(args), get<k5>(args), get<k6>(args), get<k7>(args), - get<k8>(args), get<k9>(args)); - } -}; - -#undef GMOCK_FIELD_ - -// Implements the WithArgs action. -template <typename InnerAction, int k1 = -1, int k2 = -1, int k3 = -1, - int k4 = -1, int k5 = -1, int k6 = -1, int k7 = -1, int k8 = -1, - int k9 = -1, int k10 = -1> -class WithArgsAction { - public: - explicit WithArgsAction(const InnerAction& action) : action_(action) {} - - template <typename F> - operator Action<F>() const { return MakeAction(new Impl<F>(action_)); } - - private: - template <typename F> - class Impl : public ActionInterface<F> { - public: - typedef typename Function<F>::Result Result; - typedef typename Function<F>::ArgumentTuple ArgumentTuple; - - explicit Impl(const InnerAction& action) : action_(action) {} - - virtual Result Perform(const ArgumentTuple& args) { - return action_.Perform(SelectArgs<Result, ArgumentTuple, k1, k2, k3, k4, - k5, k6, k7, k8, k9, k10>::Select(args)); - } - - private: - typedef typename SelectArgs<Result, ArgumentTuple, - k1, k2, k3, k4, k5, k6, k7, k8, k9, k10>::type InnerFunctionType; - - Action<InnerFunctionType> action_; - }; - - const InnerAction action_; - - GTEST_DISALLOW_ASSIGN_(WithArgsAction); -}; - -// A macro from the ACTION* family (defined later in this file) -// 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 {}; - -// A helper class needed for implementing the ACTION* macros. -template <typename Result, class Impl> -class ActionHelper { - public: - static Result Perform(Impl* impl, const ::testing::tuple<>& args) { - return impl->template gmock_PerformImpl<>(args, ExcessiveArg(), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg()); - } - - template <typename A0> - static Result Perform(Impl* impl, const ::testing::tuple<A0>& args) { - return impl->template gmock_PerformImpl<A0>(args, get<0>(args), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg()); - } - - template <typename A0, typename A1> - static Result Perform(Impl* impl, const ::testing::tuple<A0, A1>& args) { - return impl->template gmock_PerformImpl<A0, A1>(args, get<0>(args), - get<1>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg()); - } - - template <typename A0, typename A1, typename A2> - static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2>& args) { - return impl->template gmock_PerformImpl<A0, A1, A2>(args, get<0>(args), - get<1>(args), get<2>(args), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg()); - } - - template <typename A0, typename A1, typename A2, typename A3> - static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, - A3>& args) { - return impl->template gmock_PerformImpl<A0, A1, A2, A3>(args, get<0>(args), - get<1>(args), get<2>(args), get<3>(args), ExcessiveArg(), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg()); - } - - template <typename A0, typename A1, typename A2, typename A3, typename A4> - static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, - A4>& args) { - return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4>(args, - get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg()); - } - - template <typename A0, typename A1, typename A2, typename A3, typename A4, - typename A5> - static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4, - A5>& args) { - return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5>(args, - get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args), - get<5>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg()); - } - - template <typename A0, typename A1, typename A2, typename A3, typename A4, - typename A5, typename A6> - static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4, - A5, A6>& args) { - return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5, A6>(args, - get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args), - get<5>(args), get<6>(args), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg()); - } - - template <typename A0, typename A1, typename A2, typename A3, typename A4, - typename A5, typename A6, typename A7> - static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4, - A5, A6, A7>& args) { - return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5, A6, - A7>(args, get<0>(args), get<1>(args), get<2>(args), get<3>(args), - get<4>(args), get<5>(args), get<6>(args), get<7>(args), ExcessiveArg(), - ExcessiveArg()); - } - - template <typename A0, typename A1, typename A2, typename A3, typename A4, - typename A5, typename A6, typename A7, typename A8> - static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4, - A5, A6, A7, A8>& args) { - return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5, A6, A7, - A8>(args, get<0>(args), get<1>(args), get<2>(args), get<3>(args), - get<4>(args), get<5>(args), get<6>(args), get<7>(args), get<8>(args), - ExcessiveArg()); - } - - template <typename A0, typename A1, typename A2, typename A3, typename A4, - typename A5, typename A6, typename A7, typename A8, typename A9> - static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4, - A5, A6, A7, A8, A9>& args) { - return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5, A6, A7, A8, - A9>(args, get<0>(args), get<1>(args), get<2>(args), get<3>(args), - get<4>(args), get<5>(args), get<6>(args), get<7>(args), get<8>(args), - get<9>(args)); - } -}; - -} // namespace internal - -// Various overloads for Invoke(). - -// 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. C++ doesn't support default arguments for -// function templates, so we have to overload it. -template <int k1, typename InnerAction> -inline internal::WithArgsAction<InnerAction, k1> -WithArgs(const InnerAction& action) { - return internal::WithArgsAction<InnerAction, k1>(action); -} - -template <int k1, int k2, typename InnerAction> -inline internal::WithArgsAction<InnerAction, k1, k2> -WithArgs(const InnerAction& action) { - return internal::WithArgsAction<InnerAction, k1, k2>(action); -} - -template <int k1, int k2, int k3, typename InnerAction> -inline internal::WithArgsAction<InnerAction, k1, k2, k3> -WithArgs(const InnerAction& action) { - return internal::WithArgsAction<InnerAction, k1, k2, k3>(action); -} - -template <int k1, int k2, int k3, int k4, typename InnerAction> -inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4> -WithArgs(const InnerAction& action) { - return internal::WithArgsAction<InnerAction, k1, k2, k3, k4>(action); -} - -template <int k1, int k2, int k3, int k4, int k5, typename InnerAction> -inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5> -WithArgs(const InnerAction& action) { - return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5>(action); -} - -template <int k1, int k2, int k3, int k4, int k5, int k6, typename InnerAction> -inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6> -WithArgs(const InnerAction& action) { - return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6>(action); -} - -template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, - typename InnerAction> -inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7> -WithArgs(const InnerAction& action) { - return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, - k7>(action); -} - -template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8, - typename InnerAction> -inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8> -WithArgs(const InnerAction& action) { - return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, - k8>(action); -} - -template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8, - int k9, typename InnerAction> -inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8, k9> -WithArgs(const InnerAction& action) { - return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8, - k9>(action); -} - -template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8, - int k9, int k10, typename InnerAction> -inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8, - k9, k10> -WithArgs(const InnerAction& action) { - return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8, - k9, k10>(action); -} - -// Creates an action that does actions a1, a2, ..., sequentially in -// each invocation. -template <typename Action1, typename Action2> -inline internal::DoBothAction<Action1, Action2> -DoAll(Action1 a1, Action2 a2) { - return internal::DoBothAction<Action1, Action2>(a1, a2); -} - -template <typename Action1, typename Action2, typename Action3> -inline internal::DoBothAction<Action1, internal::DoBothAction<Action2, - Action3> > -DoAll(Action1 a1, Action2 a2, Action3 a3) { - return DoAll(a1, DoAll(a2, a3)); -} - -template <typename Action1, typename Action2, typename Action3, - typename Action4> -inline internal::DoBothAction<Action1, internal::DoBothAction<Action2, - internal::DoBothAction<Action3, Action4> > > -DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4) { - return DoAll(a1, DoAll(a2, a3, a4)); -} - -template <typename Action1, typename Action2, typename Action3, - typename Action4, typename Action5> -inline internal::DoBothAction<Action1, internal::DoBothAction<Action2, - internal::DoBothAction<Action3, internal::DoBothAction<Action4, - Action5> > > > -DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5) { - return DoAll(a1, DoAll(a2, a3, a4, a5)); -} - -template <typename Action1, typename Action2, typename Action3, - typename Action4, typename Action5, typename Action6> -inline internal::DoBothAction<Action1, internal::DoBothAction<Action2, - internal::DoBothAction<Action3, internal::DoBothAction<Action4, - internal::DoBothAction<Action5, Action6> > > > > -DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6) { - return DoAll(a1, DoAll(a2, a3, a4, a5, a6)); -} - -template <typename Action1, typename Action2, typename Action3, - typename Action4, typename Action5, typename Action6, typename Action7> -inline internal::DoBothAction<Action1, internal::DoBothAction<Action2, - internal::DoBothAction<Action3, internal::DoBothAction<Action4, - internal::DoBothAction<Action5, internal::DoBothAction<Action6, - Action7> > > > > > -DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, - Action7 a7) { - return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7)); -} - -template <typename Action1, typename Action2, typename Action3, - typename Action4, typename Action5, typename Action6, typename Action7, - typename Action8> -inline internal::DoBothAction<Action1, internal::DoBothAction<Action2, - internal::DoBothAction<Action3, internal::DoBothAction<Action4, - internal::DoBothAction<Action5, internal::DoBothAction<Action6, - internal::DoBothAction<Action7, Action8> > > > > > > -DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, - Action7 a7, Action8 a8) { - return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7, a8)); -} - -template <typename Action1, typename Action2, typename Action3, - typename Action4, typename Action5, typename Action6, typename Action7, - typename Action8, typename Action9> -inline internal::DoBothAction<Action1, internal::DoBothAction<Action2, - internal::DoBothAction<Action3, internal::DoBothAction<Action4, - internal::DoBothAction<Action5, internal::DoBothAction<Action6, - internal::DoBothAction<Action7, internal::DoBothAction<Action8, - Action9> > > > > > > > -DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, - Action7 a7, Action8 a8, Action9 a9) { - return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7, a8, a9)); -} - -template <typename Action1, typename Action2, typename Action3, - typename Action4, typename Action5, typename Action6, typename Action7, - typename Action8, typename Action9, typename Action10> -inline internal::DoBothAction<Action1, internal::DoBothAction<Action2, - internal::DoBothAction<Action3, internal::DoBothAction<Action4, - internal::DoBothAction<Action5, internal::DoBothAction<Action6, - internal::DoBothAction<Action7, internal::DoBothAction<Action8, - internal::DoBothAction<Action9, Action10> > > > > > > > > -DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, - Action7 a7, Action8 a8, Action9 a9, Action10 a10) { - return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7, a8, a9, a10)); -} - -} // namespace testing - -// 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. The reason is -// that C++ doesn't yet allow function-local types to be used to -// instantiate templates. The up-coming C++0x standard will fix this. -// Once that's done, we'll consider supporting using ACTION*() inside -// a function. -// -// MORE INFORMATION: -// -// To learn more about using these macros, please search for 'ACTION' -// on https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md - -// An internal macro needed for implementing ACTION*(). -#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\ - const args_type& args GTEST_ATTRIBUTE_UNUSED_, \ - arg0_type arg0 GTEST_ATTRIBUTE_UNUSED_, \ - arg1_type arg1 GTEST_ATTRIBUTE_UNUSED_, \ - arg2_type arg2 GTEST_ATTRIBUTE_UNUSED_, \ - arg3_type arg3 GTEST_ATTRIBUTE_UNUSED_, \ - arg4_type arg4 GTEST_ATTRIBUTE_UNUSED_, \ - arg5_type arg5 GTEST_ATTRIBUTE_UNUSED_, \ - arg6_type arg6 GTEST_ATTRIBUTE_UNUSED_, \ - arg7_type arg7 GTEST_ATTRIBUTE_UNUSED_, \ - arg8_type arg8 GTEST_ATTRIBUTE_UNUSED_, \ - arg9_type arg9 GTEST_ATTRIBUTE_UNUSED_ - -// 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(::testing::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(::testing::internal::move(gmock_p0)) -#define GMOCK_INTERNAL_INIT_AND_2_VALUE_PARAMS(p0, p1)\ - (p0##_type gmock_p0, \ - p1##_type gmock_p1) : p0(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::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(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)), \ - p2(::testing::internal::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(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)), \ - p2(::testing::internal::move(gmock_p2)), \ - p3(::testing::internal::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(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)), \ - p2(::testing::internal::move(gmock_p2)), \ - p3(::testing::internal::move(gmock_p3)), \ - p4(::testing::internal::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(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)), \ - p2(::testing::internal::move(gmock_p2)), \ - p3(::testing::internal::move(gmock_p3)), \ - p4(::testing::internal::move(gmock_p4)), \ - p5(::testing::internal::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(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)), \ - p2(::testing::internal::move(gmock_p2)), \ - p3(::testing::internal::move(gmock_p3)), \ - p4(::testing::internal::move(gmock_p4)), \ - p5(::testing::internal::move(gmock_p5)), \ - p6(::testing::internal::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(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)), \ - p2(::testing::internal::move(gmock_p2)), \ - p3(::testing::internal::move(gmock_p3)), \ - p4(::testing::internal::move(gmock_p4)), \ - p5(::testing::internal::move(gmock_p5)), \ - p6(::testing::internal::move(gmock_p6)), \ - p7(::testing::internal::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(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)), \ - p2(::testing::internal::move(gmock_p2)), \ - p3(::testing::internal::move(gmock_p3)), \ - p4(::testing::internal::move(gmock_p4)), \ - p5(::testing::internal::move(gmock_p5)), \ - p6(::testing::internal::move(gmock_p6)), \ - p7(::testing::internal::move(gmock_p7)), \ - p8(::testing::internal::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(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)), \ - p2(::testing::internal::move(gmock_p2)), \ - p3(::testing::internal::move(gmock_p3)), \ - p4(::testing::internal::move(gmock_p4)), \ - p5(::testing::internal::move(gmock_p5)), \ - p6(::testing::internal::move(gmock_p6)), \ - p7(::testing::internal::move(gmock_p7)), \ - p8(::testing::internal::move(gmock_p8)), \ - p9(::testing::internal::move(gmock_p9)) - -// 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_INIT_##value_params {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ - arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ - arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ - arg9_type arg9) const;\ - GMOCK_INTERNAL_DEFN_##value_params\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(\ - new gmock_Impl<F>(GMOCK_INTERNAL_LIST_##value_params));\ - }\ - GMOCK_INTERNAL_DEFN_##value_params\ - private:\ - GTEST_DISALLOW_ASSIGN_(GMOCK_ACTION_CLASS_(name, value_params));\ - };\ - 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 F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - typename ::testing::internal::Function<F>::Result\ - GMOCK_ACTION_CLASS_(name, value_params)<\ - GMOCK_INTERNAL_LIST_##template_params\ - GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl<F>::\ - gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION(name)\ - class name##Action {\ - public:\ - name##Action() {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - gmock_Impl() {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ - arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ - arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ - arg9_type arg9) const;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(new gmock_Impl<F>());\ - }\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##Action);\ - };\ - inline name##Action name() {\ - return name##Action();\ - }\ - template <typename F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - typename ::testing::internal::Function<F>::Result\ - name##Action::gmock_Impl<F>::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P(name, p0)\ - template <typename p0##_type>\ - class name##ActionP {\ - public:\ - explicit name##ActionP(p0##_type gmock_p0) : \ - p0(::testing::internal::forward<p0##_type>(gmock_p0)) {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - explicit gmock_Impl(p0##_type gmock_p0) : \ - p0(::testing::internal::forward<p0##_type>(gmock_p0)) {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ - arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ - arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ - arg9_type arg9) const;\ - p0##_type p0;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(new gmock_Impl<F>(p0));\ - }\ - p0##_type p0;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP);\ - };\ - template <typename p0##_type>\ - inline name##ActionP<p0##_type> name(p0##_type p0) {\ - return name##ActionP<p0##_type>(p0);\ - }\ - template <typename p0##_type>\ - template <typename F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - typename ::testing::internal::Function<F>::Result\ - name##ActionP<p0##_type>::gmock_Impl<F>::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P2(name, p0, p1)\ - template <typename p0##_type, typename p1##_type>\ - class name##ActionP2 {\ - public:\ - name##ActionP2(p0##_type gmock_p0, \ - p1##_type gmock_p1) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ - p1(::testing::internal::forward<p1##_type>(gmock_p1)) {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - gmock_Impl(p0##_type gmock_p0, \ - p1##_type gmock_p1) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ - p1(::testing::internal::forward<p1##_type>(gmock_p1)) {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ - arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ - arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ - arg9_type arg9) const;\ - p0##_type p0;\ - p1##_type p1;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(new gmock_Impl<F>(p0, p1));\ - }\ - p0##_type p0;\ - p1##_type p1;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP2);\ - };\ - template <typename p0##_type, typename p1##_type>\ - inline name##ActionP2<p0##_type, p1##_type> name(p0##_type p0, \ - p1##_type p1) {\ - return name##ActionP2<p0##_type, p1##_type>(p0, p1);\ - }\ - template <typename p0##_type, typename p1##_type>\ - template <typename F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - typename ::testing::internal::Function<F>::Result\ - name##ActionP2<p0##_type, p1##_type>::gmock_Impl<F>::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P3(name, p0, p1, p2)\ - template <typename p0##_type, typename p1##_type, typename p2##_type>\ - class name##ActionP3 {\ - public:\ - name##ActionP3(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ - p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ - p2(::testing::internal::forward<p2##_type>(gmock_p2)) {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ - p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ - p2(::testing::internal::forward<p2##_type>(gmock_p2)) {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ - arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ - arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ - arg9_type arg9) const;\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2));\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP3);\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type>\ - inline name##ActionP3<p0##_type, p1##_type, p2##_type> name(p0##_type p0, \ - p1##_type p1, p2##_type p2) {\ - return name##ActionP3<p0##_type, p1##_type, p2##_type>(p0, p1, p2);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type>\ - template <typename F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - typename ::testing::internal::Function<F>::Result\ - name##ActionP3<p0##_type, p1##_type, \ - p2##_type>::gmock_Impl<F>::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P4(name, p0, p1, p2, p3)\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type>\ - class name##ActionP4 {\ - public:\ - name##ActionP4(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, \ - p3##_type gmock_p3) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ - p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ - p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ - p3(::testing::internal::forward<p3##_type>(gmock_p3)) {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ - p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ - p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ - p3(::testing::internal::forward<p3##_type>(gmock_p3)) {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ - arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ - arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ - arg9_type arg9) const;\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2, p3));\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP4);\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type>\ - inline name##ActionP4<p0##_type, p1##_type, p2##_type, \ - p3##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, \ - p3##_type p3) {\ - return name##ActionP4<p0##_type, p1##_type, p2##_type, p3##_type>(p0, p1, \ - p2, p3);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type>\ - template <typename F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - typename ::testing::internal::Function<F>::Result\ - name##ActionP4<p0##_type, p1##_type, p2##_type, \ - p3##_type>::gmock_Impl<F>::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P5(name, p0, p1, p2, p3, p4)\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type>\ - class name##ActionP5 {\ - public:\ - name##ActionP5(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, \ - p4##_type gmock_p4) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ - p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ - p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ - p3(::testing::internal::forward<p3##_type>(gmock_p3)), \ - p4(::testing::internal::forward<p4##_type>(gmock_p4)) {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, \ - p4##_type gmock_p4) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ - p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ - p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ - p3(::testing::internal::forward<p3##_type>(gmock_p3)), \ - p4(::testing::internal::forward<p4##_type>(gmock_p4)) {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ - arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ - arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ - arg9_type arg9) const;\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2, p3, p4));\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP5);\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type>\ - inline name##ActionP5<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ - p4##_type p4) {\ - return name##ActionP5<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type>(p0, p1, p2, p3, p4);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type>\ - template <typename F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - typename ::testing::internal::Function<F>::Result\ - name##ActionP5<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type>::gmock_Impl<F>::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P6(name, p0, p1, p2, p3, p4, p5)\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type>\ - class name##ActionP6 {\ - public:\ - name##ActionP6(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(::testing::internal::forward<p0##_type>(gmock_p0)), \ - p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ - p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ - p3(::testing::internal::forward<p3##_type>(gmock_p3)), \ - p4(::testing::internal::forward<p4##_type>(gmock_p4)), \ - p5(::testing::internal::forward<p5##_type>(gmock_p5)) {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - gmock_Impl(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(::testing::internal::forward<p0##_type>(gmock_p0)), \ - p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ - p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ - p3(::testing::internal::forward<p3##_type>(gmock_p3)), \ - p4(::testing::internal::forward<p4##_type>(gmock_p4)), \ - p5(::testing::internal::forward<p5##_type>(gmock_p5)) {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ - arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ - arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ - arg9_type arg9) const;\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2, p3, p4, p5));\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP6);\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type>\ - inline name##ActionP6<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, \ - p3##_type p3, p4##_type p4, p5##_type p5) {\ - return name##ActionP6<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type>(p0, p1, p2, p3, p4, p5);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type>\ - template <typename F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - typename ::testing::internal::Function<F>::Result\ - name##ActionP6<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ - p5##_type>::gmock_Impl<F>::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P7(name, p0, p1, p2, p3, p4, p5, p6)\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type>\ - class name##ActionP7 {\ - public:\ - name##ActionP7(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(::testing::internal::forward<p0##_type>(gmock_p0)), \ - p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ - p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ - p3(::testing::internal::forward<p3##_type>(gmock_p3)), \ - p4(::testing::internal::forward<p4##_type>(gmock_p4)), \ - p5(::testing::internal::forward<p5##_type>(gmock_p5)), \ - p6(::testing::internal::forward<p6##_type>(gmock_p6)) {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - gmock_Impl(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(::testing::internal::forward<p0##_type>(gmock_p0)), \ - p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ - p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ - p3(::testing::internal::forward<p3##_type>(gmock_p3)), \ - p4(::testing::internal::forward<p4##_type>(gmock_p4)), \ - p5(::testing::internal::forward<p5##_type>(gmock_p5)), \ - p6(::testing::internal::forward<p6##_type>(gmock_p6)) {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ - arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ - arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ - arg9_type arg9) const;\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(new gmock_Impl<F>(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;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP7);\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type>\ - inline name##ActionP7<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type> name(p0##_type p0, p1##_type p1, \ - p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \ - p6##_type p6) {\ - return name##ActionP7<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type>(p0, p1, p2, p3, p4, p5, p6);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type>\ - template <typename F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - typename ::testing::internal::Function<F>::Result\ - name##ActionP7<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ - p5##_type, p6##_type>::gmock_Impl<F>::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P8(name, p0, p1, p2, p3, p4, p5, p6, p7)\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type>\ - class name##ActionP8 {\ - public:\ - name##ActionP8(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(::testing::internal::forward<p0##_type>(gmock_p0)), \ - p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ - p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ - p3(::testing::internal::forward<p3##_type>(gmock_p3)), \ - p4(::testing::internal::forward<p4##_type>(gmock_p4)), \ - p5(::testing::internal::forward<p5##_type>(gmock_p5)), \ - p6(::testing::internal::forward<p6##_type>(gmock_p6)), \ - p7(::testing::internal::forward<p7##_type>(gmock_p7)) {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - gmock_Impl(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(::testing::internal::forward<p0##_type>(gmock_p0)), \ - p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ - p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ - p3(::testing::internal::forward<p3##_type>(gmock_p3)), \ - p4(::testing::internal::forward<p4##_type>(gmock_p4)), \ - p5(::testing::internal::forward<p5##_type>(gmock_p5)), \ - p6(::testing::internal::forward<p6##_type>(gmock_p6)), \ - p7(::testing::internal::forward<p7##_type>(gmock_p7)) {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ - arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ - arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ - arg9_type arg9) const;\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - p7##_type p7;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(new gmock_Impl<F>(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;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP8);\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type>\ - inline name##ActionP8<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type> name(p0##_type p0, \ - p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \ - p6##_type p6, p7##_type p7) {\ - return name##ActionP8<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type>(p0, p1, p2, p3, p4, p5, \ - p6, p7);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type>\ - template <typename F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - typename ::testing::internal::Function<F>::Result\ - name##ActionP8<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ - p5##_type, p6##_type, \ - p7##_type>::gmock_Impl<F>::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8)\ - template <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>\ - class name##ActionP9 {\ - public:\ - name##ActionP9(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(::testing::internal::forward<p0##_type>(gmock_p0)), \ - p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ - p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ - p3(::testing::internal::forward<p3##_type>(gmock_p3)), \ - p4(::testing::internal::forward<p4##_type>(gmock_p4)), \ - p5(::testing::internal::forward<p5##_type>(gmock_p5)), \ - p6(::testing::internal::forward<p6##_type>(gmock_p6)), \ - p7(::testing::internal::forward<p7##_type>(gmock_p7)), \ - p8(::testing::internal::forward<p8##_type>(gmock_p8)) {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - gmock_Impl(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(::testing::internal::forward<p0##_type>(gmock_p0)), \ - p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ - p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ - p3(::testing::internal::forward<p3##_type>(gmock_p3)), \ - p4(::testing::internal::forward<p4##_type>(gmock_p4)), \ - p5(::testing::internal::forward<p5##_type>(gmock_p5)), \ - p6(::testing::internal::forward<p6##_type>(gmock_p6)), \ - p7(::testing::internal::forward<p7##_type>(gmock_p7)), \ - p8(::testing::internal::forward<p8##_type>(gmock_p8)) {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ - arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ - arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ - arg9_type arg9) const;\ - 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;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(new gmock_Impl<F>(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;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP9);\ - };\ - template <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>\ - inline name##ActionP9<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type, \ - p8##_type> name(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) {\ - return name##ActionP9<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type, p8##_type>(p0, p1, p2, \ - p3, p4, p5, p6, p7, p8);\ - }\ - template <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>\ - template <typename F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - typename ::testing::internal::Function<F>::Result\ - name##ActionP9<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ - p5##_type, p6##_type, p7##_type, \ - p8##_type>::gmock_Impl<F>::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)\ - template <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>\ - class name##ActionP10 {\ - public:\ - name##ActionP10(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(::testing::internal::forward<p0##_type>(gmock_p0)), \ - p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ - p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ - p3(::testing::internal::forward<p3##_type>(gmock_p3)), \ - p4(::testing::internal::forward<p4##_type>(gmock_p4)), \ - p5(::testing::internal::forward<p5##_type>(gmock_p5)), \ - p6(::testing::internal::forward<p6##_type>(gmock_p6)), \ - p7(::testing::internal::forward<p7##_type>(gmock_p7)), \ - p8(::testing::internal::forward<p8##_type>(gmock_p8)), \ - p9(::testing::internal::forward<p9##_type>(gmock_p9)) {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - gmock_Impl(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(::testing::internal::forward<p0##_type>(gmock_p0)), \ - p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ - p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ - p3(::testing::internal::forward<p3##_type>(gmock_p3)), \ - p4(::testing::internal::forward<p4##_type>(gmock_p4)), \ - p5(::testing::internal::forward<p5##_type>(gmock_p5)), \ - p6(::testing::internal::forward<p6##_type>(gmock_p6)), \ - p7(::testing::internal::forward<p7##_type>(gmock_p7)), \ - p8(::testing::internal::forward<p8##_type>(gmock_p8)), \ - p9(::testing::internal::forward<p9##_type>(gmock_p9)) {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ - arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ - arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ - arg9_type arg9) const;\ - 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;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(new gmock_Impl<F>(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;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP10);\ - };\ - template <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>\ - inline name##ActionP10<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, \ - p9##_type> name(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) {\ - return name##ActionP10<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, p9##_type>(p0, \ - p1, p2, p3, p4, p5, p6, p7, p8, p9);\ - }\ - template <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>\ - template <typename F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - typename ::testing::internal::Function<F>::Result\ - name##ActionP10<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ - p5##_type, p6##_type, p7##_type, p8##_type, \ - p9##_type>::gmock_Impl<F>::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 - -// Various overloads for InvokeArgument<N>(). -// -// 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 ByRef(). For -// example, -// -// InvokeArgument<1>(5, string("Hello"), ByRef(foo)) -// -// passes 5 and string("Hello") by value, and passes foo by -// reference. -// -// 2. If the callable takes an argument by reference but ByRef() 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. - -namespace internal { -namespace invoke_argument { - -// Appears in InvokeArgumentAdl's argument list to help avoid -// accidental calls to user functions of the same name. -struct AdlTag {}; - -// InvokeArgumentAdl - a helper for InvokeArgument. -// The basic overloads are provided here for generic functors. -// Overloads for other custom-callables are provided in the -// internal/custom/callback-actions.h header. - -template <typename R, typename F> -R InvokeArgumentAdl(AdlTag, F f) { - return f(); -} -template <typename R, typename F, typename A1> -R InvokeArgumentAdl(AdlTag, F f, A1 a1) { - return f(a1); -} -template <typename R, typename F, typename A1, typename A2> -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2) { - return f(a1, a2); -} -template <typename R, typename F, typename A1, typename A2, typename A3> -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3) { - return f(a1, a2, a3); -} -template <typename R, typename F, typename A1, typename A2, typename A3, - typename A4> -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4) { - return f(a1, a2, a3, a4); -} -template <typename R, typename F, typename A1, typename A2, typename A3, - typename A4, typename A5> -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { - return f(a1, a2, a3, a4, a5); -} -template <typename R, typename F, typename A1, typename A2, typename A3, - typename A4, typename A5, typename A6> -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) { - return f(a1, a2, a3, a4, a5, a6); -} -template <typename R, typename F, typename A1, typename A2, typename A3, - typename A4, typename A5, typename A6, typename A7> -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, - A7 a7) { - return f(a1, a2, a3, a4, a5, a6, a7); -} -template <typename R, typename F, typename A1, typename A2, typename A3, - typename A4, typename A5, typename A6, typename A7, typename A8> -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, - A7 a7, A8 a8) { - return f(a1, a2, a3, a4, a5, a6, a7, a8); -} -template <typename R, typename F, typename A1, typename A2, typename A3, - typename A4, typename A5, typename A6, typename A7, typename A8, - typename A9> -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, - A7 a7, A8 a8, A9 a9) { - return f(a1, a2, a3, a4, a5, a6, a7, a8, a9); -} -template <typename R, typename F, typename A1, typename A2, typename A3, - typename A4, typename A5, typename A6, typename A7, typename A8, - typename A9, typename A10> -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, - A7 a7, A8 a8, A9 a9, A10 a10) { - return f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); -} -} // namespace invoke_argument -} // namespace internal - -ACTION_TEMPLATE(InvokeArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_0_VALUE_PARAMS()) { - using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl<return_type>( - internal::invoke_argument::AdlTag(), - ::testing::get<k>(args)); -} - -ACTION_TEMPLATE(InvokeArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_1_VALUE_PARAMS(p0)) { - using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl<return_type>( - internal::invoke_argument::AdlTag(), - ::testing::get<k>(args), p0); -} - -ACTION_TEMPLATE(InvokeArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_2_VALUE_PARAMS(p0, p1)) { - using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl<return_type>( - internal::invoke_argument::AdlTag(), - ::testing::get<k>(args), p0, p1); -} - -ACTION_TEMPLATE(InvokeArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_3_VALUE_PARAMS(p0, p1, p2)) { - using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl<return_type>( - internal::invoke_argument::AdlTag(), - ::testing::get<k>(args), p0, p1, p2); -} - -ACTION_TEMPLATE(InvokeArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_4_VALUE_PARAMS(p0, p1, p2, p3)) { - using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl<return_type>( - internal::invoke_argument::AdlTag(), - ::testing::get<k>(args), p0, p1, p2, p3); -} - -ACTION_TEMPLATE(InvokeArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)) { - using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl<return_type>( - internal::invoke_argument::AdlTag(), - ::testing::get<k>(args), p0, p1, p2, p3, p4); -} - -ACTION_TEMPLATE(InvokeArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)) { - using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl<return_type>( - internal::invoke_argument::AdlTag(), - ::testing::get<k>(args), p0, p1, p2, p3, p4, p5); -} - -ACTION_TEMPLATE(InvokeArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)) { - using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl<return_type>( - internal::invoke_argument::AdlTag(), - ::testing::get<k>(args), p0, p1, p2, p3, p4, p5, p6); -} - -ACTION_TEMPLATE(InvokeArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)) { - using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl<return_type>( - internal::invoke_argument::AdlTag(), - ::testing::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7); -} - -ACTION_TEMPLATE(InvokeArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8)) { - using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl<return_type>( - internal::invoke_argument::AdlTag(), - ::testing::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7, p8); -} - -ACTION_TEMPLATE(InvokeArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)) { - using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl<return_type>( - internal::invoke_argument::AdlTag(), - ::testing::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); -} - -// Various overloads for ReturnNew<T>(). -// -// 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. -ACTION_TEMPLATE(ReturnNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_0_VALUE_PARAMS()) { - return new T(); -} - -ACTION_TEMPLATE(ReturnNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_1_VALUE_PARAMS(p0)) { - return new T(p0); -} - -ACTION_TEMPLATE(ReturnNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_2_VALUE_PARAMS(p0, p1)) { - return new T(p0, p1); -} - -ACTION_TEMPLATE(ReturnNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_3_VALUE_PARAMS(p0, p1, p2)) { - return new T(p0, p1, p2); -} - -ACTION_TEMPLATE(ReturnNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_4_VALUE_PARAMS(p0, p1, p2, p3)) { - return new T(p0, p1, p2, p3); -} - -ACTION_TEMPLATE(ReturnNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)) { - return new T(p0, p1, p2, p3, p4); -} - -ACTION_TEMPLATE(ReturnNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)) { - return new T(p0, p1, p2, p3, p4, p5); -} - -ACTION_TEMPLATE(ReturnNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)) { - return new T(p0, p1, p2, p3, p4, p5, p6); -} - -ACTION_TEMPLATE(ReturnNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)) { - return new T(p0, p1, p2, p3, p4, p5, p6, p7); -} - -ACTION_TEMPLATE(ReturnNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8)) { - return new T(p0, p1, p2, p3, p4, p5, p6, p7, p8); -} - -ACTION_TEMPLATE(ReturnNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)) { - return new T(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); -} - -#ifdef _MSC_VER -# pragma warning(pop) -#endif - -} // namespace testing - -// Include any custom callback actions 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-generated-actions.h" - -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ diff --git a/contrib/googletest/googlemock/include/gmock/gmock-generated-actions.h.pump b/contrib/googletest/googlemock/include/gmock/gmock-generated-actions.h.pump deleted file mode 100644 index f1ee4a61b7a4..000000000000 --- a/contrib/googletest/googlemock/include/gmock/gmock-generated-actions.h.pump +++ /dev/null @@ -1,833 +0,0 @@ -$$ -*- 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 "gmock/gmock-actions.h" -#include "gmock/internal/gmock-port.h" - -namespace testing { -namespace internal { - -// InvokeHelper<F> knows how to unpack an N-tuple and invoke an N-ary -// function, method, or callback with the unpacked values, where F is -// a function type that takes N arguments. -template <typename Result, typename ArgumentTuple> -class InvokeHelper; - - -$var max_callback_arity = 5 -$range i 0..n -$for i [[ -$range j 1..i -$var types = [[$for j [[, typename A$j]]]] -$var as = [[$for j, [[A$j]]]] -$var args = [[$if i==0 [[]] $else [[ args]]]] -$var gets = [[$for j, [[get<$(j - 1)>(args)]]]] -template <typename R$types> -class InvokeHelper<R, ::testing::tuple<$as> > { - public: - template <typename Function> - static R Invoke(Function function, const ::testing::tuple<$as>&$args) { - return function($gets); - } - - template <class Class, typename MethodPtr> - static R InvokeMethod(Class* obj_ptr, - MethodPtr method_ptr, - const ::testing::tuple<$as>&$args) { - return (obj_ptr->*method_ptr)($gets); - } - - -$if i <= max_callback_arity [[ - template <typename CallbackType> - static R InvokeCallback(CallbackType* callback, - const ::testing::tuple<$as>&$args) { - return callback->Run($gets); - } -]] $else [[ - // There is no InvokeCallback() for $i-tuples -]] - -}; - - -]] -// Implements the Invoke(callback) action. -template <typename CallbackType> -class InvokeCallbackAction { - public: - // The c'tor takes ownership of the callback. - explicit InvokeCallbackAction(CallbackType* callback) - : callback_(callback) { - callback->CheckIsRepeatable(); // Makes sure the callback is permanent. - } - - // This type conversion operator template allows Invoke(callback) to - // be used wherever the callback's type is compatible with that of - // the mock function, i.e. if the mock function's arguments can be - // implicitly converted to the callback's arguments and the - // callback's result can be implicitly converted to the mock - // function's result. - template <typename Result, typename ArgumentTuple> - Result Perform(const ArgumentTuple& args) const { - return InvokeHelper<Result, ArgumentTuple>::InvokeCallback( - callback_.get(), args); - } - private: - const linked_ptr<CallbackType> callback_; -}; - -// An INTERNAL macro for extracting the type of a tuple field. It's -// subject to change without notice - DO NOT USE IN USER CODE! -#define GMOCK_FIELD_(Tuple, N) \ - typename ::testing::tuple_element<N, Tuple>::type - -$range i 1..n - -// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::type is the -// type of an n-ary function whose i-th (1-based) argument type is the -// k{i}-th (0-based) field of ArgumentTuple, which must be a tuple -// type, and whose return type is Result. For example, -// SelectArgs<int, ::testing::tuple<bool, char, double, long>, 0, 3>::type -// is int(bool, long). -// -// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::Select(args) -// returns the selected fields (k1, k2, ..., k_n) of args as a tuple. -// For example, -// SelectArgs<int, tuple<bool, char, double>, 2, 0>::Select( -// ::testing::make_tuple(true, 'a', 2.5)) -// returns tuple (2.5, true). -// -// The numbers in list k1, k2, ..., k_n must be >= 0, where n can be -// in the range [0, $n]. Duplicates are allowed and they don't have -// to be in an ascending or descending order. - -template <typename Result, typename ArgumentTuple, $for i, [[int k$i]]> -class SelectArgs { - public: - typedef Result type($for i, [[GMOCK_FIELD_(ArgumentTuple, k$i)]]); - typedef typename Function<type>::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& args) { - return SelectedArgs($for i, [[get<k$i>(args)]]); - } -}; - - -$for i [[ -$range j 1..n -$range j1 1..i-1 -template <typename Result, typename ArgumentTuple$for j1[[, int k$j1]]> -class SelectArgs<Result, ArgumentTuple, - $for j, [[$if j <= i-1 [[k$j]] $else [[-1]]]]> { - public: - typedef Result type($for j1, [[GMOCK_FIELD_(ArgumentTuple, k$j1)]]); - typedef typename Function<type>::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& [[]] -$if i == 1 [[/* args */]] $else [[args]]) { - return SelectedArgs($for j1, [[get<k$j1>(args)]]); - } -}; - - -]] -#undef GMOCK_FIELD_ - -$var ks = [[$for i, [[k$i]]]] - -// Implements the WithArgs action. -template <typename InnerAction, $for i, [[int k$i = -1]]> -class WithArgsAction { - public: - explicit WithArgsAction(const InnerAction& action) : action_(action) {} - - template <typename F> - operator Action<F>() const { return MakeAction(new Impl<F>(action_)); } - - private: - template <typename F> - class Impl : public ActionInterface<F> { - public: - typedef typename Function<F>::Result Result; - typedef typename Function<F>::ArgumentTuple ArgumentTuple; - - explicit Impl(const InnerAction& action) : action_(action) {} - - virtual Result Perform(const ArgumentTuple& args) { - return action_.Perform(SelectArgs<Result, ArgumentTuple, $ks>::Select(args)); - } - - private: - typedef typename SelectArgs<Result, ArgumentTuple, - $ks>::type InnerFunctionType; - - Action<InnerFunctionType> action_; - }; - - const InnerAction action_; - - GTEST_DISALLOW_ASSIGN_(WithArgsAction); -}; - -// A macro from the ACTION* family (defined later in this file) -// 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 {}; - -// A helper class needed for implementing the ACTION* macros. -template <typename Result, class Impl> -class ActionHelper { - public: -$range i 0..n -$for i - -[[ -$var template = [[$if i==0 [[]] $else [[ -$range j 0..i-1 - template <$for j, [[typename A$j]]> -]]]] -$range j 0..i-1 -$var As = [[$for j, [[A$j]]]] -$var as = [[$for j, [[get<$j>(args)]]]] -$range k 1..n-i -$var eas = [[$for k, [[ExcessiveArg()]]]] -$var arg_list = [[$if (i==0) | (i==n) [[$as$eas]] $else [[$as, $eas]]]] -$template - static Result Perform(Impl* impl, const ::testing::tuple<$As>& args) { - return impl->template gmock_PerformImpl<$As>(args, $arg_list); - } - -]] -}; - -} // namespace internal - -// Various overloads for Invoke(). - -// 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. C++ doesn't support default arguments for -// function templates, so we have to overload it. - -$range i 1..n -$for i [[ -$range j 1..i -template <$for j [[int k$j, ]]typename InnerAction> -inline internal::WithArgsAction<InnerAction$for j [[, k$j]]> -WithArgs(const InnerAction& action) { - return internal::WithArgsAction<InnerAction$for j [[, k$j]]>(action); -} - - -]] -// Creates an action that does actions a1, a2, ..., sequentially in -// each invocation. -$range i 2..n -$for i [[ -$range j 2..i -$var types = [[$for j, [[typename Action$j]]]] -$var Aas = [[$for j [[, Action$j a$j]]]] - -template <typename Action1, $types> -$range k 1..i-1 - -inline $for k [[internal::DoBothAction<Action$k, ]]Action$i$for k [[>]] - -DoAll(Action1 a1$Aas) { -$if i==2 [[ - - return internal::DoBothAction<Action1, Action2>(a1, a2); -]] $else [[ -$range j2 2..i - - return DoAll(a1, DoAll($for j2, [[a$j2]])); -]] - -} - -]] - -} // namespace testing - -// 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_P$n 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. The reason is -// that C++ doesn't yet allow function-local types to be used to -// instantiate templates. The up-coming C++0x standard will fix this. -// Once that's done, we'll consider supporting using ACTION*() inside -// a function. -// -// MORE INFORMATION: -// -// To learn more about using these macros, please search for 'ACTION' -// on https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md - -$range i 0..n -$range k 0..n-1 - -// An internal macro needed for implementing ACTION*(). -#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\ - const args_type& args GTEST_ATTRIBUTE_UNUSED_ -$for k [[, \ - arg$k[[]]_type arg$k GTEST_ATTRIBUTE_UNUSED_]] - - -// 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(::testing::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(::testing::internal::move(gmock_p$j))]] - - -]] - -// 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_INIT_##value_params {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <$for k, [[typename arg$k[[]]_type]]>\ - return_type gmock_PerformImpl(const args_type& args[[]] -$for k [[, arg$k[[]]_type arg$k]]) const;\ - GMOCK_INTERNAL_DEFN_##value_params\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(\ - new gmock_Impl<F>(GMOCK_INTERNAL_LIST_##value_params));\ - }\ - GMOCK_INTERNAL_DEFN_##value_params\ - private:\ - GTEST_DISALLOW_ASSIGN_(GMOCK_ACTION_CLASS_(name, value_params));\ - };\ - 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 F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - typename ::testing::internal::Function<F>::Result\ - GMOCK_ACTION_CLASS_(name, value_params)<\ - GMOCK_INTERNAL_LIST_##template_params\ - GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl<F>::\ - gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -$for i - -[[ -$var template = [[$if i==0 [[]] $else [[ -$range j 0..i-1 - - template <$for j, [[typename p$j##_type]]>\ -]]]] -$var class_name = [[name##Action[[$if i==0 [[]] $elif i==1 [[P]] - $else [[P$i]]]]]] -$range j 0..i-1 -$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]] -$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]] -$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::testing::internal::forward<p$j##_type>(gmock_p$j))]]]]]] -$var param_field_decls = [[$for j -[[ - - p$j##_type p$j;\ -]]]] -$var param_field_decls2 = [[$for j -[[ - - p$j##_type p$j;\ -]]]] -$var params = [[$for j, [[p$j]]]] -$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]] -$var typename_arg_types = [[$for k, [[typename arg$k[[]]_type]]]] -$var arg_types_and_names = [[$for k, [[arg$k[[]]_type arg$k]]]] -$var macro_name = [[$if i==0 [[ACTION]] $elif i==1 [[ACTION_P]] - $else [[ACTION_P$i]]]] - -#define $macro_name(name$for j [[, p$j]])\$template - class $class_name {\ - public:\ - [[$if i==1 [[explicit ]]]]$class_name($ctor_param_list)$inits {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - [[$if i==1 [[explicit ]]]]gmock_Impl($ctor_param_list)$inits {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <$typename_arg_types>\ - return_type gmock_PerformImpl(const args_type& args, [[]] -$arg_types_and_names) const;\$param_field_decls - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(new gmock_Impl<F>($params));\ - }\$param_field_decls2 - private:\ - GTEST_DISALLOW_ASSIGN_($class_name);\ - };\$template - inline $class_name$param_types name($param_types_and_names) {\ - return $class_name$param_types($params);\ - }\$template - template <typename F>\ - template <$typename_arg_types>\ - typename ::testing::internal::Function<F>::Result\ - $class_name$param_types::gmock_Impl<F>::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const -]] -$$ } // This meta comment fixes auto-indentation in Emacs. It won't -$$ // show up in the generated code. - - -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 - -// Various overloads for InvokeArgument<N>(). -// -// 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 ByRef(). For -// example, -// -// InvokeArgument<1>(5, string("Hello"), ByRef(foo)) -// -// passes 5 and string("Hello") by value, and passes foo by -// reference. -// -// 2. If the callable takes an argument by reference but ByRef() 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. - -namespace internal { -namespace invoke_argument { - -// Appears in InvokeArgumentAdl's argument list to help avoid -// accidental calls to user functions of the same name. -struct AdlTag {}; - -// InvokeArgumentAdl - a helper for InvokeArgument. -// The basic overloads are provided here for generic functors. -// Overloads for other custom-callables are provided in the -// internal/custom/callback-actions.h header. - -$range i 0..n -$for i -[[ -$range j 1..i - -template <typename R, typename F[[$for j [[, typename A$j]]]]> -R InvokeArgumentAdl(AdlTag, F f[[$for j [[, A$j a$j]]]]) { - return f([[$for j, [[a$j]]]]); -} -]] - -} // namespace invoke_argument -} // namespace internal - -$range i 0..n -$for i [[ -$range j 0..i-1 - -ACTION_TEMPLATE(InvokeArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])) { - using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl<return_type>( - internal::invoke_argument::AdlTag(), - ::testing::get<k>(args)$for j [[, p$j]]); -} - -]] - -// Various overloads for ReturnNew<T>(). -// -// 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. -$range i 0..n -$for i [[ -$range j 0..i-1 -$var ps = [[$for j, [[p$j]]]] - -ACTION_TEMPLATE(ReturnNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_$i[[]]_VALUE_PARAMS($ps)) { - return new T($ps); -} - -]] - -#ifdef _MSC_VER -# pragma warning(pop) -#endif - -} // namespace testing - -// Include any custom callback actions 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-generated-actions.h" - -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ diff --git a/contrib/googletest/googlemock/include/gmock/gmock-generated-function-mockers.h b/contrib/googletest/googlemock/include/gmock/gmock-generated-function-mockers.h deleted file mode 100644 index 5792d3d53488..000000000000 --- a/contrib/googletest/googlemock/include/gmock/gmock-generated-function-mockers.h +++ /dev/null @@ -1,1380 +0,0 @@ -// This file was GENERATED by command: -// pump.py gmock-generated-function-mockers.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 function mockers of various arities. - -// GOOGLETEST_CM0002 DO NOT DELETE - -#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ - -#include "gmock/gmock-spec-builders.h" -#include "gmock/internal/gmock-internal-utils.h" - -#if GTEST_HAS_STD_FUNCTION_ -# include <functional> -#endif - -namespace testing { -namespace internal { - -template <typename F> -class FunctionMockerBase; - -// Note: class FunctionMocker 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 -// FunctionMocker in ::testing::internal and import it into ::testing. -template <typename F> -class FunctionMocker; - -template <typename R> -class FunctionMocker<R()> : public - internal::FunctionMockerBase<R()> { - public: - typedef R F(); - typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - - MockSpec<F> With() { - return MockSpec<F>(this, ::testing::make_tuple()); - } - - R Invoke() { - // Even though gcc and MSVC don't enforce it, 'this->' is required - // by the C++ standard [14.6.4] here, as the base class type is - // dependent on the template argument (and thus shouldn't be - // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple()); - } -}; - -template <typename R, typename A1> -class FunctionMocker<R(A1)> : public - internal::FunctionMockerBase<R(A1)> { - public: - typedef R F(A1); - typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - - MockSpec<F> With(const Matcher<A1>& m1) { - return MockSpec<F>(this, ::testing::make_tuple(m1)); - } - - R Invoke(A1 a1) { - // Even though gcc and MSVC don't enforce it, 'this->' is required - // by the C++ standard [14.6.4] here, as the base class type is - // dependent on the template argument (and thus shouldn't be - // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(internal::forward<A1>(a1))); - } -}; - -template <typename R, typename A1, typename A2> -class FunctionMocker<R(A1, A2)> : public - internal::FunctionMockerBase<R(A1, A2)> { - public: - typedef R F(A1, A2); - typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - - MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2) { - return MockSpec<F>(this, ::testing::make_tuple(m1, m2)); - } - - R Invoke(A1 a1, A2 a2) { - // Even though gcc and MSVC don't enforce it, 'this->' is required - // by the C++ standard [14.6.4] here, as the base class type is - // dependent on the template argument (and thus shouldn't be - // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(internal::forward<A1>(a1), - internal::forward<A2>(a2))); - } -}; - -template <typename R, typename A1, typename A2, typename A3> -class FunctionMocker<R(A1, A2, A3)> : public - internal::FunctionMockerBase<R(A1, A2, A3)> { - public: - typedef R F(A1, A2, A3); - typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - - MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2, - const Matcher<A3>& m3) { - return MockSpec<F>(this, ::testing::make_tuple(m1, m2, m3)); - } - - R Invoke(A1 a1, A2 a2, A3 a3) { - // Even though gcc and MSVC don't enforce it, 'this->' is required - // by the C++ standard [14.6.4] here, as the base class type is - // dependent on the template argument (and thus shouldn't be - // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(internal::forward<A1>(a1), - internal::forward<A2>(a2), internal::forward<A3>(a3))); - } -}; - -template <typename R, typename A1, typename A2, typename A3, typename A4> -class FunctionMocker<R(A1, A2, A3, A4)> : public - internal::FunctionMockerBase<R(A1, A2, A3, A4)> { - public: - typedef R F(A1, A2, A3, A4); - typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - - MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2, - const Matcher<A3>& m3, const Matcher<A4>& m4) { - return MockSpec<F>(this, ::testing::make_tuple(m1, m2, m3, m4)); - } - - R Invoke(A1 a1, A2 a2, A3 a3, A4 a4) { - // Even though gcc and MSVC don't enforce it, 'this->' is required - // by the C++ standard [14.6.4] here, as the base class type is - // dependent on the template argument (and thus shouldn't be - // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(internal::forward<A1>(a1), - internal::forward<A2>(a2), internal::forward<A3>(a3), - internal::forward<A4>(a4))); - } -}; - -template <typename R, typename A1, typename A2, typename A3, typename A4, - typename A5> -class FunctionMocker<R(A1, A2, A3, A4, A5)> : public - internal::FunctionMockerBase<R(A1, A2, A3, A4, A5)> { - public: - typedef R F(A1, A2, A3, A4, A5); - typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - - MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2, - const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5) { - return MockSpec<F>(this, ::testing::make_tuple(m1, m2, m3, m4, m5)); - } - - R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { - // Even though gcc and MSVC don't enforce it, 'this->' is required - // by the C++ standard [14.6.4] here, as the base class type is - // dependent on the template argument (and thus shouldn't be - // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(internal::forward<A1>(a1), - internal::forward<A2>(a2), internal::forward<A3>(a3), - internal::forward<A4>(a4), internal::forward<A5>(a5))); - } -}; - -template <typename R, typename A1, typename A2, typename A3, typename A4, - typename A5, typename A6> -class FunctionMocker<R(A1, A2, A3, A4, A5, A6)> : public - internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6)> { - public: - typedef R F(A1, A2, A3, A4, A5, A6); - typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - - MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2, - const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5, - const Matcher<A6>& m6) { - return MockSpec<F>(this, ::testing::make_tuple(m1, m2, m3, m4, m5, m6)); - } - - R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) { - // Even though gcc and MSVC don't enforce it, 'this->' is required - // by the C++ standard [14.6.4] here, as the base class type is - // dependent on the template argument (and thus shouldn't be - // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(internal::forward<A1>(a1), - internal::forward<A2>(a2), internal::forward<A3>(a3), - internal::forward<A4>(a4), internal::forward<A5>(a5), - internal::forward<A6>(a6))); - } -}; - -template <typename R, typename A1, typename A2, typename A3, typename A4, - typename A5, typename A6, typename A7> -class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7)> : public - internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7)> { - public: - typedef R F(A1, A2, A3, A4, A5, A6, A7); - typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - - MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2, - const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5, - const Matcher<A6>& m6, const Matcher<A7>& m7) { - return MockSpec<F>(this, ::testing::make_tuple(m1, m2, m3, m4, m5, m6, m7)); - } - - R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) { - // Even though gcc and MSVC don't enforce it, 'this->' is required - // by the C++ standard [14.6.4] here, as the base class type is - // dependent on the template argument (and thus shouldn't be - // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(internal::forward<A1>(a1), - internal::forward<A2>(a2), internal::forward<A3>(a3), - internal::forward<A4>(a4), internal::forward<A5>(a5), - internal::forward<A6>(a6), internal::forward<A7>(a7))); - } -}; - -template <typename R, typename A1, typename A2, typename A3, typename A4, - typename A5, typename A6, typename A7, typename A8> -class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8)> : public - internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8)> { - public: - typedef R F(A1, A2, A3, A4, A5, A6, A7, A8); - typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - - MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2, - const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5, - const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8) { - return MockSpec<F>(this, ::testing::make_tuple(m1, m2, m3, m4, m5, m6, m7, - m8)); - } - - R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) { - // Even though gcc and MSVC don't enforce it, 'this->' is required - // by the C++ standard [14.6.4] here, as the base class type is - // dependent on the template argument (and thus shouldn't be - // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(internal::forward<A1>(a1), - internal::forward<A2>(a2), internal::forward<A3>(a3), - internal::forward<A4>(a4), internal::forward<A5>(a5), - internal::forward<A6>(a6), internal::forward<A7>(a7), - internal::forward<A8>(a8))); - } -}; - -template <typename R, typename A1, typename A2, typename A3, typename A4, - typename A5, typename A6, typename A7, typename A8, typename A9> -class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> : public - internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> { - public: - typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9); - typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - - MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2, - const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5, - const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8, - const Matcher<A9>& m9) { - return MockSpec<F>(this, ::testing::make_tuple(m1, m2, m3, m4, m5, m6, m7, - m8, m9)); - } - - R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) { - // Even though gcc and MSVC don't enforce it, 'this->' is required - // by the C++ standard [14.6.4] here, as the base class type is - // dependent on the template argument (and thus shouldn't be - // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(internal::forward<A1>(a1), - internal::forward<A2>(a2), internal::forward<A3>(a3), - internal::forward<A4>(a4), internal::forward<A5>(a5), - internal::forward<A6>(a6), internal::forward<A7>(a7), - internal::forward<A8>(a8), internal::forward<A9>(a9))); - } -}; - -template <typename R, typename A1, typename A2, typename A3, typename A4, - typename A5, typename A6, typename A7, typename A8, typename A9, - typename A10> -class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> : public - internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> { - public: - typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); - typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - - MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2, - const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5, - const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8, - const Matcher<A9>& m9, const Matcher<A10>& m10) { - return MockSpec<F>(this, ::testing::make_tuple(m1, m2, m3, m4, m5, m6, m7, - m8, m9, m10)); - } - - R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, - A10 a10) { - // Even though gcc and MSVC don't enforce it, 'this->' is required - // by the C++ standard [14.6.4] here, as the base class type is - // dependent on the template argument (and thus shouldn't be - // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(internal::forward<A1>(a1), - internal::forward<A2>(a2), internal::forward<A3>(a3), - internal::forward<A4>(a4), internal::forward<A5>(a5), - internal::forward<A6>(a6), internal::forward<A7>(a7), - internal::forward<A8>(a8), internal::forward<A9>(a9), - internal::forward<A10>(a10))); - } -}; - -// Removes the given pointer; this is a helper for the expectation setter method -// for parameterless matchers. -// -// We want to make sure that the user cannot set a parameterless expectation on -// overloaded methods, including methods which are overloaded on const. Example: -// -// class MockClass { -// MOCK_METHOD0(GetName, string&()); -// MOCK_CONST_METHOD0(GetName, const string&()); -// }; -// -// TEST() { -// // This should be an error, as it's not clear which overload is expected. -// EXPECT_CALL(mock, GetName).WillOnce(ReturnRef(value)); -// } -// -// Here are the generated expectation-setter methods: -// -// class MockClass { -// // Overload 1 -// MockSpec<string&()> gmock_GetName() { ... } -// // Overload 2. Declared const so that the compiler will generate an -// // error when trying to resolve between this and overload 4 in -// // 'gmock_GetName(WithoutMatchers(), nullptr)'. -// MockSpec<string&()> gmock_GetName( -// const WithoutMatchers&, const Function<string&()>*) const { -// // Removes const from this, calls overload 1 -// return AdjustConstness_(this)->gmock_GetName(); -// } -// -// // Overload 3 -// const string& gmock_GetName() const { ... } -// // Overload 4 -// MockSpec<const string&()> gmock_GetName( -// const WithoutMatchers&, const Function<const string&()>*) const { -// // Does not remove const, calls overload 3 -// return AdjustConstness_const(this)->gmock_GetName(); -// } -// } -// -template <typename MockType> -const MockType* AdjustConstness_const(const MockType* mock) { - return mock; -} - -// Removes const from and returns the given pointer; this is a helper for the -// expectation setter method for parameterless matchers. -template <typename MockType> -MockType* AdjustConstness_(const MockType* mock) { - return 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; - -// GMOCK_RESULT_(tn, F) expands to the result type of function type F. -// We define this as a variadic macro in case F contains unprotected -// commas (the same reason that we use variadic macros in other places -// in this file). -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_RESULT_(tn, ...) \ - tn ::testing::internal::Function<__VA_ARGS__>::Result - -// The type of argument N of the given function type. -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_ARG_(tn, N, ...) \ - tn ::testing::internal::Function<__VA_ARGS__>::Argument##N - -// The matcher type for argument N of the given function type. -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_MATCHER_(tn, N, ...) \ - const ::testing::Matcher<GMOCK_ARG_(tn, N, __VA_ARGS__)>& - -// The variable for mocking the given method. -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_MOCKER_(arity, constness, Method) \ - GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD0_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method() constness { \ - GTEST_COMPILE_ASSERT_( \ - (::testing::tuple_size<tn ::testing::internal::Function< \ - __VA_ARGS__>::ArgumentTuple>::value == 0), \ - this_method_does_not_take_0_arguments); \ - GMOCK_MOCKER_(0, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(0, constness, Method).Invoke(); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method() constness { \ - GMOCK_MOCKER_(0, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(0, constness, Method).With(); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - const ::testing::internal::WithoutMatchers&, \ - constness ::testing::internal::Function<__VA_ARGS__>*) const { \ - return ::testing::internal::AdjustConstness_##constness(this) \ - ->gmock_##Method(); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(0, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD1_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) \ - ct Method(GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1) constness { \ - GTEST_COMPILE_ASSERT_( \ - (::testing::tuple_size<tn ::testing::internal::Function< \ - __VA_ARGS__>::ArgumentTuple>::value == 1), \ - this_method_does_not_take_1_argument); \ - GMOCK_MOCKER_(1, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(1, constness, Method) \ - .Invoke(::testing::internal::forward<GMOCK_ARG_(tn, 1, __VA_ARGS__)>( \ - gmock_a1)); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1) constness { \ - GMOCK_MOCKER_(1, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(1, constness, Method).With(gmock_a1); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - const ::testing::internal::WithoutMatchers&, \ - constness ::testing::internal::Function<__VA_ARGS__>*) const { \ - return ::testing::internal::AdjustConstness_##constness(this) \ - ->gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>()); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(1, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD2_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) \ - ct Method(GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2) constness { \ - GTEST_COMPILE_ASSERT_( \ - (::testing::tuple_size<tn ::testing::internal::Function< \ - __VA_ARGS__>::ArgumentTuple>::value == 2), \ - this_method_does_not_take_2_arguments); \ - GMOCK_MOCKER_(2, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(2, constness, Method) \ - .Invoke(::testing::internal::forward<GMOCK_ARG_(tn, 1, __VA_ARGS__)>( \ - gmock_a1), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>( \ - gmock_a2)); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2) constness { \ - GMOCK_MOCKER_(2, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(2, constness, Method).With(gmock_a1, gmock_a2); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - const ::testing::internal::WithoutMatchers&, \ - constness ::testing::internal::Function<__VA_ARGS__>*) const { \ - return ::testing::internal::AdjustConstness_##constness(this) \ - ->gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>()); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(2, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD3_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) \ - ct Method(GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3) constness { \ - GTEST_COMPILE_ASSERT_( \ - (::testing::tuple_size<tn ::testing::internal::Function< \ - __VA_ARGS__>::ArgumentTuple>::value == 3), \ - this_method_does_not_take_3_arguments); \ - GMOCK_MOCKER_(3, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(3, constness, Method) \ - .Invoke(::testing::internal::forward<GMOCK_ARG_(tn, 1, __VA_ARGS__)>( \ - gmock_a1), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>( \ - gmock_a2), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>( \ - gmock_a3)); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3) constness { \ - GMOCK_MOCKER_(3, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(3, constness, Method) \ - .With(gmock_a1, gmock_a2, gmock_a3); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - const ::testing::internal::WithoutMatchers&, \ - constness ::testing::internal::Function<__VA_ARGS__>*) const { \ - return ::testing::internal::AdjustConstness_##constness(this) \ - ->gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>()); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(3, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD4_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) \ - ct Method(GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4) constness { \ - GTEST_COMPILE_ASSERT_( \ - (::testing::tuple_size<tn ::testing::internal::Function< \ - __VA_ARGS__>::ArgumentTuple>::value == 4), \ - this_method_does_not_take_4_arguments); \ - GMOCK_MOCKER_(4, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(4, constness, Method) \ - .Invoke(::testing::internal::forward<GMOCK_ARG_(tn, 1, __VA_ARGS__)>( \ - gmock_a1), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>( \ - gmock_a2), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>( \ - gmock_a3), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>( \ - gmock_a4)); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4) constness { \ - GMOCK_MOCKER_(4, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(4, constness, Method) \ - .With(gmock_a1, gmock_a2, gmock_a3, gmock_a4); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - const ::testing::internal::WithoutMatchers&, \ - constness ::testing::internal::Function<__VA_ARGS__>*) const { \ - return ::testing::internal::AdjustConstness_##constness(this) \ - ->gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>()); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(4, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD5_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) \ - ct Method(GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5) constness { \ - GTEST_COMPILE_ASSERT_( \ - (::testing::tuple_size<tn ::testing::internal::Function< \ - __VA_ARGS__>::ArgumentTuple>::value == 5), \ - this_method_does_not_take_5_arguments); \ - GMOCK_MOCKER_(5, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(5, constness, Method) \ - .Invoke(::testing::internal::forward<GMOCK_ARG_(tn, 1, __VA_ARGS__)>( \ - gmock_a1), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>( \ - gmock_a2), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>( \ - gmock_a3), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>( \ - gmock_a4), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>( \ - gmock_a5)); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5) constness { \ - GMOCK_MOCKER_(5, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(5, constness, Method) \ - .With(gmock_a1, gmock_a2, gmock_a3, gmock_a4, gmock_a5); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - const ::testing::internal::WithoutMatchers&, \ - constness ::testing::internal::Function<__VA_ARGS__>*) const { \ - return ::testing::internal::AdjustConstness_##constness(this) \ - ->gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>()); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(5, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD6_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) \ - ct Method(GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \ - GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6) constness { \ - GTEST_COMPILE_ASSERT_( \ - (::testing::tuple_size<tn ::testing::internal::Function< \ - __VA_ARGS__>::ArgumentTuple>::value == 6), \ - this_method_does_not_take_6_arguments); \ - GMOCK_MOCKER_(6, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(6, constness, Method) \ - .Invoke(::testing::internal::forward<GMOCK_ARG_(tn, 1, __VA_ARGS__)>( \ - gmock_a1), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>( \ - gmock_a2), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>( \ - gmock_a3), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>( \ - gmock_a4), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>( \ - gmock_a5), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>( \ - gmock_a6)); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ - GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6) constness { \ - GMOCK_MOCKER_(6, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(6, constness, Method) \ - .With(gmock_a1, gmock_a2, gmock_a3, gmock_a4, gmock_a5, gmock_a6); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - const ::testing::internal::WithoutMatchers&, \ - constness ::testing::internal::Function<__VA_ARGS__>*) const { \ - return ::testing::internal::AdjustConstness_##constness(this) \ - ->gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>()); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(6, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD7_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) \ - ct Method(GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \ - GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ - GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7) constness { \ - GTEST_COMPILE_ASSERT_( \ - (::testing::tuple_size<tn ::testing::internal::Function< \ - __VA_ARGS__>::ArgumentTuple>::value == 7), \ - this_method_does_not_take_7_arguments); \ - GMOCK_MOCKER_(7, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(7, constness, Method) \ - .Invoke(::testing::internal::forward<GMOCK_ARG_(tn, 1, __VA_ARGS__)>( \ - gmock_a1), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>( \ - gmock_a2), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>( \ - gmock_a3), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>( \ - gmock_a4), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>( \ - gmock_a5), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>( \ - gmock_a6), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>( \ - gmock_a7)); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ - GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \ - GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7) constness { \ - GMOCK_MOCKER_(7, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(7, constness, Method) \ - .With(gmock_a1, gmock_a2, gmock_a3, gmock_a4, gmock_a5, gmock_a6, \ - gmock_a7); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - const ::testing::internal::WithoutMatchers&, \ - constness ::testing::internal::Function<__VA_ARGS__>*) const { \ - return ::testing::internal::AdjustConstness_##constness(this) \ - ->gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 7, __VA_ARGS__)>()); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(7, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD8_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) \ - ct Method(GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \ - GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ - GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \ - GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8) constness { \ - GTEST_COMPILE_ASSERT_( \ - (::testing::tuple_size<tn ::testing::internal::Function< \ - __VA_ARGS__>::ArgumentTuple>::value == 8), \ - this_method_does_not_take_8_arguments); \ - GMOCK_MOCKER_(8, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(8, constness, Method) \ - .Invoke(::testing::internal::forward<GMOCK_ARG_(tn, 1, __VA_ARGS__)>( \ - gmock_a1), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>( \ - gmock_a2), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>( \ - gmock_a3), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>( \ - gmock_a4), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>( \ - gmock_a5), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>( \ - gmock_a6), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>( \ - gmock_a7), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 8, __VA_ARGS__)>( \ - gmock_a8)); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ - GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \ - GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \ - GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8) constness { \ - GMOCK_MOCKER_(8, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(8, constness, Method) \ - .With(gmock_a1, gmock_a2, gmock_a3, gmock_a4, gmock_a5, gmock_a6, \ - gmock_a7, gmock_a8); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - const ::testing::internal::WithoutMatchers&, \ - constness ::testing::internal::Function<__VA_ARGS__>*) const { \ - return ::testing::internal::AdjustConstness_##constness(this) \ - ->gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 8, __VA_ARGS__)>()); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(8, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD9_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) \ - ct Method(GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \ - GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ - GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \ - GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8, \ - GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9) constness { \ - GTEST_COMPILE_ASSERT_( \ - (::testing::tuple_size<tn ::testing::internal::Function< \ - __VA_ARGS__>::ArgumentTuple>::value == 9), \ - this_method_does_not_take_9_arguments); \ - GMOCK_MOCKER_(9, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(9, constness, Method) \ - .Invoke(::testing::internal::forward<GMOCK_ARG_(tn, 1, __VA_ARGS__)>( \ - gmock_a1), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>( \ - gmock_a2), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>( \ - gmock_a3), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>( \ - gmock_a4), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>( \ - gmock_a5), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>( \ - gmock_a6), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>( \ - gmock_a7), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 8, __VA_ARGS__)>( \ - gmock_a8), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 9, __VA_ARGS__)>( \ - gmock_a9)); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ - GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \ - GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \ - GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \ - GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9) constness { \ - GMOCK_MOCKER_(9, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(9, constness, Method) \ - .With(gmock_a1, gmock_a2, gmock_a3, gmock_a4, gmock_a5, gmock_a6, \ - gmock_a7, gmock_a8, gmock_a9); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - const ::testing::internal::WithoutMatchers&, \ - constness ::testing::internal::Function<__VA_ARGS__>*) const { \ - return ::testing::internal::AdjustConstness_##constness(this) \ - ->gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 9, __VA_ARGS__)>()); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(9, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD10_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) \ - ct Method(GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \ - GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ - GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \ - GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8, \ - GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9, \ - GMOCK_ARG_(tn, 10, __VA_ARGS__) gmock_a10) constness { \ - GTEST_COMPILE_ASSERT_( \ - (::testing::tuple_size<tn ::testing::internal::Function< \ - __VA_ARGS__>::ArgumentTuple>::value == 10), \ - this_method_does_not_take_10_arguments); \ - GMOCK_MOCKER_(10, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(10, constness, Method) \ - .Invoke(::testing::internal::forward<GMOCK_ARG_(tn, 1, __VA_ARGS__)>( \ - gmock_a1), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>( \ - gmock_a2), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>( \ - gmock_a3), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>( \ - gmock_a4), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>( \ - gmock_a5), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>( \ - gmock_a6), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>( \ - gmock_a7), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 8, __VA_ARGS__)>( \ - gmock_a8), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 9, __VA_ARGS__)>( \ - gmock_a9), \ - ::testing::internal::forward<GMOCK_ARG_(tn, 10, __VA_ARGS__)>( \ - gmock_a10)); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ - GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \ - GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \ - GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \ - GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9, \ - GMOCK_MATCHER_(tn, 10, __VA_ARGS__) gmock_a10) constness { \ - GMOCK_MOCKER_(10, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(10, constness, Method) \ - .With(gmock_a1, gmock_a2, gmock_a3, gmock_a4, gmock_a5, gmock_a6, \ - gmock_a7, gmock_a8, gmock_a9, gmock_a10); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - const ::testing::internal::WithoutMatchers&, \ - constness ::testing::internal::Function<__VA_ARGS__>*) const { \ - return ::testing::internal::AdjustConstness_##constness(this) \ - ->gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 9, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 10, __VA_ARGS__)>()); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(10, constness, \ - Method) - -#define MOCK_METHOD0(m, ...) GMOCK_METHOD0_(, , , m, __VA_ARGS__) -#define MOCK_METHOD1(m, ...) GMOCK_METHOD1_(, , , m, __VA_ARGS__) -#define MOCK_METHOD2(m, ...) GMOCK_METHOD2_(, , , m, __VA_ARGS__) -#define MOCK_METHOD3(m, ...) GMOCK_METHOD3_(, , , m, __VA_ARGS__) -#define MOCK_METHOD4(m, ...) GMOCK_METHOD4_(, , , m, __VA_ARGS__) -#define MOCK_METHOD5(m, ...) GMOCK_METHOD5_(, , , m, __VA_ARGS__) -#define MOCK_METHOD6(m, ...) GMOCK_METHOD6_(, , , m, __VA_ARGS__) -#define MOCK_METHOD7(m, ...) GMOCK_METHOD7_(, , , m, __VA_ARGS__) -#define MOCK_METHOD8(m, ...) GMOCK_METHOD8_(, , , m, __VA_ARGS__) -#define MOCK_METHOD9(m, ...) GMOCK_METHOD9_(, , , m, __VA_ARGS__) -#define MOCK_METHOD10(m, ...) GMOCK_METHOD10_(, , , m, __VA_ARGS__) - -#define MOCK_CONST_METHOD0(m, ...) GMOCK_METHOD0_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD1(m, ...) GMOCK_METHOD1_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD2(m, ...) GMOCK_METHOD2_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD3(m, ...) GMOCK_METHOD3_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD4(m, ...) GMOCK_METHOD4_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD5(m, ...) GMOCK_METHOD5_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD6(m, ...) GMOCK_METHOD6_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD7(m, ...) GMOCK_METHOD7_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD8(m, ...) GMOCK_METHOD8_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD9(m, ...) GMOCK_METHOD9_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD10(m, ...) GMOCK_METHOD10_(, const, , m, __VA_ARGS__) - -#define MOCK_METHOD0_T(m, ...) GMOCK_METHOD0_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD1_T(m, ...) GMOCK_METHOD1_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD2_T(m, ...) GMOCK_METHOD2_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD3_T(m, ...) GMOCK_METHOD3_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD4_T(m, ...) GMOCK_METHOD4_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD5_T(m, ...) GMOCK_METHOD5_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD6_T(m, ...) GMOCK_METHOD6_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD7_T(m, ...) GMOCK_METHOD7_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD8_T(m, ...) GMOCK_METHOD8_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD9_T(m, ...) GMOCK_METHOD9_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD10_T(m, ...) GMOCK_METHOD10_(typename, , , m, __VA_ARGS__) - -#define MOCK_CONST_METHOD0_T(m, ...) \ - GMOCK_METHOD0_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD1_T(m, ...) \ - GMOCK_METHOD1_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD2_T(m, ...) \ - GMOCK_METHOD2_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD3_T(m, ...) \ - GMOCK_METHOD3_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD4_T(m, ...) \ - GMOCK_METHOD4_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD5_T(m, ...) \ - GMOCK_METHOD5_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD6_T(m, ...) \ - GMOCK_METHOD6_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD7_T(m, ...) \ - GMOCK_METHOD7_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD8_T(m, ...) \ - GMOCK_METHOD8_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD9_T(m, ...) \ - GMOCK_METHOD9_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD10_T(m, ...) \ - GMOCK_METHOD10_(typename, const, , m, __VA_ARGS__) - -#define MOCK_METHOD0_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD0_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD1_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD1_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD2_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD2_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD3_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD3_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD4_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD4_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD5_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD5_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD6_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD6_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD7_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD7_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD8_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD8_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD9_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD9_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD10_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD10_(, , ct, m, __VA_ARGS__) - -#define MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD0_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD1_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD2_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD3_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD4_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD5_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD6_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD7_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD8_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD9_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD10_(, const, ct, m, __VA_ARGS__) - -#define MOCK_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD0_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD1_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD2_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD3_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD4_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD5_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD6_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD7_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD8_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD9_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD10_(typename, , ct, m, __VA_ARGS__) - -#define MOCK_CONST_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD0_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD1_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD2_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD3_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD4_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD5_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD6_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD7_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD8_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD9_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD10_(typename, const, ct, m, __VA_ARGS__) - -// A MockFunction<F> class has one mock method whose type is 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<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()); -// } -template <typename F> -class MockFunction; - -template <typename R> -class MockFunction<R()> { - public: - MockFunction() {} - - MOCK_METHOD0_T(Call, R()); - -#if GTEST_HAS_STD_FUNCTION_ - ::std::function<R()> AsStdFunction() { - return [this]() -> R { - return this->Call(); - }; - } -#endif // GTEST_HAS_STD_FUNCTION_ - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); -}; - -template <typename R, typename A0> -class MockFunction<R(A0)> { - public: - MockFunction() {} - - MOCK_METHOD1_T(Call, R(A0)); - -#if GTEST_HAS_STD_FUNCTION_ - ::std::function<R(A0)> AsStdFunction() { - return [this](A0 a0) -> R { - return this->Call(::std::move(a0)); - }; - } -#endif // GTEST_HAS_STD_FUNCTION_ - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); -}; - -template <typename R, typename A0, typename A1> -class MockFunction<R(A0, A1)> { - public: - MockFunction() {} - - MOCK_METHOD2_T(Call, R(A0, A1)); - -#if GTEST_HAS_STD_FUNCTION_ - ::std::function<R(A0, A1)> AsStdFunction() { - return [this](A0 a0, A1 a1) -> R { - return this->Call(::std::move(a0), ::std::move(a1)); - }; - } -#endif // GTEST_HAS_STD_FUNCTION_ - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); -}; - -template <typename R, typename A0, typename A1, typename A2> -class MockFunction<R(A0, A1, A2)> { - public: - MockFunction() {} - - MOCK_METHOD3_T(Call, R(A0, A1, A2)); - -#if GTEST_HAS_STD_FUNCTION_ - ::std::function<R(A0, A1, A2)> AsStdFunction() { - return [this](A0 a0, A1 a1, A2 a2) -> R { - return this->Call(::std::move(a0), ::std::move(a1), ::std::move(a2)); - }; - } -#endif // GTEST_HAS_STD_FUNCTION_ - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); -}; - -template <typename R, typename A0, typename A1, typename A2, typename A3> -class MockFunction<R(A0, A1, A2, A3)> { - public: - MockFunction() {} - - MOCK_METHOD4_T(Call, R(A0, A1, A2, A3)); - -#if GTEST_HAS_STD_FUNCTION_ - ::std::function<R(A0, A1, A2, A3)> AsStdFunction() { - return [this](A0 a0, A1 a1, A2 a2, A3 a3) -> R { - return this->Call(::std::move(a0), ::std::move(a1), ::std::move(a2), - ::std::move(a3)); - }; - } -#endif // GTEST_HAS_STD_FUNCTION_ - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); -}; - -template <typename R, typename A0, typename A1, typename A2, typename A3, - typename A4> -class MockFunction<R(A0, A1, A2, A3, A4)> { - public: - MockFunction() {} - - MOCK_METHOD5_T(Call, R(A0, A1, A2, A3, A4)); - -#if GTEST_HAS_STD_FUNCTION_ - ::std::function<R(A0, A1, A2, A3, A4)> AsStdFunction() { - return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) -> R { - return this->Call(::std::move(a0), ::std::move(a1), ::std::move(a2), - ::std::move(a3), ::std::move(a4)); - }; - } -#endif // GTEST_HAS_STD_FUNCTION_ - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); -}; - -template <typename R, typename A0, typename A1, typename A2, typename A3, - typename A4, typename A5> -class MockFunction<R(A0, A1, A2, A3, A4, A5)> { - public: - MockFunction() {} - - MOCK_METHOD6_T(Call, R(A0, A1, A2, A3, A4, A5)); - -#if GTEST_HAS_STD_FUNCTION_ - ::std::function<R(A0, A1, A2, A3, A4, A5)> AsStdFunction() { - return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) -> R { - return this->Call(::std::move(a0), ::std::move(a1), ::std::move(a2), - ::std::move(a3), ::std::move(a4), ::std::move(a5)); - }; - } -#endif // GTEST_HAS_STD_FUNCTION_ - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); -}; - -template <typename R, typename A0, typename A1, typename A2, typename A3, - typename A4, typename A5, typename A6> -class MockFunction<R(A0, A1, A2, A3, A4, A5, A6)> { - public: - MockFunction() {} - - MOCK_METHOD7_T(Call, R(A0, A1, A2, A3, A4, A5, A6)); - -#if GTEST_HAS_STD_FUNCTION_ - ::std::function<R(A0, A1, A2, A3, A4, A5, A6)> AsStdFunction() { - return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) -> R { - return this->Call(::std::move(a0), ::std::move(a1), ::std::move(a2), - ::std::move(a3), ::std::move(a4), ::std::move(a5), ::std::move(a6)); - }; - } -#endif // GTEST_HAS_STD_FUNCTION_ - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); -}; - -template <typename R, typename A0, typename A1, typename A2, typename A3, - typename A4, typename A5, typename A6, typename A7> -class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7)> { - public: - MockFunction() {} - - MOCK_METHOD8_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7)); - -#if GTEST_HAS_STD_FUNCTION_ - ::std::function<R(A0, A1, A2, A3, A4, A5, A6, A7)> AsStdFunction() { - return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) -> R { - return this->Call(::std::move(a0), ::std::move(a1), ::std::move(a2), - ::std::move(a3), ::std::move(a4), ::std::move(a5), ::std::move(a6), - ::std::move(a7)); - }; - } -#endif // GTEST_HAS_STD_FUNCTION_ - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); -}; - -template <typename R, typename A0, typename A1, typename A2, typename A3, - typename A4, typename A5, typename A6, typename A7, typename A8> -class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7, A8)> { - public: - MockFunction() {} - - MOCK_METHOD9_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8)); - -#if GTEST_HAS_STD_FUNCTION_ - ::std::function<R(A0, A1, A2, A3, A4, A5, A6, A7, A8)> AsStdFunction() { - return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, - A8 a8) -> R { - return this->Call(::std::move(a0), ::std::move(a1), ::std::move(a2), - ::std::move(a3), ::std::move(a4), ::std::move(a5), ::std::move(a6), - ::std::move(a7), ::std::move(a8)); - }; - } -#endif // GTEST_HAS_STD_FUNCTION_ - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); -}; - -template <typename R, typename A0, typename A1, typename A2, typename A3, - typename A4, typename A5, typename A6, typename A7, typename A8, - typename A9> -class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)> { - public: - MockFunction() {} - - MOCK_METHOD10_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)); - -#if GTEST_HAS_STD_FUNCTION_ - ::std::function<R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)> AsStdFunction() { - return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, - A8 a8, A9 a9) -> R { - return this->Call(::std::move(a0), ::std::move(a1), ::std::move(a2), - ::std::move(a3), ::std::move(a4), ::std::move(a5), ::std::move(a6), - ::std::move(a7), ::std::move(a8), ::std::move(a9)); - }; - } -#endif // GTEST_HAS_STD_FUNCTION_ - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); -}; - -} // namespace testing - -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ diff --git a/contrib/googletest/googlemock/include/gmock/gmock-generated-function-mockers.h.pump b/contrib/googletest/googlemock/include/gmock/gmock-generated-function-mockers.h.pump deleted file mode 100644 index 82f9512f0774..000000000000 --- a/contrib/googletest/googlemock/include/gmock/gmock-generated-function-mockers.h.pump +++ /dev/null @@ -1,348 +0,0 @@ -$$ -*- mode: c++; -*- -$$ This is a Pump source file. Please use Pump to convert -$$ it to gmock-generated-function-mockers.h. -$$ -$var n = 10 $$ The maximum arity we support. -// 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 function mockers of various arities. - -// GOOGLETEST_CM0002 DO NOT DELETE - -#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ - -#include "gmock/gmock-spec-builders.h" -#include "gmock/internal/gmock-internal-utils.h" - -#if GTEST_HAS_STD_FUNCTION_ -# include <functional> -#endif - -namespace testing { -namespace internal { - -template <typename F> -class FunctionMockerBase; - -// Note: class FunctionMocker 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 -// FunctionMocker in ::testing::internal and import it into ::testing. -template <typename F> -class FunctionMocker; - - -$range i 0..n -$for i [[ -$range j 1..i -$var typename_As = [[$for j [[, typename A$j]]]] -$var As = [[$for j, [[A$j]]]] -$var as = [[$for j, [[internal::forward<A$j>(a$j)]]]] -$var Aas = [[$for j, [[A$j a$j]]]] -$var ms = [[$for j, [[m$j]]]] -$var matchers = [[$for j, [[const Matcher<A$j>& m$j]]]] -template <typename R$typename_As> -class FunctionMocker<R($As)> : public - internal::FunctionMockerBase<R($As)> { - public: - typedef R F($As); - typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - - MockSpec<F> With($matchers) { - return MockSpec<F>(this, ::testing::make_tuple($ms)); - } - - R Invoke($Aas) { - // Even though gcc and MSVC don't enforce it, 'this->' is required - // by the C++ standard [14.6.4] here, as the base class type is - // dependent on the template argument (and thus shouldn't be - // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple($as)); - } -}; - - -]] -// Removes the given pointer; this is a helper for the expectation setter method -// for parameterless matchers. -// -// We want to make sure that the user cannot set a parameterless expectation on -// overloaded methods, including methods which are overloaded on const. Example: -// -// class MockClass { -// MOCK_METHOD0(GetName, string&()); -// MOCK_CONST_METHOD0(GetName, const string&()); -// }; -// -// TEST() { -// // This should be an error, as it's not clear which overload is expected. -// EXPECT_CALL(mock, GetName).WillOnce(ReturnRef(value)); -// } -// -// Here are the generated expectation-setter methods: -// -// class MockClass { -// // Overload 1 -// MockSpec<string&()> gmock_GetName() { ... } -// // Overload 2. Declared const so that the compiler will generate an -// // error when trying to resolve between this and overload 4 in -// // 'gmock_GetName(WithoutMatchers(), nullptr)'. -// MockSpec<string&()> gmock_GetName( -// const WithoutMatchers&, const Function<string&()>*) const { -// // Removes const from this, calls overload 1 -// return AdjustConstness_(this)->gmock_GetName(); -// } -// -// // Overload 3 -// const string& gmock_GetName() const { ... } -// // Overload 4 -// MockSpec<const string&()> gmock_GetName( -// const WithoutMatchers&, const Function<const string&()>*) const { -// // Does not remove const, calls overload 3 -// return AdjustConstness_const(this)->gmock_GetName(); -// } -// } -// -template <typename MockType> -const MockType* AdjustConstness_const(const MockType* mock) { - return mock; -} - -// Removes const from and returns the given pointer; this is a helper for the -// expectation setter method for parameterless matchers. -template <typename MockType> -MockType* AdjustConstness_(const MockType* mock) { - return 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; - -// GMOCK_RESULT_(tn, F) expands to the result type of function type F. -// We define this as a variadic macro in case F contains unprotected -// commas (the same reason that we use variadic macros in other places -// in this file). -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_RESULT_(tn, ...) \ - tn ::testing::internal::Function<__VA_ARGS__>::Result - -// The type of argument N of the given function type. -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_ARG_(tn, N, ...) \ - tn ::testing::internal::Function<__VA_ARGS__>::Argument##N - -// The matcher type for argument N of the given function type. -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_MATCHER_(tn, N, ...) \ - const ::testing::Matcher<GMOCK_ARG_(tn, N, __VA_ARGS__)>& - -// The variable for mocking the given method. -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_MOCKER_(arity, constness, Method) \ - GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__) - - -$for i [[ -$range j 1..i -$var arg_as = [[$for j, [[GMOCK_ARG_(tn, $j, __VA_ARGS__) gmock_a$j]]]] -$var as = [[$for j, \ - [[::testing::internal::forward<GMOCK_ARG_(tn, $j, __VA_ARGS__)>(gmock_a$j)]]]] -$var matcher_arg_as = [[$for j, \ - [[GMOCK_MATCHER_(tn, $j, __VA_ARGS__) gmock_a$j]]]] -$var matcher_as = [[$for j, [[gmock_a$j]]]] -$var anything_matchers = [[$for j, \ - [[::testing::A<GMOCK_ARG_(tn, $j, __VA_ARGS__)>()]]]] -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD$i[[]]_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - $arg_as) constness { \ - GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ - tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value == $i), \ - this_method_does_not_take_$i[[]]_argument[[$if i != 1 [[s]]]]); \ - GMOCK_MOCKER_($i, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_($i, constness, Method).Invoke($as); \ - } \ - ::testing::MockSpec<__VA_ARGS__> \ - gmock_##Method($matcher_arg_as) constness { \ - GMOCK_MOCKER_($i, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_($i, constness, Method).With($matcher_as); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - const ::testing::internal::WithoutMatchers&, \ - constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ - return ::testing::internal::AdjustConstness_##constness(this)-> \ - gmock_##Method($anything_matchers); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_($i, constness, Method) - - -]] -$for i [[ -#define MOCK_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, , , m, __VA_ARGS__) - -]] - - -$for i [[ -#define MOCK_CONST_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, const, , m, __VA_ARGS__) - -]] - - -$for i [[ -#define MOCK_METHOD$i[[]]_T(m, ...) GMOCK_METHOD$i[[]]_(typename, , , m, __VA_ARGS__) - -]] - - -$for i [[ -#define MOCK_CONST_METHOD$i[[]]_T(m, ...) \ - GMOCK_METHOD$i[[]]_(typename, const, , m, __VA_ARGS__) - -]] - - -$for i [[ -#define MOCK_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD$i[[]]_(, , ct, m, __VA_ARGS__) - -]] - - -$for i [[ -#define MOCK_CONST_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD$i[[]]_(, const, ct, m, __VA_ARGS__) - -]] - - -$for i [[ -#define MOCK_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD$i[[]]_(typename, , ct, m, __VA_ARGS__) - -]] - - -$for i [[ -#define MOCK_CONST_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD$i[[]]_(typename, const, ct, m, __VA_ARGS__) - -]] - -// A MockFunction<F> class has one mock method whose type is 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<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()); -// } -template <typename F> -class MockFunction; - - -$for i [[ -$range j 0..i-1 -$var ArgTypes = [[$for j, [[A$j]]]] -$var ArgValues = [[$for j, [[::std::move(a$j)]]]] -$var ArgDecls = [[$for j, [[A$j a$j]]]] -template <typename R$for j [[, typename A$j]]> -class MockFunction<R($ArgTypes)> { - public: - MockFunction() {} - - MOCK_METHOD$i[[]]_T(Call, R($ArgTypes)); - -#if GTEST_HAS_STD_FUNCTION_ - ::std::function<R($ArgTypes)> AsStdFunction() { - return [this]($ArgDecls) -> R { - return this->Call($ArgValues); - }; - } -#endif // GTEST_HAS_STD_FUNCTION_ - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); -}; - - -]] -} // namespace testing - -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ diff --git a/contrib/googletest/googlemock/include/gmock/gmock-generated-matchers.h b/contrib/googletest/googlemock/include/gmock/gmock-generated-matchers.h deleted file mode 100644 index 41d530488239..000000000000 --- a/contrib/googletest/googlemock/include/gmock/gmock-generated-matchers.h +++ /dev/null @@ -1,2260 +0,0 @@ -// This file was GENERATED by command: -// pump.py gmock-generated-matchers.h.pump -// DO NOT EDIT BY HAND!!! - -// 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 implements some commonly used variadic matchers. - -// GOOGLETEST_CM0002 DO NOT DELETE - -#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ - -#include <iterator> -#include <sstream> -#include <string> -#include <vector> -#include "gmock/gmock-matchers.h" - -namespace testing { -namespace internal { - -// The type of the i-th (0-based) field of Tuple. -#define GMOCK_FIELD_TYPE_(Tuple, i) \ - typename ::testing::tuple_element<i, Tuple>::type - -// TupleFields<Tuple, k0, ..., kn> is for selecting fields from a -// tuple of type Tuple. It has two members: -// -// type: a tuple type whose i-th field is the ki-th field of Tuple. -// GetSelectedFields(t): returns fields k0, ..., and kn of t as a tuple. -// -// For example, in class TupleFields<tuple<bool, char, int>, 2, 0>, we have: -// -// type is tuple<int, bool>, and -// GetSelectedFields(make_tuple(true, 'a', 42)) is (42, true). - -template <class Tuple, int k0 = -1, int k1 = -1, int k2 = -1, int k3 = -1, - int k4 = -1, int k5 = -1, int k6 = -1, int k7 = -1, int k8 = -1, - int k9 = -1> -class TupleFields; - -// This generic version is used when there are 10 selectors. -template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5, int k6, - int k7, int k8, int k9> -class TupleFields { - public: - typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), - GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2), - GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4), - GMOCK_FIELD_TYPE_(Tuple, k5), GMOCK_FIELD_TYPE_(Tuple, k6), - GMOCK_FIELD_TYPE_(Tuple, k7), GMOCK_FIELD_TYPE_(Tuple, k8), - GMOCK_FIELD_TYPE_(Tuple, k9)> type; - static type GetSelectedFields(const Tuple& t) { - return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t), - get<k5>(t), get<k6>(t), get<k7>(t), get<k8>(t), get<k9>(t)); - } -}; - -// The following specialization is used for 0 ~ 9 selectors. - -template <class Tuple> -class TupleFields<Tuple, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1> { - public: - typedef ::testing::tuple<> type; - static type GetSelectedFields(const Tuple& /* t */) { - return type(); - } -}; - -template <class Tuple, int k0> -class TupleFields<Tuple, k0, -1, -1, -1, -1, -1, -1, -1, -1, -1> { - public: - typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0)> type; - static type GetSelectedFields(const Tuple& t) { - return type(get<k0>(t)); - } -}; - -template <class Tuple, int k0, int k1> -class TupleFields<Tuple, k0, k1, -1, -1, -1, -1, -1, -1, -1, -1> { - public: - typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), - GMOCK_FIELD_TYPE_(Tuple, k1)> type; - static type GetSelectedFields(const Tuple& t) { - return type(get<k0>(t), get<k1>(t)); - } -}; - -template <class Tuple, int k0, int k1, int k2> -class TupleFields<Tuple, k0, k1, k2, -1, -1, -1, -1, -1, -1, -1> { - public: - typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), - GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2)> type; - static type GetSelectedFields(const Tuple& t) { - return type(get<k0>(t), get<k1>(t), get<k2>(t)); - } -}; - -template <class Tuple, int k0, int k1, int k2, int k3> -class TupleFields<Tuple, k0, k1, k2, k3, -1, -1, -1, -1, -1, -1> { - public: - typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), - GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2), - GMOCK_FIELD_TYPE_(Tuple, k3)> type; - static type GetSelectedFields(const Tuple& t) { - return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t)); - } -}; - -template <class Tuple, int k0, int k1, int k2, int k3, int k4> -class TupleFields<Tuple, k0, k1, k2, k3, k4, -1, -1, -1, -1, -1> { - public: - typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), - GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2), - GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4)> type; - static type GetSelectedFields(const Tuple& t) { - return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t)); - } -}; - -template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5> -class TupleFields<Tuple, k0, k1, k2, k3, k4, k5, -1, -1, -1, -1> { - public: - typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), - GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2), - GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4), - GMOCK_FIELD_TYPE_(Tuple, k5)> type; - static type GetSelectedFields(const Tuple& t) { - return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t), - get<k5>(t)); - } -}; - -template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5, int k6> -class TupleFields<Tuple, k0, k1, k2, k3, k4, k5, k6, -1, -1, -1> { - public: - typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), - GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2), - GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4), - GMOCK_FIELD_TYPE_(Tuple, k5), GMOCK_FIELD_TYPE_(Tuple, k6)> type; - static type GetSelectedFields(const Tuple& t) { - return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t), - get<k5>(t), get<k6>(t)); - } -}; - -template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5, int k6, - int k7> -class TupleFields<Tuple, k0, k1, k2, k3, k4, k5, k6, k7, -1, -1> { - public: - typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), - GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2), - GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4), - GMOCK_FIELD_TYPE_(Tuple, k5), GMOCK_FIELD_TYPE_(Tuple, k6), - GMOCK_FIELD_TYPE_(Tuple, k7)> type; - static type GetSelectedFields(const Tuple& t) { - return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t), - get<k5>(t), get<k6>(t), get<k7>(t)); - } -}; - -template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5, int k6, - int k7, int k8> -class TupleFields<Tuple, k0, k1, k2, k3, k4, k5, k6, k7, k8, -1> { - public: - typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), - GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2), - GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4), - GMOCK_FIELD_TYPE_(Tuple, k5), GMOCK_FIELD_TYPE_(Tuple, k6), - GMOCK_FIELD_TYPE_(Tuple, k7), GMOCK_FIELD_TYPE_(Tuple, k8)> type; - static type GetSelectedFields(const Tuple& t) { - return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t), - get<k5>(t), get<k6>(t), get<k7>(t), get<k8>(t)); - } -}; - -#undef GMOCK_FIELD_TYPE_ - -// Implements the Args() matcher. -template <class ArgsTuple, int k0 = -1, int k1 = -1, int k2 = -1, int k3 = -1, - int k4 = -1, int k5 = -1, int k6 = -1, int k7 = -1, int k8 = -1, - int k9 = -1> -class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> { - public: - // ArgsTuple may have top-level const or reference modifiers. - typedef GTEST_REMOVE_REFERENCE_AND_CONST_(ArgsTuple) RawArgsTuple; - typedef typename internal::TupleFields<RawArgsTuple, k0, k1, k2, k3, k4, k5, - k6, k7, k8, k9>::type SelectedArgs; - typedef Matcher<const SelectedArgs&> MonomorphicInnerMatcher; - - template <typename InnerMatcher> - explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher) - : inner_matcher_(SafeMatcherCast<const SelectedArgs&>(inner_matcher)) {} - - virtual bool MatchAndExplain(ArgsTuple args, - MatchResultListener* listener) const { - const SelectedArgs& selected_args = GetSelectedArgs(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; - } - - virtual void DescribeTo(::std::ostream* os) const { - *os << "are a tuple "; - PrintIndices(os); - inner_matcher_.DescribeTo(os); - } - - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "are a tuple "; - PrintIndices(os); - inner_matcher_.DescribeNegationTo(os); - } - - private: - static SelectedArgs GetSelectedArgs(ArgsTuple args) { - return TupleFields<RawArgsTuple, k0, k1, k2, k3, k4, k5, k6, k7, k8, - k9>::GetSelectedFields(args); - } - - // Prints the indices of the selected fields. - static void PrintIndices(::std::ostream* os) { - *os << "whose fields ("; - const int indices[10] = { k0, k1, k2, k3, k4, k5, k6, k7, k8, k9 }; - for (int i = 0; i < 10; i++) { - if (indices[i] < 0) - break; - - if (i >= 1) - *os << ", "; - - *os << "#" << indices[i]; - } - *os << ") "; - } - - const MonomorphicInnerMatcher inner_matcher_; - - GTEST_DISALLOW_ASSIGN_(ArgsMatcherImpl); -}; - -template <class InnerMatcher, int k0 = -1, int k1 = -1, int k2 = -1, - int k3 = -1, int k4 = -1, int k5 = -1, int k6 = -1, int k7 = -1, - int k8 = -1, int k9 = -1> -class ArgsMatcher { - public: - explicit ArgsMatcher(const InnerMatcher& inner_matcher) - : inner_matcher_(inner_matcher) {} - - template <typename ArgsTuple> - operator Matcher<ArgsTuple>() const { - return MakeMatcher(new ArgsMatcherImpl<ArgsTuple, k0, k1, k2, k3, k4, k5, - k6, k7, k8, k9>(inner_matcher_)); - } - - private: - const InnerMatcher inner_matcher_; - - GTEST_DISALLOW_ASSIGN_(ArgsMatcher); -}; - -// A set of metafunctions for computing the result type of AllOf. -// AllOf(m1, ..., mN) returns -// AllOfResultN<decltype(m1), ..., decltype(mN)>::type. - -// Although AllOf isn't defined for one argument, AllOfResult1 is defined -// to simplify the implementation. -template <typename M1> -struct AllOfResult1 { - typedef M1 type; -}; - -template <typename M1, typename M2> -struct AllOfResult2 { - typedef BothOfMatcher< - typename AllOfResult1<M1>::type, - typename AllOfResult1<M2>::type - > type; -}; - -template <typename M1, typename M2, typename M3> -struct AllOfResult3 { - typedef BothOfMatcher< - typename AllOfResult1<M1>::type, - typename AllOfResult2<M2, M3>::type - > type; -}; - -template <typename M1, typename M2, typename M3, typename M4> -struct AllOfResult4 { - typedef BothOfMatcher< - typename AllOfResult2<M1, M2>::type, - typename AllOfResult2<M3, M4>::type - > type; -}; - -template <typename M1, typename M2, typename M3, typename M4, typename M5> -struct AllOfResult5 { - typedef BothOfMatcher< - typename AllOfResult2<M1, M2>::type, - typename AllOfResult3<M3, M4, M5>::type - > type; -}; - -template <typename M1, typename M2, typename M3, typename M4, typename M5, - typename M6> -struct AllOfResult6 { - typedef BothOfMatcher< - typename AllOfResult3<M1, M2, M3>::type, - typename AllOfResult3<M4, M5, M6>::type - > type; -}; - -template <typename M1, typename M2, typename M3, typename M4, typename M5, - typename M6, typename M7> -struct AllOfResult7 { - typedef BothOfMatcher< - typename AllOfResult3<M1, M2, M3>::type, - typename AllOfResult4<M4, M5, M6, M7>::type - > type; -}; - -template <typename M1, typename M2, typename M3, typename M4, typename M5, - typename M6, typename M7, typename M8> -struct AllOfResult8 { - typedef BothOfMatcher< - typename AllOfResult4<M1, M2, M3, M4>::type, - typename AllOfResult4<M5, M6, M7, M8>::type - > type; -}; - -template <typename M1, typename M2, typename M3, typename M4, typename M5, - typename M6, typename M7, typename M8, typename M9> -struct AllOfResult9 { - typedef BothOfMatcher< - typename AllOfResult4<M1, M2, M3, M4>::type, - typename AllOfResult5<M5, M6, M7, M8, M9>::type - > type; -}; - -template <typename M1, typename M2, typename M3, typename M4, typename M5, - typename M6, typename M7, typename M8, typename M9, typename M10> -struct AllOfResult10 { - typedef BothOfMatcher< - typename AllOfResult5<M1, M2, M3, M4, M5>::type, - typename AllOfResult5<M6, M7, M8, M9, M10>::type - > type; -}; - -// A set of metafunctions for computing the result type of AnyOf. -// AnyOf(m1, ..., mN) returns -// AnyOfResultN<decltype(m1), ..., decltype(mN)>::type. - -// Although AnyOf isn't defined for one argument, AnyOfResult1 is defined -// to simplify the implementation. -template <typename M1> -struct AnyOfResult1 { - typedef M1 type; -}; - -template <typename M1, typename M2> -struct AnyOfResult2 { - typedef EitherOfMatcher< - typename AnyOfResult1<M1>::type, - typename AnyOfResult1<M2>::type - > type; -}; - -template <typename M1, typename M2, typename M3> -struct AnyOfResult3 { - typedef EitherOfMatcher< - typename AnyOfResult1<M1>::type, - typename AnyOfResult2<M2, M3>::type - > type; -}; - -template <typename M1, typename M2, typename M3, typename M4> -struct AnyOfResult4 { - typedef EitherOfMatcher< - typename AnyOfResult2<M1, M2>::type, - typename AnyOfResult2<M3, M4>::type - > type; -}; - -template <typename M1, typename M2, typename M3, typename M4, typename M5> -struct AnyOfResult5 { - typedef EitherOfMatcher< - typename AnyOfResult2<M1, M2>::type, - typename AnyOfResult3<M3, M4, M5>::type - > type; -}; - -template <typename M1, typename M2, typename M3, typename M4, typename M5, - typename M6> -struct AnyOfResult6 { - typedef EitherOfMatcher< - typename AnyOfResult3<M1, M2, M3>::type, - typename AnyOfResult3<M4, M5, M6>::type - > type; -}; - -template <typename M1, typename M2, typename M3, typename M4, typename M5, - typename M6, typename M7> -struct AnyOfResult7 { - typedef EitherOfMatcher< - typename AnyOfResult3<M1, M2, M3>::type, - typename AnyOfResult4<M4, M5, M6, M7>::type - > type; -}; - -template <typename M1, typename M2, typename M3, typename M4, typename M5, - typename M6, typename M7, typename M8> -struct AnyOfResult8 { - typedef EitherOfMatcher< - typename AnyOfResult4<M1, M2, M3, M4>::type, - typename AnyOfResult4<M5, M6, M7, M8>::type - > type; -}; - -template <typename M1, typename M2, typename M3, typename M4, typename M5, - typename M6, typename M7, typename M8, typename M9> -struct AnyOfResult9 { - typedef EitherOfMatcher< - typename AnyOfResult4<M1, M2, M3, M4>::type, - typename AnyOfResult5<M5, M6, M7, M8, M9>::type - > type; -}; - -template <typename M1, typename M2, typename M3, typename M4, typename M5, - typename M6, typename M7, typename M8, typename M9, typename M10> -struct AnyOfResult10 { - typedef EitherOfMatcher< - typename AnyOfResult5<M1, M2, M3, M4, M5>::type, - typename AnyOfResult5<M6, M7, M8, M9, M10>::type - > type; -}; - -} // namespace internal - -// 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 <typename InnerMatcher> -inline internal::ArgsMatcher<InnerMatcher> -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher<InnerMatcher>(matcher); -} - -template <int k1, typename InnerMatcher> -inline internal::ArgsMatcher<InnerMatcher, k1> -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher<InnerMatcher, k1>(matcher); -} - -template <int k1, int k2, typename InnerMatcher> -inline internal::ArgsMatcher<InnerMatcher, k1, k2> -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher<InnerMatcher, k1, k2>(matcher); -} - -template <int k1, int k2, int k3, typename InnerMatcher> -inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3> -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher<InnerMatcher, k1, k2, k3>(matcher); -} - -template <int k1, int k2, int k3, int k4, typename InnerMatcher> -inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4> -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4>(matcher); -} - -template <int k1, int k2, int k3, int k4, int k5, typename InnerMatcher> -inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5> -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5>(matcher); -} - -template <int k1, int k2, int k3, int k4, int k5, int k6, typename InnerMatcher> -inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6> -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6>(matcher); -} - -template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, - typename InnerMatcher> -inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7> -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, - k7>(matcher); -} - -template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8, - typename InnerMatcher> -inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, k8> -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, - k8>(matcher); -} - -template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8, - int k9, typename InnerMatcher> -inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, k8, k9> -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, k8, - k9>(matcher); -} - -template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8, - int k9, int k10, typename InnerMatcher> -inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, k8, k9, - k10> -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, k8, - k9, k10>(matcher); -} - -// ElementsAre(e_1, e_2, ... e_n) matches an STL-style container with -// n elements, where the i-th element in the container must -// match the i-th argument in the list. Each argument of -// ElementsAre() can be either a value or a matcher. We support up to -// 10 arguments. -// -// The use of DecayArray in the implementation allows ElementsAre() -// to accept string literals, whose type is const char[N], but we -// want to treat them as const char*. -// -// NOTE: Since ElementsAre() cares about the order of the elements, it -// must not be used with containers whose elements's order is -// undefined (e.g. hash_map). - -inline internal::ElementsAreMatcher< - ::testing::tuple<> > -ElementsAre() { - typedef ::testing::tuple<> Args; - return internal::ElementsAreMatcher<Args>(Args()); -} - -template <typename T1> -inline internal::ElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray<T1>::type> > -ElementsAre(const T1& e1) { - typedef ::testing::tuple< - typename internal::DecayArray<T1>::type> Args; - return internal::ElementsAreMatcher<Args>(Args(e1)); -} - -template <typename T1, typename T2> -inline internal::ElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type> > -ElementsAre(const T1& e1, const T2& e2) { - typedef ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type> Args; - return internal::ElementsAreMatcher<Args>(Args(e1, e2)); -} - -template <typename T1, typename T2, typename T3> -inline internal::ElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type> > -ElementsAre(const T1& e1, const T2& e2, const T3& e3) { - typedef ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type> Args; - return internal::ElementsAreMatcher<Args>(Args(e1, e2, e3)); -} - -template <typename T1, typename T2, typename T3, typename T4> -inline internal::ElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type> > -ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4) { - typedef ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type> Args; - return internal::ElementsAreMatcher<Args>(Args(e1, e2, e3, e4)); -} - -template <typename T1, typename T2, typename T3, typename T4, typename T5> -inline internal::ElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type, - typename internal::DecayArray<T5>::type> > -ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, - const T5& e5) { - typedef ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type, - typename internal::DecayArray<T5>::type> Args; - return internal::ElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5)); -} - -template <typename T1, typename T2, typename T3, typename T4, typename T5, - typename T6> -inline internal::ElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type, - typename internal::DecayArray<T5>::type, - typename internal::DecayArray<T6>::type> > -ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, - const T5& e5, const T6& e6) { - typedef ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type, - typename internal::DecayArray<T5>::type, - typename internal::DecayArray<T6>::type> Args; - return internal::ElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5, e6)); -} - -template <typename T1, typename T2, typename T3, typename T4, typename T5, - typename T6, typename T7> -inline internal::ElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type, - typename internal::DecayArray<T5>::type, - typename internal::DecayArray<T6>::type, - typename internal::DecayArray<T7>::type> > -ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, - const T5& e5, const T6& e6, const T7& e7) { - typedef ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type, - typename internal::DecayArray<T5>::type, - typename internal::DecayArray<T6>::type, - typename internal::DecayArray<T7>::type> Args; - return internal::ElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5, e6, e7)); -} - -template <typename T1, typename T2, typename T3, typename T4, typename T5, - typename T6, typename T7, typename T8> -inline internal::ElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type, - typename internal::DecayArray<T5>::type, - typename internal::DecayArray<T6>::type, - typename internal::DecayArray<T7>::type, - typename internal::DecayArray<T8>::type> > -ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, - const T5& e5, const T6& e6, const T7& e7, const T8& e8) { - typedef ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type, - typename internal::DecayArray<T5>::type, - typename internal::DecayArray<T6>::type, - typename internal::DecayArray<T7>::type, - typename internal::DecayArray<T8>::type> Args; - return internal::ElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5, e6, e7, - e8)); -} - -template <typename T1, typename T2, typename T3, typename T4, typename T5, - typename T6, typename T7, typename T8, typename T9> -inline internal::ElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type, - typename internal::DecayArray<T5>::type, - typename internal::DecayArray<T6>::type, - typename internal::DecayArray<T7>::type, - typename internal::DecayArray<T8>::type, - typename internal::DecayArray<T9>::type> > -ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, - const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9) { - typedef ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type, - typename internal::DecayArray<T5>::type, - typename internal::DecayArray<T6>::type, - typename internal::DecayArray<T7>::type, - typename internal::DecayArray<T8>::type, - typename internal::DecayArray<T9>::type> Args; - return internal::ElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5, e6, e7, - e8, e9)); -} - -template <typename T1, typename T2, typename T3, typename T4, typename T5, - typename T6, typename T7, typename T8, typename T9, typename T10> -inline internal::ElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type, - typename internal::DecayArray<T5>::type, - typename internal::DecayArray<T6>::type, - typename internal::DecayArray<T7>::type, - typename internal::DecayArray<T8>::type, - typename internal::DecayArray<T9>::type, - typename internal::DecayArray<T10>::type> > -ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, - const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9, - const T10& e10) { - typedef ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type, - typename internal::DecayArray<T5>::type, - typename internal::DecayArray<T6>::type, - typename internal::DecayArray<T7>::type, - typename internal::DecayArray<T8>::type, - typename internal::DecayArray<T9>::type, - typename internal::DecayArray<T10>::type> Args; - return internal::ElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5, e6, e7, - e8, e9, e10)); -} - -// UnorderedElementsAre(e_1, e_2, ..., e_n) is an ElementsAre extension -// that matches n elements in any order. We support up to n=10 arguments. -// -// If you have >10 elements, consider UnorderedElementsAreArray() or -// UnorderedPointwise() instead. - -inline internal::UnorderedElementsAreMatcher< - ::testing::tuple<> > -UnorderedElementsAre() { - typedef ::testing::tuple<> Args; - return internal::UnorderedElementsAreMatcher<Args>(Args()); -} - -template <typename T1> -inline internal::UnorderedElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray<T1>::type> > -UnorderedElementsAre(const T1& e1) { - typedef ::testing::tuple< - typename internal::DecayArray<T1>::type> Args; - return internal::UnorderedElementsAreMatcher<Args>(Args(e1)); -} - -template <typename T1, typename T2> -inline internal::UnorderedElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type> > -UnorderedElementsAre(const T1& e1, const T2& e2) { - typedef ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type> Args; - return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2)); -} - -template <typename T1, typename T2, typename T3> -inline internal::UnorderedElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type> > -UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3) { - typedef ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type> Args; - return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2, e3)); -} - -template <typename T1, typename T2, typename T3, typename T4> -inline internal::UnorderedElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type> > -UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4) { - typedef ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type> Args; - return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2, e3, e4)); -} - -template <typename T1, typename T2, typename T3, typename T4, typename T5> -inline internal::UnorderedElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type, - typename internal::DecayArray<T5>::type> > -UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, - const T5& e5) { - typedef ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type, - typename internal::DecayArray<T5>::type> Args; - return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5)); -} - -template <typename T1, typename T2, typename T3, typename T4, typename T5, - typename T6> -inline internal::UnorderedElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type, - typename internal::DecayArray<T5>::type, - typename internal::DecayArray<T6>::type> > -UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, - const T5& e5, const T6& e6) { - typedef ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type, - typename internal::DecayArray<T5>::type, - typename internal::DecayArray<T6>::type> Args; - return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5, - e6)); -} - -template <typename T1, typename T2, typename T3, typename T4, typename T5, - typename T6, typename T7> -inline internal::UnorderedElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type, - typename internal::DecayArray<T5>::type, - typename internal::DecayArray<T6>::type, - typename internal::DecayArray<T7>::type> > -UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, - const T5& e5, const T6& e6, const T7& e7) { - typedef ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type, - typename internal::DecayArray<T5>::type, - typename internal::DecayArray<T6>::type, - typename internal::DecayArray<T7>::type> Args; - return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5, - e6, e7)); -} - -template <typename T1, typename T2, typename T3, typename T4, typename T5, - typename T6, typename T7, typename T8> -inline internal::UnorderedElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type, - typename internal::DecayArray<T5>::type, - typename internal::DecayArray<T6>::type, - typename internal::DecayArray<T7>::type, - typename internal::DecayArray<T8>::type> > -UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, - const T5& e5, const T6& e6, const T7& e7, const T8& e8) { - typedef ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type, - typename internal::DecayArray<T5>::type, - typename internal::DecayArray<T6>::type, - typename internal::DecayArray<T7>::type, - typename internal::DecayArray<T8>::type> Args; - return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5, - e6, e7, e8)); -} - -template <typename T1, typename T2, typename T3, typename T4, typename T5, - typename T6, typename T7, typename T8, typename T9> -inline internal::UnorderedElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type, - typename internal::DecayArray<T5>::type, - typename internal::DecayArray<T6>::type, - typename internal::DecayArray<T7>::type, - typename internal::DecayArray<T8>::type, - typename internal::DecayArray<T9>::type> > -UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, - const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9) { - typedef ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type, - typename internal::DecayArray<T5>::type, - typename internal::DecayArray<T6>::type, - typename internal::DecayArray<T7>::type, - typename internal::DecayArray<T8>::type, - typename internal::DecayArray<T9>::type> Args; - return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5, - e6, e7, e8, e9)); -} - -template <typename T1, typename T2, typename T3, typename T4, typename T5, - typename T6, typename T7, typename T8, typename T9, typename T10> -inline internal::UnorderedElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type, - typename internal::DecayArray<T5>::type, - typename internal::DecayArray<T6>::type, - typename internal::DecayArray<T7>::type, - typename internal::DecayArray<T8>::type, - typename internal::DecayArray<T9>::type, - typename internal::DecayArray<T10>::type> > -UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, - const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9, - const T10& e10) { - typedef ::testing::tuple< - typename internal::DecayArray<T1>::type, - typename internal::DecayArray<T2>::type, - typename internal::DecayArray<T3>::type, - typename internal::DecayArray<T4>::type, - typename internal::DecayArray<T5>::type, - typename internal::DecayArray<T6>::type, - typename internal::DecayArray<T7>::type, - typename internal::DecayArray<T8>::type, - typename internal::DecayArray<T9>::type, - typename internal::DecayArray<T10>::type> Args; - return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5, - e6, e7, e8, e9, e10)); -} - -// AllOf(m1, m2, ..., mk) matches any value that matches all of the given -// sub-matchers. AllOf is called fully qualified to prevent ADL from firing. - -template <typename M1, typename M2> -inline typename internal::AllOfResult2<M1, M2>::type -AllOf(M1 m1, M2 m2) { - return typename internal::AllOfResult2<M1, M2>::type( - m1, - m2); -} - -template <typename M1, typename M2, typename M3> -inline typename internal::AllOfResult3<M1, M2, M3>::type -AllOf(M1 m1, M2 m2, M3 m3) { - return typename internal::AllOfResult3<M1, M2, M3>::type( - m1, - ::testing::AllOf(m2, m3)); -} - -template <typename M1, typename M2, typename M3, typename M4> -inline typename internal::AllOfResult4<M1, M2, M3, M4>::type -AllOf(M1 m1, M2 m2, M3 m3, M4 m4) { - return typename internal::AllOfResult4<M1, M2, M3, M4>::type( - ::testing::AllOf(m1, m2), - ::testing::AllOf(m3, m4)); -} - -template <typename M1, typename M2, typename M3, typename M4, typename M5> -inline typename internal::AllOfResult5<M1, M2, M3, M4, M5>::type -AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5) { - return typename internal::AllOfResult5<M1, M2, M3, M4, M5>::type( - ::testing::AllOf(m1, m2), - ::testing::AllOf(m3, m4, m5)); -} - -template <typename M1, typename M2, typename M3, typename M4, typename M5, - typename M6> -inline typename internal::AllOfResult6<M1, M2, M3, M4, M5, M6>::type -AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6) { - return typename internal::AllOfResult6<M1, M2, M3, M4, M5, M6>::type( - ::testing::AllOf(m1, m2, m3), - ::testing::AllOf(m4, m5, m6)); -} - -template <typename M1, typename M2, typename M3, typename M4, typename M5, - typename M6, typename M7> -inline typename internal::AllOfResult7<M1, M2, M3, M4, M5, M6, M7>::type -AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7) { - return typename internal::AllOfResult7<M1, M2, M3, M4, M5, M6, M7>::type( - ::testing::AllOf(m1, m2, m3), - ::testing::AllOf(m4, m5, m6, m7)); -} - -template <typename M1, typename M2, typename M3, typename M4, typename M5, - typename M6, typename M7, typename M8> -inline typename internal::AllOfResult8<M1, M2, M3, M4, M5, M6, M7, M8>::type -AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8) { - return typename internal::AllOfResult8<M1, M2, M3, M4, M5, M6, M7, M8>::type( - ::testing::AllOf(m1, m2, m3, m4), - ::testing::AllOf(m5, m6, m7, m8)); -} - -template <typename M1, typename M2, typename M3, typename M4, typename M5, - typename M6, typename M7, typename M8, typename M9> -inline typename internal::AllOfResult9<M1, M2, M3, M4, M5, M6, M7, M8, M9>::type -AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9) { - return typename internal::AllOfResult9<M1, M2, M3, M4, M5, M6, M7, M8, - M9>::type( - ::testing::AllOf(m1, m2, m3, m4), - ::testing::AllOf(m5, m6, m7, m8, m9)); -} - -template <typename M1, typename M2, typename M3, typename M4, typename M5, - typename M6, typename M7, typename M8, typename M9, typename M10> -inline typename internal::AllOfResult10<M1, M2, M3, M4, M5, M6, M7, M8, M9, - M10>::type -AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { - return typename internal::AllOfResult10<M1, M2, M3, M4, M5, M6, M7, M8, M9, - M10>::type( - ::testing::AllOf(m1, m2, m3, m4, m5), - ::testing::AllOf(m6, m7, m8, m9, m10)); -} - -// AnyOf(m1, m2, ..., mk) matches any value that matches any of the given -// sub-matchers. AnyOf is called fully qualified to prevent ADL from firing. - -template <typename M1, typename M2> -inline typename internal::AnyOfResult2<M1, M2>::type -AnyOf(M1 m1, M2 m2) { - return typename internal::AnyOfResult2<M1, M2>::type( - m1, - m2); -} - -template <typename M1, typename M2, typename M3> -inline typename internal::AnyOfResult3<M1, M2, M3>::type -AnyOf(M1 m1, M2 m2, M3 m3) { - return typename internal::AnyOfResult3<M1, M2, M3>::type( - m1, - ::testing::AnyOf(m2, m3)); -} - -template <typename M1, typename M2, typename M3, typename M4> -inline typename internal::AnyOfResult4<M1, M2, M3, M4>::type -AnyOf(M1 m1, M2 m2, M3 m3, M4 m4) { - return typename internal::AnyOfResult4<M1, M2, M3, M4>::type( - ::testing::AnyOf(m1, m2), - ::testing::AnyOf(m3, m4)); -} - -template <typename M1, typename M2, typename M3, typename M4, typename M5> -inline typename internal::AnyOfResult5<M1, M2, M3, M4, M5>::type -AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5) { - return typename internal::AnyOfResult5<M1, M2, M3, M4, M5>::type( - ::testing::AnyOf(m1, m2), - ::testing::AnyOf(m3, m4, m5)); -} - -template <typename M1, typename M2, typename M3, typename M4, typename M5, - typename M6> -inline typename internal::AnyOfResult6<M1, M2, M3, M4, M5, M6>::type -AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6) { - return typename internal::AnyOfResult6<M1, M2, M3, M4, M5, M6>::type( - ::testing::AnyOf(m1, m2, m3), - ::testing::AnyOf(m4, m5, m6)); -} - -template <typename M1, typename M2, typename M3, typename M4, typename M5, - typename M6, typename M7> -inline typename internal::AnyOfResult7<M1, M2, M3, M4, M5, M6, M7>::type -AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7) { - return typename internal::AnyOfResult7<M1, M2, M3, M4, M5, M6, M7>::type( - ::testing::AnyOf(m1, m2, m3), - ::testing::AnyOf(m4, m5, m6, m7)); -} - -template <typename M1, typename M2, typename M3, typename M4, typename M5, - typename M6, typename M7, typename M8> -inline typename internal::AnyOfResult8<M1, M2, M3, M4, M5, M6, M7, M8>::type -AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8) { - return typename internal::AnyOfResult8<M1, M2, M3, M4, M5, M6, M7, M8>::type( - ::testing::AnyOf(m1, m2, m3, m4), - ::testing::AnyOf(m5, m6, m7, m8)); -} - -template <typename M1, typename M2, typename M3, typename M4, typename M5, - typename M6, typename M7, typename M8, typename M9> -inline typename internal::AnyOfResult9<M1, M2, M3, M4, M5, M6, M7, M8, M9>::type -AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9) { - return typename internal::AnyOfResult9<M1, M2, M3, M4, M5, M6, M7, M8, - M9>::type( - ::testing::AnyOf(m1, m2, m3, m4), - ::testing::AnyOf(m5, m6, m7, m8, m9)); -} - -template <typename M1, typename M2, typename M3, typename M4, typename M5, - typename M6, typename M7, typename M8, typename M9, typename M10> -inline typename internal::AnyOfResult10<M1, M2, M3, M4, M5, M6, M7, M8, M9, - M10>::type -AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { - return typename internal::AnyOfResult10<M1, M2, M3, M4, M5, M6, M7, M8, M9, - M10>::type( - ::testing::AnyOf(m1, m2, m3, m4, m5), - ::testing::AnyOf(m6, m7, m8, m9, m10)); -} - -} // namespace testing - - -// 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_P10 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. The reason is -// that C++ doesn't yet allow function-local types to be used to -// instantiate templates. The up-coming C++0x standard will fix this. -// Once that's done, we'll consider supporting using MATCHER*() inside -// a function. -// -// More Information -// ================ -// -// To learn more about using these macros, please search for 'MATCHER' -// on -// https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md - -#define MATCHER(name, description)\ - class name##Matcher {\ - public:\ - template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<\ - GTEST_REFERENCE_TO_CONST_(arg_type)> {\ - public:\ - gmock_Impl()\ - {}\ - virtual bool MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener) const;\ - virtual void DescribeTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(false);\ - }\ - virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ - *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, \ - ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::testing::tuple<>()));\ - }\ - };\ - template <typename arg_type>\ - operator ::testing::Matcher<arg_type>() const {\ - return ::testing::Matcher<arg_type>(\ - new gmock_Impl<arg_type>());\ - }\ - name##Matcher() {\ - }\ - private:\ - };\ - inline name##Matcher name() {\ - return name##Matcher();\ - }\ - template <typename arg_type>\ - bool name##Matcher::gmock_Impl<arg_type>::MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P(name, p0, description)\ - template <typename p0##_type>\ - class name##MatcherP {\ - public:\ - template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<\ - GTEST_REFERENCE_TO_CONST_(arg_type)> {\ - public:\ - explicit gmock_Impl(p0##_type gmock_p0)\ - : p0(::testing::internal::move(gmock_p0)) {}\ - virtual bool MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener) const;\ - virtual void DescribeTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(false);\ - }\ - virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type const p0;\ - 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(\ - ::testing::tuple<p0##_type>(p0)));\ - }\ - };\ - template <typename arg_type>\ - operator ::testing::Matcher<arg_type>() const {\ - return ::testing::Matcher<arg_type>(\ - new gmock_Impl<arg_type>(p0));\ - }\ - explicit name##MatcherP(p0##_type gmock_p0) : \ - p0(::testing::internal::move(gmock_p0)) {\ - }\ - p0##_type const p0;\ - private:\ - };\ - template <typename p0##_type>\ - inline name##MatcherP<p0##_type> name(p0##_type p0) {\ - return name##MatcherP<p0##_type>(p0);\ - }\ - template <typename p0##_type>\ - template <typename arg_type>\ - bool name##MatcherP<p0##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P2(name, p0, p1, description)\ - template <typename p0##_type, typename p1##_type>\ - class name##MatcherP2 {\ - public:\ - template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<\ - GTEST_REFERENCE_TO_CONST_(arg_type)> {\ - public:\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1)\ - : p0(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)) {}\ - virtual bool MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener) const;\ - virtual void DescribeTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(false);\ - }\ - virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - 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(\ - ::testing::tuple<p0##_type, p1##_type>(p0, p1)));\ - }\ - };\ - template <typename arg_type>\ - operator ::testing::Matcher<arg_type>() const {\ - return ::testing::Matcher<arg_type>(\ - new gmock_Impl<arg_type>(p0, p1));\ - }\ - name##MatcherP2(p0##_type gmock_p0, \ - p1##_type gmock_p1) : p0(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)) {\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - private:\ - };\ - template <typename p0##_type, typename p1##_type>\ - inline name##MatcherP2<p0##_type, p1##_type> name(p0##_type p0, \ - p1##_type p1) {\ - return name##MatcherP2<p0##_type, p1##_type>(p0, p1);\ - }\ - template <typename p0##_type, typename p1##_type>\ - template <typename arg_type>\ - bool name##MatcherP2<p0##_type, \ - p1##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P3(name, p0, p1, p2, description)\ - template <typename p0##_type, typename p1##_type, typename p2##_type>\ - class name##MatcherP3 {\ - public:\ - template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<\ - GTEST_REFERENCE_TO_CONST_(arg_type)> {\ - public:\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2)\ - : p0(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)), \ - p2(::testing::internal::move(gmock_p2)) {}\ - virtual bool MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener) const;\ - virtual void DescribeTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(false);\ - }\ - virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - 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(\ - ::testing::tuple<p0##_type, p1##_type, p2##_type>(p0, p1, \ - p2)));\ - }\ - };\ - template <typename arg_type>\ - operator ::testing::Matcher<arg_type>() const {\ - return ::testing::Matcher<arg_type>(\ - new gmock_Impl<arg_type>(p0, p1, p2));\ - }\ - name##MatcherP3(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2) : p0(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)), \ - p2(::testing::internal::move(gmock_p2)) {\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - private:\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type>\ - inline name##MatcherP3<p0##_type, p1##_type, p2##_type> name(p0##_type p0, \ - p1##_type p1, p2##_type p2) {\ - return name##MatcherP3<p0##_type, p1##_type, p2##_type>(p0, p1, p2);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type>\ - template <typename arg_type>\ - bool name##MatcherP3<p0##_type, p1##_type, \ - p2##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P4(name, p0, p1, p2, p3, description)\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type>\ - class name##MatcherP4 {\ - public:\ - template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<\ - GTEST_REFERENCE_TO_CONST_(arg_type)> {\ - public:\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3)\ - : p0(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)), \ - p2(::testing::internal::move(gmock_p2)), \ - p3(::testing::internal::move(gmock_p3)) {}\ - virtual bool MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener) const;\ - virtual void DescribeTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(false);\ - }\ - virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - 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(\ - ::testing::tuple<p0##_type, p1##_type, p2##_type, \ - p3##_type>(p0, p1, p2, p3)));\ - }\ - };\ - template <typename arg_type>\ - operator ::testing::Matcher<arg_type>() const {\ - return ::testing::Matcher<arg_type>(\ - new gmock_Impl<arg_type>(p0, p1, p2, p3));\ - }\ - name##MatcherP4(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, \ - p3##_type gmock_p3) : p0(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)), \ - p2(::testing::internal::move(gmock_p2)), \ - p3(::testing::internal::move(gmock_p3)) {\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - private:\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type>\ - inline name##MatcherP4<p0##_type, p1##_type, p2##_type, \ - p3##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, \ - p3##_type p3) {\ - return name##MatcherP4<p0##_type, p1##_type, p2##_type, p3##_type>(p0, \ - p1, p2, p3);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type>\ - template <typename arg_type>\ - bool name##MatcherP4<p0##_type, p1##_type, p2##_type, \ - p3##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P5(name, p0, p1, p2, p3, p4, description)\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type>\ - class name##MatcherP5 {\ - public:\ - template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<\ - GTEST_REFERENCE_TO_CONST_(arg_type)> {\ - public:\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4)\ - : p0(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)), \ - p2(::testing::internal::move(gmock_p2)), \ - p3(::testing::internal::move(gmock_p3)), \ - p4(::testing::internal::move(gmock_p4)) {}\ - virtual bool MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener) const;\ - virtual void DescribeTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(false);\ - }\ - virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - p4##_type const p4;\ - 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(\ - ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type>(p0, p1, p2, p3, p4)));\ - }\ - };\ - template <typename arg_type>\ - operator ::testing::Matcher<arg_type>() const {\ - return ::testing::Matcher<arg_type>(\ - new gmock_Impl<arg_type>(p0, p1, p2, p3, p4));\ - }\ - name##MatcherP5(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, \ - p4##_type gmock_p4) : p0(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)), \ - p2(::testing::internal::move(gmock_p2)), \ - p3(::testing::internal::move(gmock_p3)), \ - p4(::testing::internal::move(gmock_p4)) {\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - p4##_type const p4;\ - private:\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type>\ - inline name##MatcherP5<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ - p4##_type p4) {\ - return name##MatcherP5<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type>(p0, p1, p2, p3, p4);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type>\ - template <typename arg_type>\ - bool name##MatcherP5<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P6(name, p0, p1, p2, p3, p4, p5, description)\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type>\ - class name##MatcherP6 {\ - public:\ - template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<\ - GTEST_REFERENCE_TO_CONST_(arg_type)> {\ - public:\ - gmock_Impl(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(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)), \ - p2(::testing::internal::move(gmock_p2)), \ - p3(::testing::internal::move(gmock_p3)), \ - p4(::testing::internal::move(gmock_p4)), \ - p5(::testing::internal::move(gmock_p5)) {}\ - virtual bool MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener) const;\ - virtual void DescribeTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(false);\ - }\ - virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - p4##_type const p4;\ - p5##_type const p5;\ - 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(\ - ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type>(p0, p1, p2, p3, p4, p5)));\ - }\ - };\ - template <typename arg_type>\ - operator ::testing::Matcher<arg_type>() const {\ - return ::testing::Matcher<arg_type>(\ - new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5));\ - }\ - name##MatcherP6(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(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)), \ - p2(::testing::internal::move(gmock_p2)), \ - p3(::testing::internal::move(gmock_p3)), \ - p4(::testing::internal::move(gmock_p4)), \ - p5(::testing::internal::move(gmock_p5)) {\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - p4##_type const p4;\ - p5##_type const p5;\ - private:\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type>\ - inline name##MatcherP6<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, \ - p3##_type p3, p4##_type p4, p5##_type p5) {\ - return name##MatcherP6<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type>(p0, p1, p2, p3, p4, p5);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type>\ - template <typename arg_type>\ - bool name##MatcherP6<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ - p5##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P7(name, p0, p1, p2, p3, p4, p5, p6, description)\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type>\ - class name##MatcherP7 {\ - public:\ - template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<\ - GTEST_REFERENCE_TO_CONST_(arg_type)> {\ - public:\ - gmock_Impl(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(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)), \ - p2(::testing::internal::move(gmock_p2)), \ - p3(::testing::internal::move(gmock_p3)), \ - p4(::testing::internal::move(gmock_p4)), \ - p5(::testing::internal::move(gmock_p5)), \ - p6(::testing::internal::move(gmock_p6)) {}\ - virtual bool MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener) const;\ - virtual void DescribeTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(false);\ - }\ - virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - p4##_type const p4;\ - p5##_type const p5;\ - p6##_type const p6;\ - 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(\ - ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type>(p0, p1, p2, p3, p4, p5, \ - p6)));\ - }\ - };\ - template <typename arg_type>\ - operator ::testing::Matcher<arg_type>() const {\ - return ::testing::Matcher<arg_type>(\ - new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, p6));\ - }\ - name##MatcherP7(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(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)), \ - p2(::testing::internal::move(gmock_p2)), \ - p3(::testing::internal::move(gmock_p3)), \ - p4(::testing::internal::move(gmock_p4)), \ - p5(::testing::internal::move(gmock_p5)), \ - p6(::testing::internal::move(gmock_p6)) {\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - p4##_type const p4;\ - p5##_type const p5;\ - p6##_type const p6;\ - private:\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type>\ - inline name##MatcherP7<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type> name(p0##_type p0, p1##_type p1, \ - p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \ - p6##_type p6) {\ - return name##MatcherP7<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type>(p0, p1, p2, p3, p4, p5, p6);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type>\ - template <typename arg_type>\ - bool name##MatcherP7<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ - p5##_type, p6##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P8(name, p0, p1, p2, p3, p4, p5, p6, p7, description)\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type>\ - class name##MatcherP8 {\ - public:\ - template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<\ - GTEST_REFERENCE_TO_CONST_(arg_type)> {\ - public:\ - gmock_Impl(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(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)), \ - p2(::testing::internal::move(gmock_p2)), \ - p3(::testing::internal::move(gmock_p3)), \ - p4(::testing::internal::move(gmock_p4)), \ - p5(::testing::internal::move(gmock_p5)), \ - p6(::testing::internal::move(gmock_p6)), \ - p7(::testing::internal::move(gmock_p7)) {}\ - virtual bool MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener) const;\ - virtual void DescribeTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(false);\ - }\ - virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - p4##_type const p4;\ - p5##_type const p5;\ - p6##_type const p6;\ - p7##_type const p7;\ - 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(\ - ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type>(p0, p1, p2, \ - p3, p4, p5, p6, p7)));\ - }\ - };\ - template <typename arg_type>\ - operator ::testing::Matcher<arg_type>() const {\ - return ::testing::Matcher<arg_type>(\ - new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, p6, p7));\ - }\ - name##MatcherP8(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(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)), \ - p2(::testing::internal::move(gmock_p2)), \ - p3(::testing::internal::move(gmock_p3)), \ - p4(::testing::internal::move(gmock_p4)), \ - p5(::testing::internal::move(gmock_p5)), \ - p6(::testing::internal::move(gmock_p6)), \ - p7(::testing::internal::move(gmock_p7)) {\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - p4##_type const p4;\ - p5##_type const p5;\ - p6##_type const p6;\ - p7##_type const p7;\ - private:\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type>\ - inline name##MatcherP8<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type> name(p0##_type p0, \ - p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \ - p6##_type p6, p7##_type p7) {\ - return name##MatcherP8<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type>(p0, p1, p2, p3, p4, p5, \ - p6, p7);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type>\ - template <typename arg_type>\ - bool name##MatcherP8<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ - p5##_type, p6##_type, \ - p7##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, description)\ - template <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>\ - class name##MatcherP9 {\ - public:\ - template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<\ - GTEST_REFERENCE_TO_CONST_(arg_type)> {\ - public:\ - gmock_Impl(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(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)), \ - p2(::testing::internal::move(gmock_p2)), \ - p3(::testing::internal::move(gmock_p3)), \ - p4(::testing::internal::move(gmock_p4)), \ - p5(::testing::internal::move(gmock_p5)), \ - p6(::testing::internal::move(gmock_p6)), \ - p7(::testing::internal::move(gmock_p7)), \ - p8(::testing::internal::move(gmock_p8)) {}\ - virtual bool MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener) const;\ - virtual void DescribeTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(false);\ - }\ - virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - p4##_type const p4;\ - p5##_type const p5;\ - p6##_type const p6;\ - p7##_type const p7;\ - p8##_type const p8;\ - 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(\ - ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type, \ - p8##_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8)));\ - }\ - };\ - template <typename arg_type>\ - operator ::testing::Matcher<arg_type>() const {\ - return ::testing::Matcher<arg_type>(\ - new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8));\ - }\ - name##MatcherP9(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(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)), \ - p2(::testing::internal::move(gmock_p2)), \ - p3(::testing::internal::move(gmock_p3)), \ - p4(::testing::internal::move(gmock_p4)), \ - p5(::testing::internal::move(gmock_p5)), \ - p6(::testing::internal::move(gmock_p6)), \ - p7(::testing::internal::move(gmock_p7)), \ - p8(::testing::internal::move(gmock_p8)) {\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - p4##_type const p4;\ - p5##_type const p5;\ - p6##_type const p6;\ - p7##_type const p7;\ - p8##_type const p8;\ - private:\ - };\ - template <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>\ - inline name##MatcherP9<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type, \ - p8##_type> name(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) {\ - return name##MatcherP9<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type, p8##_type>(p0, p1, p2, \ - p3, p4, p5, p6, p7, p8);\ - }\ - template <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>\ - template <typename arg_type>\ - bool name##MatcherP9<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ - p5##_type, p6##_type, p7##_type, \ - p8##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, description)\ - template <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>\ - class name##MatcherP10 {\ - public:\ - template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<\ - GTEST_REFERENCE_TO_CONST_(arg_type)> {\ - public:\ - gmock_Impl(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(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)), \ - p2(::testing::internal::move(gmock_p2)), \ - p3(::testing::internal::move(gmock_p3)), \ - p4(::testing::internal::move(gmock_p4)), \ - p5(::testing::internal::move(gmock_p5)), \ - p6(::testing::internal::move(gmock_p6)), \ - p7(::testing::internal::move(gmock_p7)), \ - p8(::testing::internal::move(gmock_p8)), \ - p9(::testing::internal::move(gmock_p9)) {}\ - virtual bool MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener) const;\ - virtual void DescribeTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(false);\ - }\ - virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - p4##_type const p4;\ - p5##_type const p5;\ - p6##_type const p6;\ - p7##_type const p7;\ - p8##_type const p8;\ - p9##_type const p9;\ - 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(\ - ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, \ - p9##_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)));\ - }\ - };\ - template <typename arg_type>\ - operator ::testing::Matcher<arg_type>() const {\ - return ::testing::Matcher<arg_type>(\ - new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9));\ - }\ - name##MatcherP10(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(::testing::internal::move(gmock_p0)), \ - p1(::testing::internal::move(gmock_p1)), \ - p2(::testing::internal::move(gmock_p2)), \ - p3(::testing::internal::move(gmock_p3)), \ - p4(::testing::internal::move(gmock_p4)), \ - p5(::testing::internal::move(gmock_p5)), \ - p6(::testing::internal::move(gmock_p6)), \ - p7(::testing::internal::move(gmock_p7)), \ - p8(::testing::internal::move(gmock_p8)), \ - p9(::testing::internal::move(gmock_p9)) {\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - p4##_type const p4;\ - p5##_type const p5;\ - p6##_type const p6;\ - p7##_type const p7;\ - p8##_type const p8;\ - p9##_type const p9;\ - private:\ - };\ - template <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>\ - inline name##MatcherP10<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, \ - p9##_type> name(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) {\ - return name##MatcherP10<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, p9##_type>(p0, \ - p1, p2, p3, p4, p5, p6, p7, p8, p9);\ - }\ - template <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>\ - template <typename arg_type>\ - bool name##MatcherP10<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, \ - p9##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ diff --git a/contrib/googletest/googlemock/include/gmock/gmock-generated-matchers.h.pump b/contrib/googletest/googlemock/include/gmock/gmock-generated-matchers.h.pump deleted file mode 100644 index 1a59fedecff8..000000000000 --- a/contrib/googletest/googlemock/include/gmock/gmock-generated-matchers.h.pump +++ /dev/null @@ -1,678 +0,0 @@ -$$ -*- mode: c++; -*- -$$ This is a Pump source file. Please use Pump to convert -$$ it to gmock-generated-matchers.h. -$$ -$var n = 10 $$ The maximum arity we support. -$$ }} This line fixes auto-indentation of the following code in Emacs. -// 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 implements some commonly used variadic matchers. - -// GOOGLETEST_CM0002 DO NOT DELETE - -#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ - -#include <iterator> -#include <sstream> -#include <string> -#include <vector> -#include "gmock/gmock-matchers.h" - -namespace testing { -namespace internal { - -$range i 0..n-1 - -// The type of the i-th (0-based) field of Tuple. -#define GMOCK_FIELD_TYPE_(Tuple, i) \ - typename ::testing::tuple_element<i, Tuple>::type - -// TupleFields<Tuple, k0, ..., kn> is for selecting fields from a -// tuple of type Tuple. It has two members: -// -// type: a tuple type whose i-th field is the ki-th field of Tuple. -// GetSelectedFields(t): returns fields k0, ..., and kn of t as a tuple. -// -// For example, in class TupleFields<tuple<bool, char, int>, 2, 0>, we have: -// -// type is tuple<int, bool>, and -// GetSelectedFields(make_tuple(true, 'a', 42)) is (42, true). - -template <class Tuple$for i [[, int k$i = -1]]> -class TupleFields; - -// This generic version is used when there are $n selectors. -template <class Tuple$for i [[, int k$i]]> -class TupleFields { - public: - typedef ::testing::tuple<$for i, [[GMOCK_FIELD_TYPE_(Tuple, k$i)]]> type; - static type GetSelectedFields(const Tuple& t) { - return type($for i, [[get<k$i>(t)]]); - } -}; - -// The following specialization is used for 0 ~ $(n-1) selectors. - -$for i [[ -$$ }}} -$range j 0..i-1 -$range k 0..n-1 - -template <class Tuple$for j [[, int k$j]]> -class TupleFields<Tuple, $for k, [[$if k < i [[k$k]] $else [[-1]]]]> { - public: - typedef ::testing::tuple<$for j, [[GMOCK_FIELD_TYPE_(Tuple, k$j)]]> type; - static type GetSelectedFields(const Tuple& $if i==0 [[/* t */]] $else [[t]]) { - return type($for j, [[get<k$j>(t)]]); - } -}; - -]] - -#undef GMOCK_FIELD_TYPE_ - -// Implements the Args() matcher. - -$var ks = [[$for i, [[k$i]]]] -template <class ArgsTuple$for i [[, int k$i = -1]]> -class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> { - public: - // ArgsTuple may have top-level const or reference modifiers. - typedef GTEST_REMOVE_REFERENCE_AND_CONST_(ArgsTuple) RawArgsTuple; - typedef typename internal::TupleFields<RawArgsTuple, $ks>::type SelectedArgs; - typedef Matcher<const SelectedArgs&> MonomorphicInnerMatcher; - - template <typename InnerMatcher> - explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher) - : inner_matcher_(SafeMatcherCast<const SelectedArgs&>(inner_matcher)) {} - - virtual bool MatchAndExplain(ArgsTuple args, - MatchResultListener* listener) const { - const SelectedArgs& selected_args = GetSelectedArgs(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; - } - - virtual void DescribeTo(::std::ostream* os) const { - *os << "are a tuple "; - PrintIndices(os); - inner_matcher_.DescribeTo(os); - } - - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "are a tuple "; - PrintIndices(os); - inner_matcher_.DescribeNegationTo(os); - } - - private: - static SelectedArgs GetSelectedArgs(ArgsTuple args) { - return TupleFields<RawArgsTuple, $ks>::GetSelectedFields(args); - } - - // Prints the indices of the selected fields. - static void PrintIndices(::std::ostream* os) { - *os << "whose fields ("; - const int indices[$n] = { $ks }; - for (int i = 0; i < $n; i++) { - if (indices[i] < 0) - break; - - if (i >= 1) - *os << ", "; - - *os << "#" << indices[i]; - } - *os << ") "; - } - - const MonomorphicInnerMatcher inner_matcher_; - - GTEST_DISALLOW_ASSIGN_(ArgsMatcherImpl); -}; - -template <class InnerMatcher$for i [[, int k$i = -1]]> -class ArgsMatcher { - public: - explicit ArgsMatcher(const InnerMatcher& inner_matcher) - : inner_matcher_(inner_matcher) {} - - template <typename ArgsTuple> - operator Matcher<ArgsTuple>() const { - return MakeMatcher(new ArgsMatcherImpl<ArgsTuple, $ks>(inner_matcher_)); - } - - private: - const InnerMatcher inner_matcher_; - - GTEST_DISALLOW_ASSIGN_(ArgsMatcher); -}; - -// A set of metafunctions for computing the result type of AllOf. -// AllOf(m1, ..., mN) returns -// AllOfResultN<decltype(m1), ..., decltype(mN)>::type. - -// Although AllOf isn't defined for one argument, AllOfResult1 is defined -// to simplify the implementation. -template <typename M1> -struct AllOfResult1 { - typedef M1 type; -}; - -$range i 1..n - -$range i 2..n -$for i [[ -$range j 2..i -$var m = i/2 -$range k 1..m -$range t m+1..i - -template <typename M1$for j [[, typename M$j]]> -struct AllOfResult$i { - typedef BothOfMatcher< - typename AllOfResult$m<$for k, [[M$k]]>::type, - typename AllOfResult$(i-m)<$for t, [[M$t]]>::type - > type; -}; - -]] - -// A set of metafunctions for computing the result type of AnyOf. -// AnyOf(m1, ..., mN) returns -// AnyOfResultN<decltype(m1), ..., decltype(mN)>::type. - -// Although AnyOf isn't defined for one argument, AnyOfResult1 is defined -// to simplify the implementation. -template <typename M1> -struct AnyOfResult1 { - typedef M1 type; -}; - -$range i 1..n - -$range i 2..n -$for i [[ -$range j 2..i -$var m = i/2 -$range k 1..m -$range t m+1..i - -template <typename M1$for j [[, typename M$j]]> -struct AnyOfResult$i { - typedef EitherOfMatcher< - typename AnyOfResult$m<$for k, [[M$k]]>::type, - typename AnyOfResult$(i-m)<$for t, [[M$t]]>::type - > type; -}; - -]] - -} // namespace internal - -// 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. - -$range i 0..n -$for i [[ -$range j 1..i -template <$for j [[int k$j, ]]typename InnerMatcher> -inline internal::ArgsMatcher<InnerMatcher$for j [[, k$j]]> -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher<InnerMatcher$for j [[, k$j]]>(matcher); -} - - -]] -// ElementsAre(e_1, e_2, ... e_n) matches an STL-style container with -// n elements, where the i-th element in the container must -// match the i-th argument in the list. Each argument of -// ElementsAre() can be either a value or a matcher. We support up to -// $n arguments. -// -// The use of DecayArray in the implementation allows ElementsAre() -// to accept string literals, whose type is const char[N], but we -// want to treat them as const char*. -// -// NOTE: Since ElementsAre() cares about the order of the elements, it -// must not be used with containers whose elements's order is -// undefined (e.g. hash_map). - -$range i 0..n -$for i [[ - -$range j 1..i - -$if i>0 [[ - -template <$for j, [[typename T$j]]> -]] - -inline internal::ElementsAreMatcher< - ::testing::tuple< -$for j, [[ - - typename internal::DecayArray<T$j[[]]>::type]]> > -ElementsAre($for j, [[const T$j& e$j]]) { - typedef ::testing::tuple< -$for j, [[ - - typename internal::DecayArray<T$j[[]]>::type]]> Args; - return internal::ElementsAreMatcher<Args>(Args($for j, [[e$j]])); -} - -]] - -// UnorderedElementsAre(e_1, e_2, ..., e_n) is an ElementsAre extension -// that matches n elements in any order. We support up to n=$n arguments. -// -// If you have >$n elements, consider UnorderedElementsAreArray() or -// UnorderedPointwise() instead. - -$range i 0..n -$for i [[ - -$range j 1..i - -$if i>0 [[ - -template <$for j, [[typename T$j]]> -]] - -inline internal::UnorderedElementsAreMatcher< - ::testing::tuple< -$for j, [[ - - typename internal::DecayArray<T$j[[]]>::type]]> > -UnorderedElementsAre($for j, [[const T$j& e$j]]) { - typedef ::testing::tuple< -$for j, [[ - - typename internal::DecayArray<T$j[[]]>::type]]> Args; - return internal::UnorderedElementsAreMatcher<Args>(Args($for j, [[e$j]])); -} - -]] - -// AllOf(m1, m2, ..., mk) matches any value that matches all of the given -// sub-matchers. AllOf is called fully qualified to prevent ADL from firing. - -$range i 2..n -$for i [[ -$range j 1..i -$var m = i/2 -$range k 1..m -$range t m+1..i - -template <$for j, [[typename M$j]]> -inline typename internal::AllOfResult$i<$for j, [[M$j]]>::type -AllOf($for j, [[M$j m$j]]) { - return typename internal::AllOfResult$i<$for j, [[M$j]]>::type( - $if m == 1 [[m1]] $else [[::testing::AllOf($for k, [[m$k]])]], - $if m+1 == i [[m$i]] $else [[::testing::AllOf($for t, [[m$t]])]]); -} - -]] - -// AnyOf(m1, m2, ..., mk) matches any value that matches any of the given -// sub-matchers. AnyOf is called fully qualified to prevent ADL from firing. - -$range i 2..n -$for i [[ -$range j 1..i -$var m = i/2 -$range k 1..m -$range t m+1..i - -template <$for j, [[typename M$j]]> -inline typename internal::AnyOfResult$i<$for j, [[M$j]]>::type -AnyOf($for j, [[M$j m$j]]) { - return typename internal::AnyOfResult$i<$for j, [[M$j]]>::type( - $if m == 1 [[m1]] $else [[::testing::AnyOf($for k, [[m$k]])]], - $if m+1 == i [[m$i]] $else [[::testing::AnyOf($for t, [[m$t]])]]); -} - -]] - -} // namespace testing -$$ } // This Pump meta comment fixes auto-indentation in Emacs. It will not -$$ // show up in the generated code. - - -// 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. The reason is -// that C++ doesn't yet allow function-local types to be used to -// instantiate templates. The up-coming C++0x standard will fix this. -// Once that's done, we'll consider supporting using MATCHER*() inside -// a function. -// -// More Information -// ================ -// -// To learn more about using these macros, please search for 'MATCHER' -// on -// https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md - -$range i 0..n -$for i - -[[ -$var macro_name = [[$if i==0 [[MATCHER]] $elif i==1 [[MATCHER_P]] - $else [[MATCHER_P$i]]]] -$var class_name = [[name##Matcher[[$if i==0 [[]] $elif i==1 [[P]] - $else [[P$i]]]]]] -$range j 0..i-1 -$var template = [[$if i==0 [[]] $else [[ - - template <$for j, [[typename p$j##_type]]>\ -]]]] -$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]] -$var impl_ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]] -$var impl_inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::testing::internal::move(gmock_p$j))]]]]]] -$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::testing::internal::move(gmock_p$j))]]]]]] -$var params = [[$for j, [[p$j]]]] -$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]] -$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]] -$var param_field_decls = [[$for j -[[ - - p$j##_type const p$j;\ -]]]] -$var param_field_decls2 = [[$for j -[[ - - p$j##_type const p$j;\ -]]]] - -#define $macro_name(name$for j [[, p$j]], description)\$template - class $class_name {\ - public:\ - template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<\ - GTEST_REFERENCE_TO_CONST_(arg_type)> {\ - public:\ - [[$if i==1 [[explicit ]]]]gmock_Impl($impl_ctor_param_list)\ - $impl_inits {}\ - virtual bool MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener) const;\ - virtual void DescribeTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(false);\ - }\ - virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(true);\ - }\$param_field_decls - 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(\ - ::testing::tuple<$for j, [[p$j##_type]]>($for j, [[p$j]])));\ - }\ - };\ - template <typename arg_type>\ - operator ::testing::Matcher<arg_type>() const {\ - return ::testing::Matcher<arg_type>(\ - new gmock_Impl<arg_type>($params));\ - }\ - [[$if i==1 [[explicit ]]]]$class_name($ctor_param_list)$inits {\ - }\$param_field_decls2 - private:\ - };\$template - inline $class_name$param_types name($param_types_and_names) {\ - return $class_name$param_types($params);\ - }\$template - template <typename arg_type>\ - bool $class_name$param_types::gmock_Impl<arg_type>::MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const -]] - - -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ diff --git a/contrib/googletest/googlemock/include/gmock/gmock-generated-nice-strict.h b/contrib/googletest/googlemock/include/gmock/gmock-generated-nice-strict.h deleted file mode 100644 index 91ba1d9b2c07..000000000000 --- a/contrib/googletest/googlemock/include/gmock/gmock-generated-nice-strict.h +++ /dev/null @@ -1,459 +0,0 @@ -// This file was GENERATED by command: -// pump.py gmock-generated-nice-strict.h.pump -// DO NOT EDIT BY HAND!!! - -// 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_GENERATED_NICE_STRICT_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ - -#include "gmock/gmock-spec-builders.h" -#include "gmock/internal/gmock-port.h" - -namespace testing { - -template <class MockClass> -class NiceMock : public MockClass { - public: - NiceMock() : MockClass() { - ::testing::Mock::AllowUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - -#if GTEST_LANG_CXX11 - // Ideally, we would inherit base class's constructors through a using - // declaration, which would preserve their visibility. However, many existing - // tests rely on the fact that current implementation reexports protected - // constructors as public. These tests would need to be cleaned up first. - - // Single argument constructor is special-cased so that it can be - // made explicit. - template <typename A> - explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) { - ::testing::Mock::AllowUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename... An> - NiceMock(A1&& arg1, A2&& arg2, An&&... args) - : MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2), - std::forward<An>(args)...) { - ::testing::Mock::AllowUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } -#else - // C++98 doesn't have variadic templates, so we have to define one - // for each arity. - template <typename A1> - explicit NiceMock(const A1& a1) : MockClass(a1) { - ::testing::Mock::AllowUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - template <typename A1, typename A2> - NiceMock(const A1& a1, const A2& a2) : MockClass(a1, a2) { - ::testing::Mock::AllowUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename A3> - NiceMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) { - ::testing::Mock::AllowUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename A3, typename A4> - NiceMock(const A1& a1, const A2& a2, const A3& a3, - const A4& a4) : MockClass(a1, a2, a3, a4) { - ::testing::Mock::AllowUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename A3, typename A4, typename A5> - NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5) : MockClass(a1, a2, a3, a4, a5) { - ::testing::Mock::AllowUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6> - NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) { - ::testing::Mock::AllowUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6, typename A7> - NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5, - a6, a7) { - ::testing::Mock::AllowUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6, typename A7, typename A8> - NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1, - a2, a3, a4, a5, a6, a7, a8) { - ::testing::Mock::AllowUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6, typename A7, typename A8, typename A9> - NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6, const A7& a7, const A8& a8, - const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) { - ::testing::Mock::AllowUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6, typename A7, typename A8, typename A9, typename A10> - NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, - const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) { - ::testing::Mock::AllowUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - -#endif // GTEST_LANG_CXX11 - - ~NiceMock() { - ::testing::Mock::UnregisterCallReaction( - internal::ImplicitCast_<MockClass*>(this)); - } - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(NiceMock); -}; - -template <class MockClass> -class NaggyMock : public MockClass { - public: - NaggyMock() : MockClass() { - ::testing::Mock::WarnUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - -#if GTEST_LANG_CXX11 - // Ideally, we would inherit base class's constructors through a using - // declaration, which would preserve their visibility. However, many existing - // tests rely on the fact that current implementation reexports protected - // constructors as public. These tests would need to be cleaned up first. - - // Single argument constructor is special-cased so that it can be - // made explicit. - template <typename A> - explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) { - ::testing::Mock::WarnUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename... An> - NaggyMock(A1&& arg1, A2&& arg2, An&&... args) - : MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2), - std::forward<An>(args)...) { - ::testing::Mock::WarnUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } -#else - // C++98 doesn't have variadic templates, so we have to define one - // for each arity. - template <typename A1> - explicit NaggyMock(const A1& a1) : MockClass(a1) { - ::testing::Mock::WarnUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - template <typename A1, typename A2> - NaggyMock(const A1& a1, const A2& a2) : MockClass(a1, a2) { - ::testing::Mock::WarnUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename A3> - NaggyMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) { - ::testing::Mock::WarnUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename A3, typename A4> - NaggyMock(const A1& a1, const A2& a2, const A3& a3, - const A4& a4) : MockClass(a1, a2, a3, a4) { - ::testing::Mock::WarnUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename A3, typename A4, typename A5> - NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5) : MockClass(a1, a2, a3, a4, a5) { - ::testing::Mock::WarnUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6> - NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) { - ::testing::Mock::WarnUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6, typename A7> - NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5, - a6, a7) { - ::testing::Mock::WarnUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6, typename A7, typename A8> - NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1, - a2, a3, a4, a5, a6, a7, a8) { - ::testing::Mock::WarnUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6, typename A7, typename A8, typename A9> - NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6, const A7& a7, const A8& a8, - const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) { - ::testing::Mock::WarnUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6, typename A7, typename A8, typename A9, typename A10> - NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, - const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) { - ::testing::Mock::WarnUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - -#endif // GTEST_LANG_CXX11 - - ~NaggyMock() { - ::testing::Mock::UnregisterCallReaction( - internal::ImplicitCast_<MockClass*>(this)); - } - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(NaggyMock); -}; - -template <class MockClass> -class StrictMock : public MockClass { - public: - StrictMock() : MockClass() { - ::testing::Mock::FailUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - -#if GTEST_LANG_CXX11 - // Ideally, we would inherit base class's constructors through a using - // declaration, which would preserve their visibility. However, many existing - // tests rely on the fact that current implementation reexports protected - // constructors as public. These tests would need to be cleaned up first. - - // Single argument constructor is special-cased so that it can be - // made explicit. - template <typename A> - explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) { - ::testing::Mock::FailUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename... An> - StrictMock(A1&& arg1, A2&& arg2, An&&... args) - : MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2), - std::forward<An>(args)...) { - ::testing::Mock::FailUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } -#else - // C++98 doesn't have variadic templates, so we have to define one - // for each arity. - template <typename A1> - explicit StrictMock(const A1& a1) : MockClass(a1) { - ::testing::Mock::FailUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - template <typename A1, typename A2> - StrictMock(const A1& a1, const A2& a2) : MockClass(a1, a2) { - ::testing::Mock::FailUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename A3> - StrictMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) { - ::testing::Mock::FailUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename A3, typename A4> - StrictMock(const A1& a1, const A2& a2, const A3& a3, - const A4& a4) : MockClass(a1, a2, a3, a4) { - ::testing::Mock::FailUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename A3, typename A4, typename A5> - StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5) : MockClass(a1, a2, a3, a4, a5) { - ::testing::Mock::FailUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6> - StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) { - ::testing::Mock::FailUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6, typename A7> - StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5, - a6, a7) { - ::testing::Mock::FailUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6, typename A7, typename A8> - StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1, - a2, a3, a4, a5, a6, a7, a8) { - ::testing::Mock::FailUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6, typename A7, typename A8, typename A9> - StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6, const A7& a7, const A8& a8, - const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) { - ::testing::Mock::FailUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6, typename A7, typename A8, typename A9, typename A10> - StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, - const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) { - ::testing::Mock::FailUninterestingCalls( - internal::ImplicitCast_<MockClass*>(this)); - } - -#endif // GTEST_LANG_CXX11 - - ~StrictMock() { - ::testing::Mock::UnregisterCallReaction( - internal::ImplicitCast_<MockClass*>(this)); - } - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock); -}; - -// The following specializations catch some (relatively more common) -// user errors of nesting nice and strict mocks. They do NOT catch -// all possible errors. - -// These specializations are declared but not defined, as NiceMock, -// NaggyMock, and StrictMock cannot be nested. - -template <typename MockClass> -class NiceMock<NiceMock<MockClass> >; -template <typename MockClass> -class NiceMock<NaggyMock<MockClass> >; -template <typename MockClass> -class NiceMock<StrictMock<MockClass> >; - -template <typename MockClass> -class NaggyMock<NiceMock<MockClass> >; -template <typename MockClass> -class NaggyMock<NaggyMock<MockClass> >; -template <typename MockClass> -class NaggyMock<StrictMock<MockClass> >; - -template <typename MockClass> -class StrictMock<NiceMock<MockClass> >; -template <typename MockClass> -class StrictMock<NaggyMock<MockClass> >; -template <typename MockClass> -class StrictMock<StrictMock<MockClass> >; - -} // namespace testing - -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ diff --git a/contrib/googletest/googlemock/include/gmock/gmock-generated-nice-strict.h.pump b/contrib/googletest/googlemock/include/gmock/gmock-generated-nice-strict.h.pump deleted file mode 100644 index ed49f4ab0be4..000000000000 --- a/contrib/googletest/googlemock/include/gmock/gmock-generated-nice-strict.h.pump +++ /dev/null @@ -1,179 +0,0 @@ -$$ -*- mode: c++; -*- -$$ This is a Pump source file. Please use Pump to convert -$$ it to gmock-generated-nice-strict.h. -$$ -$var n = 10 $$ The maximum arity we support. -// 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_GENERATED_NICE_STRICT_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ - -#include "gmock/gmock-spec-builders.h" -#include "gmock/internal/gmock-port.h" - -namespace testing { - -$range kind 0..2 -$for kind [[ - -$var clazz=[[$if kind==0 [[NiceMock]] - $elif kind==1 [[NaggyMock]] - $else [[StrictMock]]]] - -$var method=[[$if kind==0 [[AllowUninterestingCalls]] - $elif kind==1 [[WarnUninterestingCalls]] - $else [[FailUninterestingCalls]]]] - -template <class MockClass> -class $clazz : public MockClass { - public: - $clazz() : MockClass() { - ::testing::Mock::$method( - internal::ImplicitCast_<MockClass*>(this)); - } - -#if GTEST_LANG_CXX11 - // Ideally, we would inherit base class's constructors through a using - // declaration, which would preserve their visibility. However, many existing - // tests rely on the fact that current implementation reexports protected - // constructors as public. These tests would need to be cleaned up first. - - // Single argument constructor is special-cased so that it can be - // made explicit. - template <typename A> - explicit $clazz(A&& arg) : MockClass(std::forward<A>(arg)) { - ::testing::Mock::$method( - internal::ImplicitCast_<MockClass*>(this)); - } - - template <typename A1, typename A2, typename... An> - $clazz(A1&& arg1, A2&& arg2, An&&... args) - : MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2), - std::forward<An>(args)...) { - ::testing::Mock::$method( - internal::ImplicitCast_<MockClass*>(this)); - } -#else - // C++98 doesn't have variadic templates, so we have to define one - // for each arity. - template <typename A1> - explicit $clazz(const A1& a1) : MockClass(a1) { - ::testing::Mock::$method( - internal::ImplicitCast_<MockClass*>(this)); - } - -$range i 2..n -$for i [[ -$range j 1..i - template <$for j, [[typename A$j]]> - $clazz($for j, [[const A$j& a$j]]) : MockClass($for j, [[a$j]]) { - ::testing::Mock::$method( - internal::ImplicitCast_<MockClass*>(this)); - } - - -]] -#endif // GTEST_LANG_CXX11 - - ~$clazz() { - ::testing::Mock::UnregisterCallReaction( - internal::ImplicitCast_<MockClass*>(this)); - } - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_($clazz); -}; - -]] - -// The following specializations catch some (relatively more common) -// user errors of nesting nice and strict mocks. They do NOT catch -// all possible errors. - -// These specializations are declared but not defined, as NiceMock, -// NaggyMock, and StrictMock cannot be nested. - -template <typename MockClass> -class NiceMock<NiceMock<MockClass> >; -template <typename MockClass> -class NiceMock<NaggyMock<MockClass> >; -template <typename MockClass> -class NiceMock<StrictMock<MockClass> >; - -template <typename MockClass> -class NaggyMock<NiceMock<MockClass> >; -template <typename MockClass> -class NaggyMock<NaggyMock<MockClass> >; -template <typename MockClass> -class NaggyMock<StrictMock<MockClass> >; - -template <typename MockClass> -class StrictMock<NiceMock<MockClass> >; -template <typename MockClass> -class StrictMock<NaggyMock<MockClass> >; -template <typename MockClass> -class StrictMock<StrictMock<MockClass> >; - -} // namespace testing - -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ diff --git a/contrib/googletest/googlemock/include/gmock/gmock-matchers.h b/contrib/googletest/googlemock/include/gmock/gmock-matchers.h index a7bcfc83ebd1..0f67713776a6 100644 --- a/contrib/googletest/googlemock/include/gmock/gmock-matchers.h +++ b/contrib/googletest/googlemock/include/gmock/gmock-matchers.h @@ -27,38 +27,265 @@ // (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 argument matchers. More +// 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/main/docs/gmock_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 +// IWYU pragma: private, include "gmock/gmock.h" +// IWYU pragma: friend gmock/.* -#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ -#include <math.h> #include <algorithm> +#include <cmath> +#include <exception> +#include <functional> +#include <initializer_list> +#include <ios> #include <iterator> #include <limits> +#include <memory> #include <ostream> // NOLINT #include <sstream> #include <string> +#include <type_traits> #include <utility> #include <vector> -#include "gtest/gtest.h" + #include "gmock/internal/gmock-internal-utils.h" #include "gmock/internal/gmock-port.h" +#include "gmock/internal/gmock-pp.h" +#include "gtest/gtest.h" -#if GTEST_HAS_STD_INITIALIZER_LIST_ -# include <initializer_list> // NOLINT -- must be after 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 5046 /* class A needs to have dll-interface to be used by clients of - class B */ + 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 { @@ -75,145 +302,6 @@ namespace testing { // ownership management as Matcher objects can now be copied like // plain values. -// MatchResultListener is an abstract class. Its << operator can be -// used by a matcher to explain why a value matches or doesn't match. -// -// FIXME: add method -// bool InterestedInWhy(bool result) const; -// to indicate whether the listener is interested in why the match -// result is 'result'. -class MatchResultListener { - public: - // Creates a listener object with the given underlying ostream. The - // listener does not own the ostream, and does not dereference it - // in the constructor or destructor. - explicit MatchResultListener(::std::ostream* os) : stream_(os) {} - virtual ~MatchResultListener() = 0; // Makes this class abstract. - - // Streams x to the underlying ostream; does nothing if the ostream - // is NULL. - template <typename T> - MatchResultListener& operator<<(const T& x) { - if (stream_ != NULL) - *stream_ << x; - return *this; - } - - // Returns the underlying ostream. - ::std::ostream* stream() { return stream_; } - - // Returns true iff the listener is interested in an explanation of - // the match result. A matcher's MatchAndExplain() method can use - // this information to avoid generating the explanation when no one - // intends to hear it. - bool IsInterested() const { return stream_ != NULL; } - - private: - ::std::ostream* const stream_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(MatchResultListener); -}; - -inline MatchResultListener::~MatchResultListener() { -} - -// An instance of a subclass of this knows how to describe itself as a -// matcher. -class MatcherDescriberInterface { - public: - virtual ~MatcherDescriberInterface() {} - - // Describes this matcher to an ostream. The function should print - // a verb phrase that describes the property a value matching this - // matcher should have. The subject of the verb phrase is the value - // being matched. For example, the DescribeTo() method of the Gt(7) - // matcher prints "is greater than 7". - virtual void DescribeTo(::std::ostream* os) const = 0; - - // Describes the negation of this matcher to an ostream. For - // example, if the description of this matcher is "is greater than - // 7", the negated description could be "is not greater than 7". - // You are not required to override this when implementing - // MatcherInterface, but it is highly advised so that your matcher - // can produce good error messages. - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "not ("; - DescribeTo(os); - *os << ")"; - } -}; - -// The implementation of a matcher. -template <typename T> -class MatcherInterface : public MatcherDescriberInterface { - public: - // Returns true iff the matcher matches x; also explains the match - // result to 'listener' if necessary (see the next paragraph), in - // the form of a non-restrictive relative clause ("which ...", - // "whose ...", etc) that describes x. For example, the - // MatchAndExplain() method of the Pointee(...) matcher should - // generate an explanation like "which points to ...". - // - // Implementations of MatchAndExplain() should add an explanation of - // the match result *if and only if* they can provide additional - // information that's not already present (or not obvious) in the - // print-out of x and the matcher's description. Whether the match - // succeeds is not a factor in deciding whether an explanation is - // needed, as sometimes the caller needs to print a failure message - // when the match succeeds (e.g. when the matcher is used inside - // Not()). - // - // For example, a "has at least 10 elements" matcher should explain - // what the actual element count is, regardless of the match result, - // as it is useful information to the reader; on the other hand, an - // "is empty" matcher probably only needs to explain what the actual - // size is when the match fails, as it's redundant to say that the - // size is 0 when the value is already known to be empty. - // - // You should override this method when defining a new matcher. - // - // It's the responsibility of the caller (Google Mock) to guarantee - // that 'listener' is not NULL. This helps to simplify a matcher's - // implementation when it doesn't care about the performance, as it - // can talk to 'listener' without checking its validity first. - // However, in order to implement dummy listeners efficiently, - // listener->stream() may be NULL. - virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0; - - // Inherits these methods from MatcherDescriberInterface: - // virtual void DescribeTo(::std::ostream* os) const = 0; - // virtual void DescribeNegationTo(::std::ostream* os) const; -}; - -namespace internal { - -// Converts a MatcherInterface<T> to a MatcherInterface<const T&>. -template <typename T> -class MatcherInterfaceAdapter : public MatcherInterface<const T&> { - public: - explicit MatcherInterfaceAdapter(const MatcherInterface<T>* impl) - : impl_(impl) {} - virtual ~MatcherInterfaceAdapter() { delete impl_; } - - virtual void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); } - - virtual void DescribeNegationTo(::std::ostream* os) const { - impl_->DescribeNegationTo(os); - } - - virtual bool MatchAndExplain(const T& x, - MatchResultListener* listener) const { - return impl_->MatchAndExplain(x, listener); - } - - private: - const MatcherInterface<T>* const impl_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(MatcherInterfaceAdapter); -}; - -} // namespace internal - // A match result listener that stores the explanation in a string. class StringMatchResultListener : public MatchResultListener { public: @@ -228,412 +316,11 @@ class StringMatchResultListener : public MatchResultListener { private: ::std::stringstream ss_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(StringMatchResultListener); -}; - -namespace internal { - -struct AnyEq { - template <typename A, typename B> - bool operator()(const A& a, const B& b) const { return a == b; } -}; -struct AnyNe { - template <typename A, typename B> - bool operator()(const A& a, const B& b) const { return a != b; } -}; -struct AnyLt { - template <typename A, typename B> - bool operator()(const A& a, const B& b) const { return a < b; } -}; -struct AnyGt { - template <typename A, typename B> - bool operator()(const A& a, const B& b) const { return a > b; } -}; -struct AnyLe { - template <typename A, typename B> - bool operator()(const A& a, const B& b) const { return a <= b; } -}; -struct AnyGe { - template <typename A, typename B> - bool operator()(const A& a, const B& b) const { return a >= b; } -}; - -// A match result listener that ignores the explanation. -class DummyMatchResultListener : public MatchResultListener { - public: - DummyMatchResultListener() : MatchResultListener(NULL) {} - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(DummyMatchResultListener); -}; - -// A match result listener that forwards the explanation to a given -// ostream. The difference between this and MatchResultListener is -// that the former is concrete. -class StreamMatchResultListener : public MatchResultListener { - public: - explicit StreamMatchResultListener(::std::ostream* os) - : MatchResultListener(os) {} - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamMatchResultListener); -}; - -// An internal class for implementing Matcher<T>, which will derive -// from it. We put functionalities common to all Matcher<T> -// specializations here to avoid code duplication. -template <typename T> -class MatcherBase { - public: - // Returns true iff the matcher matches x; also explains the match - // result to 'listener'. - bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) x, - MatchResultListener* listener) const { - return impl_->MatchAndExplain(x, listener); - } - - // Returns true iff this matcher matches x. - bool Matches(GTEST_REFERENCE_TO_CONST_(T) x) const { - DummyMatchResultListener dummy; - return MatchAndExplain(x, &dummy); - } - - // Describes this matcher to an ostream. - void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); } - - // Describes the negation of this matcher to an ostream. - void DescribeNegationTo(::std::ostream* os) const { - impl_->DescribeNegationTo(os); - } - - // Explains why x matches, or doesn't match, the matcher. - void ExplainMatchResultTo(GTEST_REFERENCE_TO_CONST_(T) x, - ::std::ostream* os) const { - StreamMatchResultListener listener(os); - MatchAndExplain(x, &listener); - } - - // Returns the describer for this matcher object; retains ownership - // of the describer, which is only guaranteed to be alive when - // this matcher object is alive. - const MatcherDescriberInterface* GetDescriber() const { - return impl_.get(); - } - - protected: - MatcherBase() {} - - // Constructs a matcher from its implementation. - explicit MatcherBase( - const MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)>* impl) - : impl_(impl) {} - - template <typename U> - explicit MatcherBase( - const MatcherInterface<U>* impl, - typename internal::EnableIf< - !internal::IsSame<U, GTEST_REFERENCE_TO_CONST_(U)>::value>::type* = - NULL) - : impl_(new internal::MatcherInterfaceAdapter<U>(impl)) {} - - virtual ~MatcherBase() {} - - private: - // shared_ptr (util/gtl/shared_ptr.h) and linked_ptr have similar - // interfaces. The former dynamically allocates a chunk of memory - // to hold the reference count, while the latter tracks all - // references using a circular linked list without allocating - // memory. It has been observed that linked_ptr performs better in - // typical scenarios. However, shared_ptr can out-perform - // linked_ptr when there are many more uses of the copy constructor - // than the default constructor. - // - // If performance becomes a problem, we should see if using - // shared_ptr helps. - ::testing::internal::linked_ptr< - const MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)> > - impl_; -}; - -} // namespace internal - -// A Matcher<T> is a copyable and IMMUTABLE (except by assignment) -// object that can check whether a value of type T matches. The -// implementation of Matcher<T> is just a linked_ptr to const -// MatcherInterface<T>, so copying is fairly cheap. Don't inherit -// from Matcher! -template <typename T> -class Matcher : public internal::MatcherBase<T> { - public: - // Constructs a null matcher. Needed for storing Matcher objects in STL - // containers. A default-constructed matcher is not yet initialized. You - // cannot use it until a valid value has been assigned to it. - explicit Matcher() {} // NOLINT - - // Constructs a matcher from its implementation. - explicit Matcher(const MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)>* impl) - : internal::MatcherBase<T>(impl) {} - - template <typename U> - explicit Matcher(const MatcherInterface<U>* impl, - typename internal::EnableIf<!internal::IsSame< - U, GTEST_REFERENCE_TO_CONST_(U)>::value>::type* = NULL) - : internal::MatcherBase<T>(impl) {} - - // Implicit constructor here allows people to write - // EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes - Matcher(T value); // NOLINT -}; - -// The following two specializations allow the user to write str -// instead of Eq(str) and "foo" instead of Eq("foo") when a std::string -// matcher is expected. -template <> -class GTEST_API_ Matcher<const std::string&> - : public internal::MatcherBase<const std::string&> { - public: - Matcher() {} - - explicit Matcher(const MatcherInterface<const std::string&>* impl) - : internal::MatcherBase<const std::string&>(impl) {} - - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a std::string object. - Matcher(const std::string& s); // NOLINT - -#if GTEST_HAS_GLOBAL_STRING - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a ::string object. - Matcher(const ::string& s); // NOLINT -#endif // GTEST_HAS_GLOBAL_STRING - - // Allows the user to write "foo" instead of Eq("foo") sometimes. - Matcher(const char* s); // NOLINT -}; - -template <> -class GTEST_API_ Matcher<std::string> - : public internal::MatcherBase<std::string> { - public: - Matcher() {} - - explicit Matcher(const MatcherInterface<const std::string&>* impl) - : internal::MatcherBase<std::string>(impl) {} - explicit Matcher(const MatcherInterface<std::string>* impl) - : internal::MatcherBase<std::string>(impl) {} - - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a string object. - Matcher(const std::string& s); // NOLINT - -#if GTEST_HAS_GLOBAL_STRING - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a ::string object. - Matcher(const ::string& s); // NOLINT -#endif // GTEST_HAS_GLOBAL_STRING - - // Allows the user to write "foo" instead of Eq("foo") sometimes. - Matcher(const char* s); // NOLINT -}; - -#if GTEST_HAS_GLOBAL_STRING -// The following two specializations allow the user to write str -// instead of Eq(str) and "foo" instead of Eq("foo") when a ::string -// matcher is expected. -template <> -class GTEST_API_ Matcher<const ::string&> - : public internal::MatcherBase<const ::string&> { - public: - Matcher() {} - - explicit Matcher(const MatcherInterface<const ::string&>* impl) - : internal::MatcherBase<const ::string&>(impl) {} - - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a std::string object. - Matcher(const std::string& s); // NOLINT - - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a ::string object. - Matcher(const ::string& s); // NOLINT - - // Allows the user to write "foo" instead of Eq("foo") sometimes. - Matcher(const char* s); // NOLINT -}; - -template <> -class GTEST_API_ Matcher< ::string> - : public internal::MatcherBase< ::string> { - public: - Matcher() {} - - explicit Matcher(const MatcherInterface<const ::string&>* impl) - : internal::MatcherBase< ::string>(impl) {} - explicit Matcher(const MatcherInterface< ::string>* impl) - : internal::MatcherBase< ::string>(impl) {} - - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a std::string object. - Matcher(const std::string& s); // NOLINT - - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a ::string object. - Matcher(const ::string& s); // NOLINT - - // Allows the user to write "foo" instead of Eq("foo") sometimes. - Matcher(const char* s); // NOLINT -}; -#endif // GTEST_HAS_GLOBAL_STRING - -#if GTEST_HAS_ABSL -// The following two specializations allow the user to write str -// instead of Eq(str) and "foo" instead of Eq("foo") when a absl::string_view -// matcher is expected. -template <> -class GTEST_API_ Matcher<const absl::string_view&> - : public internal::MatcherBase<const absl::string_view&> { - public: - Matcher() {} - - explicit Matcher(const MatcherInterface<const absl::string_view&>* impl) - : internal::MatcherBase<const absl::string_view&>(impl) {} - - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a std::string object. - Matcher(const std::string& s); // NOLINT - -#if GTEST_HAS_GLOBAL_STRING - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a ::string object. - Matcher(const ::string& s); // NOLINT -#endif // GTEST_HAS_GLOBAL_STRING - - // Allows the user to write "foo" instead of Eq("foo") sometimes. - Matcher(const char* s); // NOLINT - - // Allows the user to pass absl::string_views directly. - Matcher(absl::string_view s); // NOLINT -}; - -template <> -class GTEST_API_ Matcher<absl::string_view> - : public internal::MatcherBase<absl::string_view> { - public: - Matcher() {} - - explicit Matcher(const MatcherInterface<const absl::string_view&>* impl) - : internal::MatcherBase<absl::string_view>(impl) {} - explicit Matcher(const MatcherInterface<absl::string_view>* impl) - : internal::MatcherBase<absl::string_view>(impl) {} - - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a std::string object. - Matcher(const std::string& s); // NOLINT - -#if GTEST_HAS_GLOBAL_STRING - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a ::string object. - Matcher(const ::string& s); // NOLINT -#endif // GTEST_HAS_GLOBAL_STRING - - // Allows the user to write "foo" instead of Eq("foo") sometimes. - Matcher(const char* s); // NOLINT - - // Allows the user to pass absl::string_views directly. - Matcher(absl::string_view s); // NOLINT -}; -#endif // GTEST_HAS_ABSL - -// Prints a matcher in a human-readable format. -template <typename T> -std::ostream& operator<<(std::ostream& os, const Matcher<T>& matcher) { - matcher.DescribeTo(&os); - return os; -} - -// The PolymorphicMatcher class template makes it easy to implement a -// polymorphic matcher (i.e. a matcher that can match values of more -// than one type, e.g. Eq(n) and NotNull()). -// -// To define a polymorphic matcher, a user should provide an Impl -// class that has a DescribeTo() method and a DescribeNegationTo() -// method, and define a member function (or member function template) -// -// bool MatchAndExplain(const Value& value, -// MatchResultListener* listener) const; -// -// See the definition of NotNull() for a complete example. -template <class Impl> -class PolymorphicMatcher { - public: - explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {} - - // Returns a mutable reference to the underlying matcher - // implementation object. - Impl& mutable_impl() { return impl_; } - - // Returns an immutable reference to the underlying matcher - // implementation object. - const Impl& impl() const { return impl_; } - - template <typename T> - operator Matcher<T>() const { - return Matcher<T>(new MonomorphicImpl<GTEST_REFERENCE_TO_CONST_(T)>(impl_)); - } - - private: - template <typename T> - class MonomorphicImpl : public MatcherInterface<T> { - public: - explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {} - - virtual void DescribeTo(::std::ostream* os) const { - impl_.DescribeTo(os); - } - - virtual void DescribeNegationTo(::std::ostream* os) const { - impl_.DescribeNegationTo(os); - } - - virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { - return impl_.MatchAndExplain(x, listener); - } - - private: - const Impl impl_; - - GTEST_DISALLOW_ASSIGN_(MonomorphicImpl); - }; - - Impl impl_; - - GTEST_DISALLOW_ASSIGN_(PolymorphicMatcher); + StringMatchResultListener(const StringMatchResultListener&) = delete; + StringMatchResultListener& operator=(const StringMatchResultListener&) = + delete; }; -// Creates a matcher from its implementation. This is easier to use -// than the Matcher<T> constructor as it doesn't require you to -// explicitly write the template argument, e.g. -// -// MakeMatcher(foo); -// vs -// Matcher<const string&>(foo); -template <typename T> -inline Matcher<T> MakeMatcher(const MatcherInterface<T>* impl) { - return Matcher<T>(impl); -} - -// Creates a polymorphic matcher from its implementation. This is -// easier to use than the PolymorphicMatcher<Impl> constructor as it -// doesn't require you to explicitly write the template argument, e.g. -// -// MakePolymorphicMatcher(foo); -// vs -// PolymorphicMatcher<TypeOfFoo>(foo); -template <class Impl> -inline PolymorphicMatcher<Impl> MakePolymorphicMatcher(const Impl& impl) { - return PolymorphicMatcher<Impl>(impl); -} - // Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION // and MUST NOT BE USED IN USER CODE!!! namespace internal { @@ -661,23 +348,20 @@ class MatcherCastImpl { // constructor from M (this usually happens when T has an implicit // constructor from any type). // - // It won't work to unconditionally implict_cast + // It won't work to unconditionally implicit_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, - BooleanConstant< - internal::ImplicitlyConvertible<M, Matcher<T> >::value>(), - BooleanConstant< - internal::ImplicitlyConvertible<M, T>::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, - BooleanConstant<true> /* convertible_to_matcher */, - BooleanConstant<Ignore>) { + 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 @@ -692,9 +376,9 @@ class MatcherCastImpl { // M can't be implicitly converted to Matcher<T>, so M isn't a polymorphic // matcher. It's a value of a type implicitly convertible to T. Use direct // initialization to create a matcher. - static Matcher<T> CastImpl( - const M& value, BooleanConstant<false> /* convertible_to_matcher */, - BooleanConstant<true> /* convertible_to_T */) { + 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)); } @@ -708,16 +392,16 @@ class MatcherCastImpl { // (e.g. std::pair<const int, int> vs. std::pair<int, int>). // // We don't define this method inline as we need the declaration of Eq(). - static Matcher<T> CastImpl( - const M& value, BooleanConstant<false> /* convertible_to_matcher */, - BooleanConstant<false> /* convertible_to_T */); + 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> > { +class MatcherCastImpl<T, Matcher<U>> { public: static Matcher<T> Cast(const Matcher<U>& source_matcher) { return Matcher<T>(new Impl(source_matcher)); @@ -730,8 +414,7 @@ class MatcherCastImpl<T, Matcher<U> > { : source_matcher_(source_matcher) {} // We delegate the matching logic to the source matcher. - virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { -#if GTEST_LANG_CXX11 + 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< @@ -745,34 +428,82 @@ class MatcherCastImpl<T, Matcher<U> > { std::is_same<FromType, ToType>::value || !std::is_base_of<FromType, ToType>::value, "Can't implicitly convert from <base> to <derived>"); -#endif // GTEST_LANG_CXX11 - return source_matcher_.MatchAndExplain(static_cast<U>(x), listener); + // 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); } - virtual void DescribeTo(::std::ostream* os) const { + void DescribeTo(::std::ostream* os) const override { source_matcher_.DescribeTo(os); } - virtual void DescribeNegationTo(::std::ostream* os) const { + void DescribeNegationTo(::std::ostream* os) const override { source_matcher_.DescribeNegationTo(os); } private: const Matcher<U> source_matcher_; - - GTEST_DISALLOW_ASSIGN_(Impl); }; }; // This even more specialized version is used for efficiently casting // a matcher to its own type. template <typename T> -class MatcherCastImpl<T, Matcher<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 @@ -784,59 +515,42 @@ inline Matcher<T> MatcherCast(const M& matcher) { return internal::MatcherCastImpl<T, M>::Cast(matcher); } -// Implements SafeMatcherCast(). -// -// We use an intermediate class to do the actual safe casting as Nokia's -// Symbian compiler cannot decide between -// template <T, M> ... (M) and -// template <T, U> ... (const Matcher<U>&) -// for function templates but can for member function templates. -template <typename T> -class SafeMatcherCastImpl { - public: - // This overload handles polymorphic matchers and values only since - // monomorphic matchers are handled by the next one. - template <typename M> - static inline Matcher<T> Cast(const M& polymorphic_matcher_or_value) { - return internal::MatcherCastImpl<T, M>::Cast(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 U> - static inline Matcher<T> Cast(const Matcher<U>& matcher) { - // Enforce that T can be implicitly converted to U. - GTEST_COMPILE_ASSERT_((internal::ImplicitlyConvertible<T, 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_( - internal::is_reference<T>::value || !internal::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; - const bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther; - const 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); - } -}; - +// 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) { - return SafeMatcherCastImpl<T>::Cast(polymorphic_matcher); +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. + static_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; + static_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. @@ -850,7 +564,7 @@ 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 != NULL) { + if (!explanation.empty() && os != nullptr) { *os << ", " << explanation; } } @@ -899,13 +613,13 @@ template <size_t N> class TuplePrefix { public: // TuplePrefix<N>::Matches(matcher_tuple, value_tuple) returns true - // iff the first N fields of matcher_tuple matches the first N - // fields of value_tuple, respectively. + // 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) - && get<N - 1>(matcher_tuple).Matches(get<N - 1>(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) @@ -921,16 +635,14 @@ class TuplePrefix { // Then describes the failure (if any) in the (N - 1)-th (0-based) // field. - typename tuple_element<N - 1, MatcherTuple>::type matcher = - get<N - 1>(matchers); - typedef typename tuple_element<N - 1, ValueTuple>::type Value; - GTEST_REFERENCE_TO_CONST_(Value) value = get<N - 1>(values); + 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)) { - // FIXME: include in the message the name of the parameter - // as used in MOCK_METHOD*() when possible. *os << " Expected arg #" << N - 1 << ": "; - get<N - 1>(matchers).DescribeTo(os); + 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 @@ -960,8 +672,8 @@ class TuplePrefix<0> { ::std::ostream* /* os */) {} }; -// TupleMatches(matcher_tuple, value_tuple) returns true iff all -// matchers in matcher_tuple match the corresponding fields in +// 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. @@ -970,20 +682,19 @@ 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_(tuple_size<MatcherTuple>::value == - tuple_size<ValueTuple>::value, - matcher_and_value_have_different_numbers_of_fields); - return TuplePrefix<tuple_size<ValueTuple>::value>:: - Matches(matcher_tuple, value_tuple); + static_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<tuple_size<MatcherTuple>::value>::ExplainMatchFailuresTo( + const ValueTuple& values, ::std::ostream* os) { + TuplePrefix<std::tuple_size<MatcherTuple>::value>::ExplainMatchFailuresTo( matchers, values, os); } @@ -994,7 +705,7 @@ void ExplainMatchFailureTupleTo(const MatcherTuple& matchers, template <typename Tuple, typename Func, typename OutIter> class TransformTupleValuesHelper { private: - typedef ::testing::tuple_size<Tuple> TupleSize; + typedef ::std::tuple_size<Tuple> TupleSize; public: // For each member of tuple 't', taken in order, evaluates '*out++ = f(t)'. @@ -1006,14 +717,14 @@ class TransformTupleValuesHelper { private: template <typename Tup, size_t kRemainingSize> struct IterateOverTuple { - OutIter operator() (Func f, const Tup& t, OutIter out) const { - *out++ = f(::testing::get<TupleSize::value - kRemainingSize>(t)); + 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 { + OutIter operator()(Func /* f */, const Tup& /* t */, OutIter out) const { return out; } }; @@ -1027,124 +738,25 @@ 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<GTEST_REFERENCE_TO_CONST_(T)> { - public: - virtual bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) /* x */, - MatchResultListener* /* listener */) const { - return true; - } - virtual void DescribeTo(::std::ostream* os) const { *os << "is anything"; } - virtual void DescribeNegationTo(::std::ostream* os) const { - // 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>(); } -}; + using is_gtest_matcher = void; -// Implements a matcher that compares a given value with a -// pre-supplied value using one of the ==, <=, <, etc, operators. The -// two values being compared don't have to have the same type. -// -// The matcher defined here is polymorphic (for example, Eq(5) can be -// used to match an int, a short, a double, etc). Therefore we use -// a template type conversion operator in the implementation. -// -// The following template definition assumes that the Rhs parameter is -// a "bare" type (i.e. neither 'const T' nor 'T&'). -template <typename D, typename Rhs, typename Op> -class ComparisonBase { - public: - explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {} - template <typename Lhs> - operator Matcher<Lhs>() const { - return MakeMatcher(new Impl<Lhs>(rhs_)); + template <typename T> + bool MatchAndExplain(const T& /* x */, std::ostream* /* listener */) const { + return true; + } + void DescribeTo(std::ostream* os) const { *os << "is anything"; } + void DescribeNegationTo(::std::ostream* os) const { + // This is mostly for completeness' sake, 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"; } - - private: - template <typename Lhs> - class Impl : public MatcherInterface<Lhs> { - public: - explicit Impl(const Rhs& rhs) : rhs_(rhs) {} - virtual bool MatchAndExplain( - Lhs lhs, MatchResultListener* /* listener */) const { - return Op()(lhs, rhs_); - } - virtual void DescribeTo(::std::ostream* os) const { - *os << D::Desc() << " "; - UniversalPrint(rhs_, os); - } - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << D::NegatedDesc() << " "; - UniversalPrint(rhs_, os); - } - private: - Rhs rhs_; - GTEST_DISALLOW_ASSIGN_(Impl); - }; - Rhs rhs_; - GTEST_DISALLOW_ASSIGN_(ComparisonBase); -}; - -template <typename Rhs> -class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq> { - public: - explicit EqMatcher(const Rhs& rhs) - : ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq>(rhs) { } - static const char* Desc() { return "is equal to"; } - static const char* NegatedDesc() { return "isn't equal to"; } -}; -template <typename Rhs> -class NeMatcher : public ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe> { - public: - explicit NeMatcher(const Rhs& rhs) - : ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe>(rhs) { } - static const char* Desc() { return "isn't equal to"; } - static const char* NegatedDesc() { return "is equal to"; } -}; -template <typename Rhs> -class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt> { - public: - explicit LtMatcher(const Rhs& rhs) - : ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt>(rhs) { } - static const char* Desc() { return "is <"; } - static const char* NegatedDesc() { return "isn't <"; } -}; -template <typename Rhs> -class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt> { - public: - explicit GtMatcher(const Rhs& rhs) - : ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt>(rhs) { } - static const char* Desc() { return "is >"; } - static const char* NegatedDesc() { return "isn't >"; } -}; -template <typename Rhs> -class LeMatcher : public ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe> { - public: - explicit LeMatcher(const Rhs& rhs) - : ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe>(rhs) { } - static const char* Desc() { return "is <="; } - static const char* NegatedDesc() { return "isn't <="; } -}; -template <typename Rhs> -class GeMatcher : public ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe> { - public: - explicit GeMatcher(const Rhs& rhs) - : ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe>(rhs) { } - static const char* Desc() { return "is >="; } - static const char* NegatedDesc() { return "isn't >="; } }; // Implements the polymorphic IsNull() matcher, which matches any raw or smart @@ -1154,17 +766,11 @@ class IsNullMatcher { template <typename Pointer> bool MatchAndExplain(const Pointer& p, MatchResultListener* /* listener */) const { -#if GTEST_LANG_CXX11 return p == nullptr; -#else // GTEST_LANG_CXX11 - return GetRawPointer(p) == NULL; -#endif // GTEST_LANG_CXX11 } void DescribeTo(::std::ostream* os) const { *os << "is NULL"; } - void DescribeNegationTo(::std::ostream* os) const { - *os << "isn't NULL"; - } + void DescribeNegationTo(::std::ostream* os) const { *os << "isn't NULL"; } }; // Implements the polymorphic NotNull() matcher, which matches any raw or smart @@ -1174,17 +780,11 @@ class NotNullMatcher { template <typename Pointer> bool MatchAndExplain(const Pointer& p, MatchResultListener* /* listener */) const { -#if GTEST_LANG_CXX11 return p != nullptr; -#else // GTEST_LANG_CXX11 - return GetRawPointer(p) != NULL; -#endif // GTEST_LANG_CXX11 } void DescribeTo(::std::ostream* os) const { *os << "isn't NULL"; } - void DescribeNegationTo(::std::ostream* os) const { - *os << "is NULL"; - } + void DescribeNegationTo(::std::ostream* os) const { *os << "is NULL"; } }; // Ref(variable) matches any argument that is a reference to @@ -1234,31 +834,27 @@ class RefMatcher<T&> { // MatchAndExplain() takes a Super& (as opposed to const Super&) // in order to match the interface MatcherInterface<Super&>. - virtual bool MatchAndExplain( - Super& x, MatchResultListener* listener) const { + bool MatchAndExplain(Super& x, + MatchResultListener* listener) const override { *listener << "which is located @" << static_cast<const void*>(&x); return &x == &object_; } - virtual void DescribeTo(::std::ostream* os) const { + void DescribeTo(::std::ostream* os) const override { *os << "references the variable "; UniversalPrinter<Super&>::Print(object_, os); } - virtual void DescribeNegationTo(::std::ostream* os) const { + void DescribeNegationTo(::std::ostream* os) const override { *os << "does not reference the variable "; UniversalPrinter<Super&>::Print(object_, os); } private: const Super& object_; - - GTEST_DISALLOW_ASSIGN_(Impl); }; T& object_; - - GTEST_DISALLOW_ASSIGN_(RefMatcher); }; // Polymorphic helper functions for narrow and wide string matchers. @@ -1274,8 +870,7 @@ inline bool CaseInsensitiveCStringEquals(const wchar_t* lhs, // String comparison for narrow or wide strings that can have embedded NUL // characters. template <typename StringType> -bool CaseInsensitiveStringEquals(const StringType& s1, - const StringType& s2) { +bool CaseInsensitiveStringEquals(const StringType& s1, const StringType& s2) { // Are the heads equal? if (!CaseInsensitiveCStringEquals(s1.c_str(), s2.c_str())) { return false; @@ -1300,22 +895,20 @@ bool CaseInsensitiveStringEquals(const StringType& s1, template <typename StringType> class StrEqualityMatcher { public: - StrEqualityMatcher(const StringType& str, bool expect_eq, - bool case_sensitive) - : string_(str), expect_eq_(expect_eq), case_sensitive_(case_sensitive) {} + StrEqualityMatcher(StringType str, bool expect_eq, bool case_sensitive) + : string_(std::move(str)), + expect_eq_(expect_eq), + case_sensitive_(case_sensitive) {} -#if GTEST_HAS_ABSL - bool MatchAndExplain(const absl::string_view& s, +#if GTEST_INTERNAL_HAS_STRING_VIEW + bool MatchAndExplain(const internal::StringView& s, MatchResultListener* listener) const { - if (s.data() == NULL) { - return !expect_eq_; - } - // This should fail to compile if absl::string_view is used with wide + // This should fail to compile if StringView is used with wide // strings. - const StringType& str = string(s); + const StringType& str = std::string(s); return MatchAndExplain(str, listener); } -#endif // GTEST_HAS_ABSL +#endif // GTEST_INTERNAL_HAS_STRING_VIEW // Accepts pointer types, particularly: // const char* @@ -1324,7 +917,7 @@ class StrEqualityMatcher { // wchar_t* template <typename CharType> bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { - if (s == NULL) { + if (s == nullptr) { return !expect_eq_; } return MatchAndExplain(StringType(s), listener); @@ -1333,13 +926,13 @@ class StrEqualityMatcher { // Matches anything that can convert to StringType. // // This is a template, not just a plain function with const StringType&, - // because absl::string_view has some interfering non-explicit constructors. + // 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_); + const StringType s2(s); + const bool eq = case_sensitive_ ? s2 == string_ + : CaseInsensitiveStringEquals(s2, string_); return expect_eq_ == eq; } @@ -1364,8 +957,6 @@ class StrEqualityMatcher { const StringType string_; const bool expect_eq_; const bool case_sensitive_; - - GTEST_DISALLOW_ASSIGN_(StrEqualityMatcher); }; // Implements the polymorphic HasSubstr(substring) matcher, which @@ -1377,18 +968,15 @@ class HasSubstrMatcher { explicit HasSubstrMatcher(const StringType& substring) : substring_(substring) {} -#if GTEST_HAS_ABSL - bool MatchAndExplain(const absl::string_view& s, +#if GTEST_INTERNAL_HAS_STRING_VIEW + bool MatchAndExplain(const internal::StringView& s, MatchResultListener* listener) const { - if (s.data() == NULL) { - return false; - } - // This should fail to compile if absl::string_view is used with wide + // This should fail to compile if StringView is used with wide // strings. - const StringType& str = string(s); + const StringType& str = std::string(s); return MatchAndExplain(str, listener); } -#endif // GTEST_HAS_ABSL +#endif // GTEST_INTERNAL_HAS_STRING_VIEW // Accepts pointer types, particularly: // const char* @@ -1397,18 +985,17 @@ class HasSubstrMatcher { // wchar_t* template <typename CharType> bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { - return s != NULL && MatchAndExplain(StringType(s), listener); + 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 absl::string_view has some interfering non-explicit constructors. + // 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.find(substring_) != StringType::npos; + return StringType(s).find(substring_) != StringType::npos; } // Describes what this matcher matches. @@ -1424,8 +1011,6 @@ class HasSubstrMatcher { private: const StringType substring_; - - GTEST_DISALLOW_ASSIGN_(HasSubstrMatcher); }; // Implements the polymorphic StartsWith(substring) matcher, which @@ -1434,21 +1019,17 @@ class HasSubstrMatcher { template <typename StringType> class StartsWithMatcher { public: - explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) { - } + explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) {} -#if GTEST_HAS_ABSL - bool MatchAndExplain(const absl::string_view& s, +#if GTEST_INTERNAL_HAS_STRING_VIEW + bool MatchAndExplain(const internal::StringView& s, MatchResultListener* listener) const { - if (s.data() == NULL) { - return false; - } - // This should fail to compile if absl::string_view is used with wide + // This should fail to compile if StringView is used with wide // strings. - const StringType& str = string(s); + const StringType& str = std::string(s); return MatchAndExplain(str, listener); } -#endif // GTEST_HAS_ABSL +#endif // GTEST_INTERNAL_HAS_STRING_VIEW // Accepts pointer types, particularly: // const char* @@ -1457,19 +1038,19 @@ class StartsWithMatcher { // wchar_t* template <typename CharType> bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { - return s != NULL && MatchAndExplain(StringType(s), listener); + 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 absl::string_view has some interfering non-explicit constructors. + // 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_; + s2.substr(0, prefix_.length()) == prefix_; } void DescribeTo(::std::ostream* os) const { @@ -1484,8 +1065,6 @@ class StartsWithMatcher { private: const StringType prefix_; - - GTEST_DISALLOW_ASSIGN_(StartsWithMatcher); }; // Implements the polymorphic EndsWith(substring) matcher, which @@ -1496,18 +1075,15 @@ class EndsWithMatcher { public: explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {} -#if GTEST_HAS_ABSL - bool MatchAndExplain(const absl::string_view& s, +#if GTEST_INTERNAL_HAS_STRING_VIEW + bool MatchAndExplain(const internal::StringView& s, MatchResultListener* listener) const { - if (s.data() == NULL) { - return false; - } - // This should fail to compile if absl::string_view is used with wide + // This should fail to compile if StringView is used with wide // strings. - const StringType& str = string(s); + const StringType& str = std::string(s); return MatchAndExplain(str, listener); } -#endif // GTEST_HAS_ABSL +#endif // GTEST_INTERNAL_HAS_STRING_VIEW // Accepts pointer types, particularly: // const char* @@ -1516,19 +1092,19 @@ class EndsWithMatcher { // wchar_t* template <typename CharType> bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { - return s != NULL && MatchAndExplain(StringType(s), listener); + 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 absl::string_view has some interfering non-explicit constructors. + // 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_; + s2.substr(s2.length() - suffix_.length()) == suffix_; } void DescribeTo(::std::ostream* os) const { @@ -1543,64 +1119,45 @@ class EndsWithMatcher { private: const StringType suffix_; - - GTEST_DISALLOW_ASSIGN_(EndsWithMatcher); }; -// Implements polymorphic matchers MatchesRegex(regex) and -// ContainsRegex(regex), which can be used as a Matcher<T> as long as -// T can be converted to a string. -class MatchesRegexMatcher { +// Implements the polymorphic WhenBase64Unescaped(matcher) matcher, which can be +// used as a Matcher<T> as long as T can be converted to a string. +class WhenBase64UnescapedMatcher { public: - MatchesRegexMatcher(const RE* regex, bool full_match) - : regex_(regex), full_match_(full_match) {} + using is_gtest_matcher = void; -#if GTEST_HAS_ABSL - bool MatchAndExplain(const absl::string_view& s, - MatchResultListener* listener) const { - return s.data() && MatchAndExplain(string(s), listener); - } -#endif // GTEST_HAS_ABSL - - // Accepts pointer types, particularly: - // const char* - // char* - // const wchar_t* - // wchar_t* - template <typename CharType> - bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { - return s != NULL && MatchAndExplain(std::string(s), listener); - } + explicit WhenBase64UnescapedMatcher( + const Matcher<const std::string&>& internal_matcher) + : internal_matcher_(internal_matcher) {} // Matches anything that can convert to std::string. - // - // This is a template, not just a plain function with const std::string&, - // because absl::string_view has some interfering non-explicit constructors. - template <class MatcheeStringType> + template <typename MatcheeStringType> bool MatchAndExplain(const MatcheeStringType& s, - MatchResultListener* /* listener */) const { - const std::string& s2(s); - return full_match_ ? RE::FullMatch(s2, *regex_) : - RE::PartialMatch(s2, *regex_); + MatchResultListener* listener) const { + const std::string s2(s); // NOLINT (needed for working with string_view). + std::string unescaped; + if (!internal::Base64Unescape(s2, &unescaped)) { + if (listener != nullptr) { + *listener << "is not a valid base64 escaped string"; + } + return false; + } + return MatchPrintAndExplain(unescaped, internal_matcher_, listener); } void DescribeTo(::std::ostream* os) const { - *os << (full_match_ ? "matches" : "contains") - << " regular expression "; - UniversalPrinter<std::string>::Print(regex_->pattern(), os); + *os << "matches after Base64Unescape "; + internal_matcher_.DescribeTo(os); } void DescribeNegationTo(::std::ostream* os) const { - *os << "doesn't " << (full_match_ ? "match" : "contain") - << " regular expression "; - UniversalPrinter<std::string>::Print(regex_->pattern(), os); + *os << "does not match after Base64Unescape "; + internal_matcher_.DescribeTo(os); } private: - const internal::linked_ptr<const RE> regex_; - const bool full_match_; - - GTEST_DISALLOW_ASSIGN_(MatchesRegexMatcher); + const Matcher<const std::string&> internal_matcher_; }; // Implements a matcher that compares the two fields of a 2-tuple @@ -1608,19 +1165,19 @@ class MatchesRegexMatcher { // compared don't have to have the same type. // // The matcher defined here is polymorphic (for example, Eq() can be -// used to match a tuple<int, short>, a tuple<const long&, double>, +// 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< ::testing::tuple<T1, T2> >() const { - return MakeMatcher(new Impl< ::testing::tuple<T1, 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 ::testing::tuple<T1, T2>&>() const { - return MakeMatcher(new Impl<const ::testing::tuple<T1, T2>&>); + operator Matcher<const ::std::tuple<T1, T2>&>() const { + return MakeMatcher(new Impl<const ::std::tuple<T1, T2>&>); } private: @@ -1631,41 +1188,40 @@ class PairMatchBase { template <typename Tuple> class Impl : public MatcherInterface<Tuple> { public: - virtual bool MatchAndExplain( - Tuple args, - MatchResultListener* /* listener */) const { - return Op()(::testing::get<0>(args), ::testing::get<1>(args)); + bool MatchAndExplain(Tuple args, + MatchResultListener* /* listener */) const override { + return Op()(::std::get<0>(args), ::std::get<1>(args)); } - virtual void DescribeTo(::std::ostream* os) const { + void DescribeTo(::std::ostream* os) const override { *os << "are " << GetDesc; } - virtual void DescribeNegationTo(::std::ostream* os) const { + void DescribeNegationTo(::std::ostream* os) const override { *os << "aren't " << GetDesc; } }; }; -class Eq2Matcher : public PairMatchBase<Eq2Matcher, AnyEq> { +class Eq2Matcher : public PairMatchBase<Eq2Matcher, std::equal_to<>> { public: static const char* Desc() { return "an equal pair"; } }; -class Ne2Matcher : public PairMatchBase<Ne2Matcher, AnyNe> { +class Ne2Matcher : public PairMatchBase<Ne2Matcher, std::not_equal_to<>> { public: static const char* Desc() { return "an unequal pair"; } }; -class Lt2Matcher : public PairMatchBase<Lt2Matcher, AnyLt> { +class Lt2Matcher : public PairMatchBase<Lt2Matcher, std::less<>> { public: static const char* Desc() { return "a pair where the first < the second"; } }; -class Gt2Matcher : public PairMatchBase<Gt2Matcher, AnyGt> { +class Gt2Matcher : public PairMatchBase<Gt2Matcher, std::greater<>> { public: static const char* Desc() { return "a pair where the first > the second"; } }; -class Le2Matcher : public PairMatchBase<Le2Matcher, AnyLe> { +class Le2Matcher : public PairMatchBase<Le2Matcher, std::less_equal<>> { public: static const char* Desc() { return "a pair where the first <= the second"; } }; -class Ge2Matcher : public PairMatchBase<Ge2Matcher, AnyGe> { +class Ge2Matcher : public PairMatchBase<Ge2Matcher, std::greater_equal<>> { public: static const char* Desc() { return "a pair where the first >= the second"; } }; @@ -1675,28 +1231,25 @@ class Ge2Matcher : public PairMatchBase<Ge2Matcher, AnyGe> { // will prevent different instantiations of NotMatcher from sharing // the same NotMatcherImpl<T> class. template <typename T> -class NotMatcherImpl : public MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)> { +class NotMatcherImpl : public MatcherInterface<const T&> { public: - explicit NotMatcherImpl(const Matcher<T>& matcher) - : matcher_(matcher) {} + explicit NotMatcherImpl(const Matcher<T>& matcher) : matcher_(matcher) {} - virtual bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) x, - MatchResultListener* listener) const { + bool MatchAndExplain(const T& x, + MatchResultListener* listener) const override { return !matcher_.MatchAndExplain(x, listener); } - virtual void DescribeTo(::std::ostream* os) const { + void DescribeTo(::std::ostream* os) const override { matcher_.DescribeNegationTo(os); } - virtual void DescribeNegationTo(::std::ostream* os) const { + void DescribeNegationTo(::std::ostream* os) const override { matcher_.DescribeTo(os); } private: const Matcher<T> matcher_; - - GTEST_DISALLOW_ASSIGN_(NotMatcherImpl); }; // Implements the Not(m) matcher, which matches a value that doesn't @@ -1715,8 +1268,6 @@ class NotMatcher { private: InnerMatcher matcher_; - - GTEST_DISALLOW_ASSIGN_(NotMatcher); }; // Implements the AllOf(m1, m2) matcher for a particular argument type @@ -1724,13 +1275,12 @@ class NotMatcher { // that will prevent different instantiations of BothOfMatcher from // sharing the same BothOfMatcherImpl<T> class. template <typename T> -class AllOfMatcherImpl - : public MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)> { +class AllOfMatcherImpl : public MatcherInterface<const T&> { public: - explicit AllOfMatcherImpl(std::vector<Matcher<T> > matchers) - : matchers_(internal::move(matchers)) {} + explicit AllOfMatcherImpl(std::vector<Matcher<T>> matchers) + : matchers_(std::move(matchers)) {} - virtual void DescribeTo(::std::ostream* os) const { + void DescribeTo(::std::ostream* os) const override { *os << "("; for (size_t i = 0; i < matchers_.size(); ++i) { if (i != 0) *os << ") and ("; @@ -1739,7 +1289,7 @@ class AllOfMatcherImpl *os << ")"; } - virtual void DescribeNegationTo(::std::ostream* os) const { + void DescribeNegationTo(::std::ostream* os) const override { *os << "("; for (size_t i = 0; i < matchers_.size(); ++i) { if (i != 0) *os << ") or ("; @@ -1748,8 +1298,8 @@ class AllOfMatcherImpl *os << ")"; } - virtual bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) x, - MatchResultListener* listener) const { + 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; @@ -1778,12 +1328,9 @@ class AllOfMatcherImpl } private: - const std::vector<Matcher<T> > matchers_; - - GTEST_DISALLOW_ASSIGN_(AllOfMatcherImpl); + const std::vector<Matcher<T>> matchers_; }; -#if GTEST_LANG_CXX11 // 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 @@ -1796,19 +1343,22 @@ class VariadicMatcher { 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; + std::vector<Matcher<T>> values; CreateVariadicMatcher<T>(&values, std::integral_constant<size_t, 0>()); - return Matcher<T>(new CombiningMatcher<T>(internal::move(values))); + return Matcher<T>(new CombiningMatcher<T>(std::move(values))); } private: template <typename T, size_t I> - void CreateVariadicMatcher(std::vector<Matcher<T> >* values, + 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>()); @@ -1816,57 +1366,26 @@ class VariadicMatcher { template <typename T> void CreateVariadicMatcher( - std::vector<Matcher<T> >*, + std::vector<Matcher<T>>*, std::integral_constant<size_t, sizeof...(Args)>) const {} - tuple<Args...> matchers_; - - GTEST_DISALLOW_ASSIGN_(VariadicMatcher); + std::tuple<Args...> matchers_; }; template <typename... Args> using AllOfMatcher = VariadicMatcher<AllOfMatcherImpl, Args...>; -#endif // GTEST_LANG_CXX11 - -// Used for implementing the AllOf(m_1, ..., m_n) matcher, which -// matches a value that matches all of the matchers m_1, ..., and m_n. -template <typename Matcher1, typename Matcher2> -class BothOfMatcher { - public: - BothOfMatcher(Matcher1 matcher1, Matcher2 matcher2) - : matcher1_(matcher1), matcher2_(matcher2) {} - - // This template type conversion operator allows a - // BothOfMatcher<Matcher1, Matcher2> object to match any type that - // both Matcher1 and Matcher2 can match. - template <typename T> - operator Matcher<T>() const { - std::vector<Matcher<T> > values; - values.push_back(SafeMatcherCast<T>(matcher1_)); - values.push_back(SafeMatcherCast<T>(matcher2_)); - return Matcher<T>(new AllOfMatcherImpl<T>(internal::move(values))); - } - - private: - Matcher1 matcher1_; - Matcher2 matcher2_; - - GTEST_DISALLOW_ASSIGN_(BothOfMatcher); -}; - // 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<GTEST_REFERENCE_TO_CONST_(T)> { +class AnyOfMatcherImpl : public MatcherInterface<const T&> { public: - explicit AnyOfMatcherImpl(std::vector<Matcher<T> > matchers) - : matchers_(internal::move(matchers)) {} + explicit AnyOfMatcherImpl(std::vector<Matcher<T>> matchers) + : matchers_(std::move(matchers)) {} - virtual void DescribeTo(::std::ostream* os) const { + void DescribeTo(::std::ostream* os) const override { *os << "("; for (size_t i = 0; i < matchers_.size(); ++i) { if (i != 0) *os << ") or ("; @@ -1875,7 +1394,7 @@ class AnyOfMatcherImpl *os << ")"; } - virtual void DescribeNegationTo(::std::ostream* os) const { + void DescribeNegationTo(::std::ostream* os) const override { *os << "("; for (size_t i = 0; i < matchers_.size(); ++i) { if (i != 0) *os << ") and ("; @@ -1884,8 +1403,8 @@ class AnyOfMatcherImpl *os << ")"; } - virtual bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) x, - MatchResultListener* listener) const { + 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 @@ -1914,45 +1433,65 @@ class AnyOfMatcherImpl } private: - const std::vector<Matcher<T> > matchers_; - - GTEST_DISALLOW_ASSIGN_(AnyOfMatcherImpl); + const std::vector<Matcher<T>> matchers_; }; -#if GTEST_LANG_CXX11 // AnyOfMatcher is used for the variadic implementation of AnyOf(m_1, m_2, ...). template <typename... Args> using AnyOfMatcher = VariadicMatcher<AnyOfMatcherImpl, Args...>; -#endif // GTEST_LANG_CXX11 - -// Used for implementing the AnyOf(m_1, ..., m_n) matcher, which -// matches a value that matches at least one of the matchers m_1, ..., -// and m_n. -template <typename Matcher1, typename Matcher2> -class EitherOfMatcher { +// ConditionalMatcher is the implementation of Conditional(cond, m1, m2) +template <typename MatcherTrue, typename MatcherFalse> +class ConditionalMatcher { public: - EitherOfMatcher(Matcher1 matcher1, Matcher2 matcher2) - : matcher1_(matcher1), matcher2_(matcher2) {} + ConditionalMatcher(bool condition, MatcherTrue matcher_true, + MatcherFalse matcher_false) + : condition_(condition), + matcher_true_(std::move(matcher_true)), + matcher_false_(std::move(matcher_false)) {} - // This template type conversion operator allows a - // EitherOfMatcher<Matcher1, Matcher2> object to match any type that - // both Matcher1 and Matcher2 can match. template <typename T> - operator Matcher<T>() const { - std::vector<Matcher<T> > values; - values.push_back(SafeMatcherCast<T>(matcher1_)); - values.push_back(SafeMatcherCast<T>(matcher2_)); - return Matcher<T>(new AnyOfMatcherImpl<T>(internal::move(values))); + operator Matcher<T>() const { // NOLINT(runtime/explicit) + return condition_ ? SafeMatcherCast<T>(matcher_true_) + : SafeMatcherCast<T>(matcher_false_); } private: - Matcher1 matcher1_; - Matcher2 matcher2_; + bool condition_; + MatcherTrue matcher_true_; + MatcherFalse matcher_false_; +}; - GTEST_DISALLOW_ASSIGN_(EitherOfMatcher); +// 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; + matchers.reserve(matchers_.size()); + 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> @@ -1966,15 +1505,15 @@ class TrulyMatcher { // interested in the address of the argument. template <typename T> bool MatchAndExplain(T& x, // NOLINT - MatchResultListener* /* listener */) const { + 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; + if (predicate_(x)) return true; + *listener << "didn't satisfy the given predicate"; return false; } @@ -1988,8 +1527,6 @@ class TrulyMatcher { private: Predicate predicate_; - - GTEST_DISALLOW_ASSIGN_(TrulyMatcher); }; // Used for implementing Matches(matcher), which turns a matcher into @@ -2026,8 +1563,6 @@ class MatcherAsPredicate { private: M matcher_; - - GTEST_DISALLOW_ASSIGN_(MatcherAsPredicate); }; // For implementing ASSERT_THAT() and EXPECT_THAT(). The template @@ -2035,7 +1570,7 @@ class MatcherAsPredicate { template <typename M> class PredicateFormatterFromMatcher { public: - explicit PredicateFormatterFromMatcher(M m) : matcher_(internal::move(m)) {} + 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 @@ -2054,22 +1589,30 @@ class PredicateFormatterFromMatcher { // 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_); - StringMatchResultListener listener; - if (MatchPrintAndExplain(x, matcher, &listener)) + + // 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_; - - GTEST_DISALLOW_ASSIGN_(PredicateFormatterFromMatcher); }; // A helper function for converting a matcher to a predicate-formatter @@ -2077,11 +1620,25 @@ class PredicateFormatterFromMatcher { // 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>(internal::move(matcher)); +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 @@ -2095,9 +1652,8 @@ class FloatingEqMatcher { // 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) { - } + 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 @@ -2120,8 +1676,8 @@ class FloatingEqMatcher { nan_eq_nan_(nan_eq_nan), max_abs_error_(max_abs_error) {} - virtual bool MatchAndExplain(T value, - MatchResultListener* listener) const { + bool MatchAndExplain(T value, + MatchResultListener* listener) const override { const FloatingPoint<FloatType> actual(value), expected(expected_); // Compares NaNs first, if nan_eq_nan_ is true. @@ -2142,7 +1698,7 @@ class FloatingEqMatcher { } const FloatType diff = value - expected_; - if (fabs(diff) <= max_abs_error_) { + if (::std::fabs(diff) <= max_abs_error_) { return true; } @@ -2155,12 +1711,12 @@ class FloatingEqMatcher { } } - virtual void DescribeTo(::std::ostream* os) const { + 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); + 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"; @@ -2176,10 +1732,10 @@ class FloatingEqMatcher { os->precision(old_precision); } - virtual void DescribeNegationTo(::std::ostream* os) const { + 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); + 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"; @@ -2197,24 +1753,17 @@ class FloatingEqMatcher { } private: - bool HasMaxAbsError() const { - return max_abs_error_ >= 0; - } + 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_; - - GTEST_DISALLOW_ASSIGN_(Impl); }; // 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. - // (While Google's C++ coding style doesn't allow arguments passed - // by non-const reference, we may see them in code not conforming to - // the style. Therefore Google Mock needs to support them.) operator Matcher<FloatType>() const { return MakeMatcher( new Impl<FloatType>(expected_, nan_eq_nan_, max_abs_error_)); @@ -2235,8 +1784,6 @@ class FloatingEqMatcher { const bool nan_eq_nan_; // max_abs_error will be used for value comparison when >= 0. const FloatType max_abs_error_; - - GTEST_DISALLOW_ASSIGN_(FloatingEqMatcher); }; // A 2-tuple ("binary") wrapper around FloatingEqMatcher: @@ -2260,14 +1807,14 @@ class FloatingEq2Matcher { } template <typename T1, typename T2> - operator Matcher< ::testing::tuple<T1, T2> >() const { + operator Matcher<::std::tuple<T1, T2>>() const { return MakeMatcher( - new Impl< ::testing::tuple<T1, T2> >(max_abs_error_, nan_eq_nan_)); + new Impl<::std::tuple<T1, T2>>(max_abs_error_, nan_eq_nan_)); } template <typename T1, typename T2> - operator Matcher<const ::testing::tuple<T1, T2>&>() const { + operator Matcher<const ::std::tuple<T1, T2>&>() const { return MakeMatcher( - new Impl<const ::testing::tuple<T1, T2>&>(max_abs_error_, nan_eq_nan_)); + new Impl<const ::std::tuple<T1, T2>&>(max_abs_error_, nan_eq_nan_)); } private: @@ -2278,27 +1825,26 @@ class FloatingEq2Matcher { 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) {} + Impl(FloatType max_abs_error, bool nan_eq_nan) + : max_abs_error_(max_abs_error), nan_eq_nan_(nan_eq_nan) {} - virtual bool MatchAndExplain(Tuple args, - MatchResultListener* listener) const { + bool MatchAndExplain(Tuple args, + MatchResultListener* listener) const override { if (max_abs_error_ == -1) { - FloatingEqMatcher<FloatType> fm(::testing::get<0>(args), nan_eq_nan_); - return static_cast<Matcher<FloatType> >(fm).MatchAndExplain( - ::testing::get<1>(args), listener); + 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(::testing::get<0>(args), nan_eq_nan_, + FloatingEqMatcher<FloatType> fm(::std::get<0>(args), nan_eq_nan_, max_abs_error_); - return static_cast<Matcher<FloatType> >(fm).MatchAndExplain( - ::testing::get<1>(args), listener); + return static_cast<Matcher<FloatType>>(fm).MatchAndExplain( + ::std::get<1>(args), listener); } } - virtual void DescribeTo(::std::ostream* os) const { + void DescribeTo(::std::ostream* os) const override { *os << "are " << GetDesc; } - virtual void DescribeNegationTo(::std::ostream* os) const { + void DescribeNegationTo(::std::ostream* os) const override { *os << "aren't " << GetDesc; } @@ -2332,8 +1878,7 @@ class PointeeMatcher { // enough for implementing the DescribeTo() method of Pointee(). template <typename Pointer> operator Matcher<Pointer>() const { - return Matcher<Pointer>( - new Impl<GTEST_REFERENCE_TO_CONST_(Pointer)>(matcher_)); + return Matcher<Pointer>(new Impl<const Pointer&>(matcher_)); } private: @@ -2341,26 +1886,26 @@ class PointeeMatcher { template <typename Pointer> class Impl : public MatcherInterface<Pointer> { public: - typedef typename PointeeOf<GTEST_REMOVE_CONST_( // NOLINT - GTEST_REMOVE_REFERENCE_(Pointer))>::type Pointee; + using Pointee = + typename std::pointer_traits<GTEST_REMOVE_REFERENCE_AND_CONST_( + Pointer)>::element_type; explicit Impl(const InnerMatcher& matcher) : matcher_(MatcherCast<const Pointee&>(matcher)) {} - virtual void DescribeTo(::std::ostream* os) const { + void DescribeTo(::std::ostream* os) const override { *os << "points to a value that "; matcher_.DescribeTo(os); } - virtual void DescribeNegationTo(::std::ostream* os) const { + void DescribeNegationTo(::std::ostream* os) const override { *os << "does not point to a value that "; matcher_.DescribeTo(os); } - virtual bool MatchAndExplain(Pointer pointer, - MatchResultListener* listener) const { - if (GetRawPointer(pointer) == NULL) - return false; + bool MatchAndExplain(Pointer pointer, + MatchResultListener* listener) const override { + if (GetRawPointer(pointer) == nullptr) return false; *listener << "which points to "; return MatchPrintAndExplain(*pointer, matcher_, listener); @@ -2368,13 +1913,67 @@ class PointeeMatcher { private: const Matcher<const Pointee&> matcher_; - - GTEST_DISALLOW_ASSIGN_(Impl); }; 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_)); + } - GTEST_DISALLOW_ASSIGN_(PointeeMatcher); + 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 @@ -2403,16 +2002,12 @@ class WhenDynamicCastToMatcherBase { protected: const Matcher<To> matcher_; - static std::string GetToName() { - return GetTypeName<To>(); - } + static std::string GetToName() { return GetTypeName<To>(); } private: static void GetCastTypeDescription(::std::ostream* os) { *os << "when dynamic_cast to " << GetToName() << ", "; } - - GTEST_DISALLOW_ASSIGN_(WhenDynamicCastToMatcherBase); }; // Primary template. @@ -2425,7 +2020,6 @@ class WhenDynamicCastToMatcher : public WhenDynamicCastToMatcherBase<To> { template <typename From> bool MatchAndExplain(From from, MatchResultListener* listener) const { - // FIXME: Add more detail on failures. ie did the dyn_cast fail? To to = dynamic_cast<To>(from); return MatchPrintAndExplain(to, this->matcher_, listener); } @@ -2443,7 +2037,7 @@ class WhenDynamicCastToMatcher<To&> : public WhenDynamicCastToMatcherBase<To&> { 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 == NULL) { + if (to == nullptr) { *listener << "which cannot be dynamic_cast to " << this->GetToName(); return false; } @@ -2479,32 +2073,30 @@ class FieldMatcher { 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 ::testing::internal:: - is_pointer<GTEST_REMOVE_CONST_(T)>::type(), + typename std::is_pointer<typename std::remove_const<T>::type>::type(), value, listener); } private: - // The first argument of MatchAndExplainImpl() is needed to help - // Symbian's C++ compiler choose which overload to use. Its type is - // true_type iff the Field() matcher is used to match a pointer. - bool MatchAndExplainImpl(false_type /* is_not_pointer */, const Class& obj, + 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(true_type /* is_pointer */, const Class* p, + bool MatchAndExplainImpl(std::true_type /* is_pointer */, const Class* p, MatchResultListener* listener) const { - if (p == NULL) - return false; + 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(false_type(), *p, listener); + return MatchAndExplainImpl(std::false_type(), *p, listener); } const FieldType Class::*field_; @@ -2513,8 +2105,6 @@ class FieldMatcher { // Contains either "whose given field " if the name of the field is unknown // or "whose field `name_of_field` " if the name is known. const std::string whose_field_; - - GTEST_DISALLOW_ASSIGN_(FieldMatcher); }; // Implements the Property() matcher for matching a property @@ -2525,11 +2115,7 @@ class FieldMatcher { template <typename Class, typename PropertyType, typename Property> class PropertyMatcher { public: - // The property may have a reference type, so 'const PropertyType&' - // may cause double references and fail to compile. That's why we - // need GTEST_REFERENCE_TO_CONST, which works regardless of - // PropertyType being a reference or not. - typedef GTEST_REFERENCE_TO_CONST_(PropertyType) RefToConstProperty; + typedef const PropertyType& RefToConstProperty; PropertyMatcher(Property property, const Matcher<RefToConstProperty>& matcher) : property_(property), @@ -2553,43 +2139,32 @@ class PropertyMatcher { } template <typename T> - bool MatchAndExplain(const T&value, MatchResultListener* listener) const { + bool MatchAndExplain(const T& value, MatchResultListener* listener) const { return MatchAndExplainImpl( - typename ::testing::internal:: - is_pointer<GTEST_REMOVE_CONST_(T)>::type(), + typename std::is_pointer<typename std::remove_const<T>::type>::type(), value, listener); } private: - // The first argument of MatchAndExplainImpl() is needed to help - // Symbian's C++ compiler choose which overload to use. Its type is - // true_type iff the Property() matcher is used to match a pointer. - bool MatchAndExplainImpl(false_type /* is_not_pointer */, const Class& obj, + 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. -#if defined(_PREFAST_ ) && _MSC_VER == 1800 - // Workaround bug in VC++ 2013's /analyze parser. - // https://connect.microsoft.com/VisualStudio/feedback/details/1106363/internal-compiler-error-with-analyze-due-to-failure-to-infer-move - posix::Abort(); // To make sure it is never run. - return false; -#else RefToConstProperty result = (obj.*property_)(); return MatchPrintAndExplain(result, matcher_, listener); -#endif } - bool MatchAndExplainImpl(true_type /* is_pointer */, const Class* p, + bool MatchAndExplainImpl(std::true_type /* is_pointer */, const Class* p, MatchResultListener* listener) const { - if (p == NULL) - return false; + 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(false_type(), *p, listener); + return MatchAndExplainImpl(std::false_type(), *p, listener); } Property property_; @@ -2598,8 +2173,6 @@ class PropertyMatcher { // Contains either "whose given property " if the name of the property is // unknown or "whose property `name_of_property` " if the name is known. const std::string whose_property_; - - GTEST_DISALLOW_ASSIGN_(PropertyMatcher); }; // Type traits specifying various features of different functors for ResultOf. @@ -2610,28 +2183,24 @@ struct CallableTraits { static void CheckIsValid(Functor /* functor */) {} -#if GTEST_LANG_CXX11 template <typename T> - static auto Invoke(Functor f, T arg) -> decltype(f(arg)) { return f(arg); } -#else - typedef typename Functor::result_type ResultType; - template <typename T> - static ResultType Invoke(Functor f, T arg) { return f(arg); } -#endif + 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)> { +struct CallableTraits<ResType (*)(ArgType)> { typedef ResType ResultType; - typedef ResType(*StorageType)(ArgType); + typedef ResType (*StorageType)(ArgType); - static void CheckIsValid(ResType(*f)(ArgType)) { - GTEST_CHECK_(f != NULL) + 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) { + static ResType Invoke(ResType (*f)(ArgType), T arg) { return (*f)(arg); } }; @@ -2642,13 +2211,21 @@ template <typename Callable, typename InnerMatcher> class ResultOfMatcher { public: ResultOfMatcher(Callable callable, InnerMatcher matcher) - : callable_(internal::move(callable)), matcher_(internal::move(matcher)) { + : ResultOfMatcher(/*result_description=*/"", std::move(callable), + std::move(matcher)) {} + + ResultOfMatcher(const std::string& result_description, Callable callable, + InnerMatcher matcher) + : result_description_(result_description), + callable_(std::move(callable)), + matcher_(std::move(matcher)) { CallableTraits<Callable>::CheckIsValid(callable_); } template <typename T> operator Matcher<T>() const { - return Matcher<T>(new Impl<T>(callable_, matcher_)); + return Matcher<T>( + new Impl<const T&>(result_description_, callable_, matcher_)); } private: @@ -2656,30 +2233,41 @@ class ResultOfMatcher { template <typename T> class Impl : public MatcherInterface<T> { -#if GTEST_LANG_CXX11 using ResultType = decltype(CallableTraits<Callable>::template Invoke<T>( std::declval<CallableStorageType>(), std::declval<T>())); -#else - typedef typename CallableTraits<Callable>::ResultType ResultType; -#endif public: template <typename M> - Impl(const CallableStorageType& callable, const M& matcher) - : callable_(callable), matcher_(MatcherCast<ResultType>(matcher)) {} - - virtual void DescribeTo(::std::ostream* os) const { - *os << "is mapped by the given callable to a value that "; + Impl(const std::string& result_description, + const CallableStorageType& callable, const M& matcher) + : result_description_(result_description), + callable_(callable), + matcher_(MatcherCast<ResultType>(matcher)) {} + + void DescribeTo(::std::ostream* os) const override { + if (result_description_.empty()) { + *os << "is mapped by the given callable to a value that "; + } else { + *os << "whose " << result_description_ << " "; + } matcher_.DescribeTo(os); } - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "is mapped by the given callable to a value that "; + void DescribeNegationTo(::std::ostream* os) const override { + if (result_description_.empty()) { + *os << "is mapped by the given callable to a value that "; + } else { + *os << "whose " << result_description_ << " "; + } matcher_.DescribeNegationTo(os); } - virtual bool MatchAndExplain(T obj, MatchResultListener* listener) const { - *listener << "which is mapped by the given callable to "; + bool MatchAndExplain(T obj, MatchResultListener* listener) const override { + if (result_description_.empty()) { + *listener << "which is mapped by the given callable to "; + } else { + *listener << "whose " << result_description_ << " is "; + } // 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 @@ -2690,6 +2278,7 @@ class ResultOfMatcher { } private: + const std::string result_description_; // 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 @@ -2697,14 +2286,11 @@ class ResultOfMatcher { // how many times the callable will be invoked. mutable CallableStorageType callable_; const Matcher<ResultType> matcher_; - - GTEST_DISALLOW_ASSIGN_(Impl); }; // class Impl + const std::string result_description_; const CallableStorageType callable_; const InnerMatcher matcher_; - - GTEST_DISALLOW_ASSIGN_(ResultOfMatcher); }; // Implements a matcher that checks the size of an STL-style container. @@ -2712,51 +2298,46 @@ template <typename SizeMatcher> class SizeIsMatcher { public: explicit SizeIsMatcher(const SizeMatcher& size_matcher) - : size_matcher_(size_matcher) { - } + : size_matcher_(size_matcher) {} template <typename Container> operator Matcher<Container>() const { - return MakeMatcher(new Impl<Container>(size_matcher_)); + return Matcher<Container>(new Impl<const Container&>(size_matcher_)); } template <typename Container> class Impl : public MatcherInterface<Container> { public: - typedef internal::StlContainerView< - GTEST_REMOVE_REFERENCE_AND_CONST_(Container)> ContainerView; - typedef typename ContainerView::type::size_type SizeType; + using SizeType = decltype(std::declval<Container>().size()); explicit Impl(const SizeMatcher& size_matcher) : size_matcher_(MatcherCast<SizeType>(size_matcher)) {} - virtual void DescribeTo(::std::ostream* os) const { - *os << "size "; + void DescribeTo(::std::ostream* os) const override { + *os << "has a size that "; size_matcher_.DescribeTo(os); } - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "size "; + void DescribeNegationTo(::std::ostream* os) const override { + *os << "has a size that "; size_matcher_.DescribeNegationTo(os); } - virtual bool MatchAndExplain(Container container, - MatchResultListener* listener) const { + 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"); + *listener << "whose size " << size + << (result ? " matches" : " doesn't match"); PrintIfNotEmpty(size_listener.str(), listener->stream()); return result; } private: const Matcher<SizeType> size_matcher_; - GTEST_DISALLOW_ASSIGN_(Impl); }; private: const SizeMatcher size_matcher_; - GTEST_DISALLOW_ASSIGN_(SizeIsMatcher); }; // Implements a matcher that checks the begin()..end() distance of an STL-style @@ -2769,38 +2350,35 @@ class BeginEndDistanceIsMatcher { template <typename Container> operator Matcher<Container>() const { - return MakeMatcher(new Impl<Container>(distance_matcher_)); + 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 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)) {} - virtual void DescribeTo(::std::ostream* os) const { + void DescribeTo(::std::ostream* os) const override { *os << "distance between begin() and end() "; distance_matcher_.DescribeTo(os); } - virtual void DescribeNegationTo(::std::ostream* os) const { + void DescribeNegationTo(::std::ostream* os) const override { *os << "distance between begin() and end() "; distance_matcher_.DescribeNegationTo(os); } - virtual bool MatchAndExplain(Container container, - MatchResultListener* listener) const { -#if GTEST_HAS_STD_BEGIN_AND_END_ + bool MatchAndExplain(Container container, + MatchResultListener* listener) const override { using std::begin; using std::end; DistanceType distance = std::distance(begin(container), end(container)); -#else - DistanceType distance = std::distance(container.begin(), container.end()); -#endif StringMatchResultListener distance_listener; const bool result = distance_matcher_.MatchAndExplain(distance, &distance_listener); @@ -2812,12 +2390,10 @@ class BeginEndDistanceIsMatcher { private: const Matcher<DistanceType> distance_matcher_; - GTEST_DISALLOW_ASSIGN_(Impl); }; private: const DistanceMatcher distance_matcher_; - GTEST_DISALLOW_ASSIGN_(BeginEndDistanceIsMatcher); }; // Implements an equality matcher for any STL-style container whose elements @@ -2837,15 +2413,15 @@ class ContainerEqMatcher { 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)) { - // Makes sure the user doesn't instantiate this class template - // with a const or reference type. - (void)testing::StaticAssertTypeEq<Container, - GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>(); - } + : expected_(View::Copy(expected)) {} void DescribeTo(::std::ostream* os) const { *os << "equals "; @@ -2859,22 +2435,18 @@ class ContainerEqMatcher { template <typename LhsContainer> bool MatchAndExplain(const LhsContainer& lhs, MatchResultListener* listener) const { - // GTEST_REMOVE_CONST_() is needed to work around an MSVC 8.0 bug - // that causes LhsContainer to be a const type sometimes. - typedef internal::StlContainerView<GTEST_REMOVE_CONST_(LhsContainer)> + 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; + if (lhs_stl_container == expected_) return true; ::std::ostream* const os = listener->stream(); - if (os != NULL) { + 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) { + for (auto it = lhs_stl_container.begin(); it != lhs_stl_container.end(); + ++it) { if (internal::ArrayAwareFind(expected_.begin(), expected_.end(), *it) == expected_.end()) { if (printed_header) { @@ -2889,11 +2461,10 @@ class ContainerEqMatcher { // 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()) { + for (auto 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 { @@ -2911,14 +2482,14 @@ class ContainerEqMatcher { private: const StlContainer expected_; - - GTEST_DISALLOW_ASSIGN_(ContainerEqMatcher); }; // 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; } + bool operator()(const T& lhs, const U& rhs) const { + return lhs < rhs; + } }; // Implements WhenSortedBy(comparator, container_matcher). @@ -2937,35 +2508,37 @@ class WhenSortedByMatcher { template <typename LhsContainer> class Impl : public MatcherInterface<LhsContainer> { public: - typedef internal::StlContainerView< - GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)> LhsView; + 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; + typedef + typename RemoveConstFromKey<typename LhsStlContainer::value_type>::type + LhsValue; Impl(const Comparator& comparator, const ContainerMatcher& matcher) : comparator_(comparator), matcher_(matcher) {} - virtual void DescribeTo(::std::ostream* os) const { + void DescribeTo(::std::ostream* os) const override { *os << "(when sorted) "; matcher_.DescribeTo(os); } - virtual void DescribeNegationTo(::std::ostream* os) const { + void DescribeNegationTo(::std::ostream* os) const override { *os << "(when sorted) "; matcher_.DescribeNegationTo(os); } - virtual bool MatchAndExplain(LhsContainer lhs, - MatchResultListener* listener) const { + 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_); + ::std::sort(sorted_container.begin(), sorted_container.end(), + comparator_); if (!listener->IsInterested()) { // If the listener is not interested, we do not need to @@ -2978,8 +2551,8 @@ class WhenSortedByMatcher { *listener << " when sorted"; StringMatchResultListener inner_listener; - const bool match = matcher_.MatchAndExplain(sorted_container, - &inner_listener); + const bool match = + matcher_.MatchAndExplain(sorted_container, &inner_listener); PrintIfNotEmpty(inner_listener.str(), listener->stream()); return match; } @@ -2988,55 +2561,56 @@ class WhenSortedByMatcher { const Comparator comparator_; const Matcher<const ::std::vector<LhsValue>&> matcher_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(Impl); + Impl(const Impl&) = delete; + Impl& operator=(const Impl&) = delete; }; private: const Comparator comparator_; const ContainerMatcher matcher_; - - GTEST_DISALLOW_ASSIGN_(WhenSortedByMatcher); }; // Implements Pointwise(tuple_matcher, rhs_container). tuple_matcher -// must be able to be safely cast to Matcher<tuple<const T1&, const +// 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_( + static_assert( !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(RhsContainer)>::value, - use_UnorderedPointwise_with_hash_tables); + "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)) { - // Makes sure the user doesn't instantiate this class template - // with a const or reference type. - (void)testing::StaticAssertTypeEq<RhsContainer, - GTEST_REMOVE_REFERENCE_AND_CONST_(RhsContainer)>(); - } + : tuple_matcher_(tuple_matcher), rhs_(RhsView::Copy(rhs)) {} template <typename LhsContainer> operator Matcher<LhsContainer>() const { - GTEST_COMPILE_ASSERT_( + static_assert( !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)>::value, - use_UnorderedPointwise_with_hash_tables); + "use UnorderedPointwise with hash tables"); - return MakeMatcher(new Impl<LhsContainer>(tuple_matcher_, rhs_)); + 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 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; @@ -3044,21 +2618,21 @@ class PointwiseMatcher { // 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 ::testing::tuple<const LhsValue&, const RhsValue&> InnerMatcherArg; + 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) {} - virtual void DescribeTo(::std::ostream* os) const { + 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); } - virtual void DescribeNegationTo(::std::ostream* os) const { + 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 "; @@ -3067,8 +2641,8 @@ class PointwiseMatcher { mono_tuple_matcher_.DescribeNegationTo(os); } - virtual bool MatchAndExplain(LhsContainer lhs, - MatchResultListener* listener) const { + 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()) { @@ -3076,14 +2650,14 @@ class PointwiseMatcher { return false; } - typename LhsStlContainer::const_iterator left = lhs_stl_container.begin(); - typename RhsStlContainer::const_iterator right = rhs_.begin(); + auto left = lhs_stl_container.begin(); + auto 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>. + // return temp objects, e.g. for vector<bool>. if (!mono_tuple_matcher_.MatchAndExplain( InnerMatcherArg(ImplicitCast_<const LhsValue&>(*left), ImplicitCast_<const RhsValue&>(*right)), @@ -3110,15 +2684,11 @@ class PointwiseMatcher { private: const Matcher<InnerMatcherArg> mono_tuple_matcher_; const RhsStlContainer rhs_; - - GTEST_DISALLOW_ASSIGN_(Impl); }; private: const TupleMatcher tuple_matcher_; const RhsStlContainer rhs_; - - GTEST_DISALLOW_ASSIGN_(PointwiseMatcher); }; // Holds the logic common to ContainsMatcherImpl and EachMatcherImpl. @@ -3134,18 +2704,17 @@ class QuantifierMatcherImpl : public MatcherInterface<Container> { template <typename InnerMatcher> explicit QuantifierMatcherImpl(InnerMatcher inner_matcher) : inner_matcher_( - testing::SafeMatcherCast<const Element&>(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, + 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) { + for (auto it = stl_container.begin(); it != stl_container.end(); + ++it, ++i) { StringMatchResultListener inner_listener; const bool matches = inner_matcher_.MatchAndExplain(*it, &inner_listener); @@ -3159,10 +2728,56 @@ class QuantifierMatcherImpl : public MatcherInterface<Container> { return all_elements_should_match; } + bool MatchAndExplainImpl(const Matcher<size_t>& count_matcher, + Container container, + MatchResultListener* listener) const { + StlContainerReference stl_container = View::ConstReference(container); + size_t i = 0; + std::vector<size_t> match_elements; + for (auto it = stl_container.begin(); it != stl_container.end(); + ++it, ++i) { + StringMatchResultListener inner_listener; + const bool matches = inner_matcher_.MatchAndExplain(*it, &inner_listener); + if (matches) { + match_elements.push_back(i); + } + } + if (listener->IsInterested()) { + if (match_elements.empty()) { + *listener << "has no element that matches"; + } else if (match_elements.size() == 1) { + *listener << "whose element #" << match_elements[0] << " matches"; + } else { + *listener << "whose elements ("; + std::string sep = ""; + for (size_t e : match_elements) { + *listener << sep << e; + sep = ", "; + } + *listener << ") match"; + } + } + StringMatchResultListener count_listener; + if (count_matcher.MatchAndExplain(match_elements.size(), &count_listener)) { + *listener << " and whose match quantity of " << match_elements.size() + << " matches"; + PrintIfNotEmpty(count_listener.str(), listener->stream()); + return true; + } else { + if (match_elements.empty()) { + *listener << " and"; + } else { + *listener << " but"; + } + *listener << " whose match quantity of " << match_elements.size() + << " does not match"; + PrintIfNotEmpty(count_listener.str(), listener->stream()); + return false; + } + } + protected: const Matcher<const Element&> inner_matcher_; - - GTEST_DISALLOW_ASSIGN_(QuantifierMatcherImpl); }; // Implements Contains(element_matcher) for the given argument type Container. @@ -3175,23 +2790,20 @@ class ContainsMatcherImpl : public QuantifierMatcherImpl<Container> { : QuantifierMatcherImpl<Container>(inner_matcher) {} // Describes what this matcher does. - virtual void DescribeTo(::std::ostream* os) const { + void DescribeTo(::std::ostream* os) const override { *os << "contains at least one element that "; this->inner_matcher_.DescribeTo(os); } - virtual void DescribeNegationTo(::std::ostream* os) const { + void DescribeNegationTo(::std::ostream* os) const override { *os << "doesn't contain any element that "; this->inner_matcher_.DescribeTo(os); } - virtual bool MatchAndExplain(Container container, - MatchResultListener* listener) const { + bool MatchAndExplain(Container container, + MatchResultListener* listener) const override { return this->MatchAndExplainImpl(false, container, listener); } - - private: - GTEST_DISALLOW_ASSIGN_(ContainsMatcherImpl); }; // Implements Each(element_matcher) for the given argument type Container. @@ -3204,23 +2816,72 @@ class EachMatcherImpl : public QuantifierMatcherImpl<Container> { : QuantifierMatcherImpl<Container>(inner_matcher) {} // Describes what this matcher does. - virtual void DescribeTo(::std::ostream* os) const { + void DescribeTo(::std::ostream* os) const override { *os << "only contains elements that "; this->inner_matcher_.DescribeTo(os); } - virtual void DescribeNegationTo(::std::ostream* os) const { + void DescribeNegationTo(::std::ostream* os) const override { *os << "contains some element that "; this->inner_matcher_.DescribeNegationTo(os); } - virtual bool MatchAndExplain(Container container, - MatchResultListener* listener) const { + bool MatchAndExplain(Container container, + MatchResultListener* listener) const override { return this->MatchAndExplainImpl(true, container, listener); } +}; + +// Implements Contains(element_matcher).Times(n) for the given argument type +// Container. +template <typename Container> +class ContainsTimesMatcherImpl : public QuantifierMatcherImpl<Container> { + public: + template <typename InnerMatcher> + explicit ContainsTimesMatcherImpl(InnerMatcher inner_matcher, + Matcher<size_t> count_matcher) + : QuantifierMatcherImpl<Container>(inner_matcher), + count_matcher_(std::move(count_matcher)) {} + + void DescribeTo(::std::ostream* os) const override { + *os << "quantity of elements that match "; + this->inner_matcher_.DescribeTo(os); + *os << " "; + count_matcher_.DescribeTo(os); + } + + void DescribeNegationTo(::std::ostream* os) const override { + *os << "quantity of elements that match "; + this->inner_matcher_.DescribeTo(os); + *os << " "; + count_matcher_.DescribeNegationTo(os); + } + + bool MatchAndExplain(Container container, + MatchResultListener* listener) const override { + return this->MatchAndExplainImpl(count_matcher_, container, listener); + } + + private: + const Matcher<size_t> count_matcher_; +}; + +// Implements polymorphic Contains(element_matcher).Times(n). +template <typename M> +class ContainsTimesMatcher { + public: + explicit ContainsTimesMatcher(M m, Matcher<size_t> count_matcher) + : inner_matcher_(m), count_matcher_(std::move(count_matcher)) {} + + template <typename Container> + operator Matcher<Container>() const { // NOLINT + return Matcher<Container>(new ContainsTimesMatcherImpl<const Container&>( + inner_matcher_, count_matcher_)); + } private: - GTEST_DISALLOW_ASSIGN_(EachMatcherImpl); + const M inner_matcher_; + const Matcher<size_t> count_matcher_; }; // Implements polymorphic Contains(element_matcher). @@ -3230,14 +2891,17 @@ class ContainsMatcher { explicit ContainsMatcher(M m) : inner_matcher_(m) {} template <typename Container> - operator Matcher<Container>() const { - return MakeMatcher(new ContainsMatcherImpl<Container>(inner_matcher_)); + operator Matcher<Container>() const { // NOLINT + return Matcher<Container>( + new ContainsMatcherImpl<const Container&>(inner_matcher_)); + } + + ContainsTimesMatcher<M> Times(Matcher<size_t> count_matcher) const { + return ContainsTimesMatcher<M>(inner_matcher_, std::move(count_matcher)); } private: const M inner_matcher_; - - GTEST_DISALLOW_ASSIGN_(ContainsMatcher); }; // Implements polymorphic Each(element_matcher). @@ -3247,21 +2911,19 @@ class EachMatcher { explicit EachMatcher(M m) : inner_matcher_(m) {} template <typename Container> - operator Matcher<Container>() const { - return MakeMatcher(new EachMatcherImpl<Container>(inner_matcher_)); + operator Matcher<Container>() const { // NOLINT + return Matcher<Container>( + new EachMatcherImpl<const Container&>(inner_matcher_)); } private: const M inner_matcher_; - - GTEST_DISALLOW_ASSIGN_(EachMatcher); }; struct Rank1 {}; struct Rank0 : Rank1 {}; namespace pair_getters { -#if GTEST_LANG_CXX11 using std::get; template <typename T> auto First(T& x, Rank1) -> decltype(get<0>(x)) { // NOLINT @@ -3280,25 +2942,6 @@ template <typename T> auto Second(T& x, Rank0) -> decltype((x.second)) { // NOLINT return x.second; } -#else -template <typename T> -typename T::first_type& First(T& x, Rank0) { // NOLINT - return x.first; -} -template <typename T> -const typename T::first_type& First(const T& x, Rank0) { - return x.first; -} - -template <typename T> -typename T::second_type& Second(T& x, Rank0) { // NOLINT - return x.second; -} -template <typename T> -const typename T::second_type& Second(const T& x, Rank0) { - return x.second; -} -#endif // GTEST_LANG_CXX11 } // namespace pair_getters // Implements Key(inner_matcher) for the given argument pair type. @@ -3314,38 +2957,36 @@ class KeyMatcherImpl : public MatcherInterface<PairType> { template <typename InnerMatcher> explicit KeyMatcherImpl(InnerMatcher inner_matcher) : inner_matcher_( - testing::SafeMatcherCast<const KeyType&>(inner_matcher)) { - } + testing::SafeMatcherCast<const KeyType&>(inner_matcher)) {} - // Returns true iff 'key_value.first' (the key) matches the inner matcher. - virtual bool MatchAndExplain(PairType key_value, - MatchResultListener* listener) const { + // 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 != "") { + if (!explanation.empty()) { *listener << "whose first field is a value " << explanation; } return match; } // Describes what this matcher does. - virtual void DescribeTo(::std::ostream* os) const { + void DescribeTo(::std::ostream* os) const override { *os << "has a key that "; inner_matcher_.DescribeTo(os); } // Describes what the negation of this matcher does. - virtual void DescribeNegationTo(::std::ostream* os) const { + 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_; - - GTEST_DISALLOW_ASSIGN_(KeyMatcherImpl); }; // Implements polymorphic Key(matcher_for_key). @@ -3356,13 +2997,55 @@ class KeyMatcher { template <typename PairType> operator Matcher<PairType>() const { - return MakeMatcher(new KeyMatcherImpl<PairType>(matcher_for_key_)); + 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)) {} - GTEST_DISALLOW_ASSIGN_(KeyMatcher); + 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 @@ -3379,11 +3062,10 @@ class PairMatcherImpl : public MatcherInterface<PairType> { : first_matcher_( testing::SafeMatcherCast<const FirstType&>(first_matcher)), second_matcher_( - testing::SafeMatcherCast<const SecondType&>(second_matcher)) { - } + testing::SafeMatcherCast<const SecondType&>(second_matcher)) {} // Describes what this matcher does. - virtual void DescribeTo(::std::ostream* os) const { + void DescribeTo(::std::ostream* os) const override { *os << "has a first field that "; first_matcher_.DescribeTo(os); *os << ", and has a second field that "; @@ -3391,17 +3073,17 @@ class PairMatcherImpl : public MatcherInterface<PairType> { } // Describes what the negation of this matcher does. - virtual void DescribeNegationTo(::std::ostream* os) const { + 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 iff 'a_pair.first' matches first_matcher and 'a_pair.second' - // matches second_matcher. - virtual bool MatchAndExplain(PairType a_pair, - MatchResultListener* listener) const { + // 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. @@ -3432,12 +3114,12 @@ class PairMatcherImpl : public MatcherInterface<PairType> { const std::string& second_explanation, MatchResultListener* listener) const { *listener << "whose both fields match"; - if (first_explanation != "") { + if (!first_explanation.empty()) { *listener << ", where the first field is a value " << first_explanation; } - if (second_explanation != "") { + if (!second_explanation.empty()) { *listener << ", "; - if (first_explanation != "") { + if (!first_explanation.empty()) { *listener << "and "; } else { *listener << "where "; @@ -3448,8 +3130,6 @@ class PairMatcherImpl : public MatcherInterface<PairType> { const Matcher<const FirstType&> first_matcher_; const Matcher<const SecondType&> second_matcher_; - - GTEST_DISALLOW_ASSIGN_(PairMatcherImpl); }; // Implements polymorphic Pair(first_matcher, second_matcher). @@ -3460,17 +3140,226 @@ class PairMatcher { : first_matcher_(first_matcher), second_matcher_(second_matcher) {} template <typename PairType> - operator Matcher<PairType> () const { - return MakeMatcher( - new PairMatcherImpl<PairType>( - first_matcher_, second_matcher_)); + 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); +} +template <typename T> +auto UnpackStructImpl(const T& t, MakeIndexSequence<17>, char) { + const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q] = t; + return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q); +} +template <typename T> +auto UnpackStructImpl(const T& t, MakeIndexSequence<18>, char) { + const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r] = t; + return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r); +} +template <typename T> +auto UnpackStructImpl(const T& t, MakeIndexSequence<19>, char) { + const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s] = t; + return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s); +} +#endif // defined(__cpp_structured_bindings) - GTEST_DISALLOW_ASSIGN_(PairMatcher); +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(). @@ -3493,7 +3382,7 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> { } // Describes what this matcher does. - virtual void DescribeTo(::std::ostream* os) const { + void DescribeTo(::std::ostream* os) const override { if (count() == 0) { *os << "is empty"; } else if (count() == 1) { @@ -3512,7 +3401,7 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> { } // Describes what the negation of this matcher does. - virtual void DescribeNegationTo(::std::ostream* os) const { + void DescribeNegationTo(::std::ostream* os) const override { if (count() == 0) { *os << "isn't empty"; return; @@ -3528,8 +3417,8 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> { } } - virtual bool MatchAndExplain(Container container, - MatchResultListener* listener) const { + bool MatchAndExplain(Container container, + MatchResultListener* listener) const override { // To work with stream-like "containers", we must only walk // through the elements in one pass. @@ -3538,7 +3427,7 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> { // 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(); + auto it = stl_container.begin(); size_t exam_pos = 0; bool mismatch_found = false; // Have we found a mismatched element yet? @@ -3615,9 +3504,7 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> { size_t count() const { return matchers_.size(); } - ::std::vector<Matcher<const Element&> > matchers_; - - GTEST_DISALLOW_ASSIGN_(ElementsAreMatcherImpl); + ::std::vector<Matcher<const Element&>> matchers_; }; // Connectivity matrix of (elements X matchers), in element-major order. @@ -3629,8 +3516,7 @@ class GTEST_API_ MatchMatrix { MatchMatrix(size_t num_elements, size_t num_matchers) : num_elements_(num_elements), num_matchers_(num_matchers), - matched_(num_elements_* num_matchers_, 0) { - } + matched_(num_elements_ * num_matchers_, 0) {} size_t LhsSize() const { return num_elements_; } size_t RhsSize() const { return num_matchers_; } @@ -3669,8 +3555,7 @@ 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); +GTEST_API_ ElementMatcherPairs FindMaxBipartiteMatching(const MatchMatrix& g); struct UnorderedMatcherRequire { enum Flags { @@ -3707,9 +3592,7 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase { bool FindPairing(const MatchMatrix& matrix, MatchResultListener* listener) const; - MatcherDescriberVec& matcher_describers() { - return matcher_describers_; - } + MatcherDescriberVec& matcher_describers() { return matcher_describers_; } static Message Elements(size_t n) { return Message() << n << " element" << (n == 1 ? "" : "s"); @@ -3720,8 +3603,6 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase { private: UnorderedMatcherRequire::Flags match_flags_; MatcherDescriberVec matcher_describers_; - - GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImplBase); }; // Implements UnorderedElementsAre, UnorderedElementsAreArray, IsSubsetOf, and @@ -3735,7 +3616,6 @@ class UnorderedElementsAreMatcherImpl 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> @@ -3744,45 +3624,30 @@ class UnorderedElementsAreMatcherImpl : UnorderedElementsAreMatcherImplBase(matcher_flags) { for (; first != last; ++first) { matchers_.push_back(MatcherCast<const Element&>(*first)); - matcher_describers().push_back(matchers_.back().GetDescriber()); + } + for (const auto& m : matchers_) { + matcher_describers().push_back(m.GetDescriber()); } } // Describes what this matcher does. - virtual void DescribeTo(::std::ostream* os) const { + void DescribeTo(::std::ostream* os) const override { return UnorderedElementsAreMatcherImplBase::DescribeToImpl(os); } // Describes what the negation of this matcher does. - virtual void DescribeNegationTo(::std::ostream* os) const { + void DescribeNegationTo(::std::ostream* os) const override { return UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(os); } - virtual bool MatchAndExplain(Container container, - MatchResultListener* listener) const { + 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); } @@ -3795,12 +3660,14 @@ class UnorderedElementsAreMatcherImpl 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(Matches(matchers_[irhs])(*elem_first)); + did_match.push_back( + matchers_[irhs].MatchAndExplain(*elem_first, &dummy)); } } @@ -3814,9 +3681,7 @@ class UnorderedElementsAreMatcherImpl return matrix; } - ::std::vector<Matcher<const Element&> > matchers_; - - GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImpl); + ::std::vector<Matcher<const Element&>> matchers_; }; // Functor for use in TransformTuple. @@ -3841,18 +3706,19 @@ class UnorderedElementsAreMatcher { 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; + typedef ::std::vector<Matcher<const Element&>> MatcherVec; MatcherVec matchers; - matchers.reserve(::testing::tuple_size<MatcherTuple>::value); + matchers.reserve(::std::tuple_size<MatcherTuple>::value); TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_, ::std::back_inserter(matchers)); - return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>( - UnorderedMatcherRequire::ExactMatch, matchers.begin(), matchers.end())); + return Matcher<Container>( + new UnorderedElementsAreMatcherImpl<const Container&>( + UnorderedMatcherRequire::ExactMatch, matchers.begin(), + matchers.end())); } private: const MatcherTuple matchers_; - GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcher); }; // Implements ElementsAre. @@ -3863,26 +3729,25 @@ class ElementsAreMatcher { template <typename Container> operator Matcher<Container>() const { - GTEST_COMPILE_ASSERT_( + static_assert( !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value || - ::testing::tuple_size<MatcherTuple>::value < 2, - use_UnorderedElementsAre_with_hash_tables); + ::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; + typedef ::std::vector<Matcher<const Element&>> MatcherVec; MatcherVec matchers; - matchers.reserve(::testing::tuple_size<MatcherTuple>::value); + matchers.reserve(::std::tuple_size<MatcherTuple>::value); TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_, ::std::back_inserter(matchers)); - return MakeMatcher(new ElementsAreMatcherImpl<Container>( - matchers.begin(), matchers.end())); + return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>( + matchers.begin(), matchers.end())); } private: const MatcherTuple matchers_; - GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher); }; // Implements UnorderedElementsAreArray(), IsSubsetOf(), and IsSupersetOf(). @@ -3896,15 +3761,14 @@ class UnorderedElementsAreArrayMatcher { template <typename Container> operator Matcher<Container>() const { - return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>( - match_flags_, matchers_.begin(), matchers_.end())); + return Matcher<Container>( + new UnorderedElementsAreMatcherImpl<const Container&>( + match_flags_, matchers_.begin(), matchers_.end())); } private: UnorderedMatcherRequire::Flags match_flags_; ::std::vector<T> matchers_; - - GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreArrayMatcher); }; // Implements ElementsAreArray(). @@ -3916,24 +3780,22 @@ class ElementsAreArrayMatcher { template <typename Container> operator Matcher<Container>() const { - GTEST_COMPILE_ASSERT_( + static_assert( !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value, - use_UnorderedElementsAreArray_with_hash_tables); + "use UnorderedElementsAreArray with hash tables"); - return MakeMatcher(new ElementsAreMatcherImpl<Container>( + return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>( matchers_.begin(), matchers_.end())); } private: const ::std::vector<T> matchers_; - - GTEST_DISALLOW_ASSIGN_(ElementsAreArrayMatcher); }; // 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 iff tm -// matches tuple (x, second). Useful for implementing +// 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 @@ -3945,6 +3807,8 @@ class BoundSecondMatcher { 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_)); @@ -3966,20 +3830,20 @@ class BoundSecondMatcher { template <typename T> class Impl : public MatcherInterface<T> { public: - typedef ::testing::tuple<T, Second> ArgTuple; + typedef ::std::tuple<T, Second> ArgTuple; Impl(const Tuple2Matcher& tm, const Second& second) : mono_tuple2_matcher_(SafeMatcherCast<const ArgTuple&>(tm)), second_value_(second) {} - virtual void DescribeTo(::std::ostream* os) const { + void DescribeTo(::std::ostream* os) const override { *os << "and "; UniversalPrint(second_value_, os); *os << " "; mono_tuple2_matcher_.DescribeTo(os); } - virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { + bool MatchAndExplain(T x, MatchResultListener* listener) const override { return mono_tuple2_matcher_.MatchAndExplain(ArgTuple(x, second_value_), listener); } @@ -3987,8 +3851,6 @@ class BoundSecondMatcher { private: const Matcher<const ArgTuple&> mono_tuple2_matcher_; const Second second_value_; - - GTEST_DISALLOW_ASSIGN_(Impl); }; const Tuple2Matcher tuple2_matcher_; @@ -3997,8 +3859,8 @@ class BoundSecondMatcher { // Given a 2-tuple matcher tm and a value second, // MatcherBindSecond(tm, second) returns a matcher that matches a -// value x iff tm matches tuple (x, second). Useful for implementing -// UnorderedPointwise() in terms of UnorderedElementsAreArray(). +// 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) { @@ -4010,9 +3872,9 @@ BoundSecondMatcher<Tuple2Matcher, Second> MatcherBindSecond( // '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); +GTEST_API_ std::string FormatMatcherDescription( + bool negation, const char* matcher_name, + const std::vector<const char*>& param_names, const Strings& param_values); // Implements a matcher that checks the value of a optional<> type variable. template <typename ValueMatcher> @@ -4023,7 +3885,7 @@ class OptionalMatcher { template <typename Optional> operator Matcher<Optional>() const { - return MakeMatcher(new Impl<Optional>(value_matcher_)); + return Matcher<Optional>(new Impl<const Optional&>(value_matcher_)); } template <typename Optional> @@ -4034,18 +3896,18 @@ class OptionalMatcher { explicit Impl(const ValueMatcher& value_matcher) : value_matcher_(MatcherCast<ValueType>(value_matcher)) {} - virtual void DescribeTo(::std::ostream* os) const { + void DescribeTo(::std::ostream* os) const override { *os << "value "; value_matcher_.DescribeTo(os); } - virtual void DescribeNegationTo(::std::ostream* os) const { + void DescribeNegationTo(::std::ostream* os) const override { *os << "value "; value_matcher_.DescribeNegationTo(os); } - virtual bool MatchAndExplain(Optional optional, - MatchResultListener* listener) const { + bool MatchAndExplain(Optional optional, + MatchResultListener* listener) const override { if (!optional) { *listener << "which is not engaged"; return false; @@ -4061,12 +3923,10 @@ class OptionalMatcher { private: const Matcher<ValueType> value_matcher_; - GTEST_DISALLOW_ASSIGN_(Impl); }; private: const ValueMatcher value_matcher_; - GTEST_DISALLOW_ASSIGN_(OptionalMatcher); }; namespace variant_matcher { @@ -4081,11 +3941,12 @@ template <typename T> class VariantMatcher { public: explicit VariantMatcher(::testing::Matcher<const T&> matcher) - : matcher_(internal::move(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)); } @@ -4148,11 +4009,11 @@ class AnyCastMatcher { ::testing::MatchResultListener* listener) const { if (!listener->IsInterested()) { const T* ptr = any_cast<T>(&value); - return ptr != NULL && matcher_.Matches(*ptr); + return ptr != nullptr && matcher_.Matches(*ptr); } const T* elem = any_cast<T>(&value); - if (elem == NULL) { + if (elem == nullptr) { *listener << "whose value is not of type '" << GetTypeName() << "'"; return false; } @@ -4190,6 +4051,85 @@ class AnyCastMatcher { }; } // 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; + // The static_cast to void is needed to silence Clang's -Wcomma warning. + // This pattern looks suspiciously like we may have mismatched parentheses + // and may have been trying to use the first operation of the comma operator + // as a member of the array, so Clang warns that we may have made a mistake. + const char* dummy[] = { + "", (static_cast<void>(*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) @@ -4216,30 +4156,28 @@ ElementsAreArray(Iter first, Iter last) { } template <typename T> -inline internal::ElementsAreArrayMatcher<T> ElementsAreArray( - const T* pointer, size_t count) { +inline auto ElementsAreArray(const T* pointer, size_t count) + -> decltype(ElementsAreArray(pointer, pointer + count)) { return ElementsAreArray(pointer, pointer + count); } template <typename T, size_t N> -inline internal::ElementsAreArrayMatcher<T> ElementsAreArray( - const T (&array)[N]) { +inline auto ElementsAreArray(const T (&array)[N]) + -> decltype(ElementsAreArray(array, N)) { return ElementsAreArray(array, N); } template <typename Container> -inline internal::ElementsAreArrayMatcher<typename Container::value_type> -ElementsAreArray(const Container& container) { +inline auto ElementsAreArray(const Container& container) + -> decltype(ElementsAreArray(container.begin(), container.end())) { return ElementsAreArray(container.begin(), container.end()); } -#if GTEST_HAS_STD_INITIALIZER_LIST_ template <typename T> -inline internal::ElementsAreArrayMatcher<T> -ElementsAreArray(::std::initializer_list<T> xs) { +inline auto ElementsAreArray(::std::initializer_list<T> xs) + -> decltype(ElementsAreArray(xs.begin(), xs.end())) { return ElementsAreArray(xs.begin(), xs.end()); } -#endif // UnorderedElementsAreArray(iterator_first, iterator_last) // UnorderedElementsAreArray(pointer, count) @@ -4264,14 +4202,14 @@ UnorderedElementsAreArray(Iter first, Iter last) { } template <typename T> -inline internal::UnorderedElementsAreArrayMatcher<T> -UnorderedElementsAreArray(const T* pointer, size_t count) { +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]) { +inline internal::UnorderedElementsAreArrayMatcher<T> UnorderedElementsAreArray( + const T (&array)[N]) { return UnorderedElementsAreArray(array, N); } @@ -4282,13 +4220,11 @@ UnorderedElementsAreArray(const Container& container) { return UnorderedElementsAreArray(container.begin(), container.end()); } -#if GTEST_HAS_STD_INITIALIZER_LIST_ template <typename T> -inline internal::UnorderedElementsAreArrayMatcher<T> -UnorderedElementsAreArray(::std::initializer_list<T> xs) { +inline internal::UnorderedElementsAreArrayMatcher<T> UnorderedElementsAreArray( + ::std::initializer_list<T> xs) { return UnorderedElementsAreArray(xs.begin(), xs.end()); } -#endif // _ is a matcher that matches anything of any type. // @@ -4303,86 +4239,31 @@ 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>()); + return _; } // Creates a matcher that matches any value of the given type T. template <typename T> -inline Matcher<T> An() { return A<T>(); } - -// Creates a polymorphic matcher that matches anything equal to x. -// Note: if the parameter of Eq() were declared as const T&, Eq("foo") -// wouldn't compile. -template <typename T> -inline internal::EqMatcher<T> Eq(T x) { return internal::EqMatcher<T>(x); } - -// Constructs a Matcher<T> from a 'value' of type T. The constructed -// matcher matches any value that's equal to 'value'. -template <typename T> -Matcher<T>::Matcher(T value) { *this = Eq(value); } +inline Matcher<T> An() { + return _; +} template <typename T, typename M> Matcher<T> internal::MatcherCastImpl<T, M>::CastImpl( - const M& value, - internal::BooleanConstant<false> /* convertible_to_matcher */, - internal::BooleanConstant<false> /* convertible_to_T */) { + const M& value, std::false_type /* convertible_to_matcher */, + std::false_type /* convertible_to_T */) { return Eq(value); } -// Creates a monomorphic matcher that matches anything with type Lhs -// and equal to rhs. A user may need to use this instead of Eq(...) -// in order to resolve an overloading ambiguity. -// -// TypedEq<T>(x) is just a convenient short-hand for Matcher<T>(Eq(x)) -// or Matcher<T>(x), but more readable than the latter. -// -// We could define similar monomorphic matchers for other comparison -// operations (e.g. TypedLt, TypedGe, and etc), but decided not to do -// it yet as those are used much less than Eq() in practice. A user -// can always write Matcher<T>(Lt(5)) to be explicit about the type, -// for example. -template <typename Lhs, typename Rhs> -inline Matcher<Lhs> TypedEq(const Rhs& rhs) { return Eq(rhs); } - -// Creates a polymorphic matcher that matches anything >= x. -template <typename Rhs> -inline internal::GeMatcher<Rhs> Ge(Rhs x) { - return internal::GeMatcher<Rhs>(x); -} - -// Creates a polymorphic matcher that matches anything > x. -template <typename Rhs> -inline internal::GtMatcher<Rhs> Gt(Rhs x) { - return internal::GtMatcher<Rhs>(x); -} - -// Creates a polymorphic matcher that matches anything <= x. -template <typename Rhs> -inline internal::LeMatcher<Rhs> Le(Rhs x) { - return internal::LeMatcher<Rhs>(x); -} - -// Creates a polymorphic matcher that matches anything < x. -template <typename Rhs> -inline internal::LtMatcher<Rhs> Lt(Rhs x) { - return internal::LtMatcher<Rhs>(x); -} - -// Creates a polymorphic matcher that matches anything != x. -template <typename Rhs> -inline internal::NeMatcher<Rhs> Ne(Rhs x) { - return internal::NeMatcher<Rhs>(x); -} - // Creates a polymorphic matcher that matches any NULL pointer. -inline PolymorphicMatcher<internal::IsNullMatcher > IsNull() { +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() { +inline PolymorphicMatcher<internal::NotNullMatcher> NotNull() { return MakePolymorphicMatcher(internal::NotNullMatcher()); } @@ -4393,6 +4274,11 @@ inline internal::RefMatcher<T&> Ref(T& x) { // NOLINT return internal::RefMatcher<T&>(x); } +// Creates a polymorphic matcher that matches any NaN floating point. +inline PolymorphicMatcher<internal::IsNanMatcher> IsNan() { + return MakePolymorphicMatcher(internal::IsNanMatcher()); +} + // Creates a matcher that matches any double argument approximately // equal to rhs, where two NANs are considered unequal. inline internal::FloatingEqMatcher<double> DoubleEq(double rhs) { @@ -4408,8 +4294,8 @@ inline internal::FloatingEqMatcher<double> NanSensitiveDoubleEq(double rhs) { // 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) { +inline internal::FloatingEqMatcher<double> DoubleNear(double rhs, + double max_abs_error) { return internal::FloatingEqMatcher<double>(rhs, false, max_abs_error); } @@ -4436,8 +4322,8 @@ inline internal::FloatingEqMatcher<float> NanSensitiveFloatEq(float rhs) { // 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) { +inline internal::FloatingEqMatcher<float> FloatNear(float rhs, + float max_abs_error) { return internal::FloatingEqMatcher<float>(rhs, false, max_abs_error); } @@ -4465,7 +4351,7 @@ inline internal::PointeeMatcher<InnerMatcher> Pointee( // If To is a reference and the cast fails, this matcher returns false // immediately. template <typename To> -inline PolymorphicMatcher<internal::WhenDynamicCastToMatcher<To> > +inline PolymorphicMatcher<internal::WhenDynamicCastToMatcher<To>> WhenDynamicCastTo(const Matcher<To>& inner_matcher) { return MakePolymorphicMatcher( internal::WhenDynamicCastToMatcher<To>(inner_matcher)); @@ -4475,14 +4361,12 @@ WhenDynamicCastTo(const Matcher<To>& inner_matcher) { // Creates a matcher that matches an object whose given field matches // 'matcher'. For example, // Field(&Foo::number, Ge(5)) -// matches a Foo object x iff x.number >= 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( +inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType>> Field( FieldType Class::*field, const FieldMatcher& matcher) { - return MakePolymorphicMatcher( - internal::FieldMatcher<Class, FieldType>( - field, MatcherCast<const FieldType&>(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) @@ -4492,7 +4376,7 @@ inline PolymorphicMatcher< // 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( +inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType>> Field( const std::string& field_name, FieldType Class::*field, const FieldMatcher& matcher) { return MakePolymorphicMatcher(internal::FieldMatcher<Class, FieldType>( @@ -4502,17 +4386,16 @@ inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType> > Field( // Creates a matcher that matches an object whose given property // matches 'matcher'. For example, // Property(&Foo::str, StartsWith("hi")) -// matches a Foo object x iff x.str() starts with "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> > + Class, PropertyType, PropertyType (Class::*)() const>> Property(PropertyType (Class::*property)() const, const PropertyMatcher& matcher) { return MakePolymorphicMatcher( internal::PropertyMatcher<Class, PropertyType, PropertyType (Class::*)() const>( - property, - MatcherCast<GTEST_REFERENCE_TO_CONST_(PropertyType)>(matcher))); + 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) @@ -4523,51 +4406,45 @@ Property(PropertyType (Class::*property)() const, // better error messages. template <typename Class, typename PropertyType, typename PropertyMatcher> inline PolymorphicMatcher<internal::PropertyMatcher< - Class, PropertyType, PropertyType (Class::*)() const> > + Class, PropertyType, PropertyType (Class::*)() const>> Property(const std::string& property_name, PropertyType (Class::*property)() const, const PropertyMatcher& matcher) { return MakePolymorphicMatcher( internal::PropertyMatcher<Class, PropertyType, PropertyType (Class::*)() const>( - property_name, property, - MatcherCast<GTEST_REFERENCE_TO_CONST_(PropertyType)>(matcher))); + property_name, property, MatcherCast<const PropertyType&>(matcher))); } -#if GTEST_LANG_CXX11 // 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 &, + Class, PropertyType, PropertyType (Class::*)() const&>> +Property(PropertyType (Class::*property)() const&, const PropertyMatcher& matcher) { return MakePolymorphicMatcher( internal::PropertyMatcher<Class, PropertyType, - PropertyType (Class::*)() const &>( - property, - MatcherCast<GTEST_REFERENCE_TO_CONST_(PropertyType)>(matcher))); + 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 &> > + Class, PropertyType, PropertyType (Class::*)() const&>> Property(const std::string& property_name, - PropertyType (Class::*property)() const &, + PropertyType (Class::*property)() const&, const PropertyMatcher& matcher) { return MakePolymorphicMatcher( internal::PropertyMatcher<Class, PropertyType, - PropertyType (Class::*)() const &>( - property_name, property, - MatcherCast<GTEST_REFERENCE_TO_CONST_(PropertyType)>(matcher))); + PropertyType (Class::*)() const&>( + property_name, property, MatcherCast<const PropertyType&>(matcher))); } -#endif -// Creates a matcher that matches an object iff the result of applying -// a callable to x matches 'matcher'. -// For example, +// 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 iff f(x) starts with "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 @@ -4575,137 +4452,133 @@ Property(const std::string& property_name, 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)); +} + +// Same as ResultOf() above, but also takes a description of the `callable` +// result to provide better error messages. +template <typename Callable, typename InnerMatcher> +internal::ResultOfMatcher<Callable, InnerMatcher> ResultOf( + const std::string& result_description, Callable callable, + InnerMatcher matcher) { return internal::ResultOfMatcher<Callable, InnerMatcher>( - internal::move(callable), internal::move(matcher)); + result_description, std::move(callable), std::move(matcher)); } // String matchers. // Matches a string equal to str. -inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrEq( - const std::string& str) { +template <typename T = std::string> +PolymorphicMatcher<internal::StrEqualityMatcher<std::string>> StrEq( + const internal::StringLike<T>& str) { return MakePolymorphicMatcher( - internal::StrEqualityMatcher<std::string>(str, true, true)); + internal::StrEqualityMatcher<std::string>(std::string(str), true, true)); } // Matches a string not equal to str. -inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrNe( - const std::string& str) { +template <typename T = std::string> +PolymorphicMatcher<internal::StrEqualityMatcher<std::string>> StrNe( + const internal::StringLike<T>& str) { return MakePolymorphicMatcher( - internal::StrEqualityMatcher<std::string>(str, false, true)); + internal::StrEqualityMatcher<std::string>(std::string(str), false, true)); } // Matches a string equal to str, ignoring case. -inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseEq( - const std::string& str) { +template <typename T = std::string> +PolymorphicMatcher<internal::StrEqualityMatcher<std::string>> StrCaseEq( + const internal::StringLike<T>& str) { return MakePolymorphicMatcher( - internal::StrEqualityMatcher<std::string>(str, true, false)); + internal::StrEqualityMatcher<std::string>(std::string(str), true, false)); } // Matches a string not equal to str, ignoring case. -inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseNe( - const std::string& str) { - return MakePolymorphicMatcher( - internal::StrEqualityMatcher<std::string>(str, false, false)); +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. -inline PolymorphicMatcher<internal::HasSubstrMatcher<std::string> > HasSubstr( - const std::string& substring) { +template <typename T = std::string> +PolymorphicMatcher<internal::HasSubstrMatcher<std::string>> HasSubstr( + const internal::StringLike<T>& substring) { return MakePolymorphicMatcher( - internal::HasSubstrMatcher<std::string>(substring)); + internal::HasSubstrMatcher<std::string>(std::string(substring))); } // Matches a string that starts with 'prefix' (case-sensitive). -inline PolymorphicMatcher<internal::StartsWithMatcher<std::string> > StartsWith( - const std::string& prefix) { +template <typename T = std::string> +PolymorphicMatcher<internal::StartsWithMatcher<std::string>> StartsWith( + const internal::StringLike<T>& prefix) { return MakePolymorphicMatcher( - internal::StartsWithMatcher<std::string>(prefix)); + internal::StartsWithMatcher<std::string>(std::string(prefix))); } // Matches a string that ends with 'suffix' (case-sensitive). -inline PolymorphicMatcher<internal::EndsWithMatcher<std::string> > EndsWith( - const std::string& suffix) { - return MakePolymorphicMatcher(internal::EndsWithMatcher<std::string>(suffix)); -} - -// Matches a string that fully matches regular expression 'regex'. -// The matcher takes ownership of 'regex'. -inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex( - const internal::RE* regex) { - return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true)); -} -inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex( - const std::string& regex) { - return MatchesRegex(new internal::RE(regex)); -} - -// Matches a string that contains regular expression 'regex'. -// The matcher takes ownership of 'regex'. -inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex( - const internal::RE* regex) { - return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false)); -} -inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex( - const std::string& regex) { - return ContainsRegex(new internal::RE(regex)); +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_GLOBAL_WSTRING || GTEST_HAS_STD_WSTRING +#if GTEST_HAS_STD_WSTRING // Wide string matchers. // Matches a string equal to str. -inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > StrEq( +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( +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) { +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) { +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( +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) { +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( +inline PolymorphicMatcher<internal::EndsWithMatcher<std::wstring>> EndsWith( const std::wstring& suffix) { return MakePolymorphicMatcher( internal::EndsWithMatcher<std::wstring>(suffix)); } -#endif // GTEST_HAS_GLOBAL_WSTRING || GTEST_HAS_STD_WSTRING +#endif // GTEST_HAS_STD_WSTRING // Creates a polymorphic matcher that matches a 2-tuple where the // first field == the second field. @@ -4794,8 +4667,8 @@ inline internal::NotMatcher<InnerMatcher> Not(InnerMatcher m) { // 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) { +inline PolymorphicMatcher<internal::TrulyMatcher<Predicate>> Truly( + Predicate pred) { return MakePolymorphicMatcher(internal::TrulyMatcher<Predicate>(pred)); } @@ -4806,8 +4679,8 @@ Truly(Predicate pred) { // 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) { +inline internal::SizeIsMatcher<SizeMatcher> SizeIs( + const SizeMatcher& size_matcher) { return internal::SizeIsMatcher<SizeMatcher>(size_matcher); } @@ -4817,8 +4690,8 @@ SizeIs(const SizeMatcher& size_matcher) { // 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) { +inline internal::BeginEndDistanceIsMatcher<DistanceMatcher> BeginEndDistanceIs( + const DistanceMatcher& distance_matcher) { return internal::BeginEndDistanceIsMatcher<DistanceMatcher>(distance_matcher); } @@ -4827,22 +4700,17 @@ BeginEndDistanceIs(const DistanceMatcher& distance_matcher) { // 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< // NOLINT - GTEST_REMOVE_CONST_(Container)> > - ContainerEq(const Container& rhs) { - // This following line is for working around a bug in MSVC 8.0, - // which causes Container to be a const type sometimes. - typedef GTEST_REMOVE_CONST_(Container) RawContainer; - return MakePolymorphicMatcher( - internal::ContainerEqMatcher<RawContainer>(rhs)); +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) { +inline internal::WhenSortedByMatcher<Comparator, ContainerMatcher> WhenSortedBy( + const Comparator& comparator, const ContainerMatcher& container_matcher) { return internal::WhenSortedByMatcher<Comparator, ContainerMatcher>( comparator, container_matcher); } @@ -4852,46 +4720,38 @@ WhenSortedBy(const Comparator& comparator, template <typename ContainerMatcher> inline internal::WhenSortedByMatcher<internal::LessComparator, ContainerMatcher> WhenSorted(const ContainerMatcher& container_matcher) { - return - internal::WhenSortedByMatcher<internal::LessComparator, ContainerMatcher>( - internal::LessComparator(), 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<tuple<const +// 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, - GTEST_REMOVE_CONST_(Container)> + typename std::remove_const<Container>::type> Pointwise(const TupleMatcher& tuple_matcher, const Container& rhs) { - // This following line is for working around a bug in MSVC 8.0, - // which causes Container to be a const type sometimes (e.g. when - // rhs is a const int[]).. - typedef GTEST_REMOVE_CONST_(Container) RawContainer; - return internal::PointwiseMatcher<TupleMatcher, RawContainer>( - tuple_matcher, rhs); + return internal::PointwiseMatcher<TupleMatcher, Container>(tuple_matcher, + rhs); } -#if GTEST_HAS_STD_INITIALIZER_LIST_ - // Supports the Pointwise(m, {a, b, c}) syntax. template <typename TupleMatcher, typename T> -inline internal::PointwiseMatcher<TupleMatcher, std::vector<T> > Pointwise( +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)); } -#endif // GTEST_HAS_STD_INITIALIZER_LIST_ - // 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<tuple<const T1&, const T2&> >, where T1 and T2 are +// 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. // @@ -4900,48 +4760,39 @@ inline internal::PointwiseMatcher<TupleMatcher, std::vector<T> > Pointwise( template <typename Tuple2Matcher, typename RhsContainer> inline internal::UnorderedElementsAreArrayMatcher< typename internal::BoundSecondMatcher< - Tuple2Matcher, typename internal::StlContainerView<GTEST_REMOVE_CONST_( - RhsContainer)>::type::value_type> > + Tuple2Matcher, + typename internal::StlContainerView< + typename std::remove_const<RhsContainer>::type>::type::value_type>> UnorderedPointwise(const Tuple2Matcher& tuple2_matcher, const RhsContainer& rhs_container) { - // This following line is for working around a bug in MSVC 8.0, - // which causes RhsContainer to be a const type sometimes (e.g. when - // rhs_container is a const int[]). - typedef GTEST_REMOVE_CONST_(RhsContainer) RawRhsContainer; - // 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<RawRhsContainer> RhsView; + 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)); + ::std::vector<internal::BoundSecondMatcher<Tuple2Matcher, Second>> matchers; + for (auto 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); } -#if GTEST_HAS_STD_INITIALIZER_LIST_ - // Supports the UnorderedPointwise(m, {a, b, c}) syntax. template <typename Tuple2Matcher, typename T> inline internal::UnorderedElementsAreArrayMatcher< - typename internal::BoundSecondMatcher<Tuple2Matcher, T> > + typename internal::BoundSecondMatcher<Tuple2Matcher, T>> UnorderedPointwise(const Tuple2Matcher& tuple2_matcher, std::initializer_list<T> rhs) { return UnorderedPointwise(tuple2_matcher, std::vector<T>(rhs)); } -#endif // GTEST_HAS_STD_INITIALIZER_LIST_ - // Matches an STL-style container or a native array that contains at // least one element matching the given value or matcher. // @@ -4951,7 +4802,7 @@ UnorderedPointwise(const Tuple2Matcher& tuple2_matcher, // page_ids.insert(1); // EXPECT_THAT(page_ids, Contains(1)); // EXPECT_THAT(page_ids, Contains(Gt(2))); -// EXPECT_THAT(page_ids, Not(Contains(4))); +// EXPECT_THAT(page_ids, Not(Contains(4))); // See below for Times(0) // // ::std::map<int, size_t> page_lengths; // page_lengths[1] = 100; @@ -4960,6 +4811,19 @@ UnorderedPointwise(const Tuple2Matcher& tuple2_matcher, // // const char* user_ids[] = { "joe", "mike", "tom" }; // EXPECT_THAT(user_ids, Contains(Eq(::std::string("tom")))); +// +// The matcher supports a modifier `Times` that allows to check for arbitrary +// occurrences including testing for absence with Times(0). +// +// Examples: +// ::std::vector<int> ids; +// ids.insert(1); +// ids.insert(1); +// ids.insert(3); +// EXPECT_THAT(ids, Contains(1).Times(2)); // 1 occurs 2 times +// EXPECT_THAT(ids, Contains(2).Times(0)); // 2 is not present +// EXPECT_THAT(ids, Contains(3).Times(Ge(1))); // 3 occurs at least once + template <typename M> inline internal::ContainsMatcher<M> Contains(M matcher) { return internal::ContainsMatcher<M>(matcher); @@ -5020,13 +4884,11 @@ IsSupersetOf(const Container& container) { return IsSupersetOf(container.begin(), container.end()); } -#if GTEST_HAS_STD_INITIALIZER_LIST_ template <typename T> inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf( ::std::initializer_list<T> xs) { return IsSupersetOf(xs.begin(), xs.end()); } -#endif // IsSubsetOf(iterator_first, iterator_last) // IsSubsetOf(pointer, count) @@ -5079,18 +4941,16 @@ IsSubsetOf(const Container& container) { return IsSubsetOf(container.begin(), container.end()); } -#if GTEST_HAS_STD_INITIALIZER_LIST_ template <typename T> inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf( ::std::initializer_list<T> xs) { return IsSubsetOf(xs.begin(), xs.end()); } -#endif // Matches an STL-style container or a native array that contains only // elements matching the given value or matcher. // -// Each(m) is semantically equivalent to Not(Contains(Not(m))). Only +// Each(m) is semantically equivalent to `Not(Contains(Not(m)))`. Only // the messages are different. // // Examples: @@ -5133,12 +4993,61 @@ inline internal::KeyMatcher<M> Key(M inner_matcher) { // 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); +inline internal::PairMatcher<FirstMatcher, SecondMatcher> Pair( + FirstMatcher first_matcher, SecondMatcher second_matcher) { + return internal::PairMatcher<FirstMatcher, SecondMatcher>(first_matcher, + second_matcher); } +namespace no_adl { +// Conditional() creates a matcher that conditionally uses either the first or +// second matcher provided. For example, we could create an `equal if, and only +// if' matcher using the Conditional wrapper as follows: +// +// EXPECT_THAT(result, Conditional(condition, Eq(expected), Ne(expected))); +template <typename MatcherTrue, typename MatcherFalse> +internal::ConditionalMatcher<MatcherTrue, MatcherFalse> Conditional( + bool condition, MatcherTrue matcher_true, MatcherFalse matcher_false) { + return internal::ConditionalMatcher<MatcherTrue, MatcherFalse>( + condition, std::move(matcher_true), std::move(matcher_false)); +} + +// 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); +} + +// Matches a base64 escaped string, when the unescaped string matches the +// internal matcher. +template <typename MatcherType> +internal::WhenBase64UnescapedMatcher WhenBase64Unescaped( + const MatcherType& internal_matcher) { + return internal::WhenBase64UnescapedMatcher(internal_matcher); +} +} // namespace no_adl + // Returns a predicate that is satisfied by anything that matches the // given matcher. template <typename M> @@ -5146,7 +5055,7 @@ inline internal::MatcherAsPredicate<M> Matches(M matcher) { return internal::MatcherAsPredicate<M>(matcher); } -// Returns true iff the value matches the 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); @@ -5155,8 +5064,8 @@ inline bool Value(const T& value, M matcher) { // 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) { +inline bool ExplainMatchResult(M matcher, const T& value, + MatchResultListener* listener) { return SafeMatcherCast<const T&>(matcher).MatchAndExplain(value, listener); } @@ -5166,7 +5075,8 @@ inline bool ExplainMatchResult( // // MATCHER_P(XAndYThat, matcher, // "X that " + DescribeMatcher<int>(matcher, negation) + -// " and Y that " + DescribeMatcher<double>(matcher, negation)) { +// (negation ? " or" : " and") + " Y that " + +// DescribeMatcher<double>(matcher, negation)) { // return ExplainMatchResult(matcher, arg.x(), result_listener) && // ExplainMatchResult(matcher, arg.y(), result_listener); // } @@ -5182,9 +5092,25 @@ std::string DescribeMatcher(const M& matcher, bool negation = false) { return ss.str(); } -#if GTEST_LANG_CXX11 -// Define variadic matcher versions. They are overloaded in -// gmock-generated-matchers.h for the cases supported by pre C++11 compilers. +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) { @@ -5199,24 +5125,97 @@ internal::AnyOfMatcher<typename std::decay<const Args&>::type...> AnyOf( matchers...); } -template <typename... Args> -internal::ElementsAreMatcher<tuple<typename std::decay<const Args&>::type...>> -ElementsAre(const Args&... matchers) { - return internal::ElementsAreMatcher< - tuple<typename std::decay<const Args&>::type...>>( - make_tuple(matchers...)); +// 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... Args> -internal::UnorderedElementsAreMatcher< - tuple<typename std::decay<const Args&>::type...>> -UnorderedElementsAre(const Args&... matchers) { - return internal::UnorderedElementsAreMatcher< - tuple<typename std::decay<const Args&>::type...>>( - make_tuple(matchers...)); +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()); } -#endif // GTEST_LANG_CXX11 +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 // @@ -5226,7 +5225,9 @@ UnorderedElementsAre(const Args&... matchers) { // // EXPECT_CALL(foo, Bar(_, _)).With(Eq()); template <typename InnerMatcher> -inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; } +inline InnerMatcher AllArgs(const InnerMatcher& matcher) { + return matcher; +} // Returns a matcher that matches the value of an optional<> type variable. // The matcher implementation only uses '!arg' and requires that the optional<> @@ -5234,7 +5235,7 @@ inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; } // and is printable using 'PrintToString'. It is compatible with // std::optional/std::experimental::optional. // Note that to compare an optional type variable against nullopt you should -// use Eq(nullopt) and not Optional(Eq(nullopt)). The latter implies that the +// 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( @@ -5244,7 +5245,7 @@ inline internal::OptionalMatcher<ValueMatcher> Optional( // Returns a matcher that matches the value of a absl::any type variable. template <typename T> -PolymorphicMatcher<internal::any_cast_matcher::AnyCastMatcher<T> > AnyWith( +PolymorphicMatcher<internal::any_cast_matcher::AnyCastMatcher<T>> AnyWith( const Matcher<const T&>& matcher) { return MakePolymorphicMatcher( internal::any_cast_matcher::AnyCastMatcher<T>(matcher)); @@ -5255,20 +5256,360 @@ PolymorphicMatcher<internal::any_cast_matcher::AnyCastMatcher<T> > AnyWith( // functions. // It is compatible with std::variant. template <typename T> -PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T> > VariantWith( +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() (of value = " << err.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 iff 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) +// 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* macros 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 { \ + /* NOLINTNEXTLINE readability-redundant-string-init */ \ + ::std::string gmock_description = (description); \ + if (!gmock_description.empty()) { \ + return gmock_description; \ + } \ + return ::testing::internal::FormatMatcherDescription(negation, #name, \ + {}, {}); \ + } \ + }; \ + }; \ + inline name##Matcher GMOCK_INTERNAL_WARNING_PUSH() \ + GMOCK_INTERNAL_WARNING_CLANG(ignored, "-Wunused-function") \ + GMOCK_INTERNAL_WARNING_CLANG(ignored, "-Wunused-member-function") \ + name GMOCK_INTERNAL_WARNING_POP()() { \ + 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), (p0)) +#define MATCHER_P2(name, p0, p1, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP2, description, (#p0, #p1), \ + (p0, p1)) +#define MATCHER_P3(name, p0, p1, p2, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP3, description, (#p0, #p1, #p2), \ + (p0, p1, p2)) +#define MATCHER_P4(name, p0, p1, p2, p3, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP4, description, \ + (#p0, #p1, #p2, #p3), (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), (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), \ + (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), \ + (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), \ + (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), \ + (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), \ + (p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)) + +#define GMOCK_INTERNAL_MATCHER(name, full_name, description, arg_names, 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; \ + gmock_description = (description); \ + if (!gmock_description.empty()) { \ + return gmock_description; \ + } \ + return ::testing::internal::FormatMatcherDescription( \ + negation, #name, {GMOCK_PP_REMOVE_PARENS(arg_names)}, \ + ::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 @@ -5279,4 +5620,4 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 5046 // declarations from this file. #include "gmock/internal/custom/gmock-matchers.h" -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ diff --git a/contrib/googletest/googlemock/include/gmock/gmock-more-actions.h b/contrib/googletest/googlemock/include/gmock/gmock-more-actions.h index 4d9a28ea8a85..40300766f084 100644 --- a/contrib/googletest/googlemock/include/gmock/gmock-more-actions.h +++ b/contrib/googletest/googlemock/include/gmock/gmock-more-actions.h @@ -27,221 +27,632 @@ // (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 actions that depend on gmock-generated-actions.h. - -// GOOGLETEST_CM0002 DO NOT DELETE - -#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_ - -#include <algorithm> - -#include "gmock/gmock-generated-actions.h" - -namespace testing { -namespace internal { - -// Implements the Invoke(f) action. The template argument -// FunctionImpl is the implementation type of f, which can be either a -// function pointer or a functor. Invoke(f) can be used as an -// Action<F> as long as f's type is compatible with F (i.e. f can be -// assigned to a tr1::function<F>). -template <typename FunctionImpl> -class InvokeAction { - public: - // The c'tor makes a copy of function_impl (either a function - // pointer or a functor). - explicit InvokeAction(FunctionImpl function_impl) - : function_impl_(function_impl) {} - - template <typename Result, typename ArgumentTuple> - Result Perform(const ArgumentTuple& args) { - return InvokeHelper<Result, ArgumentTuple>::Invoke(function_impl_, args); - } - - private: - FunctionImpl function_impl_; - - GTEST_DISALLOW_ASSIGN_(InvokeAction); -}; - -// Implements the Invoke(object_ptr, &Class::Method) action. -template <class Class, typename MethodPtr> -class InvokeMethodAction { - public: - InvokeMethodAction(Class* obj_ptr, MethodPtr method_ptr) - : method_ptr_(method_ptr), obj_ptr_(obj_ptr) {} - - template <typename Result, typename ArgumentTuple> - Result Perform(const ArgumentTuple& args) const { - return InvokeHelper<Result, ArgumentTuple>::InvokeMethod( - obj_ptr_, method_ptr_, args); - } - - private: - // The order of these members matters. Reversing the order can trigger - // warning C4121 in MSVC (see - // http://computer-programming-forum.com/7-vc.net/6fbc30265f860ad1.htm ). - const MethodPtr method_ptr_; - Class* const obj_ptr_; - - GTEST_DISALLOW_ASSIGN_(InvokeMethodAction); -}; +// This file implements some commonly used variadic actions. -// An internal replacement for std::copy which mimics its behavior. This is -// necessary because Visual Studio deprecates ::std::copy, issuing warning 4996. -// However Visual Studio 2010 and later do not honor #pragmas which disable that -// warning. -template<typename InputIterator, typename OutputIterator> -inline OutputIterator CopyElements(InputIterator first, - InputIterator last, - OutputIterator output) { - for (; first != last; ++first, ++output) { - *output = *first; - } - return output; -} +// IWYU pragma: private, include "gmock/gmock.h" +// IWYU pragma: friend gmock/.* -} // namespace internal +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_ -// Various overloads for Invoke(). +#include <memory> +#include <utility> -// Creates an action that invokes 'function_impl' with the mock -// function's arguments. -template <typename FunctionImpl> -PolymorphicAction<internal::InvokeAction<FunctionImpl> > Invoke( - FunctionImpl function_impl) { - return MakePolymorphicAction( - internal::InvokeAction<FunctionImpl>(function_impl)); -} +#include "gmock/gmock-actions.h" +#include "gmock/internal/gmock-port.h" -// Creates an action that invokes the given method on the given object -// with the mock function's arguments. -template <class Class, typename MethodPtr> -PolymorphicAction<internal::InvokeMethodAction<Class, MethodPtr> > Invoke( - Class* obj_ptr, MethodPtr method_ptr) { - return MakePolymorphicAction( - internal::InvokeMethodAction<Class, MethodPtr>(obj_ptr, method_ptr)); -} +// Include any custom callback actions added by the local installation. +#include "gmock/internal/custom/gmock-generated-actions.h" -// 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> -inline internal::WithArgsAction<InnerAction> -WithoutArgs(const InnerAction& action) { - return internal::WithArgsAction<InnerAction>(action); -} +// 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() \ + {} // 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) &) noexcept GMOCK_INTERNAL_DEFN_COPY_ \ + ##value_params \ + GMOCK_ACTION_CLASS_(name, value_params)(GMOCK_ACTION_CLASS_( \ + name, value_params) &&) noexcept 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 -// 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 <int k, typename InnerAction> -inline internal::WithArgsAction<InnerAction, k> -WithArg(const InnerAction& action) { - return internal::WithArgsAction<InnerAction, k>(action); -} +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 - -// Action ReturnArg<k>() returns the k-th argument of the mock function. -ACTION_TEMPLATE(ReturnArg, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_0_VALUE_PARAMS()) { - return ::testing::get<k>(args); -} - -// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the -// mock function to *pointer. -ACTION_TEMPLATE(SaveArg, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_1_VALUE_PARAMS(pointer)) { - *pointer = ::testing::get<k>(args); -} +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100) -// Action SaveArgPointee<k>(pointer) saves the value pointed to -// by the k-th (0-based) argument of the mock function to *pointer. -ACTION_TEMPLATE(SaveArgPointee, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_1_VALUE_PARAMS(pointer)) { - *pointer = *::testing::get<k>(args); -} - -// Action SetArgReferee<k>(value) assigns 'value' to the variable -// referenced by the k-th (0-based) argument of the mock function. -ACTION_TEMPLATE(SetArgReferee, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_1_VALUE_PARAMS(value)) { - typedef typename ::testing::tuple_element<k, args_type>::type argk_type; - // Ensures that argument #k is a reference. If you get a compiler - // error on the next line, you are using SetArgReferee<k>(value) in - // a mock function whose k-th (0-based) argument is not a reference. - GTEST_COMPILE_ASSERT_(internal::is_reference<argk_type>::value, - SetArgReferee_must_be_used_with_a_reference_argument); - ::testing::get<k>(args) = 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. -ACTION_TEMPLATE(SetArrayArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_2_VALUE_PARAMS(first, last)) { - // Visual Studio deprecates ::std::copy, so we use our own copy in that case. -#ifdef _MSC_VER - internal::CopyElements(first, last, ::testing::get<k>(args)); -#else - ::std::copy(first, last, ::testing::get<k>(args)); -#endif -} +namespace internal { -// Action DeleteArg<k>() deletes the k-th (0-based) argument of the mock -// function. -ACTION_TEMPLATE(DeleteArg, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_0_VALUE_PARAMS()) { - delete ::testing::get<k>(args); +// 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...); } -// This action returns the value pointed to by 'pointer'. -ACTION_P(ReturnPointee, pointer) { return *pointer; } +template <std::size_t index, typename... Params> +struct InvokeArgumentAction { + template <typename... Args, + typename = typename std::enable_if<(index < sizeof...(Args))>::type> + 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...); + }); + } -// 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 + internal::FlatTuple<Params...> params; +}; -// Suppresses the 'unreachable code' warning that VC generates in opt modes. -# ifdef _MSC_VER -# pragma warning(push) // Saves the current warning state. -# pragma warning(disable:4702) // Temporarily disables warning 4702. -# endif -ACTION_P(Throw, exception) { throw exception; } -# ifdef _MSC_VER -# pragma warning(pop) // Restores the warning state. -# endif +} // namespace internal -#endif // GTEST_HAS_EXCEPTIONS +// 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 +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100 } // namespace testing -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_ diff --git a/contrib/googletest/googlemock/include/gmock/gmock-more-matchers.h b/contrib/googletest/googlemock/include/gmock/gmock-more-matchers.h index 1c9a399a341e..54ea68be969d 100644 --- a/contrib/googletest/googlemock/include/gmock/gmock-more-matchers.h +++ b/contrib/googletest/googlemock/include/gmock/gmock-more-matchers.h @@ -27,43 +27,71 @@ // (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-generated-matchers.h. +// 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 +// IWYU pragma: private, include "gmock/gmock.h" +// IWYU pragma: friend gmock/.* + +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_ -#ifndef GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_ -#define GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_ +#include <ostream> +#include <string> -#include "gmock/gmock-generated-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) +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100) +#if defined(_MSC_VER) && (_MSC_VER == 1900) // and silence C4800 (C4800: 'int *const ': forcing value // to bool 'true' or 'false') for MSVC 14 -# pragma warning(disable:4800) - #endif +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800) #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; +namespace internal { + +// Implements the polymorphic IsEmpty matcher, which +// can be used as a Matcher<T> as long as T is either a container that defines +// empty() and size() (e.g. std::vector or std::string), or a C-style string. +class IsEmptyMatcher { + public: + // Matches anything that defines empty() and size(). + template <typename MatcheeContainerType> + bool MatchAndExplain(const MatcheeContainerType& c, + MatchResultListener* listener) const { + if (c.empty()) { + return true; + } + *listener << "whose size is " << c.size(); + return false; + } + + // Matches C-style strings. + bool MatchAndExplain(const char* s, MatchResultListener* listener) const { + return MatchAndExplain(std::string(s), listener); } - *result_listener << "whose size is " << arg.size(); - return false; + + // Describes what this matcher matches. + void DescribeTo(std::ostream* os) const { *os << "is empty"; } + + void DescribeNegationTo(std::ostream* os) const { *os << "isn't empty"; } +}; + +} // namespace internal + +// Creates a polymorphic matcher that matches an empty container or C-style +// string. The container must support both size() and empty(), which all +// STL-like containers provide. +inline PolymorphicMatcher<internal::IsEmptyMatcher> IsEmpty() { + return MakePolymorphicMatcher(internal::IsEmptyMatcher()); } // Define a matcher that matches a value that evaluates in boolean @@ -82,11 +110,11 @@ MATCHER(IsFalse, negation ? "is true" : "is false") { return !static_cast<bool>(arg); } -#ifdef _MSC_VER -# pragma warning(pop) +#if defined(_MSC_VER) && (_MSC_VER == 1900) +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4800 #endif - +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100 } // namespace testing -#endif // GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_ diff --git a/contrib/googletest/googlemock/include/gmock/gmock-nice-strict.h b/contrib/googletest/googlemock/include/gmock/gmock-nice-strict.h new file mode 100644 index 000000000000..056d471417e3 --- /dev/null +++ b/contrib/googletest/googlemock/include/gmock/gmock-nice-strict.h @@ -0,0 +1,277 @@ +// 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. + +// IWYU pragma: private, include "gmock/gmock.h" +// IWYU pragma: friend gmock/.* + +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_ + +#include <cstdint> +#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 defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MINGW) && \ + (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(reinterpret_cast<uintptr_t>(this)); + } + + ~NiceMockImpl() { + ::testing::Mock::UnregisterCallReaction(reinterpret_cast<uintptr_t>(this)); + } +}; + +template <typename Base> +class NaggyMockImpl { + public: + NaggyMockImpl() { + ::testing::Mock::WarnUninterestingCalls(reinterpret_cast<uintptr_t>(this)); + } + + ~NaggyMockImpl() { + ::testing::Mock::UnregisterCallReaction(reinterpret_cast<uintptr_t>(this)); + } +}; + +template <typename Base> +class StrictMockImpl { + public: + StrictMockImpl() { + ::testing::Mock::FailUninterestingCalls(reinterpret_cast<uintptr_t>(this)); + } + + ~StrictMockImpl() { + ::testing::Mock::UnregisterCallReaction(reinterpret_cast<uintptr_t>(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://google.github.io/googletest/" + "gmock_cook_book.html#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: + NiceMock(const NiceMock&) = delete; + NiceMock& operator=(const NiceMock&) = delete; +}; + +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://google.github.io/googletest/" + "gmock_cook_book.html#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: + NaggyMock(const NaggyMock&) = delete; + NaggyMock& operator=(const NaggyMock&) = delete; +}; + +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://google.github.io/googletest/" + "gmock_cook_book.html#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: + StrictMock(const StrictMock&) = delete; + StrictMock& operator=(const StrictMock&) = delete; +}; + +#undef GTEST_INTERNAL_EMPTY_BASE_CLASS + +} // namespace testing + +#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_ diff --git a/contrib/googletest/googlemock/include/gmock/gmock-spec-builders.h b/contrib/googletest/googlemock/include/gmock/gmock-spec-builders.h index 436e2d8b7747..78ca15d05e0f 100644 --- a/contrib/googletest/googlemock/include/gmock/gmock-spec-builders.h +++ b/contrib/googletest/googlemock/include/gmock/gmock-spec-builders.h @@ -27,7 +27,6 @@ // (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. @@ -56,16 +55,24 @@ // where all clauses are optional, and .InSequence()/.After()/ // .WillOnce() can appear any number of times. -// GOOGLETEST_CM0002 DO NOT DELETE +// IWYU pragma: private, include "gmock/gmock.h" +// IWYU pragma: friend gmock/.* -#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ +#include <cstdint> +#include <functional> #include <map> +#include <memory> +#include <ostream> #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" @@ -74,7 +81,7 @@ #include "gtest/gtest.h" #if GTEST_HAS_EXCEPTIONS -# include <stdexcept> // NOLINT +#include <stdexcept> // NOLINT #endif GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ @@ -93,19 +100,26 @@ class ExpectationSet; namespace internal { // Implements a mock function. -template <typename F> class FunctionMocker; +template <typename F> +class FunctionMocker; // Base class for expectations. class ExpectationBase; // Implements an expectation. -template <typename F> class TypedExpectation; +template <typename F> +class TypedExpectation; // Helper class for testing the Expectation class template. class ExpectationTester; -// Base class for function mockers. -template <typename F> class FunctionMockerBase; +// 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. @@ -120,12 +134,9 @@ template <typename F> class FunctionMockerBase; // 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 FunctionMockerBase. This is the +// Abstract base class of FunctionMocker. This is the // type-agnostic part of the function mocker interface. Its pure -// virtual methods are implemented by FunctionMockerBase. +// virtual methods are implemented by FunctionMocker. class GTEST_API_ UntypedFunctionMockerBase { public: UntypedFunctionMockerBase(); @@ -145,27 +156,12 @@ class GTEST_API_ UntypedFunctionMockerBase { // 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; + 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, @@ -174,10 +170,9 @@ class GTEST_API_ UntypedFunctionMockerBase { // 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, + const void* untyped_args, const void** untyped_action, bool* is_excessive, ::std::ostream* what, ::std::ostream* why) - GTEST_LOCK_EXCLUDED_(g_gmock_mutex) = 0; + GTEST_LOCK_EXCLUDED_(g_gmock_mutex) = 0; // Prints the given function arguments to the ostream. virtual void UntypedPrintArgs(const void* untyped_args, @@ -187,9 +182,7 @@ class GTEST_API_ UntypedFunctionMockerBase { // this information in the global mock registry. Will be called // whenever an EXPECT_CALL() or ON_CALL() is executed on this mock // method. - // FIXME: rename to SetAndRegisterOwner(). - void RegisterOwner(const void* mock_obj) - GTEST_LOCK_EXCLUDED_(g_gmock_mutex); + 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 @@ -200,26 +193,19 @@ class GTEST_API_ UntypedFunctionMockerBase { // 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); + 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); + const char* Name() const GTEST_LOCK_EXCLUDED_(g_gmock_mutex); protected: typedef std::vector<const void*> UntypedOnCallSpecs; - typedef std::vector<internal::linked_ptr<ExpectationBase> > - UntypedExpectations; + using UntypedExpectations = std::vector<std::shared_ptr<ExpectationBase>>; + + struct UninterestingCallCleanupHandler; + struct FailureCleanupHandler; // Returns an Expectation object that references and co-owns exp, // which must be an expectation on this mock function. @@ -304,11 +290,9 @@ class OnCallSpec : public UntypedOnCallSpecBase { : UntypedOnCallSpecBase(a_file, a_line), matchers_(matchers), // By default, extra_matcher_ should match anything. However, - // we cannot initialize it with _ as that triggers a compiler - // bug in Symbian's C++ compiler (cannot decide between two - // overloaded constructors of Matcher<const ArgumentTuple&>). - extra_matcher_(A<const ArgumentTuple&>()) { - } + // 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) { @@ -335,7 +319,7 @@ class OnCallSpec : public UntypedOnCallSpecBase { return *this; } - // Returns true iff the given arguments match the matchers. + // 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); } @@ -393,53 +377,60 @@ class GTEST_API_ Mock { GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); // Verifies all expectations on the given mock object and clears its - // default actions and expectations. Returns true iff the + // 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::FunctionMockerBase; - - template <typename M> - friend class NiceMock; - - template <typename M> - friend class NaggyMock; + friend class internal::FunctionMocker; - template <typename M> - friend class StrictMock; + 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) + static void AllowUninterestingCalls(uintptr_t 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) + static void WarnUninterestingCalls(uintptr_t 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) + static void FailUninterestingCalls(uintptr_t 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) + static void UnregisterCallReaction(uintptr_t 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); + 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 @@ -452,22 +443,21 @@ class GTEST_API_ Mock { 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); + 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); + 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 - // FunctionMockerBase. + // FunctionMocker. static void UnregisterLocked(internal::UntypedFunctionMockerBase* mocker) GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex); }; // class Mock @@ -487,17 +477,15 @@ class GTEST_API_ Mock { // - 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(). -// - The constructors and destructor are defined out-of-line because -// the Symbian WINSCW compiler wants to otherwise instantiate them -// when it sees this class definition, at which point it doesn't have -// ExpectationBase available yet, leading to incorrect destruction -// in the linked_ptr (or compilation errors if using a checking -// linked_ptr). + 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 @@ -514,7 +502,8 @@ class GTEST_API_ Expectation { // The compiler-generated copy ctor and operator= work exactly as // intended, so we don't need to define our own. - // Returns true iff rhs references the same expectation as this object does. + // 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_; } @@ -528,7 +517,7 @@ class GTEST_API_ Expectation { friend class ::testing::internal::UntypedFunctionMockerBase; template <typename F> - friend class ::testing::internal::FunctionMockerBase; + friend class ::testing::internal::FunctionMocker; template <typename F> friend class ::testing::internal::TypedExpectation; @@ -544,16 +533,15 @@ class GTEST_API_ Expectation { typedef ::std::set<Expectation, Less> Set; Expectation( - const internal::linked_ptr<internal::ExpectationBase>& expectation_base); + const std::shared_ptr<internal::ExpectationBase>& expectation_base); // Returns the expectation this object references. - const internal::linked_ptr<internal::ExpectationBase>& - expectation_base() const { + const std::shared_ptr<internal::ExpectationBase>& expectation_base() const { return expectation_base_; } - // A linked_ptr that co-owns the expectation this handle references. - internal::linked_ptr<internal::ExpectationBase> 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 @@ -578,7 +566,7 @@ class ExpectationSet { typedef Expectation::Set::value_type value_type; // Constructs an empty set. - ExpectationSet() {} + ExpectationSet() = default; // This single-argument ctor must not be explicit, in order to support the // ExpectationSet es = EXPECT_CALL(...); @@ -597,8 +585,8 @@ class ExpectationSet { // The compiler-generator ctor and operator= works exactly as // intended, so we don't need to define our own. - // Returns true iff rhs contains the same set of Expectation objects - // as this does. + // 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_; } @@ -621,7 +609,6 @@ class ExpectationSet { 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). @@ -635,11 +622,8 @@ class GTEST_API_ Sequence { void AddExpectation(const Expectation& expectation) const; private: - // The last expectation in this sequence. We use a linked_ptr here - // because Sequence objects are copyable and we want the copies to - // be aliases. The linked_ptr allows the copies to co-own and share - // the same Expectation object. - internal::linked_ptr<Expectation> last_expectation_; + // The last expectation in this sequence. + std::shared_ptr<Expectation> last_expectation_; }; // class Sequence // An object of this type causes all EXPECT_CALL() statements @@ -670,11 +654,13 @@ class GTEST_API_ InSequence { public: InSequence(); ~InSequence(); + private: bool sequence_created_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(InSequence); // NOLINT -} GTEST_ATTRIBUTE_UNUSED_; + InSequence(const InSequence&) = delete; + InSequence& operator=(const InSequence&) = delete; +}; namespace internal { @@ -724,6 +710,12 @@ class GTEST_API_ ExpectationBase { // describes it to the ostream. virtual void MaybeDescribeExtraMatcherTo(::std::ostream* os) = 0; + // Do not rely on this for correctness. + // This is only for making human-readable test output easier to understand. + void UntypedDescription(std::string description) { + description_ = std::move(description); + } + protected: friend class ::testing::Expectation; friend class UntypedFunctionMockerBase; @@ -762,8 +754,8 @@ class GTEST_API_ ExpectationBase { // by the subclasses to implement the .Times() clause. void SpecifyCardinality(const Cardinality& cardinality); - // Returns true iff the user specified the cardinality explicitly - // using a .Times(). + // 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. @@ -776,45 +768,44 @@ class GTEST_API_ ExpectationBase { // the current thread. // Retires all pre-requisites of this expectation. - void RetireAllPreRequisites() - GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex); + void RetireAllPreRequisites() GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex); - // Returns true iff this expectation is retired. - bool is_retired() const - 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) { + void Retire() GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { g_gmock_mutex.AssertHeld(); retired_ = true; } - // Returns true iff this expectation is satisfied. - bool IsSatisfied() const - GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + // Returns a human-readable description of this expectation. + // Do not rely on this for correctness. It is only for human readability. + const std::string& GetDescription() const { return description_; } + + // 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 iff this expectation is saturated. - bool IsSaturated() const - GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + // 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 iff this expectation is over-saturated. - bool IsOverSaturated() const - GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + // 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 iff all pre-requisites of this expectation are satisfied. + // Returns true if and only if all pre-requisites of this expectation are + // satisfied. bool AllPrerequisitesAreSatisfied() const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex); @@ -823,15 +814,13 @@ class GTEST_API_ ExpectationBase { 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) { + 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) { + void IncrementCallCount() GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { g_gmock_mutex.AssertHeld(); call_count_++; } @@ -840,8 +829,7 @@ class GTEST_API_ ExpectationBase { // 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_); + void CheckActionCountIfNotDone() const GTEST_LOCK_EXCLUDED_(mutex_); friend class ::testing::Sequence; friend class ::testing::internal::ExpectationTester; @@ -854,15 +842,16 @@ class GTEST_API_ ExpectationBase { // 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 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 iff the cardinality is specified explicitly. + std::string description_; // User-readable name for the expectation. + // True if and only if the cardinality is specified explicitly. bool cardinality_specified_; - Cardinality cardinality_; // The cardinality of the expectation. + 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 linked_ptr in the set because we want an + // 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. @@ -871,40 +860,43 @@ class GTEST_API_ ExpectationBase { // 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 iff this expectation has retired. + 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_. - - GTEST_DISALLOW_ASSIGN_(ExpectationBase); -}; // class ExpectationBase + mutable Mutex mutex_; // Protects action_count_checked_. +}; // class ExpectationBase -// Impements an expectation for the given function type. template <typename F> -class TypedExpectation : public ExpectationBase { +class TypedExpectation; + +// Implements an expectation for the given function type. +template <typename R, typename... Args> +class TypedExpectation<R(Args...)> : public ExpectationBase { + private: + using F = R(Args...); + public: typedef typename Function<F>::ArgumentTuple ArgumentTuple; typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple; typedef typename Function<F>::Result Result; - TypedExpectation(FunctionMockerBase<F>* owner, const char* a_file, int a_line, + 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 triggers a compiler - // bug in Symbian's C++ compiler (cannot decide between two - // overloaded constructors of Matcher<const ArgumentTuple&>). + // 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()) {} - virtual ~TypedExpectation() { + ~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(); @@ -932,6 +924,13 @@ class TypedExpectation : public ExpectationBase { return *this; } + // Do not rely on this for correctness. + // This is only for making human-readable test output easier to understand. + TypedExpectation& Description(std::string name) { + ExpectationBase::UntypedDescription(std::move(name)); + return *this; + } + // Implements the .Times() clause. TypedExpectation& Times(const Cardinality& a_cardinality) { ExpectationBase::UntypedTimes(a_cardinality); @@ -939,9 +938,7 @@ class TypedExpectation : public ExpectationBase { } // Implements the .Times() clause. - TypedExpectation& Times(int n) { - return Times(Exactly(n)); - } + TypedExpectation& Times(int n) { return Times(Exactly(n)); } // Implements the .InSequence() clause. TypedExpectation& InSequence(const Sequence& s) { @@ -1001,14 +998,31 @@ class TypedExpectation : public ExpectationBase { return After(s1, s2, s3, s4).After(s5); } - // Implements the .WillOnce() clause. - TypedExpectation& WillOnce(const Action<F>& action) { + // Preferred, type-safe overload: consume anything that can be directly + // converted to a OnceAction, except for Action<F> objects themselves. + TypedExpectation& WillOnce(OnceAction<F> once_action) { + // Call the overload below, smuggling the OnceAction as a copyable callable. + // We know this is safe because a WillOnce action will not be called more + // than once. + return WillOnce(Action<F>(ActionAdaptor{ + std::make_shared<OnceAction<F>>(std::move(once_action)), + })); + } + + // Fallback overload: accept Action<F> objects and those actions that define + // `operator Action<F>` but not `operator OnceAction<F>`. + // + // This is templated in order to cause the overload above to be preferred + // when the input is convertible to either type. + template <int&... ExplicitArgumentBarrier, typename = void> + TypedExpectation& WillOnce(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)); + untyped_actions_.push_back(new Action<F>(std::move(action))); + if (!cardinality_specified()) { set_cardinality(Exactly(static_cast<int>(untyped_actions_.size()))); } @@ -1056,9 +1070,7 @@ class TypedExpectation : public ExpectationBase { // Returns the matchers for the arguments as specified inside the // EXPECT_CALL() macro. - const ArgumentMatcherTuple& matchers() const { - return matchers_; - } + const ArgumentMatcherTuple& matchers() const { return matchers_; } // Returns the matcher specified by the .With() clause. const Matcher<const ArgumentTuple&>& extra_matcher() const { @@ -1070,7 +1082,7 @@ class TypedExpectation : public ExpectationBase { // If this mock method has an extra matcher (i.e. .With(matcher)), // describes it to the ostream. - virtual void MaybeDescribeExtraMatcherTo(::std::ostream* os) { + void MaybeDescribeExtraMatcherTo(::std::ostream* os) override { if (extra_matcher_specified_) { *os << " Expected args: "; extra_matcher_.DescribeTo(os); @@ -1080,26 +1092,35 @@ class TypedExpectation : public ExpectationBase { private: template <typename Function> - friend class FunctionMockerBase; + friend class FunctionMocker; + + // An adaptor that turns a OneAction<F> into something compatible with + // Action<F>. Must be called at most once. + struct ActionAdaptor { + std::shared_ptr<OnceAction<R(Args...)>> once_action; + + R operator()(Args&&... args) const { + return std::move(*once_action).Call(std::forward<Args>(args)...); + } + }; // Returns an Expectation object that references and co-owns this // expectation. - virtual Expectation GetHandle() { - return owner_->GetHandleOf(this); - } + 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 iff this expectation matches the given arguments. + // 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 iff this expectation should handle the given arguments. + // 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(); @@ -1114,10 +1135,8 @@ class TypedExpectation : public ExpectationBase { // 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) { + void ExplainMatchResultTo(const ArgumentTuple& args, ::std::ostream* os) const + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { g_gmock_mutex.AssertHeld(); if (is_retired()) { @@ -1159,10 +1178,9 @@ class TypedExpectation : public ExpectationBase { } // Returns the action that should be taken for the current invocation. - const Action<F>& GetCurrentAction( - const FunctionMockerBase<F>* mocker, - const ArgumentTuple& args) const - GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + 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__, @@ -1177,16 +1195,17 @@ class TypedExpectation : public ExpectationBase { ::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 - "; + << "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_[count - 1]) : - repeated_action(); + 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 @@ -1196,24 +1215,25 @@ class TypedExpectation : public ExpectationBase { // 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 FunctionMockerBase<F>* mocker, - const ArgumentTuple& args, - ::std::ostream* what, - ::std::ostream* why) - GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + 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(); + const ::std::string& expectation_description = GetDescription(); if (IsSaturated()) { // We have an excessive call. IncrementCallCount(); - *what << "Mock function called more times than expected - "; + *what << "Mock function "; + if (!expectation_description.empty()) { + *what << "\"" << expectation_description << "\" "; + } + *what << "called more times than expected - "; mocker->DescribeDefaultActionTo(args, what); DescribeCallCountTo(why); - // FIXME: allow the user to control whether - // unexpected calls should fail immediately or continue using a - // flag --gmock_unexpected_calls_are_fatal. - return NULL; + return nullptr; } IncrementCallCount(); @@ -1224,18 +1244,23 @@ class TypedExpectation : public ExpectationBase { } // Must be done after IncrementCount()! - *what << "Mock function call matches " << source_text() <<"...\n"; + *what << "Mock function "; + if (!expectation_description.empty()) { + *what << "\"" << expectation_description << "\" "; + } + *what << "call matches " << source_text() << "...\n"; return &(GetCurrentAction(mocker, args)); } // All the fields below won't change once the EXPECT_CALL() // statement finishes. - FunctionMockerBase<F>* const owner_; + FunctionMocker<F>* const owner_; ArgumentMatcherTuple matchers_; Matcher<const ArgumentTuple&> extra_matcher_; Action<F> repeated_action_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(TypedExpectation); + TypedExpectation(const TypedExpectation&) = delete; + TypedExpectation& operator=(const TypedExpectation&) = delete; }; // class TypedExpectation // A MockSpec object is used by ON_CALL() or EXPECT_CALL() for @@ -1257,19 +1282,20 @@ template <typename F> class MockSpec { public: typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - typedef typename internal::Function<F>::ArgumentMatcherTuple - ArgumentMatcherTuple; + typedef + typename internal::Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple; // Constructs a MockSpec object, given the function mocker object // that the spec is associated with. - MockSpec(internal::FunctionMockerBase<F>* function_mocker, + 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) { + 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_); @@ -1277,13 +1303,14 @@ class MockSpec { // 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) { + 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_); + return function_mocker_->AddNewExpectation(file, line, source_text, + matchers_); } // This operator overload is used to swallow the superfluous parameter list @@ -1298,11 +1325,9 @@ class MockSpec { friend class internal::FunctionMocker; // The function mocker that owns this spec. - internal::FunctionMockerBase<F>* const function_mocker_; + internal::FunctionMocker<F>* const function_mocker_; // The argument matchers specified in the spec. ArgumentMatcherTuple matchers_; - - GTEST_DISALLOW_ASSIGN_(MockSpec); }; // class MockSpec // Wrapper type for generically holding an ordinary value or lvalue reference. @@ -1318,22 +1343,18 @@ template <typename T> class ReferenceOrValueWrapper { public: // Constructs a wrapper from the given value/reference. - explicit ReferenceOrValueWrapper(T value) - : value_(::testing::internal::move(value)) { - } + 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 ::testing::internal::move(value_); } + T Unwrap() { return std::move(value_); } // Provides nondestructive access to the underlying value/reference. // Always returns a const reference (more precisely, - // const RemoveReference<T>&). The behavior of calling this after - // calling Unwrap on the same object is unspecified. - const T& Peek() const { - return value_; - } + // 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_; @@ -1347,8 +1368,7 @@ class ReferenceOrValueWrapper<T&> { // 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) {} + explicit ReferenceOrValueWrapper(reference ref) : value_ptr_(&ref) {} T& Unwrap() { return *value_ptr_; } const T& Peek() const { return *value_ptr_; } @@ -1356,129 +1376,97 @@ class ReferenceOrValueWrapper<T&> { T* value_ptr_; }; -// MSVC warns about using 'this' in base member initializer list, so -// we need to temporarily disable the warning. We have to do it for -// the entire class to suppress the warning, even though it's about -// the constructor only. -GTEST_DISABLE_MSC_WARNINGS_PUSH_(4355) - -// 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. +// Prints the held value as an action's result to os. template <typename T> -class ActionResultHolder : public UntypedActionResultHolderBase { - public: - // Returns the held value. Must not be called more than once. - T Unwrap() { - return result_.Unwrap(); - } +void PrintAsActionResult(const T& result, std::ostream& os) { + os << "\n Returns: "; + // T may be a reference type, so we don't use UniversalPrint(). + UniversalPrinter<T>::Print(result, &os); +} - // Prints the held value as an action's result to os. - virtual void PrintAsActionResult(::std::ostream* os) const { - *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 FunctionMockerBase<F>* func_mocker, - typename RvalueRef<typename Function<F>::ArgumentTuple>::type args, - const std::string& call_description) { - return new ActionResultHolder(Wrapper(func_mocker->PerformDefaultAction( - internal::move(args), call_description))); - } +// Reports an uninteresting call (whose description is in msg) in the +// manner specified by 'reaction'. +GTEST_API_ void ReportUninterestingCall(CallReaction reaction, + const std::string& msg); - // Performs the given action and returns the result in a new-ed - // ActionResultHolder. - template <typename F> - static ActionResultHolder* PerformAction( - const Action<F>& action, - typename RvalueRef<typename Function<F>::ArgumentTuple>::type args) { - return new ActionResultHolder( - Wrapper(action.Perform(internal::move(args)))); - } +// A generic RAII type that runs a user-provided function in its destructor. +class Cleanup final { + public: + explicit Cleanup(std::function<void()> f) : f_(std::move(f)) {} + ~Cleanup() { f_(); } private: - typedef ReferenceOrValueWrapper<T> Wrapper; - - explicit ActionResultHolder(Wrapper result) - : result_(::testing::internal::move(result)) { - } - - Wrapper result_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionResultHolder); + std::function<void()> f_; }; -// Specialization for T = void. -template <> -class ActionResultHolder<void> : public UntypedActionResultHolderBase { - public: - void Unwrap() { } - - virtual void PrintAsActionResult(::std::ostream* /* os */) const {} +struct UntypedFunctionMockerBase::UninterestingCallCleanupHandler { + CallReaction reaction; + std::stringstream& ss; - // Performs the given mock function's default action and returns ownership - // of an empty ActionResultHolder*. - template <typename F> - static ActionResultHolder* PerformDefaultAction( - const FunctionMockerBase<F>* func_mocker, - typename RvalueRef<typename Function<F>::ArgumentTuple>::type args, - const std::string& call_description) { - func_mocker->PerformDefaultAction(internal::move(args), call_description); - return new ActionResultHolder; + ~UninterestingCallCleanupHandler() { + ReportUninterestingCall(reaction, ss.str()); } +}; - // Performs the given action and returns ownership of an empty - // ActionResultHolder*. - template <typename F> - static ActionResultHolder* PerformAction( - const Action<F>& action, - typename RvalueRef<typename Function<F>::ArgumentTuple>::type args) { - action.Perform(internal::move(args)); - return new ActionResultHolder; +struct UntypedFunctionMockerBase::FailureCleanupHandler { + std::stringstream& ss; + std::stringstream& why; + std::stringstream& loc; + const ExpectationBase* untyped_expectation; + bool found; + bool is_excessive; + + ~FailureCleanupHandler() { + 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); + } } - - private: - ActionResultHolder() {} - GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionResultHolder); }; -// The base of the function mocker class for the given function type. -// We put the methods in this class instead of its child to avoid code -// bloat. template <typename F> -class FunctionMockerBase : public UntypedFunctionMockerBase { +class FunctionMocker; + +template <typename R, typename... Args> +class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase { + using F = R(Args...); + public: - typedef typename Function<F>::Result Result; - typedef typename Function<F>::ArgumentTuple ArgumentTuple; - typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple; + using Result = R; + using ArgumentTuple = std::tuple<Args...>; + using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>; - FunctionMockerBase() {} + FunctionMocker() = default; + + // 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. - virtual ~FunctionMockerBase() - GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { + ~FunctionMocker() override GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { MutexLock l(&g_gmock_mutex); VerifyAndClearExpectationsLocked(); Mock::UnregisterLocked(this); @@ -1488,33 +1476,29 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { // 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(); + 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; + if (spec->Matches(args)) return spec; } - return NULL; + 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 + // exceptions are enabled) with a helpful call description 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( - typename RvalueRef<typename Function<F>::ArgumentTuple>::type args, - const std::string& call_description) const { - const OnCallSpec<F>* const spec = - this->FindOnCallSpec(args); - if (spec != NULL) { - return spec->GetAction().Perform(internal::move(args)); + 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 + @@ -1530,35 +1514,9 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { 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 = * - virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction( - void* untyped_args, // must point to an ArgumentTuple - const std::string& call_description) const { - ArgumentTuple* args = static_cast<ArgumentTuple*>(untyped_args); - return ResultHolder::PerformDefaultAction(this, internal::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 = * - virtual UntypedActionResultHolderBase* UntypedPerformAction( - const void* untyped_action, void* untyped_args) const { - // 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, internal::move(*args)); - } - // Implements UntypedFunctionMockerBase::ClearDefaultActionsLocked(): // clears the ON_CALL()s set on this mock function. - virtual void ClearDefaultActionsLocked() + void ClearDefaultActionsLocked() override GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { g_gmock_mutex.AssertHeld(); @@ -1573,8 +1531,7 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { untyped_on_call_specs_.swap(specs_to_delete); g_gmock_mutex.Unlock(); - for (UntypedOnCallSpecs::const_iterator it = - specs_to_delete.begin(); + for (UntypedOnCallSpecs::const_iterator it = specs_to_delete.begin(); it != specs_to_delete.end(); ++it) { delete static_cast<const OnCallSpec<F>*>(*it); } @@ -1584,31 +1541,25 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { g_gmock_mutex.Lock(); } - protected: - template <typename Function> - friend class MockSpec; - - typedef ActionResultHolder<Result> ResultHolder; - // Returns the result of invoking this mock function with the given // arguments. This function can be safely called from multiple // threads concurrently. - Result InvokeWith( - typename RvalueRef<typename Function<F>::ArgumentTuple>::type args) - GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { - // const_cast is required since in C++98 we still pass ArgumentTuple around - // by const& instead of rvalue reference. - void* untyped_args = const_cast<void*>(static_cast<const void*>(&args)); - scoped_ptr<ResultHolder> holder( - DownCast_<ResultHolder*>(this->UntypedInvokeWith(untyped_args))); - return holder->Unwrap(); + Result Invoke(Args... args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { + return InvokeWith(ArgumentTuple(std::forward<Args>(args)...)); + } + + MockSpec<F> With(Matcher<Args>... m) { + return MockSpec<F>(this, ::std::make_tuple(std::move(m)...)); } + protected: + template <typename Function> + friend class MockSpec; + // 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) { + 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); @@ -1623,14 +1574,14 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line); TypedExpectation<F>* const expectation = new TypedExpectation<F>(this, file, line, source_text, m); - const linked_ptr<ExpectationBase> untyped_expectation(expectation); + 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 != NULL) { + if (implicit_sequence != nullptr) { implicit_sequence->AddExpectation(Expectation(untyped_expectation)); } @@ -1638,7 +1589,8 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { } private: - template <typename Func> friend class TypedExpectation; + template <typename Func> + friend class TypedExpectation; // Some utilities needed for implementing UntypedInvokeWith(). @@ -1649,10 +1601,9 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ::std::ostream* os) const { const OnCallSpec<F>* const spec = FindOnCallSpec(args); - if (spec == NULL) { - *os << (internal::type_equals<Result, void>::value ? - "returning directly.\n" : - "returning default value.\n"); + 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"; @@ -1662,10 +1613,9 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { // 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) { + 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 - "; @@ -1690,18 +1640,17 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { // 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. - 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) { + 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 == NULL) { // A match wasn't found. + if (exp == nullptr) { // A match wasn't found. this->FormatUnexpectedCallMessageLocked(args, what, why); - return NULL; + return nullptr; } // This line must be done before calling GetActionForArguments(), @@ -1709,15 +1658,15 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { // its saturation status. *is_excessive = exp->IsSaturated(); const Action<F>* action = exp->GetActionForArguments(this, args, what, why); - if (action != NULL && action->IsDoDefault()) - action = NULL; // Normalize "do default" to NULL. + 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. - virtual void UntypedPrintArgs(const void* untyped_args, - ::std::ostream* os) const { + void UntypedPrintArgs(const void* untyped_args, + ::std::ostream* os) const override { const ArgumentTuple& args = *static_cast<const ArgumentTuple*>(untyped_args); UniversalPrint(args, os); @@ -1725,9 +1674,8 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { // 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) { + 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. @@ -1740,15 +1688,14 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { return exp; } } - return NULL; + 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) { + 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); @@ -1757,17 +1704,16 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { // 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) { + void PrintTriedExpectationsLocked(const ArgumentTuple& args, + ::std::ostream* why) const + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { g_gmock_mutex.AssertHeld(); - const int count = static_cast<int>(untyped_expectations_.size()); + 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") + << (count == 1 ? "expectation, but it didn't match" + : "expectations, but none matched") << ":\n"; - for (int i = 0; i < count; i++) { + for (size_t i = 0; i < count; i++) { TypedExpectation<F>* const expectation = static_cast<TypedExpectation<F>*>(untyped_expectations_[i].get()); *why << "\n"; @@ -1781,35 +1727,316 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { } } - // 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: + // Performs the given action (or the default if it's null) with the given + // arguments and returns the action's result. + // L = * + R PerformAction(const void* untyped_action, ArgumentTuple&& args, + const std::string& call_description) const { + if (untyped_action == nullptr) { + return PerformDefaultAction(std::move(args), call_description); + } + + // 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); + return action.Perform(std::move(args)); + } + + // Is it possible to store an object of the supplied type in a local variable + // for the sake of printing it, then return it on to the caller? + template <typename T> + using can_print_result = internal::conjunction< + // void can't be stored as an object (and we also don't need to print it). + internal::negation<std::is_void<T>>, + // Non-moveable types can't be returned on to the user, so there's no way + // for us to intercept and print them. + std::is_move_constructible<T>>; + + // Perform the supplied action, printing the result to os. + template <typename T = R, + typename std::enable_if<can_print_result<T>::value, int>::type = 0> + R PerformActionAndPrintResult(const void* const untyped_action, + ArgumentTuple&& args, + const std::string& call_description, + std::ostream& os) { + R result = PerformAction(untyped_action, std::move(args), call_description); + + PrintAsActionResult(result, os); + return std::forward<R>(result); + } + + // An overload for when it's not possible to print the result. In this case we + // simply perform the action. + template <typename T = R, + typename std::enable_if< + internal::negation<can_print_result<T>>::value, int>::type = 0> + R PerformActionAndPrintResult(const void* const untyped_action, + ArgumentTuple&& args, + const std::string& call_description, + std::ostream&) { + return PerformAction(untyped_action, std::move(args), call_description); + } + + // Returns the result of invoking this mock function with the given + // arguments. This function can be safely called from multiple + // threads concurrently. + R InvokeWith(ArgumentTuple&& args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex); +}; // class FunctionMocker + +// Calculates the result of invoking this mock function with the given +// arguments, prints it, and returns it. +template <typename R, typename... Args> +R FunctionMocker<R(Args...)>::InvokeWith(ArgumentTuple&& 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->PerformDefaultAction( + std::move(args), "Function call: " + std::string(Name())); + } + + // Warns about the uninteresting call. + ::std::stringstream ss; + this->UntypedDescribeUninterestingCall(&args, &ss); + + // Perform the action, print the result, and then report the uninteresting + // call. + // + // We use RAII to do the latter in case R is void or a non-moveable type. In + // either case we can't assign it to a local variable. + // + // Note that std::bind() is essential here. + // We *don't* use any local callback types (like lambdas). + // Doing so slows down compilation dramatically because the *constructor* of + // std::function<T> is re-instantiated with different template + // parameters each time. + const UninterestingCallCleanupHandler report_uninteresting_call = { + reaction, ss + }; + + return PerformActionAndPrintResult(nullptr, std::move(args), ss.str(), ss); + } + + 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(&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 PerformAction(untyped_action, std::move(args), ""); + } + + ss << " Function call: " << Name(); + this->UntypedPrintArgs(&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); + } + + // Perform the action, print the result, and then fail or log in whatever way + // is appropriate. // - // class MockFoo : public Foo { - // public: - // // Defines a copy constructor explicitly. - // MockFoo(const MockFoo& src) {} - // ... - // }; - GTEST_DISALLOW_COPY_AND_ASSIGN_(FunctionMockerBase); -}; // class FunctionMockerBase + // We use RAII to do the latter in case R is void or a non-moveable type. In + // either case we can't assign it to a local variable. + // + // Note that we *don't* use any local callback types (like lambdas) here. + // Doing so slows down compilation dramatically because the *constructor* of + // std::function<T> is re-instantiated with different template + // parameters each time. + const FailureCleanupHandler handle_failures = { + ss, why, loc, untyped_expectation, found, is_excessive + }; -GTEST_DISABLE_MSC_WARNINGS_POP_() // 4355 + return PerformActionAndPrintResult(untyped_action, std::move(args), ss.str(), + ss); +} -// Implements methods of FunctionMockerBase. +} // namespace internal -// 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. +namespace internal { -// Reports an uninteresting call (whose description is in msg) in the -// manner specified by 'reaction'. -void ReportUninterestingCall(CallReaction reaction, const std::string& msg); +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 a signature type itself and any template +that can be parameterized with a signature, including std::function and +boost::function. +*/ + +template <typename F, typename = void> +struct SignatureOf; + +template <typename R, typename... Args> +struct SignatureOf<R(Args...)> { + using type = R(Args...); +}; + +template <template <typename> class C, typename F> +struct SignatureOf<C<F>, + typename std::enable_if<std::is_function<F>::value>::type> + : 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 @@ -1833,7 +2060,9 @@ using internal::MockSpec; // // Expects a call to const MockFoo::Bar(). // EXPECT_CALL(Const(foo), Bar()); template <typename T> -inline const T& Const(const T& x) { return x; } +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 @@ -1905,8 +2134,9 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 // second argument is an internal type derived from the method signature. The // failure to disambiguate two overloads of this method in the ON_CALL statement // is how we block callers from setting expectations on overloaded methods. -#define GMOCK_ON_CALL_IMPL_(mock_expr, Setter, call) \ - ((mock_expr).gmock_##call)(::testing::internal::GetWithoutMatchers(), NULL) \ +#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) \ @@ -1915,4 +2145,4 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 #define EXPECT_CALL(obj, call) \ GMOCK_ON_CALL_IMPL_(obj, InternalExpectedAt, call) -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ diff --git a/contrib/googletest/googlemock/include/gmock/gmock.h b/contrib/googletest/googlemock/include/gmock/gmock.h index dd9622605649..568c8c71d785 100644 --- a/contrib/googletest/googlemock/include/gmock/gmock.h +++ b/contrib/googletest/googlemock/include/gmock/gmock.h @@ -27,26 +27,23 @@ // (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_ +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_ // This file implements the following syntax: // -// ON_CALL(mock_object.Method(...)) +// ON_CALL(mock_object, Method(...)) // .With(...) ? // .WillByDefault(...); // // where With() is optional and WillByDefault() must appear exactly // once. // -// EXPECT_CALL(mock_object.Method(...)) +// EXPECT_CALL(mock_object, Method(...)) // .With(...) ? // .Times(...) ? // .InSequence(...) * @@ -58,22 +55,21 @@ #include "gmock/gmock-actions.h" #include "gmock/gmock-cardinalities.h" -#include "gmock/gmock-generated-actions.h" -#include "gmock/gmock-generated-function-mockers.h" -#include "gmock/gmock-generated-matchers.h" -#include "gmock/gmock-generated-nice-strict.h" +#include "gmock/gmock-function-mocker.h" #include "gmock/gmock-matchers.h" #include "gmock/gmock-more-actions.h" #include "gmock/gmock-more-matchers.h" +#include "gmock/gmock-nice-strict.h" #include "gmock/internal/gmock-internal-utils.h" - -namespace testing { +#include "gmock/internal/gmock-port.h" // 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); +namespace testing { + // 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, @@ -91,6 +87,10 @@ GTEST_API_ void InitGoogleMock(int* argc, char** argv); // 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_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_ diff --git a/contrib/googletest/googlemock/include/gmock/internal/custom/README.md b/contrib/googletest/googlemock/include/gmock/internal/custom/README.md index f6c93f616d62..9c4874fd0cb3 100644 --- a/contrib/googletest/googlemock/include/gmock/internal/custom/README.md +++ b/contrib/googletest/googlemock/include/gmock/internal/custom/README.md @@ -14,3 +14,5 @@ The following macros can be defined: * `GMOCK_DEFINE_bool_(name, default_val, doc)` * `GMOCK_DEFINE_int32_(name, default_val, doc)` * `GMOCK_DEFINE_string_(name, default_val, doc)` +* `GMOCK_FLAG_GET(flag_name)` +* `GMOCK_FLAG_SET(flag_name, value)` diff --git a/contrib/googletest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h b/contrib/googletest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h index 92d910cf06df..bbcad31c76ef 100644 --- a/contrib/googletest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h +++ b/contrib/googletest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h @@ -1,10 +1,7 @@ -// This file was GENERATED by command: -// pump.py gmock-generated-actions.h.pump -// DO NOT EDIT BY HAND!!! +// IWYU pragma: private, include "gmock/gmock.h" +// IWYU pragma: friend gmock/.* -// GOOGLETEST_CM0002 DO NOT DELETE +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ -#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ -#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ - -#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ diff --git a/contrib/googletest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h.pump b/contrib/googletest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h.pump deleted file mode 100644 index 67c221f14c72..000000000000 --- a/contrib/googletest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h.pump +++ /dev/null @@ -1,12 +0,0 @@ -$$ -*- 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/contrib/googletest/googlemock/include/gmock/internal/custom/gmock-matchers.h b/contrib/googletest/googlemock/include/gmock/internal/custom/gmock-matchers.h index 14aafaabe6b5..bb7dcbaa4cb2 100644 --- a/contrib/googletest/googlemock/include/gmock/internal/custom/gmock-matchers.h +++ b/contrib/googletest/googlemock/include/gmock/internal/custom/gmock-matchers.h @@ -26,11 +26,12 @@ // 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_ +// IWYU pragma: private, include "gmock/gmock.h" +// IWYU pragma: friend gmock/.* + +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ diff --git a/contrib/googletest/googlemock/include/gmock/internal/custom/gmock-port.h b/contrib/googletest/googlemock/include/gmock/internal/custom/gmock-port.h index 0030fe91118a..f055f7506b82 100644 --- a/contrib/googletest/googlemock/include/gmock/internal/custom/gmock-port.h +++ b/contrib/googletest/googlemock/include/gmock/internal/custom/gmock-port.h @@ -26,14 +26,15 @@ // 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 +// IWYU pragma: private, include "gmock/gmock.h" +// IWYU pragma: friend gmock/.* -#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ -#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ -#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ diff --git a/contrib/googletest/googlemock/include/gmock/internal/gmock-generated-internal-utils.h b/contrib/googletest/googlemock/include/gmock/internal/gmock-generated-internal-utils.h deleted file mode 100644 index eaa56be977ff..000000000000 --- a/contrib/googletest/googlemock/include/gmock/internal/gmock-generated-internal-utils.h +++ /dev/null @@ -1,287 +0,0 @@ -// This file was GENERATED by command: -// pump.py gmock-generated-internal-utils.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 contains template meta-programming utility classes needed -// for implementing Google Mock. - -// GOOGLETEST_CM0002 DO NOT DELETE - -#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_ -#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_ - -#include "gmock/internal/gmock-port.h" - -namespace testing { - -template <typename T> -class Matcher; - -namespace internal { - -// An IgnoredValue object can be implicitly constructed from ANY value. -// This is used in implementing the IgnoreResult(a) action. -class IgnoredValue { - public: - // This constructor template allows any value to be implicitly - // converted to IgnoredValue. The object has no data member and - // doesn't try to remember anything about the argument. We - // deliberately omit the 'explicit' keyword in order to allow the - // conversion to be implicit. - template <typename T> - IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit) -}; - -// MatcherTuple<T>::type is a tuple type where each field is a Matcher -// for the corresponding field in tuple type T. -template <typename Tuple> -struct MatcherTuple; - -template <> -struct MatcherTuple< ::testing::tuple<> > { - typedef ::testing::tuple< > type; -}; - -template <typename A1> -struct MatcherTuple< ::testing::tuple<A1> > { - typedef ::testing::tuple<Matcher<A1> > type; -}; - -template <typename A1, typename A2> -struct MatcherTuple< ::testing::tuple<A1, A2> > { - typedef ::testing::tuple<Matcher<A1>, Matcher<A2> > type; -}; - -template <typename A1, typename A2, typename A3> -struct MatcherTuple< ::testing::tuple<A1, A2, A3> > { - typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3> > type; -}; - -template <typename A1, typename A2, typename A3, typename A4> -struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4> > { - typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4> > - type; -}; - -template <typename A1, typename A2, typename A3, typename A4, typename A5> -struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5> > { - typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>, - Matcher<A5> > - type; -}; - -template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6> -struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6> > { - typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>, - Matcher<A5>, Matcher<A6> > - type; -}; - -template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6, typename A7> -struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7> > { - typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>, - Matcher<A5>, Matcher<A6>, Matcher<A7> > - type; -}; - -template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6, typename A7, typename A8> -struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8> > { - typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>, - Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8> > - type; -}; - -template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6, typename A7, typename A8, typename A9> -struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> > { - typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>, - Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, - Matcher<A9> > - type; -}; - -template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6, typename A7, typename A8, typename A9, typename A10> -struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9, - A10> > { - typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>, - Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, - Matcher<A9>, Matcher<A10> > - type; -}; - -// Template struct Function<F>, where F must be a function type, contains -// the following typedefs: -// -// Result: the function's return type. -// ArgumentN: the type of the N-th argument, where N starts with 1. -// 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 F> -struct Function; - -template <typename R> -struct Function<R()> { - typedef R Result; - typedef ::testing::tuple<> ArgumentTuple; - typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple; - typedef void MakeResultVoid(); - typedef IgnoredValue MakeResultIgnoredValue(); -}; - -template <typename R, typename A1> -struct Function<R(A1)> - : Function<R()> { - typedef A1 Argument1; - typedef ::testing::tuple<A1> ArgumentTuple; - typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple; - typedef void MakeResultVoid(A1); - typedef IgnoredValue MakeResultIgnoredValue(A1); -}; - -template <typename R, typename A1, typename A2> -struct Function<R(A1, A2)> - : Function<R(A1)> { - typedef A2 Argument2; - typedef ::testing::tuple<A1, A2> ArgumentTuple; - typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple; - typedef void MakeResultVoid(A1, A2); - typedef IgnoredValue MakeResultIgnoredValue(A1, A2); -}; - -template <typename R, typename A1, typename A2, typename A3> -struct Function<R(A1, A2, A3)> - : Function<R(A1, A2)> { - typedef A3 Argument3; - typedef ::testing::tuple<A1, A2, A3> ArgumentTuple; - typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple; - typedef void MakeResultVoid(A1, A2, A3); - typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3); -}; - -template <typename R, typename A1, typename A2, typename A3, typename A4> -struct Function<R(A1, A2, A3, A4)> - : Function<R(A1, A2, A3)> { - typedef A4 Argument4; - typedef ::testing::tuple<A1, A2, A3, A4> ArgumentTuple; - typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple; - typedef void MakeResultVoid(A1, A2, A3, A4); - typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4); -}; - -template <typename R, typename A1, typename A2, typename A3, typename A4, - typename A5> -struct Function<R(A1, A2, A3, A4, A5)> - : Function<R(A1, A2, A3, A4)> { - typedef A5 Argument5; - typedef ::testing::tuple<A1, A2, A3, A4, A5> ArgumentTuple; - typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple; - typedef void MakeResultVoid(A1, A2, A3, A4, A5); - typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5); -}; - -template <typename R, typename A1, typename A2, typename A3, typename A4, - typename A5, typename A6> -struct Function<R(A1, A2, A3, A4, A5, A6)> - : Function<R(A1, A2, A3, A4, A5)> { - typedef A6 Argument6; - typedef ::testing::tuple<A1, A2, A3, A4, A5, A6> ArgumentTuple; - typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple; - typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6); - typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6); -}; - -template <typename R, typename A1, typename A2, typename A3, typename A4, - typename A5, typename A6, typename A7> -struct Function<R(A1, A2, A3, A4, A5, A6, A7)> - : Function<R(A1, A2, A3, A4, A5, A6)> { - typedef A7 Argument7; - typedef ::testing::tuple<A1, A2, A3, A4, A5, A6, A7> ArgumentTuple; - typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple; - typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7); - typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7); -}; - -template <typename R, typename A1, typename A2, typename A3, typename A4, - typename A5, typename A6, typename A7, typename A8> -struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8)> - : Function<R(A1, A2, A3, A4, A5, A6, A7)> { - typedef A8 Argument8; - typedef ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8> ArgumentTuple; - typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple; - typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8); - typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8); -}; - -template <typename R, typename A1, typename A2, typename A3, typename A4, - typename A5, typename A6, typename A7, typename A8, typename A9> -struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> - : Function<R(A1, A2, A3, A4, A5, A6, A7, A8)> { - typedef A9 Argument9; - typedef ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> ArgumentTuple; - typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple; - typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8, A9); - typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8, - A9); -}; - -template <typename R, typename A1, typename A2, typename A3, typename A4, - typename A5, typename A6, typename A7, typename A8, typename A9, - typename A10> -struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> - : Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> { - typedef A10 Argument10; - typedef ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9, - A10> ArgumentTuple; - typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple; - typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); - typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8, - A9, A10); -}; - -} // namespace internal - -} // namespace testing - -#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_ diff --git a/contrib/googletest/googlemock/include/gmock/internal/gmock-generated-internal-utils.h.pump b/contrib/googletest/googlemock/include/gmock/internal/gmock-generated-internal-utils.h.pump deleted file mode 100644 index c10327988f18..000000000000 --- a/contrib/googletest/googlemock/include/gmock/internal/gmock-generated-internal-utils.h.pump +++ /dev/null @@ -1,137 +0,0 @@ -$$ -*- mode: c++; -*- -$$ This is a Pump source file. Please use Pump to convert it to -$$ gmock-generated-function-mockers.h. -$$ -$var n = 10 $$ The maximum arity we support. -// 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 contains template meta-programming utility classes needed -// for implementing Google Mock. - -// GOOGLETEST_CM0002 DO NOT DELETE - -#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_ -#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_ - -#include "gmock/internal/gmock-port.h" - -namespace testing { - -template <typename T> -class Matcher; - -namespace internal { - -// An IgnoredValue object can be implicitly constructed from ANY value. -// This is used in implementing the IgnoreResult(a) action. -class IgnoredValue { - public: - // This constructor template allows any value to be implicitly - // converted to IgnoredValue. The object has no data member and - // doesn't try to remember anything about the argument. We - // deliberately omit the 'explicit' keyword in order to allow the - // conversion to be implicit. - template <typename T> - IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit) -}; - -// MatcherTuple<T>::type is a tuple type where each field is a Matcher -// for the corresponding field in tuple type T. -template <typename Tuple> -struct MatcherTuple; - - -$range i 0..n -$for i [[ -$range j 1..i -$var typename_As = [[$for j, [[typename A$j]]]] -$var As = [[$for j, [[A$j]]]] -$var matcher_As = [[$for j, [[Matcher<A$j>]]]] -template <$typename_As> -struct MatcherTuple< ::testing::tuple<$As> > { - typedef ::testing::tuple<$matcher_As > type; -}; - - -]] -// Template struct Function<F>, where F must be a function type, contains -// the following typedefs: -// -// Result: the function's return type. -// ArgumentN: the type of the N-th argument, where N starts with 1. -// 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 F> -struct Function; - -template <typename R> -struct Function<R()> { - typedef R Result; - typedef ::testing::tuple<> ArgumentTuple; - typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple; - typedef void MakeResultVoid(); - typedef IgnoredValue MakeResultIgnoredValue(); -}; - - -$range i 1..n -$for i [[ -$range j 1..i -$var typename_As = [[$for j [[, typename A$j]]]] -$var As = [[$for j, [[A$j]]]] -$var matcher_As = [[$for j, [[Matcher<A$j>]]]] -$range k 1..i-1 -$var prev_As = [[$for k, [[A$k]]]] -template <typename R$typename_As> -struct Function<R($As)> - : Function<R($prev_As)> { - typedef A$i Argument$i; - typedef ::testing::tuple<$As> ArgumentTuple; - typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple; - typedef void MakeResultVoid($As); - typedef IgnoredValue MakeResultIgnoredValue($As); -}; - - -]] -} // namespace internal - -} // namespace testing - -#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_ diff --git a/contrib/googletest/googlemock/include/gmock/internal/gmock-internal-utils.h b/contrib/googletest/googlemock/include/gmock/internal/gmock-internal-utils.h index 989b804acf32..ead6d7c805e9 100644 --- a/contrib/googletest/googlemock/include/gmock/internal/gmock-internal-utils.h +++ b/contrib/googletest/googlemock/include/gmock/internal/gmock-internal-utils.h @@ -27,39 +27,43 @@ // (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 +// IWYU pragma: private, include "gmock/gmock.h" +// IWYU pragma: friend gmock/.* -#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ -#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ #include <stdio.h> + #include <ostream> // NOLINT #include <string> -#include "gmock/internal/gmock-generated-internal-utils.h" +#include <type_traits> +#include <vector> + #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 +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100 4805) // 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); +GTEST_API_ std::string JoinAsKeyValueTuple( + const std::vector<const char*>& names, const Strings& values); // 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 @@ -67,20 +71,6 @@ GTEST_API_ std::string JoinAsTuple(const Strings& fields); // "foo_bar_123" are converted to "foo bar 123". GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name); -// PointeeOf<Pointer>::type is the type of a value pointed to by a -// Pointer, which can be either a smart pointer or a raw pointer. The -// following default implementation is for the case where Pointer is a -// smart pointer. -template <typename Pointer> -struct PointeeOf { - // Smart pointer classes define type element_type as the type of - // their pointees. - typedef typename Pointer::element_type type; -}; -// This specialization is for the raw pointer case. -template <typename T> -struct PointeeOf<T*> { typedef T type; }; // NOLINT - // 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. @@ -88,51 +78,45 @@ template <typename Pointer> inline const typename Pointer::element_type* GetRawPointer(const Pointer& p) { return p.get(); } +// This overload version is for std::reference_wrapper, which does not work with +// the overload above, as it does not have an `element_type`. +template <typename Element> +inline const Element* GetRawPointer(const std::reference_wrapper<Element>& r) { + return &r.get(); +} + // This overloaded version is for the raw pointer case. template <typename Element> -inline Element* GetRawPointer(Element* p) { return p; } +inline Element* GetRawPointer(Element* p) { + return p; +} -// This comparator allows linked_ptr to be stored in sets. -template <typename T> -struct LinkedPtrLessThan { - bool operator()(const ::testing::internal::linked_ptr<T>& lhs, - const ::testing::internal::linked_ptr<T>& rhs) const { - return lhs.get() < rhs.get(); - } -}; +// Default definitions for all compilers. +// NOTE: If you implement support for other compilers, make sure to avoid +// unexpected overlaps. +// (e.g., Clang also processes #pragma GCC, and clang-cl also handles _MSC_VER.) +#define GMOCK_INTERNAL_WARNING_PUSH() +#define GMOCK_INTERNAL_WARNING_CLANG(Level, Name) +#define GMOCK_INTERNAL_WARNING_POP() + +#if defined(__clang__) +#undef GMOCK_INTERNAL_WARNING_PUSH +#define GMOCK_INTERNAL_WARNING_PUSH() _Pragma("clang diagnostic push") +#undef GMOCK_INTERNAL_WARNING_CLANG +#define GMOCK_INTERNAL_WARNING_CLANG(Level, Warning) \ + _Pragma(GMOCK_PP_INTERNAL_STRINGIZE(clang diagnostic Level Warning)) +#undef GMOCK_INTERNAL_WARNING_POP +#define GMOCK_INTERNAL_WARNING_POP() _Pragma("clang diagnostic pop") +#endif -// Symbian compilation can be done with wchar_t being either a native -// type or a typedef. Using Google Mock with OpenC without wchar_t -// should require the definition of _STLP_NO_WCHAR_T. -// // 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 (GTEST_OS_SYMBIAN && defined(_STLP_NO_WCHAR_T)) || \ - (defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED)) +#if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED) // wchar_t is a typedef. #else -# define GMOCK_WCHAR_T_IS_NATIVE_ 1 -#endif - -// signed wchar_t and unsigned wchar_t are NOT in the C++ standard. -// Using them is a bad practice and not portable. So DON'T use them. -// -// Still, Google Mock is designed to work even if the user uses signed -// wchar_t or unsigned wchar_t (obviously, assuming the compiler -// supports them). -// -// To gcc, -// wchar_t == signed wchar_t != unsigned wchar_t == unsigned int -// -// gcc-9 appears to treat signed/unsigned wchar_t as ill-formed -// regardless of the signage of its underlying type. -#ifdef __GNUC__ -#if !defined(__WCHAR_UNSIGNED__) && (__GNUC__ < 9) -// signed/unsigned wchar_t are valid types. -# define GMOCK_HAS_SIGNED_WCHAR_T_ 1 -#endif +#define GMOCK_WCHAR_T_IS_NATIVE_ 1 #endif // In what follows, we use the term "kind" to indicate whether a type @@ -140,18 +124,20 @@ struct LinkedPtrLessThan { // 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 -}; +enum TypeKind { kBool, kInteger, kFloatingPoint, kOther }; // KindOf<T>::value is the kind of type T. -template <typename T> struct KindOf { +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 }; } + template <> \ + struct KindOf<type> { \ + enum { value = kind }; \ + } GMOCK_DECLARE_KIND_(bool, kBool); @@ -159,21 +145,19 @@ GMOCK_DECLARE_KIND_(bool, kBool); 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_(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, 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 -// Non-standard integer types. -GMOCK_DECLARE_KIND_(Int64, kInteger); -GMOCK_DECLARE_KIND_(UInt64, kInteger); - // All standard floating-point types. GMOCK_DECLARE_KIND_(float, kFloatingPoint); GMOCK_DECLARE_KIND_(double, kFloatingPoint); @@ -182,15 +166,12 @@ GMOCK_DECLARE_KIND_(long double, kFloatingPoint); #undef GMOCK_DECLARE_KIND_ // Evaluates to the kind of 'type'. -#define GMOCK_KIND_OF_(type) \ +#define GMOCK_KIND_OF_(type) \ static_cast< ::testing::internal::TypeKind>( \ ::testing::internal::KindOf<type>::value) -// Evaluates to true iff integer type T is signed. -#define GMOCK_IS_SIGNED_(T) (static_cast<T>(-1) < 0) - // LosslessArithmeticConvertibleImpl<kFromKind, From, kToKind, To>::value -// is true iff arithmetic type From can be losslessly converted to +// 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 @@ -199,88 +180,51 @@ GMOCK_DECLARE_KIND_(long double, kFloatingPoint); // 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> -struct LosslessArithmeticConvertibleImpl : public false_type {}; - -// Converting bool to bool is lossless. -template <> -struct LosslessArithmeticConvertibleImpl<kBool, bool, kBool, bool> - : public true_type {}; // NOLINT - -// Converting bool to any integer type is lossless. -template <typename To> -struct LosslessArithmeticConvertibleImpl<kBool, bool, kInteger, To> - : public true_type {}; // NOLINT - -// Converting bool to any floating-point type is lossless. -template <typename To> -struct LosslessArithmeticConvertibleImpl<kBool, bool, kFloatingPoint, To> - : public true_type {}; // NOLINT - -// Converting an integer to bool is lossy. -template <typename From> -struct LosslessArithmeticConvertibleImpl<kInteger, From, kBool, bool> - : public false_type {}; // NOLINT - -// Converting an integer to another non-bool integer is lossless iff -// the target type's range encloses the source type's range. -template <typename From, typename To> -struct LosslessArithmeticConvertibleImpl<kInteger, From, kInteger, To> - : public bool_constant< - // When converting from a smaller size to a larger size, we are - // fine as long as we are not converting from signed to unsigned. - ((sizeof(From) < sizeof(To)) && - (!GMOCK_IS_SIGNED_(From) || GMOCK_IS_SIGNED_(To))) || - // When converting between the same size, the signedness must match. - ((sizeof(From) == sizeof(To)) && - (GMOCK_IS_SIGNED_(From) == GMOCK_IS_SIGNED_(To)))> {}; // NOLINT - -#undef GMOCK_IS_SIGNED_ - -// Converting an integer to a floating-point type may be lossy, since -// the format of a floating-point number is implementation-defined. -template <typename From, typename To> -struct LosslessArithmeticConvertibleImpl<kInteger, From, kFloatingPoint, To> - : public false_type {}; // NOLINT - -// Converting a floating-point to bool is lossy. -template <typename From> -struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kBool, bool> - : public false_type {}; // NOLINT - -// Converting a floating-point to an integer is lossy. -template <typename From, typename To> -struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kInteger, To> - : public false_type {}; // NOLINT - -// Converting a floating-point to another floating-point is lossless -// iff the target type is at least as big as the source type. -template <typename From, typename To> -struct LosslessArithmeticConvertibleImpl< - kFloatingPoint, From, kFloatingPoint, To> - : public bool_constant<sizeof(From) <= sizeof(To)> {}; // NOLINT - -// LosslessArithmeticConvertible<From, To>::value is true iff arithmetic -// type From can be losslessly converted to arithmetic type 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> -struct LosslessArithmeticConvertible - : public LosslessArithmeticConvertibleImpl< - GMOCK_KIND_OF_(From), From, GMOCK_KIND_OF_(To), To> {}; // NOLINT +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 - }; + enum FailureType { kNonfatal, kFatal }; - virtual ~FailureReporterInterface() {} + virtual ~FailureReporterInterface() = default; // Reports a failure that occurred at the given source file location. virtual void ReportFailure(FailureType type, const char* file, int line, @@ -298,8 +242,8 @@ GTEST_API_ FailureReporterInterface* GetFailureReporter(); inline void Assert(bool condition, const char* file, int line, const std::string& msg) { if (!condition) { - GetFailureReporter()->ReportFailure(FailureReporterInterface::kFatal, - file, line, msg); + GetFailureReporter()->ReportFailure(FailureReporterInterface::kFatal, file, + line, msg); } } inline void Assert(bool condition, const char* file, int line) { @@ -320,10 +264,7 @@ inline void Expect(bool condition, const char* file, int line) { } // Severity level of a log. -enum LogSeverity { - kInfo = 0, - kWarning = 1 -}; +enum LogSeverity { kInfo = 0, kWarning = 1 }; // Valid values for the --gmock_verbose flag. @@ -334,11 +275,11 @@ const char kWarningVerbosity[] = "warning"; // No logs are printed. const char kErrorVerbosity[] = "error"; -// Returns true iff a log with the given severity is visible according -// to the --gmock_verbose flag. +// 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 iff 'severity' >= the level +// 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 @@ -363,42 +304,6 @@ class WithoutMatchers { // Internal use only: access the singleton instance of WithoutMatchers. GTEST_API_ WithoutMatchers GetWithoutMatchers(); -// FIXME: group all type utilities together. - -// Type traits. - -// is_reference<T>::value is non-zero iff T is a reference type. -template <typename T> struct is_reference : public false_type {}; -template <typename T> struct is_reference<T&> : public true_type {}; - -// type_equals<T1, T2>::value is non-zero iff T1 and T2 are the same type. -template <typename T1, typename T2> struct type_equals : public false_type {}; -template <typename T> struct type_equals<T, T> : public true_type {}; - -// remove_reference<T>::type removes the reference from type T, if any. -template <typename T> struct remove_reference { typedef T type; }; // NOLINT -template <typename T> struct remove_reference<T&> { typedef T type; }; // NOLINT - -// DecayArray<T>::type turns an array type U[N] to const U* and preserves -// other types. Useful for saving a copy of a function argument. -template <typename T> struct DecayArray { typedef T type; }; // NOLINT -template <typename T, size_t N> struct DecayArray<T[N]> { - typedef const T* type; -}; -// Sometimes people use arrays whose size is not available at the use site -// (e.g. extern const char kNamePrefix[]). This specialization covers that -// case. -template <typename T> struct DecayArray<T[]> { - typedef const T* type; -}; - -// 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 @@ -406,16 +311,16 @@ template <typename T> struct DecayArray<T[]> { // 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. + Assert(/*condition=*/false, /*file=*/"", /*line=*/-1, + "Internal error: attempt to return invalid value"); +#if defined(__GNUC__) || defined(__clang__) + __builtin_unreachable(); +#elif defined(_MSC_VER) + __assume(0); +#else 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 @@ -440,9 +345,8 @@ class StlContainerView { typedef const type& const_reference; static const_reference ConstReference(const RawContainer& container) { - // Ensures that RawContainer is not a const type. - testing::StaticAssertTypeEq<RawContainer, - GTEST_REMOVE_CONST_(RawContainer)>(); + static_assert(!std::is_const<RawContainer>::value, + "RawContainer type must not be const"); return container; } static type Copy(const RawContainer& container) { return container; } @@ -452,7 +356,7 @@ class StlContainerView { template <typename Element, size_t N> class StlContainerView<Element[N]> { public: - typedef GTEST_REMOVE_CONST_(Element) RawElement; + 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' @@ -462,59 +366,40 @@ class StlContainerView<Element[N]> { typedef const type const_reference; static const_reference ConstReference(const Element (&array)[N]) { - // Ensures that Element is not a const type. - testing::StaticAssertTypeEq<Element, RawElement>(); -#if GTEST_OS_SYMBIAN - // The Nokia Symbian compiler confuses itself in template instantiation - // for this call without the cast to Element*: - // function call '[testing::internal::NativeArray<char *>].NativeArray( - // {lval} const char *[4], long, testing::internal::RelationToSource)' - // does not match - // 'testing::internal::NativeArray<char *>::NativeArray( - // char *const *, unsigned int, testing::internal::RelationToSource)' - // (instantiating: 'testing::internal::ContainsMatcherImpl - // <const char * (&)[4]>::Matches(const char * (&)[4]) const') - // (instantiating: 'testing::internal::StlContainerView<char *[4]>:: - // ConstReference(const char * (&)[4])') - // (and though the N parameter type is mismatched in the above explicit - // conversion of it doesn't help - only the conversion of the array). - return type(const_cast<Element*>(&array[0]), N, - RelationToSourceReference()); -#else + static_assert(std::is_same<Element, RawElement>::value, + "Element type must not be const"); return type(array, N, RelationToSourceReference()); -#endif // GTEST_OS_SYMBIAN } static type Copy(const Element (&array)[N]) { -#if GTEST_OS_SYMBIAN - return type(const_cast<Element*>(&array[0]), N, RelationToSourceCopy()); -#else return type(array, N, RelationToSourceCopy()); -#endif // GTEST_OS_SYMBIAN } }; // This specialization is used when RawContainer is a native array // represented as a (pointer, size) tuple. template <typename ElementPointer, typename Size> -class StlContainerView< ::testing::tuple<ElementPointer, Size> > { +class StlContainerView< ::std::tuple<ElementPointer, Size> > { public: - typedef GTEST_REMOVE_CONST_( - typename internal::PointeeOf<ElementPointer>::type) RawElement; + 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 ::testing::tuple<ElementPointer, Size>& array) { - return type(get<0>(array), get<1>(array), RelationToSourceReference()); + const ::std::tuple<ElementPointer, Size>& array) { + return type(std::get<0>(array), std::get<1>(array), + RelationToSourceReference()); } - static type Copy(const ::testing::tuple<ElementPointer, Size>& array) { - return type(get<0>(array), get<1>(array), RelationToSourceCopy()); + 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&>; +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, @@ -530,49 +415,73 @@ struct RemoveConstFromKey<std::pair<const K, V> > { typedef std::pair<K, V> type; }; -// Mapping from booleans to types. Similar to boost::bool_<kValue> and -// std::integral_constant<bool, kValue>. -template <bool kValue> -struct BooleanConstant {}; - // 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); -#if GTEST_LANG_CXX11 -// Helper types for Apply() below. -template <size_t... Is> struct int_pack { typedef int_pack type; }; - -template <class Pack, size_t I> struct append; -template <size_t... Is, size_t I> -struct append<int_pack<Is...>, I> : int_pack<Is..., I> {}; - -template <size_t C> -struct make_int_pack : append<typename make_int_pack<C - 1>::type, C - 1> {}; -template <> struct make_int_pack<0> : int_pack<> {}; - template <typename F, typename Tuple, size_t... Idx> -auto ApplyImpl(F&& f, Tuple&& args, int_pack<Idx...>) -> decltype( - std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...)) { +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), - make_int_pack<std::tuple_size<Tuple>::value>())) { +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), - make_int_pack<std::tuple_size<Tuple>::value>()); + MakeIndexSequence<std::tuple_size< + typename std::remove_reference<Tuple>::type>::value>()); } -#endif +// 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...); +}; -#ifdef _MSC_VER -# pragma warning(pop) +#ifdef GTEST_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL +template <typename R, typename... Args> +constexpr size_t Function<R(Args...)>::ArgumentCount; #endif +// Workaround for MSVC error C2039: 'type': is not a member of 'std' +// when std::tuple_element is used. +// See: https://github.com/google/googletest/issues/3931 +// Can be replaced with std::tuple_element_t in C++14. +template <size_t I, typename T> +using TupleElement = typename std::tuple_element<I, T>::type; + +bool Base64Unescape(const std::string& encoded, std::string* decoded); + +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100 4805 + } // namespace internal } // namespace testing -#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ diff --git a/contrib/googletest/googlemock/include/gmock/internal/gmock-port.h b/contrib/googletest/googlemock/include/gmock/internal/gmock-port.h index fda27dbae482..55ddfb6c6a3b 100644 --- a/contrib/googletest/googlemock/include/gmock/internal/gmock-port.h +++ b/contrib/googletest/googlemock/include/gmock/internal/gmock-port.h @@ -27,7 +27,6 @@ // (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 @@ -35,13 +34,15 @@ // end with _ are part of Google Mock's public API and can be used by // code outside Google Mock. -// GOOGLETEST_CM0002 DO NOT DELETE +// IWYU pragma: private, include "gmock/gmock.h" +// IWYU pragma: friend gmock/.* -#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ -#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ +#define GOOGLEMOCK_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 @@ -52,37 +53,87 @@ // 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-linked_ptr.h" -#include "gtest/internal/gtest-port.h" #include "gmock/internal/custom/gmock-port.h" +#include "gtest/internal/gtest-port.h" -// For MS Visual C++, check the compiler version. At least VS 2003 is +#ifdef GTEST_HAS_ABSL +#include "absl/flags/declare.h" +#include "absl/flags/flag.h" +#endif + +// For MS Visual C++, check the compiler version. At least VS 2015 is // required to compile Google Mock. -#if defined(_MSC_VER) && _MSC_VER < 1310 -# error "At least Visual C++ 2003 (7.1) 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_(name) gmock_##name #define GMOCK_FLAG(name) FLAGS_gmock_##name -#if !defined(GMOCK_DECLARE_bool_) +// Pick a command line flags implementation. +#ifdef GTEST_HAS_ABSL + +// Macros for defining flags. +#define GMOCK_DEFINE_bool_(name, default_val, doc) \ + ABSL_FLAG(bool, GMOCK_FLAG_NAME_(name), default_val, doc) +#define GMOCK_DEFINE_int32_(name, default_val, doc) \ + ABSL_FLAG(int32_t, GMOCK_FLAG_NAME_(name), default_val, doc) +#define GMOCK_DEFINE_string_(name, default_val, doc) \ + ABSL_FLAG(std::string, GMOCK_FLAG_NAME_(name), default_val, doc) // Macros for declaring flags. -# define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name) -# define GMOCK_DECLARE_int32_(name) \ - extern GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) -# define GMOCK_DECLARE_string_(name) \ - extern GTEST_API_ ::std::string GMOCK_FLAG(name) +#define GMOCK_DECLARE_bool_(name) \ + ABSL_DECLARE_FLAG(bool, GMOCK_FLAG_NAME_(name)) +#define GMOCK_DECLARE_int32_(name) \ + ABSL_DECLARE_FLAG(int32_t, GMOCK_FLAG_NAME_(name)) +#define GMOCK_DECLARE_string_(name) \ + ABSL_DECLARE_FLAG(std::string, GMOCK_FLAG_NAME_(name)) + +#define GMOCK_FLAG_GET(name) ::absl::GetFlag(GMOCK_FLAG(name)) +#define GMOCK_FLAG_SET(name, value) \ + (void)(::absl::SetFlag(&GMOCK_FLAG(name), value)) + +#else // GTEST_HAS_ABSL // 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_ ::testing::internal::Int32 GMOCK_FLAG(name) = (default_val) -# define GMOCK_DEFINE_string_(name, default_val, doc) \ - GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val) +#define GMOCK_DEFINE_bool_(name, default_val, doc) \ + namespace testing { \ + GTEST_API_ bool GMOCK_FLAG(name) = (default_val); \ + } \ + static_assert(true, "no-op to require trailing semicolon") +#define GMOCK_DEFINE_int32_(name, default_val, doc) \ + namespace testing { \ + GTEST_API_ int32_t GMOCK_FLAG(name) = (default_val); \ + } \ + static_assert(true, "no-op to require trailing semicolon") +#define GMOCK_DEFINE_string_(name, default_val, doc) \ + namespace testing { \ + GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val); \ + } \ + static_assert(true, "no-op to require trailing semicolon") + +// Macros for declaring flags. +#define GMOCK_DECLARE_bool_(name) \ + namespace testing { \ + GTEST_API_ extern bool GMOCK_FLAG(name); \ + } \ + static_assert(true, "no-op to require trailing semicolon") +#define GMOCK_DECLARE_int32_(name) \ + namespace testing { \ + GTEST_API_ extern int32_t GMOCK_FLAG(name); \ + } \ + static_assert(true, "no-op to require trailing semicolon") +#define GMOCK_DECLARE_string_(name) \ + namespace testing { \ + GTEST_API_ extern ::std::string GMOCK_FLAG(name); \ + } \ + static_assert(true, "no-op to require trailing semicolon") + +#define GMOCK_FLAG_GET(name) ::testing::GMOCK_FLAG(name) +#define GMOCK_FLAG_SET(name, value) (void)(::testing::GMOCK_FLAG(name) = value) -#endif // !defined(GMOCK_DECLARE_bool_) +#endif // GTEST_HAS_ABSL -#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ diff --git a/contrib/googletest/googlemock/include/gmock/internal/gmock-pp.h b/contrib/googletest/googlemock/include/gmock/internal/gmock-pp.h new file mode 100644 index 000000000000..94d61c09c870 --- /dev/null +++ b/contrib/googletest/googlemock/include/gmock/internal/gmock-pp.h @@ -0,0 +1,279 @@ +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_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 // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_ diff --git a/contrib/googletest/googlemock/make/Makefile b/contrib/googletest/googlemock/make/Makefile deleted file mode 100644 index 7c13e05fa961..000000000000 --- a/contrib/googletest/googlemock/make/Makefile +++ /dev/null @@ -1,101 +0,0 @@ -# A sample Makefile for building both Google Mock and Google Test and -# using them in user tests. This file is self-contained, so you don't -# need to use the Makefile in Google Test's source tree. Please tweak -# it to suit your environment and project. You may want to move it to -# your project's root directory. -# -# SYNOPSIS: -# -# make [all] - makes everything. -# make TARGET - makes the given target. -# make clean - removes all files generated by make. - -# Please tweak the following variable definitions as needed by your -# project, except GMOCK_HEADERS and GTEST_HEADERS, which you can use -# in your own targets but shouldn't modify. - -# Points to the root of Google Test, relative to where this file is. -# Remember to tweak this if you move this file, or if you want to use -# a copy of Google Test at a different location. -GTEST_DIR = ../../googletest - -# Points to the root of Google Mock, relative to where this file is. -# Remember to tweak this if you move this file. -GMOCK_DIR = .. - -# Where to find user code. -USER_DIR = ../test - -# Flags passed to the preprocessor. -# Set Google Test and Google Mock's header directories as system -# directories, such that the compiler doesn't generate warnings in -# these headers. -CPPFLAGS += -isystem $(GTEST_DIR)/include -isystem $(GMOCK_DIR)/include - -# Flags passed to the C++ compiler. -CXXFLAGS += -g -Wall -Wextra -pthread - -# All tests produced by this Makefile. Remember to add new tests you -# created to the list. -TESTS = gmock_test - -# All Google Test headers. Usually you shouldn't change this -# definition. -GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \ - $(GTEST_DIR)/include/gtest/internal/*.h - -# All Google Mock headers. Note that all Google Test headers are -# included here too, as they are #included by Google Mock headers. -# Usually you shouldn't change this definition. -GMOCK_HEADERS = $(GMOCK_DIR)/include/gmock/*.h \ - $(GMOCK_DIR)/include/gmock/internal/*.h \ - $(GTEST_HEADERS) - -# House-keeping build targets. - -all : $(TESTS) - -clean : - rm -f $(TESTS) gmock.a gmock_main.a *.o - -# Builds gmock.a and gmock_main.a. These libraries contain both -# Google Mock and Google Test. A test should link with either gmock.a -# or gmock_main.a, depending on whether it defines its own main() -# function. It's fine if your test only uses features from Google -# Test (and not Google Mock). - -# Usually you shouldn't tweak such internal variables, indicated by a -# trailing _. -GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS) -GMOCK_SRCS_ = $(GMOCK_DIR)/src/*.cc $(GMOCK_HEADERS) - -# For simplicity and to avoid depending on implementation details of -# Google Mock and Google Test, the dependencies specified below are -# conservative and not optimized. This is fine as Google Mock and -# Google Test compile fast and for ordinary users their source rarely -# changes. -gtest-all.o : $(GTEST_SRCS_) - $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GMOCK_DIR) $(CXXFLAGS) \ - -c $(GTEST_DIR)/src/gtest-all.cc - -gmock-all.o : $(GMOCK_SRCS_) - $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GMOCK_DIR) $(CXXFLAGS) \ - -c $(GMOCK_DIR)/src/gmock-all.cc - -gmock_main.o : $(GMOCK_SRCS_) - $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GMOCK_DIR) $(CXXFLAGS) \ - -c $(GMOCK_DIR)/src/gmock_main.cc - -gmock.a : gmock-all.o gtest-all.o - $(AR) $(ARFLAGS) $@ $^ - -gmock_main.a : gmock-all.o gtest-all.o gmock_main.o - $(AR) $(ARFLAGS) $@ $^ - -# Builds a sample test. - -gmock_test.o : $(USER_DIR)/gmock_test.cc $(GMOCK_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/gmock_test.cc - -gmock_test : gmock_test.o gmock_main.a - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ diff --git a/contrib/googletest/googlemock/msvc/2005/gmock.sln b/contrib/googletest/googlemock/msvc/2005/gmock.sln deleted file mode 100644 index b752f876b319..000000000000 --- a/contrib/googletest/googlemock/msvc/2005/gmock.sln +++ /dev/null @@ -1,32 +0,0 @@ -
-Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual Studio 2005
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmock", "gmock.vcproj", "{34681F0D-CE45-415D-B5F2-5C662DFE3BD5}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmock_test", "gmock_test.vcproj", "{F10D22F8-AC7B-4213-8720-608E7D878CD2}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmock_main", "gmock_main.vcproj", "{E4EF614B-30DF-4954-8C53-580A0BF6B589}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- Release|Win32 = Release|Win32
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {34681F0D-CE45-415D-B5F2-5C662DFE3BD5}.Debug|Win32.ActiveCfg = Debug|Win32
- {34681F0D-CE45-415D-B5F2-5C662DFE3BD5}.Debug|Win32.Build.0 = Debug|Win32
- {34681F0D-CE45-415D-B5F2-5C662DFE3BD5}.Release|Win32.ActiveCfg = Release|Win32
- {34681F0D-CE45-415D-B5F2-5C662DFE3BD5}.Release|Win32.Build.0 = Release|Win32
- {F10D22F8-AC7B-4213-8720-608E7D878CD2}.Debug|Win32.ActiveCfg = Debug|Win32
- {F10D22F8-AC7B-4213-8720-608E7D878CD2}.Debug|Win32.Build.0 = Debug|Win32
- {F10D22F8-AC7B-4213-8720-608E7D878CD2}.Release|Win32.ActiveCfg = Release|Win32
- {F10D22F8-AC7B-4213-8720-608E7D878CD2}.Release|Win32.Build.0 = Release|Win32
- {E4EF614B-30DF-4954-8C53-580A0BF6B589}.Debug|Win32.ActiveCfg = Debug|Win32
- {E4EF614B-30DF-4954-8C53-580A0BF6B589}.Debug|Win32.Build.0 = Debug|Win32
- {E4EF614B-30DF-4954-8C53-580A0BF6B589}.Release|Win32.ActiveCfg = Release|Win32
- {E4EF614B-30DF-4954-8C53-580A0BF6B589}.Release|Win32.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/contrib/googletest/googlemock/msvc/2005/gmock.vcproj b/contrib/googletest/googlemock/msvc/2005/gmock.vcproj deleted file mode 100644 index 4bbfe9899794..000000000000 --- a/contrib/googletest/googlemock/msvc/2005/gmock.vcproj +++ /dev/null @@ -1,191 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="gmock"
- ProjectGUID="{34681F0D-CE45-415D-B5F2-5C662DFE3BD5}"
- RootNamespace="gmock"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(OutDir)\$(ProjectName)"
- ConfigurationType="4"
- InheritedPropertySheets=".\gmock_config.vsprops"
- CharacterSet="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\include;..\.."
- PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(OutDir)\$(ProjectName)"
- ConfigurationType="4"
- InheritedPropertySheets=".\gmock_config.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\include;..\.."
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
- RuntimeLibrary="0"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\..\src\gmock-all.cc"
- >
- </File>
- <File
- RelativePath="$(GTestDir)\src\gtest-all.cc"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="$(GTestDir)"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="$(GTestDir)"
- />
- </FileConfiguration>
- </File>
- </Filter>
- <Filter
- Name="Public Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- </Filter>
- <Filter
- Name="Private Header Files"
- >
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/contrib/googletest/googlemock/msvc/2005/gmock_config.vsprops b/contrib/googletest/googlemock/msvc/2005/gmock_config.vsprops deleted file mode 100644 index 875939c18373..000000000000 --- a/contrib/googletest/googlemock/msvc/2005/gmock_config.vsprops +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="gmock_config"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""$(GTestDir)/include""
- />
- <UserMacro
- Name="GTestDir"
- Value="../../../googletest"
- />
-</VisualStudioPropertySheet>
diff --git a/contrib/googletest/googlemock/msvc/2005/gmock_main.vcproj b/contrib/googletest/googlemock/msvc/2005/gmock_main.vcproj deleted file mode 100644 index 01505a9312b2..000000000000 --- a/contrib/googletest/googlemock/msvc/2005/gmock_main.vcproj +++ /dev/null @@ -1,187 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="gmock_main"
- ProjectGUID="{E4EF614B-30DF-4954-8C53-580A0BF6B589}"
- RootNamespace="gmock_main"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(OutDir)\$(ProjectName)"
- ConfigurationType="4"
- InheritedPropertySheets=".\gmock_config.vsprops"
- CharacterSet="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="../../include"
- PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(OutDir)\$(ProjectName)"
- ConfigurationType="4"
- InheritedPropertySheets=".\gmock_config.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="../../include"
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
- RuntimeLibrary="0"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- <ProjectReference
- ReferencedProjectIdentifier="{34681F0D-CE45-415D-B5F2-5C662DFE3BD5}"
- RelativePathToProject=".\gmock.vcproj"
- />
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\..\src\gmock_main.cc"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="../../include"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="../../include"
- />
- </FileConfiguration>
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/contrib/googletest/googlemock/msvc/2005/gmock_test.vcproj b/contrib/googletest/googlemock/msvc/2005/gmock_test.vcproj deleted file mode 100644 index d1e01e71a8a0..000000000000 --- a/contrib/googletest/googlemock/msvc/2005/gmock_test.vcproj +++ /dev/null @@ -1,201 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="gmock_test"
- ProjectGUID="{F10D22F8-AC7B-4213-8720-608E7D878CD2}"
- RootNamespace="gmock_test"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(OutDir)\$(ProjectName)"
- ConfigurationType="1"
- InheritedPropertySheets=".\gmock_config.vsprops"
- CharacterSet="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions="/bigobj"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\include;..\.."
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- LinkIncremental="2"
- GenerateDebugInformation="true"
- SubSystem="1"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(OutDir)\$(ProjectName)"
- ConfigurationType="1"
- InheritedPropertySheets=".\gmock_config.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions="/bigobj"
- AdditionalIncludeDirectories="..\..\include;..\.."
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
- RuntimeLibrary="0"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- LinkIncremental="1"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- <ProjectReference
- ReferencedProjectIdentifier="{E4EF614B-30DF-4954-8C53-580A0BF6B589}"
- RelativePathToProject=".\gmock_main.vcproj"
- />
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\..\test\gmock_all_test.cc"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/contrib/googletest/googlemock/msvc/2010/gmock.sln b/contrib/googletest/googlemock/msvc/2010/gmock.sln deleted file mode 100644 index bb48f5be0315..000000000000 --- a/contrib/googletest/googlemock/msvc/2010/gmock.sln +++ /dev/null @@ -1,46 +0,0 @@ -
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual C++ Express 2010
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmock", "gmock.vcxproj", "{34681F0D-CE45-415D-B5F2-5C662DFE3BD5}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmock_test", "gmock_test.vcxproj", "{F10D22F8-AC7B-4213-8720-608E7D878CD2}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmock_main", "gmock_main.vcxproj", "{E4EF614B-30DF-4954-8C53-580A0BF6B589}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- Debug|x64 = Debug|x64
- Release|Win32 = Release|Win32
- Release|x64 = Release|x64
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {34681F0D-CE45-415D-B5F2-5C662DFE3BD5}.Debug|Win32.ActiveCfg = Debug|Win32
- {34681F0D-CE45-415D-B5F2-5C662DFE3BD5}.Debug|Win32.Build.0 = Debug|Win32
- {34681F0D-CE45-415D-B5F2-5C662DFE3BD5}.Debug|x64.ActiveCfg = Debug|x64
- {34681F0D-CE45-415D-B5F2-5C662DFE3BD5}.Debug|x64.Build.0 = Debug|x64
- {34681F0D-CE45-415D-B5F2-5C662DFE3BD5}.Release|Win32.ActiveCfg = Release|Win32
- {34681F0D-CE45-415D-B5F2-5C662DFE3BD5}.Release|Win32.Build.0 = Release|Win32
- {34681F0D-CE45-415D-B5F2-5C662DFE3BD5}.Release|x64.ActiveCfg = Release|x64
- {34681F0D-CE45-415D-B5F2-5C662DFE3BD5}.Release|x64.Build.0 = Release|x64
- {F10D22F8-AC7B-4213-8720-608E7D878CD2}.Debug|Win32.ActiveCfg = Debug|Win32
- {F10D22F8-AC7B-4213-8720-608E7D878CD2}.Debug|Win32.Build.0 = Debug|Win32
- {F10D22F8-AC7B-4213-8720-608E7D878CD2}.Debug|x64.ActiveCfg = Debug|x64
- {F10D22F8-AC7B-4213-8720-608E7D878CD2}.Debug|x64.Build.0 = Debug|x64
- {F10D22F8-AC7B-4213-8720-608E7D878CD2}.Release|Win32.ActiveCfg = Release|Win32
- {F10D22F8-AC7B-4213-8720-608E7D878CD2}.Release|Win32.Build.0 = Release|Win32
- {F10D22F8-AC7B-4213-8720-608E7D878CD2}.Release|x64.ActiveCfg = Release|x64
- {F10D22F8-AC7B-4213-8720-608E7D878CD2}.Release|x64.Build.0 = Release|x64
- {E4EF614B-30DF-4954-8C53-580A0BF6B589}.Debug|Win32.ActiveCfg = Debug|Win32
- {E4EF614B-30DF-4954-8C53-580A0BF6B589}.Debug|Win32.Build.0 = Debug|Win32
- {E4EF614B-30DF-4954-8C53-580A0BF6B589}.Debug|x64.ActiveCfg = Debug|x64
- {E4EF614B-30DF-4954-8C53-580A0BF6B589}.Debug|x64.Build.0 = Debug|x64
- {E4EF614B-30DF-4954-8C53-580A0BF6B589}.Release|Win32.ActiveCfg = Release|Win32
- {E4EF614B-30DF-4954-8C53-580A0BF6B589}.Release|Win32.Build.0 = Release|Win32
- {E4EF614B-30DF-4954-8C53-580A0BF6B589}.Release|x64.ActiveCfg = Release|x64
- {E4EF614B-30DF-4954-8C53-580A0BF6B589}.Release|x64.Build.0 = Release|x64
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/contrib/googletest/googlemock/msvc/2010/gmock.vcxproj b/contrib/googletest/googlemock/msvc/2010/gmock.vcxproj deleted file mode 100644 index 7bc71d31df9d..000000000000 --- a/contrib/googletest/googlemock/msvc/2010/gmock.vcxproj +++ /dev/null @@ -1,145 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <ProjectGuid>{34681F0D-CE45-415D-B5F2-5C662DFE3BD5}</ProjectGuid>
- <RootNamespace>gmock</RootNamespace>
- <Keyword>Win32Proj</Keyword>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>StaticLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v100</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
- <ConfigurationType>StaticLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v100</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>StaticLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v100</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
- <ConfigurationType>StaticLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v100</PlatformToolset>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- <Import Project="gmock_config.props" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- <Import Project="gmock_config.props" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- <Import Project="gmock_config.props" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- <Import Project="gmock_config.props" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup>
- <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)-$(Configuration)\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)$(ProjectName)\</IntDir>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)-$(Configuration)\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(OutDir)$(ProjectName)\</IntDir>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <OutDir>$(SolutionDir)$(Platform)-$(Configuration)\</OutDir>
- <IntDir>$(OutDir)$(ProjectName)\</IntDir>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <OutDir>$(SolutionDir)$(Platform)-$(Configuration)\</OutDir>
- <IntDir>$(OutDir)$(ProjectName)\</IntDir>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>WIN32;_VARIADIC_MAX=10;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <MinimalRebuild>true</MinimalRebuild>
- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
- <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
- <PrecompiledHeader>
- </PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
- </ClCompile>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <ClCompile>
- <Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>WIN32;_VARIADIC_MAX=10;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
- <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
- <PrecompiledHeader>
- </PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
- </ClCompile>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <AdditionalIncludeDirectories>..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>WIN32;_VARIADIC_MAX=10;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
- <PrecompiledHeader>
- </PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
- </ClCompile>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <ClCompile>
- <AdditionalIncludeDirectories>..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>WIN32;_VARIADIC_MAX=10;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
- <PrecompiledHeader>
- </PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
- </ClCompile>
- </ItemDefinitionGroup>
- <ItemGroup>
- <ClCompile Include="..\..\src\gmock-all.cc" />
- <ClCompile Include="$(GTestDir)\src\gtest-all.cc">
- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(GTestDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(GTestDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(GTestDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(GTestDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- </ClCompile>
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
-</Project>
\ No newline at end of file diff --git a/contrib/googletest/googlemock/msvc/2010/gmock_config.props b/contrib/googletest/googlemock/msvc/2010/gmock_config.props deleted file mode 100644 index 017d710b4115..000000000000 --- a/contrib/googletest/googlemock/msvc/2010/gmock_config.props +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup Label="UserMacros">
- <GTestDir>../../../googletest</GTestDir>
- </PropertyGroup>
- <PropertyGroup>
- <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
- </PropertyGroup>
- <ItemDefinitionGroup>
- <ClCompile>
- <AdditionalIncludeDirectories>$(GTestDir)/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- </ClCompile>
- </ItemDefinitionGroup>
- <ItemGroup>
- <BuildMacro Include="GTestDir">
- <Value>$(GTestDir)</Value>
- </BuildMacro>
- </ItemGroup>
-</Project>
\ No newline at end of file diff --git a/contrib/googletest/googlemock/msvc/2010/gmock_main.vcxproj b/contrib/googletest/googlemock/msvc/2010/gmock_main.vcxproj deleted file mode 100644 index 43da043df9ef..000000000000 --- a/contrib/googletest/googlemock/msvc/2010/gmock_main.vcxproj +++ /dev/null @@ -1,151 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <ProjectGuid>{E4EF614B-30DF-4954-8C53-580A0BF6B589}</ProjectGuid>
- <RootNamespace>gmock_main</RootNamespace>
- <Keyword>Win32Proj</Keyword>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>StaticLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v100</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
- <ConfigurationType>StaticLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v100</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>StaticLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v100</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
- <ConfigurationType>StaticLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v100</PlatformToolset>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- <Import Project="gmock_config.props" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- <Import Project="gmock_config.props" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- <Import Project="gmock_config.props" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- <Import Project="gmock_config.props" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup>
- <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)-$(Configuration)\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)$(ProjectName)\</IntDir>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)-$(Configuration)\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(OutDir)$(ProjectName)\</IntDir>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <OutDir>$(SolutionDir)$(Platform)-$(Configuration)\</OutDir>
- <IntDir>$(OutDir)$(ProjectName)\</IntDir>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <OutDir>$(SolutionDir)$(Platform)-$(Configuration)\</OutDir>
- <IntDir>$(OutDir)$(ProjectName)\</IntDir>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>WIN32;_VARIADIC_MAX=10;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <MinimalRebuild>true</MinimalRebuild>
- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
- <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
- <PrecompiledHeader>
- </PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
- </ClCompile>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <ClCompile>
- <Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>WIN32;_VARIADIC_MAX=10;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
- <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
- <PrecompiledHeader>
- </PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
- </ClCompile>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>WIN32;_VARIADIC_MAX=10;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
- <PrecompiledHeader>
- </PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
- </ClCompile>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <ClCompile>
- <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>WIN32;_VARIADIC_MAX=10;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
- <PrecompiledHeader>
- </PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
- </ClCompile>
- </ItemDefinitionGroup>
- <ItemGroup>
- <ProjectReference Include="gmock.vcxproj">
- <Project>{34681f0d-ce45-415d-b5f2-5c662dfe3bd5}</Project>
- <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
- <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
- </ProjectReference>
- </ItemGroup>
- <ItemGroup>
- <ClCompile Include="..\..\src\gmock_main.cc">
- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- </ClCompile>
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
-</Project>
\ No newline at end of file diff --git a/contrib/googletest/googlemock/msvc/2010/gmock_test.vcxproj b/contrib/googletest/googlemock/msvc/2010/gmock_test.vcxproj deleted file mode 100644 index dcbeb587a239..000000000000 --- a/contrib/googletest/googlemock/msvc/2010/gmock_test.vcxproj +++ /dev/null @@ -1,176 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <ProjectGuid>{F10D22F8-AC7B-4213-8720-608E7D878CD2}</ProjectGuid>
- <RootNamespace>gmock_test</RootNamespace>
- <Keyword>Win32Proj</Keyword>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v100</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v100</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v100</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v100</PlatformToolset>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- <Import Project="gmock_config.props" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- <Import Project="gmock_config.props" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- <Import Project="gmock_config.props" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- <Import Project="gmock_config.props" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup>
- <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)-$(Configuration)\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)$(ProjectName)\</IntDir>
- <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
- <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)-$(Configuration)\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(OutDir)$(ProjectName)\</IntDir>
- <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
- <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <OutDir>$(SolutionDir)$(Platform)-$(Configuration)\</OutDir>
- <IntDir>$(OutDir)$(ProjectName)\</IntDir>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <OutDir>$(SolutionDir)$(Platform)-$(Configuration)\</OutDir>
- <IntDir>$(OutDir)$(ProjectName)\</IntDir>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
- <Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>..\..\include;..\..;$(GTestDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>WIN32;_VARIADIC_MAX=10;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <MinimalRebuild>true</MinimalRebuild>
- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
- <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
- <PrecompiledHeader>
- </PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
- </ClCompile>
- <Link>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <SubSystem>Console</SubSystem>
- <TargetMachine>MachineX86</TargetMachine>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <ClCompile>
- <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
- <Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>..\..\include;..\..;$(GTestDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>WIN32;_VARIADIC_MAX=10;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
- <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
- <PrecompiledHeader>
- </PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
- </ClCompile>
- <Link>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <SubSystem>Console</SubSystem>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
- <AdditionalIncludeDirectories>..\..\include;..\..;$(GTestDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>WIN32;_VARIADIC_MAX=10;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
- <PrecompiledHeader>
- </PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
- </ClCompile>
- <Link>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <SubSystem>Console</SubSystem>
- <OptimizeReferences>true</OptimizeReferences>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <TargetMachine>MachineX86</TargetMachine>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <ClCompile>
- <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
- <AdditionalIncludeDirectories>..\..\include;..\..;$(GTestDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>WIN32;_VARIADIC_MAX=10;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
- <PrecompiledHeader>
- </PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
- </ClCompile>
- <Link>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <SubSystem>Console</SubSystem>
- <OptimizeReferences>true</OptimizeReferences>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- </Link>
- </ItemDefinitionGroup>
- <ItemGroup>
- <ProjectReference Include="gmock_main.vcxproj">
- <Project>{e4ef614b-30df-4954-8c53-580a0bf6b589}</Project>
- <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
- <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
- </ProjectReference>
- </ItemGroup>
- <ItemGroup>
- <ClCompile Include="..\..\test\gmock_all_test.cc" />
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
-</Project>
\ No newline at end of file diff --git a/contrib/googletest/googlemock/msvc/2015/gmock.sln b/contrib/googletest/googlemock/msvc/2015/gmock.sln deleted file mode 100644 index d4203a844244..000000000000 --- a/contrib/googletest/googlemock/msvc/2015/gmock.sln +++ /dev/null @@ -1,46 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmock", "gmock.vcxproj", "{34681F0D-CE45-415D-B5F2-5C662DFE3BD5}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmock_test", "gmock_test.vcxproj", "{F10D22F8-AC7B-4213-8720-608E7D878CD2}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmock_main", "gmock_main.vcxproj", "{E4EF614B-30DF-4954-8C53-580A0BF6B589}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {34681F0D-CE45-415D-B5F2-5C662DFE3BD5}.Debug|Win32.ActiveCfg = Debug|Win32 - {34681F0D-CE45-415D-B5F2-5C662DFE3BD5}.Debug|Win32.Build.0 = Debug|Win32 - {34681F0D-CE45-415D-B5F2-5C662DFE3BD5}.Debug|x64.ActiveCfg = Debug|x64 - {34681F0D-CE45-415D-B5F2-5C662DFE3BD5}.Debug|x64.Build.0 = Debug|x64 - {34681F0D-CE45-415D-B5F2-5C662DFE3BD5}.Release|Win32.ActiveCfg = Release|Win32 - {34681F0D-CE45-415D-B5F2-5C662DFE3BD5}.Release|Win32.Build.0 = Release|Win32 - {34681F0D-CE45-415D-B5F2-5C662DFE3BD5}.Release|x64.ActiveCfg = Release|x64 - {34681F0D-CE45-415D-B5F2-5C662DFE3BD5}.Release|x64.Build.0 = Release|x64 - {F10D22F8-AC7B-4213-8720-608E7D878CD2}.Debug|Win32.ActiveCfg = Debug|Win32 - {F10D22F8-AC7B-4213-8720-608E7D878CD2}.Debug|Win32.Build.0 = Debug|Win32 - {F10D22F8-AC7B-4213-8720-608E7D878CD2}.Debug|x64.ActiveCfg = Debug|x64 - {F10D22F8-AC7B-4213-8720-608E7D878CD2}.Debug|x64.Build.0 = Debug|x64 - {F10D22F8-AC7B-4213-8720-608E7D878CD2}.Release|Win32.ActiveCfg = Release|Win32 - {F10D22F8-AC7B-4213-8720-608E7D878CD2}.Release|Win32.Build.0 = Release|Win32 - {F10D22F8-AC7B-4213-8720-608E7D878CD2}.Release|x64.ActiveCfg = Release|x64 - {F10D22F8-AC7B-4213-8720-608E7D878CD2}.Release|x64.Build.0 = Release|x64 - {E4EF614B-30DF-4954-8C53-580A0BF6B589}.Debug|Win32.ActiveCfg = Debug|Win32 - {E4EF614B-30DF-4954-8C53-580A0BF6B589}.Debug|Win32.Build.0 = Debug|Win32 - {E4EF614B-30DF-4954-8C53-580A0BF6B589}.Debug|x64.ActiveCfg = Debug|x64 - {E4EF614B-30DF-4954-8C53-580A0BF6B589}.Debug|x64.Build.0 = Debug|x64 - {E4EF614B-30DF-4954-8C53-580A0BF6B589}.Release|Win32.ActiveCfg = Release|Win32 - {E4EF614B-30DF-4954-8C53-580A0BF6B589}.Release|Win32.Build.0 = Release|Win32 - {E4EF614B-30DF-4954-8C53-580A0BF6B589}.Release|x64.ActiveCfg = Release|x64 - {E4EF614B-30DF-4954-8C53-580A0BF6B589}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/contrib/googletest/googlemock/msvc/2015/gmock.vcxproj b/contrib/googletest/googlemock/msvc/2015/gmock.vcxproj deleted file mode 100644 index c6b56e612f0b..000000000000 --- a/contrib/googletest/googlemock/msvc/2015/gmock.vcxproj +++ /dev/null @@ -1,145 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{34681F0D-CE45-415D-B5F2-5C662DFE3BD5}</ProjectGuid> - <RootNamespace>gmock</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>v140</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>v140</PlatformToolset> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="gmock_config.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="gmock_config.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="gmock_config.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="gmock_config.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)-$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)$(ProjectName)\</IntDir> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)-$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(OutDir)$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <OutDir>$(SolutionDir)$(Platform)-$(Configuration)\</OutDir> - <IntDir>$(OutDir)$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <OutDir>$(SolutionDir)$(Platform)-$(Configuration)\</OutDir> - <IntDir>$(OutDir)$(ProjectName)\</IntDir> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <Optimization>Disabled</Optimization> - <AdditionalIncludeDirectories>..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - </ClCompile> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <Optimization>Disabled</Optimization> - <AdditionalIncludeDirectories>..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - </ClCompile> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <AdditionalIncludeDirectories>..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - </ClCompile> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <AdditionalIncludeDirectories>..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - </ClCompile> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\..\src\gmock-all.cc" /> - <ClCompile Include="$(GTestDir)\src\gtest-all.cc"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(GTestDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(GTestDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(GTestDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(GTestDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - </ClCompile> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project>
\ No newline at end of file diff --git a/contrib/googletest/googlemock/msvc/2015/gmock_config.props b/contrib/googletest/googlemock/msvc/2015/gmock_config.props deleted file mode 100644 index 77bc95b192d9..000000000000 --- a/contrib/googletest/googlemock/msvc/2015/gmock_config.props +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <PropertyGroup Label="UserMacros"> - <GTestDir>../../../googletest</GTestDir> - </PropertyGroup> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <ClCompile> - <AdditionalIncludeDirectories>$(GTestDir)/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - </ClCompile> - </ItemDefinitionGroup> - <ItemGroup> - <BuildMacro Include="GTestDir"> - <Value>$(GTestDir)</Value> - </BuildMacro> - </ItemGroup> -</Project> diff --git a/contrib/googletest/googlemock/msvc/2015/gmock_main.vcxproj b/contrib/googletest/googlemock/msvc/2015/gmock_main.vcxproj deleted file mode 100644 index 42381dfa3102..000000000000 --- a/contrib/googletest/googlemock/msvc/2015/gmock_main.vcxproj +++ /dev/null @@ -1,151 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{E4EF614B-30DF-4954-8C53-580A0BF6B589}</ProjectGuid> - <RootNamespace>gmock_main</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>v140</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>v140</PlatformToolset> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="gmock_config.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="gmock_config.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="gmock_config.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="gmock_config.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)-$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)$(ProjectName)\</IntDir> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)-$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(OutDir)$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <OutDir>$(SolutionDir)$(Platform)-$(Configuration)\</OutDir> - <IntDir>$(OutDir)$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <OutDir>$(SolutionDir)$(Platform)-$(Configuration)\</OutDir> - <IntDir>$(OutDir)$(ProjectName)\</IntDir> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <Optimization>Disabled</Optimization> - <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - </ClCompile> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <Optimization>Disabled</Optimization> - <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - </ClCompile> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - </ClCompile> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - </ClCompile> - </ItemDefinitionGroup> - <ItemGroup> - <ProjectReference Include="gmock.vcxproj"> - <Project>{34681f0d-ce45-415d-b5f2-5c662dfe3bd5}</Project> - <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies> - <ReferenceOutputAssembly>true</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\..\src\gmock_main.cc"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - </ClCompile> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project>
\ No newline at end of file diff --git a/contrib/googletest/googlemock/msvc/2015/gmock_test.vcxproj b/contrib/googletest/googlemock/msvc/2015/gmock_test.vcxproj deleted file mode 100644 index 01d1f201b5b2..000000000000 --- a/contrib/googletest/googlemock/msvc/2015/gmock_test.vcxproj +++ /dev/null @@ -1,176 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{F10D22F8-AC7B-4213-8720-608E7D878CD2}</ProjectGuid> - <RootNamespace>gmock_test</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>v140</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>v140</PlatformToolset> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="gmock_config.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="gmock_config.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="gmock_config.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="gmock_config.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)-$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)$(ProjectName)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)-$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(OutDir)$(ProjectName)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <OutDir>$(SolutionDir)$(Platform)-$(Configuration)\</OutDir> - <IntDir>$(OutDir)$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <OutDir>$(SolutionDir)$(Platform)-$(Configuration)\</OutDir> - <IntDir>$(OutDir)$(ProjectName)\</IntDir> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions> - <Optimization>Disabled</Optimization> - <AdditionalIncludeDirectories>..\..\include;..\..;$(GTestDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - </ClCompile> - <Link> - <GenerateDebugInformation>true</GenerateDebugInformation> - <SubSystem>Console</SubSystem> - <TargetMachine>MachineX86</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions> - <Optimization>Disabled</Optimization> - <AdditionalIncludeDirectories>..\..\include;..\..;$(GTestDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - </ClCompile> - <Link> - <GenerateDebugInformation>true</GenerateDebugInformation> - <SubSystem>Console</SubSystem> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions> - <AdditionalIncludeDirectories>..\..\include;..\..;$(GTestDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - </ClCompile> - <Link> - <GenerateDebugInformation>true</GenerateDebugInformation> - <SubSystem>Console</SubSystem> - <OptimizeReferences>true</OptimizeReferences> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <TargetMachine>MachineX86</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions> - <AdditionalIncludeDirectories>..\..\include;..\..;$(GTestDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - </ClCompile> - <Link> - <GenerateDebugInformation>true</GenerateDebugInformation> - <SubSystem>Console</SubSystem> - <OptimizeReferences>true</OptimizeReferences> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ProjectReference Include="gmock_main.vcxproj"> - <Project>{e4ef614b-30df-4954-8c53-580a0bf6b589}</Project> - <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies> - <ReferenceOutputAssembly>true</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\..\test\gmock_all_test.cc" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project>
\ No newline at end of file diff --git a/contrib/googletest/googlemock/scripts/fuse_gmock_files.py b/contrib/googletest/googlemock/scripts/fuse_gmock_files.py deleted file mode 100755 index 9b6956f2beb6..000000000000 --- a/contrib/googletest/googlemock/scripts/fuse_gmock_files.py +++ /dev/null @@ -1,240 +0,0 @@ -#!/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/CookBook.md for more -information. -""" - -__author__ = 'wan@google.com (Zhanyong Wan)' - -import os -import re -import sets -import sys - -# 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 -gtest = fuse_gtest_files - -# 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. - """ - - 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. - """ - - 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 = file(os.path.join(output_dir, GMOCK_H_OUTPUT), 'w') - processed_files = sets.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. - for line in file(os.path.join(gmock_root, gmock_header_path), 'r'): - m = INCLUDE_GMOCK_FILE_REGEX.match(line) - if m: - # It's '#include "gmock/..."' - let's process it recursively. - ProcessFile('include/' + m.group(1)) - else: - m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line) - if m: - # It's '#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 not gtest.GTEST_H_SEED 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 = sets.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. - for line in file(os.path.join(gmock_root, gmock_source_file), 'r'): - m = INCLUDE_GMOCK_FILE_REGEX.match(line) - if m: - # It's '#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. - - # There is no need to #include "gmock/gmock.h" more than once. - if not GMOCK_H_SEED 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: - # It's '#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.""" - - output_file = file(os.path.join(output_dir, GMOCK_GTEST_ALL_CC_OUTPUT), 'w') - # 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) - output_file.close() - - -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/contrib/googletest/googlemock/scripts/generator/LICENSE b/contrib/googletest/googlemock/scripts/generator/LICENSE deleted file mode 100644 index 87ea0636510a..000000000000 --- a/contrib/googletest/googlemock/scripts/generator/LICENSE +++ /dev/null @@ -1,203 +0,0 @@ - - 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/contrib/googletest/googlemock/scripts/generator/README b/contrib/googletest/googlemock/scripts/generator/README deleted file mode 100644 index 01fd463dda7f..000000000000 --- a/contrib/googletest/googlemock/scripts/generator/README +++ /dev/null @@ -1,34 +0,0 @@ - -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/contrib/googletest/googlemock/scripts/generator/README.cppclean b/contrib/googletest/googlemock/scripts/generator/README.cppclean deleted file mode 100644 index 65431b617593..000000000000 --- a/contrib/googletest/googlemock/scripts/generator/README.cppclean +++ /dev/null @@ -1,115 +0,0 @@ -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/contrib/googletest/googlemock/scripts/generator/cpp/__init__.py b/contrib/googletest/googlemock/scripts/generator/cpp/__init__.py deleted file mode 100755 index e69de29bb2d1..000000000000 --- a/contrib/googletest/googlemock/scripts/generator/cpp/__init__.py +++ /dev/null diff --git a/contrib/googletest/googlemock/scripts/generator/cpp/ast.py b/contrib/googletest/googlemock/scripts/generator/cpp/ast.py deleted file mode 100755 index f14728b4612a..000000000000 --- a/contrib/googletest/googlemock/scripts/generator/cpp/ast.py +++ /dev/null @@ -1,1736 +0,0 @@ -#!/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++.""" - -__author__ = 'nnorwitz@google.com (Neal Norwitz)' - - -# TODO: -# * 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 comparison. - 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 comparison. - 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 - for s in tokens: - if not first_token: - first_token = s - 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)): - 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._GetVarTokensUpTo(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 - - # TODO(nnorwitz): remove _IgnoreUpTo() it shouldn't be necessary. - 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() - return next(self.tokens) - - 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): - token = self._GetNextToken() - if not (token.token_type == tokenize.NAME and token.name == 'class'): - self._AddBackToken(token) - 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._GetTokensUpTo(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): - token = self._GetNextToken() - # Support anonymous namespaces. - name = None - if token.token_type == tokenize.NAME: - name = token.name - token = self._GetNextToken() - 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/contrib/googletest/googlemock/scripts/generator/cpp/gmock_class.py b/contrib/googletest/googlemock/scripts/generator/cpp/gmock_class.py deleted file mode 100755 index f9966cbb4b0e..000000000000 --- a/contrib/googletest/googlemock/scripts/generator/cpp/gmock_class.py +++ /dev/null @@ -1,227 +0,0 @@ -#!/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. -""" - -__author__ = 'nnorwitz@google.com (Neal Norwitz)' - - -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 _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. - const = '' - if node.modifiers & ast.FUNCTION_CONST: - const = 'CONST_' - return_type = 'void' - if node.return_type: - # Add modifiers like 'const'. - modifiers = '' - if node.return_type.modifiers: - modifiers = ' '.join(node.return_type.modifiers) + ' ' - return_type = modifiers + node.return_type.name - template_args = [arg.name for arg in node.return_type.templated_types] - if template_args: - return_type += '<' + ', '.join(template_args) + '>' - if len(template_args) > 1: - for line in [ - '// The following line won\'t really compile, as the return', - '// type has multiple template arguments. To fix it, use a', - '// typedef for the return type.']: - output_lines.append(indent + line) - if node.return_type.pointer: - return_type += '*' - if node.return_type.reference: - return_type += '&' - num_parameters = len(node.parameters) - if len(node.parameters) == 1: - first_param = node.parameters[0] - if source[first_param.start:first_param.end].strip() == 'void': - # We must treat T(void) as a function with no parameters. - num_parameters = 0 - tmpl = '' - if class_node.templated_types: - tmpl = '_T' - mock_method_macro = 'MOCK_%sMETHOD%d%s' % (const, num_parameters, tmpl) - - args = '' - if node.parameters: - # Due to the parser limitations, it is impossible to keep comments - # while stripping the default parameters. When defaults are - # present, we choose to strip them and comments (and produce - # compilable code). - # TODO(nnorwitz@google.com): Investigate whether it is possible to - # preserve parameter name when reconstructing parameter text from - # the AST. - if len([param for param in node.parameters if param.default]) > 0: - args = ', '.join(param.type.name for param in node.parameters) - else: - # Get the full text of the parameters from the start - # of the first parameter to the end of the last parameter. - start = node.parameters[0].start - end = node.parameters[-1].end - # Remove // comments. - args_strings = re.sub(r'//.*', '', source[start:end]) - # Condense multiple spaces and eliminate newlines putting the - # parameters together on a single line. Ensure there is a - # space in an argument which is split by a newline without - # intervening whitespace, e.g.: int\nBar - args = re.sub(' +', ' ', args_strings.replace('\n', ' ')) - - # Create the mock method definition. - output_lines.extend(['%s%s(%s,' % (indent, mock_method_macro, node.name), - '%s%s(%s));' % (indent*3, return_type, args)]) - - -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/contrib/googletest/googlemock/scripts/generator/cpp/gmock_class_test.py b/contrib/googletest/googlemock/scripts/generator/cpp/gmock_class_test.py deleted file mode 100755 index c53e60003e1c..000000000000 --- a/contrib/googletest/googlemock/scripts/generator/cpp/gmock_class_test.py +++ /dev/null @@ -1,466 +0,0 @@ -#!/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.""" - -__author__ = 'nnorwitz@google.com (Neal Norwitz)' - - -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.""" - - def StripLeadingWhitespace(self, 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): - - def GenerateMethodSource(self, 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_METHOD0(Bar,\nint());', - 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_METHOD0(Bar,\nint());', - self.GenerateMethodSource(source)) - - def testVirtualDestructor(self): - source = """ -class Foo { - public: - virtual ~Foo(); - virtual int Bar() = 0; -}; -""" - # The destructor should be ignored. - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD0(Bar,\nint());', - 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_METHOD0(Bar,\nint());', - 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_METHOD0(Bar,\nint());', - self.GenerateMethodSource(source)) - - def testSimpleOverrideMethod(self): - source = """ -class Foo { - public: - int Bar() override; -}; -""" - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD0(Bar,\nint());', - self.GenerateMethodSource(source)) - - def testSimpleConstMethod(self): - source = """ -class Foo { - public: - virtual void Bar(bool flag) const; -}; -""" - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_CONST_METHOD1(Bar,\nvoid(bool flag));', - self.GenerateMethodSource(source)) - - def testExplicitVoid(self): - source = """ -class Foo { - public: - virtual int Bar(void); -}; -""" - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD0(Bar,\nint(void));', - self.GenerateMethodSource(source)) - - def testStrangeNewlineInParameter(self): - source = """ -class Foo { - public: - virtual void Bar(int -a) = 0; -}; -""" - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD1(Bar,\nvoid(int a));', - self.GenerateMethodSource(source)) - - def testDefaultParameters(self): - source = """ -class Foo { - public: - virtual void Bar(int a, char c = 'x') = 0; -}; -""" - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD2(Bar,\nvoid(int, char));', - self.GenerateMethodSource(source)) - - def testMultipleDefaultParameters(self): - source = """ -class Foo { - public: - virtual void Bar(int a = 42, char c = 'x') = 0; -}; -""" - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD2(Bar,\nvoid(int, char));', - 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_METHOD2(Bar,\nvoid(int, char));', - 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_CONST_METHOD2(Bar,\nvoid(int a, int b));', - 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_METHOD2(Bar,\nconst string&(int /* keeper */, int b));', - self.GenerateMethodSource(source)) - - def testArgsOfTemplateTypes(self): - source = """ -class Foo { - public: - virtual int Bar(const vector<int>& v, map<int, string>* output); -};""" - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD2(Bar,\n' - 'int(const vector<int>& v, map<int, string>* output));', - self.GenerateMethodSource(source)) - - def testReturnTypeWithOneTemplateArg(self): - source = """ -class Foo { - public: - virtual vector<int>* Bar(int n); -};""" - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD1(Bar,\nvector<int>*(int n));', - self.GenerateMethodSource(source)) - - def testReturnTypeWithManyTemplateArgs(self): - source = """ -class Foo { - public: - virtual map<int, string> Bar(); -};""" - # Comparing the comment text is brittle - we'll think of something - # better in case this gets annoying, but for now let's keep it simple. - self.assertEqualIgnoreLeadingWhitespace( - '// The following line won\'t really compile, as the return\n' - '// type has multiple template arguments. To fix it, use a\n' - '// typedef for the return type.\n' - 'MOCK_METHOD0(Bar,\nmap<int, string>());', - self.GenerateMethodSource(source)) - - def testSimpleMethodInTemplatedClass(self): - source = """ -template<class T> -class Foo { - public: - virtual int Bar(); -}; -""" - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD0_T(Bar,\nint());', - self.GenerateMethodSource(source)) - - def testPointerArgWithoutNames(self): - source = """ -class Foo { - virtual int Bar(C*); -}; -""" - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD1(Bar,\nint(C*));', - self.GenerateMethodSource(source)) - - def testReferenceArgWithoutNames(self): - source = """ -class Foo { - virtual int Bar(C&); -}; -""" - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD1(Bar,\nint(C&));', - self.GenerateMethodSource(source)) - - def testArrayArgWithoutNames(self): - source = """ -class Foo { - virtual int Bar(C[]); -}; -""" - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD1(Bar,\nint(C[]));', - self.GenerateMethodSource(source)) - - -class GenerateMocksTest(TestCase): - - def GenerateMocks(self, 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 { - -class Test { - public: - virtual void Foo(); -}; - -} // namespace Baz -} // namespace Foo -""" - expected = """\ -namespace Foo { -namespace Baz { - -class MockTest : public Test { -public: -MOCK_METHOD0(Foo, -void()); -}; - -} // namespace Baz -} // 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_METHOD0(Foo, -void()); -}; -""" - 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_METHOD0(Foo, -void()); -}; -""" - 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_METHOD0_T(Foo, -void()); -}; -""" - 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_METHOD1(Bar, -void(const FooType& test_arg)); -}; -""" - 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_METHOD1(Bar, -void(const FooType& test_arg)); -}; -""" - self.assertEqualIgnoreLeadingWhitespace( - expected, self.GenerateMocks(source)) - - def testEnumClass(self): - source = """ -class Test { - public: - enum class Baz { BAZINGA }; - virtual void Bar(const FooType& test_arg); -}; -""" - expected = """\ -class MockTest : public Test { -public: -MOCK_METHOD1(Bar, -void(const FooType& test_arg)); -}; -""" - self.assertEqualIgnoreLeadingWhitespace( - expected, self.GenerateMocks(source)) - -if __name__ == '__main__': - unittest.main() diff --git a/contrib/googletest/googlemock/scripts/generator/cpp/keywords.py b/contrib/googletest/googlemock/scripts/generator/cpp/keywords.py deleted file mode 100755 index f694450e373e..000000000000 --- a/contrib/googletest/googlemock/scripts/generator/cpp/keywords.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/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.""" - -__author__ = 'nnorwitz@google.com (Neal Norwitz)' - - -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/contrib/googletest/googlemock/scripts/generator/cpp/tokenize.py b/contrib/googletest/googlemock/scripts/generator/cpp/tokenize.py deleted file mode 100755 index 359d5562d78c..000000000000 --- a/contrib/googletest/googlemock/scripts/generator/cpp/tokenize.py +++ /dev/null @@ -1,287 +0,0 @@ -#!/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.""" - -__author__ = 'nnorwitz@google.com (Neal Norwitz)' - - -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/contrib/googletest/googlemock/scripts/generator/cpp/utils.py b/contrib/googletest/googlemock/scripts/generator/cpp/utils.py deleted file mode 100755 index eab36eec335e..000000000000 --- a/contrib/googletest/googlemock/scripts/generator/cpp/utils.py +++ /dev/null @@ -1,41 +0,0 @@ -#!/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.""" - -__author__ = 'nnorwitz@google.com (Neal Norwitz)' - - -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/contrib/googletest/googlemock/scripts/generator/gmock_gen.py b/contrib/googletest/googlemock/scripts/generator/gmock_gen.py deleted file mode 100755 index 8cc0d135d6f2..000000000000 --- a/contrib/googletest/googlemock/scripts/generator/gmock_gen.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/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.""" - -__author__ = 'nnorwitz@google.com (Neal Norwitz)' - -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/contrib/googletest/googlemock/scripts/gmock-config.in b/contrib/googletest/googlemock/scripts/gmock-config.in deleted file mode 100755 index 2baefe94d6fb..000000000000 --- a/contrib/googletest/googlemock/scripts/gmock-config.in +++ /dev/null @@ -1,303 +0,0 @@ -#!/bin/sh - -# These variables are automatically filled in by the configure script. -name="@PACKAGE_TARNAME@" -version="@PACKAGE_VERSION@" - -show_usage() -{ - echo "Usage: gmock-config [OPTIONS...]" -} - -show_help() -{ - show_usage - cat <<\EOF - -The `gmock-config' script provides access to the necessary compile and linking -flags to connect with Google C++ Mocking Framework, both in a build prior to -installation, and on the system proper after installation. The installation -overrides may be issued in combination with any other queries, but will only -affect installation queries if called on a built but not installed gmock. The -installation queries may not be issued with any other types of queries, and -only one installation query may be made at a time. The version queries and -compiler flag queries may be combined as desired but not mixed. Different -version queries are always combined with logical "and" semantics, and only the -last of any particular query is used while all previous ones ignored. All -versions must be specified as a sequence of numbers separated by periods. -Compiler flag queries output the union of the sets of flags when combined. - - Examples: - gmock-config --min-version=1.0 || echo "Insufficient Google Mock version." - - g++ $(gmock-config --cppflags --cxxflags) -o foo.o -c foo.cpp - g++ $(gmock-config --ldflags --libs) -o foo foo.o - - # When using a built but not installed Google Mock: - g++ $(../../my_gmock_build/scripts/gmock-config ...) ... - - # When using an installed Google Mock, but with installation overrides: - export GMOCK_PREFIX="/opt" - g++ $(gmock-config --libdir="/opt/lib64" ...) ... - - Help: - --usage brief usage information - --help display this help message - - Installation Overrides: - --prefix=<dir> overrides the installation prefix - --exec-prefix=<dir> overrides the executable installation prefix - --libdir=<dir> overrides the library installation prefix - --includedir=<dir> overrides the header file installation prefix - - Installation Queries: - --prefix installation prefix - --exec-prefix executable installation prefix - --libdir library installation directory - --includedir header file installation directory - --version the version of the Google Mock installation - - Version Queries: - --min-version=VERSION return 0 if the version is at least VERSION - --exact-version=VERSION return 0 if the version is exactly VERSION - --max-version=VERSION return 0 if the version is at most VERSION - - Compilation Flag Queries: - --cppflags compile flags specific to the C-like preprocessors - --cxxflags compile flags appropriate for C++ programs - --ldflags linker flags - --libs libraries for linking - -EOF -} - -# This function bounds our version with a min and a max. It uses some clever -# POSIX-compliant variable expansion to portably do all the work in the shell -# and avoid any dependency on a particular "sed" or "awk" implementation. -# Notable is that it will only ever compare the first 3 components of versions. -# Further components will be cleanly stripped off. All versions must be -# unadorned, so "v1.0" will *not* work. The minimum version must be in $1, and -# the max in $2. TODO(chandlerc@google.com): If this ever breaks, we should -# investigate expanding this via autom4te from AS_VERSION_COMPARE rather than -# continuing to maintain our own shell version. -check_versions() -{ - major_version=${version%%.*} - minor_version="0" - point_version="0" - if test "${version#*.}" != "${version}"; then - minor_version=${version#*.} - minor_version=${minor_version%%.*} - fi - if test "${version#*.*.}" != "${version}"; then - point_version=${version#*.*.} - point_version=${point_version%%.*} - fi - - min_version="$1" - min_major_version=${min_version%%.*} - min_minor_version="0" - min_point_version="0" - if test "${min_version#*.}" != "${min_version}"; then - min_minor_version=${min_version#*.} - min_minor_version=${min_minor_version%%.*} - fi - if test "${min_version#*.*.}" != "${min_version}"; then - min_point_version=${min_version#*.*.} - min_point_version=${min_point_version%%.*} - fi - - max_version="$2" - max_major_version=${max_version%%.*} - max_minor_version="0" - max_point_version="0" - if test "${max_version#*.}" != "${max_version}"; then - max_minor_version=${max_version#*.} - max_minor_version=${max_minor_version%%.*} - fi - if test "${max_version#*.*.}" != "${max_version}"; then - max_point_version=${max_version#*.*.} - max_point_version=${max_point_version%%.*} - fi - - test $(($major_version)) -lt $(($min_major_version)) && exit 1 - if test $(($major_version)) -eq $(($min_major_version)); then - test $(($minor_version)) -lt $(($min_minor_version)) && exit 1 - if test $(($minor_version)) -eq $(($min_minor_version)); then - test $(($point_version)) -lt $(($min_point_version)) && exit 1 - fi - fi - - test $(($major_version)) -gt $(($max_major_version)) && exit 1 - if test $(($major_version)) -eq $(($max_major_version)); then - test $(($minor_version)) -gt $(($max_minor_version)) && exit 1 - if test $(($minor_version)) -eq $(($max_minor_version)); then - test $(($point_version)) -gt $(($max_point_version)) && exit 1 - fi - fi - - exit 0 -} - -# Show the usage line when no arguments are specified. -if test $# -eq 0; then - show_usage - exit 1 -fi - -while test $# -gt 0; do - case $1 in - --usage) show_usage; exit 0;; - --help) show_help; exit 0;; - - # Installation overrides - --prefix=*) GMOCK_PREFIX=${1#--prefix=};; - --exec-prefix=*) GMOCK_EXEC_PREFIX=${1#--exec-prefix=};; - --libdir=*) GMOCK_LIBDIR=${1#--libdir=};; - --includedir=*) GMOCK_INCLUDEDIR=${1#--includedir=};; - - # Installation queries - --prefix|--exec-prefix|--libdir|--includedir|--version) - if test -n "${do_query}"; then - show_usage - exit 1 - fi - do_query=${1#--} - ;; - - # Version checking - --min-version=*) - do_check_versions=yes - min_version=${1#--min-version=} - ;; - --max-version=*) - do_check_versions=yes - max_version=${1#--max-version=} - ;; - --exact-version=*) - do_check_versions=yes - exact_version=${1#--exact-version=} - ;; - - # Compiler flag output - --cppflags) echo_cppflags=yes;; - --cxxflags) echo_cxxflags=yes;; - --ldflags) echo_ldflags=yes;; - --libs) echo_libs=yes;; - - # Everything else is an error - *) show_usage; exit 1;; - esac - shift -done - -# These have defaults filled in by the configure script but can also be -# overridden by environment variables or command line parameters. -prefix="${GMOCK_PREFIX:-@prefix@}" -exec_prefix="${GMOCK_EXEC_PREFIX:-@exec_prefix@}" -libdir="${GMOCK_LIBDIR:-@libdir@}" -includedir="${GMOCK_INCLUDEDIR:-@includedir@}" - -# We try and detect if our binary is not located at its installed location. If -# it's not, we provide variables pointing to the source and build tree rather -# than to the install tree. We also locate Google Test using the configured -# gtest-config script rather than searching the PATH and our bindir for one. -# This allows building against a just-built gmock rather than an installed -# gmock. -bindir="@bindir@" -this_relative_bindir=`dirname $0` -this_bindir=`cd ${this_relative_bindir}; pwd -P` -if test "${this_bindir}" = "${this_bindir%${bindir}}"; then - # The path to the script doesn't end in the bindir sequence from Autoconf, - # assume that we are in a build tree. - build_dir=`dirname ${this_bindir}` - src_dir=`cd ${this_bindir}/@top_srcdir@; pwd -P` - - # TODO(chandlerc@google.com): This is a dangerous dependency on libtool, we - # should work to remove it, and/or remove libtool altogether, replacing it - # with direct references to the library and a link path. - gmock_libs="${build_dir}/lib/libgmock.la" - gmock_ldflags="" - - # We provide hooks to include from either the source or build dir, where the - # build dir is always preferred. This will potentially allow us to write - # build rules for generated headers and have them automatically be preferred - # over provided versions. - gmock_cppflags="-I${build_dir}/include -I${src_dir}/include" - gmock_cxxflags="" - - # Directly invoke the gtest-config script used during the build process. - gtest_config="@GTEST_CONFIG@" -else - # We're using an installed gmock, although it may be staged under some - # prefix. Assume (as our own libraries do) that we can resolve the prefix, - # and are present in the dynamic link paths. - gmock_ldflags="-L${libdir}" - gmock_libs="-l${name}" - gmock_cppflags="-I${includedir}" - gmock_cxxflags="" - - # We also prefer any gtest-config script installed in our prefix. Lacking - # one, we look in the PATH for one. - gtest_config="${bindir}/gtest-config" - if test ! -x "${gtest_config}"; then - gtest_config=`which gtest-config` - fi -fi - -# Ensure that we have located a Google Test to link against. -if ! test -x "${gtest_config}"; then - echo "Unable to locate Google Test, check your Google Mock configuration" \ - "and installation" >&2 - exit 1 -elif ! "${gtest_config}" "--exact-version=@GTEST_VERSION@"; then - echo "The Google Test found is not the same version as Google Mock was " \ - "built against" >&2 - exit 1 -fi - -# Add the necessary Google Test bits into the various flag variables -gmock_cppflags="${gmock_cppflags} `${gtest_config} --cppflags`" -gmock_cxxflags="${gmock_cxxflags} `${gtest_config} --cxxflags`" -gmock_ldflags="${gmock_ldflags} `${gtest_config} --ldflags`" -gmock_libs="${gmock_libs} `${gtest_config} --libs`" - -# Do an installation query if requested. -if test -n "$do_query"; then - case $do_query in - prefix) echo $prefix; exit 0;; - exec-prefix) echo $exec_prefix; exit 0;; - libdir) echo $libdir; exit 0;; - includedir) echo $includedir; exit 0;; - version) echo $version; exit 0;; - *) show_usage; exit 1;; - esac -fi - -# Do a version check if requested. -if test "$do_check_versions" = "yes"; then - # Make sure we didn't receive a bad combination of parameters. - test "$echo_cppflags" = "yes" && show_usage && exit 1 - test "$echo_cxxflags" = "yes" && show_usage && exit 1 - test "$echo_ldflags" = "yes" && show_usage && exit 1 - test "$echo_libs" = "yes" && show_usage && exit 1 - - if test "$exact_version" != ""; then - check_versions $exact_version $exact_version - # unreachable - else - check_versions ${min_version:-0.0.0} ${max_version:-9999.9999.9999} - # unreachable - fi -fi - -# Do the output in the correct order so that these can be used in-line of -# a compiler invocation. -output="" -test "$echo_cppflags" = "yes" && output="$output $gmock_cppflags" -test "$echo_cxxflags" = "yes" && output="$output $gmock_cxxflags" -test "$echo_ldflags" = "yes" && output="$output $gmock_ldflags" -test "$echo_libs" = "yes" && output="$output $gmock_libs" -echo $output - -exit 0 diff --git a/contrib/googletest/googlemock/scripts/gmock_doctor.py b/contrib/googletest/googlemock/scripts/gmock_doctor.py deleted file mode 100755 index 74992bc74481..000000000000 --- a/contrib/googletest/googlemock/scripts/gmock_doctor.py +++ /dev/null @@ -1,640 +0,0 @@ -#!/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. - -"""Converts compiler's errors in code using Google Mock to plain English.""" - -__author__ = 'wan@google.com (Zhanyong Wan)' - -import re -import sys - -_VERSION = '1.0.3' - -_EMAIL = 'googlemock@googlegroups.com' - -_COMMON_GMOCK_SYMBOLS = [ - # Matchers - '_', - 'A', - 'AddressSatisfies', - 'AllOf', - 'An', - 'AnyOf', - 'ContainerEq', - 'Contains', - 'ContainsRegex', - 'DoubleEq', - 'ElementsAre', - 'ElementsAreArray', - 'EndsWith', - 'Eq', - 'Field', - 'FloatEq', - 'Ge', - 'Gt', - 'HasSubstr', - 'IsInitializedProto', - 'Le', - 'Lt', - 'MatcherCast', - 'Matches', - 'MatchesRegex', - 'NanSensitiveDoubleEq', - 'NanSensitiveFloatEq', - 'Ne', - 'Not', - 'NotNull', - 'Pointee', - 'Property', - 'Ref', - 'ResultOf', - 'SafeMatcherCast', - 'StartsWith', - 'StrCaseEq', - 'StrCaseNe', - 'StrEq', - 'StrNe', - 'Truly', - 'TypedEq', - 'Value', - - # Actions - 'Assign', - 'ByRef', - 'DeleteArg', - 'DoAll', - 'DoDefault', - 'IgnoreResult', - 'Invoke', - 'InvokeArgument', - 'InvokeWithoutArgs', - 'Return', - 'ReturnNew', - 'ReturnNull', - 'ReturnRef', - 'SaveArg', - 'SetArgReferee', - 'SetArgPointee', - 'SetArgumentPointee', - 'SetArrayArgument', - 'SetErrnoAndReturn', - 'Throw', - 'WithArg', - 'WithArgs', - 'WithoutArgs', - - # Cardinalities - 'AnyNumber', - 'AtLeast', - 'AtMost', - 'Between', - 'Exactly', - - # Sequences - 'InSequence', - 'Sequence', - - # Misc - 'DefaultValue', - 'Mock', - ] - -# Regex for matching source file path and line number in the compiler's errors. -_GCC_FILE_LINE_RE = r'(?P<file>.*):(?P<line>\d+):(\d+:)?\s+' -_CLANG_FILE_LINE_RE = r'(?P<file>.*):(?P<line>\d+):(?P<column>\d+):\s+' -_CLANG_NON_GMOCK_FILE_LINE_RE = ( - r'(?P<file>.*[/\\^](?!gmock-)[^/\\]+):(?P<line>\d+):(?P<column>\d+):\s+') - - -def _FindAllMatches(regex, s): - """Generates all matches of regex in string s.""" - - r = re.compile(regex) - return r.finditer(s) - - -def _GenericDiagnoser(short_name, long_name, diagnoses, msg): - """Diagnoses the given disease by pattern matching. - - Can provide different diagnoses for different patterns. - - Args: - short_name: Short name of the disease. - long_name: Long name of the disease. - diagnoses: A list of pairs (regex, pattern for formatting the diagnosis - for matching regex). - msg: Compiler's error messages. - Yields: - Tuples of the form - (short name of disease, long name of disease, diagnosis). - """ - for regex, diagnosis in diagnoses: - if re.search(regex, msg): - diagnosis = '%(file)s:%(line)s:' + diagnosis - for m in _FindAllMatches(regex, msg): - yield (short_name, long_name, diagnosis % m.groupdict()) - - -def _NeedToReturnReferenceDiagnoser(msg): - """Diagnoses the NRR disease, given the error messages by the compiler.""" - - gcc_regex = (r'In member function \'testing::internal::ReturnAction<R>.*\n' - + _GCC_FILE_LINE_RE + r'instantiated from here\n' - r'.*gmock-actions\.h.*error: creating array with negative size') - clang_regex = (r'error:.*array.*negative.*\r?\n' - r'(.*\n)*?' + - _CLANG_NON_GMOCK_FILE_LINE_RE + - r'note: in instantiation of function template specialization ' - r'\'testing::internal::ReturnAction<(?P<type>.*)>' - r'::operator Action<.*>\' requested here') - clang11_re = (r'use_ReturnRef_instead_of_Return_to_return_a_reference.*' - r'(.*\n)*?' + _CLANG_NON_GMOCK_FILE_LINE_RE) - - diagnosis = """ -You are using a Return() action in a function that returns a reference to -%(type)s. Please use ReturnRef() instead.""" - return _GenericDiagnoser('NRR', 'Need to Return Reference', - [(clang_regex, diagnosis), - (clang11_re, diagnosis % {'type': 'a type'}), - (gcc_regex, diagnosis % {'type': 'a type'})], - msg) - - -def _NeedToReturnSomethingDiagnoser(msg): - """Diagnoses the NRS disease, given the error messages by the compiler.""" - - gcc_regex = (_GCC_FILE_LINE_RE + r'(instantiated from here\n.' - r'*gmock.*actions\.h.*error: void value not ignored)' - r'|(error: control reaches end of non-void function)') - clang_regex1 = (_CLANG_FILE_LINE_RE + - r'error: cannot initialize return object ' - r'of type \'Result\' \(aka \'(?P<return_type>.*)\'\) ' - r'with an rvalue of type \'void\'') - clang_regex2 = (_CLANG_FILE_LINE_RE + - r'error: cannot initialize return object ' - r'of type \'(?P<return_type>.*)\' ' - r'with an rvalue of type \'void\'') - diagnosis = """ -You are using an action that returns void, but it needs to return -%(return_type)s. Please tell it *what* to return. Perhaps you can use -the pattern DoAll(some_action, Return(some_value))?""" - return _GenericDiagnoser( - 'NRS', - 'Need to Return Something', - [(gcc_regex, diagnosis % {'return_type': '*something*'}), - (clang_regex1, diagnosis), - (clang_regex2, diagnosis)], - msg) - - -def _NeedToReturnNothingDiagnoser(msg): - """Diagnoses the NRN disease, given the error messages by the compiler.""" - - gcc_regex = (_GCC_FILE_LINE_RE + r'instantiated from here\n' - r'.*gmock-actions\.h.*error: instantiation of ' - r'\'testing::internal::ReturnAction<R>::Impl<F>::value_\' ' - r'as type \'void\'') - clang_regex1 = (r'error: field has incomplete type ' - r'\'Result\' \(aka \'void\'\)(\r)?\n' - r'(.*\n)*?' + - _CLANG_NON_GMOCK_FILE_LINE_RE + r'note: in instantiation ' - r'of function template specialization ' - r'\'testing::internal::ReturnAction<(?P<return_type>.*)>' - r'::operator Action<void \(.*\)>\' requested here') - clang_regex2 = (r'error: field has incomplete type ' - r'\'Result\' \(aka \'void\'\)(\r)?\n' - r'(.*\n)*?' + - _CLANG_NON_GMOCK_FILE_LINE_RE + r'note: in instantiation ' - r'of function template specialization ' - r'\'testing::internal::DoBothAction<.*>' - r'::operator Action<(?P<return_type>.*) \(.*\)>\' ' - r'requested here') - diagnosis = """ -You are using an action that returns %(return_type)s, but it needs to return -void. Please use a void-returning action instead. - -All actions but the last in DoAll(...) must return void. Perhaps you need -to re-arrange the order of actions in a DoAll(), if you are using one?""" - return _GenericDiagnoser( - 'NRN', - 'Need to Return Nothing', - [(gcc_regex, diagnosis % {'return_type': '*something*'}), - (clang_regex1, diagnosis), - (clang_regex2, diagnosis)], - msg) - - -def _IncompleteByReferenceArgumentDiagnoser(msg): - """Diagnoses the IBRA disease, given the error messages by the compiler.""" - - gcc_regex = (_GCC_FILE_LINE_RE + r'instantiated from here\n' - r'.*gtest-printers\.h.*error: invalid application of ' - r'\'sizeof\' to incomplete type \'(?P<type>.*)\'') - - clang_regex = (r'.*gtest-printers\.h.*error: invalid application of ' - r'\'sizeof\' to an incomplete type ' - r'\'(?P<type>.*)( const)?\'\r?\n' - r'(.*\n)*?' + - _CLANG_NON_GMOCK_FILE_LINE_RE + - r'note: in instantiation of member function ' - r'\'testing::internal2::TypeWithoutFormatter<.*>::' - r'PrintValue\' requested here') - diagnosis = """ -In order to mock this function, Google Mock needs to see the definition -of type "%(type)s" - declaration alone is not enough. Either #include -the header that defines it, or change the argument to be passed -by pointer.""" - - return _GenericDiagnoser('IBRA', 'Incomplete By-Reference Argument Type', - [(gcc_regex, diagnosis), - (clang_regex, diagnosis)], - msg) - - -def _OverloadedFunctionMatcherDiagnoser(msg): - """Diagnoses the OFM disease, given the error messages by the compiler.""" - - gcc_regex = (_GCC_FILE_LINE_RE + r'error: no matching function for ' - r'call to \'Truly\(<unresolved overloaded function type>\)') - clang_regex = (_CLANG_FILE_LINE_RE + r'error: no matching function for ' - r'call to \'Truly') - diagnosis = """ -The argument you gave to Truly() is an overloaded function. Please tell -your compiler which overloaded version you want to use. - -For example, if you want to use the version whose signature is - bool Foo(int n); -you should write - Truly(static_cast<bool (*)(int n)>(Foo))""" - return _GenericDiagnoser('OFM', 'Overloaded Function Matcher', - [(gcc_regex, diagnosis), - (clang_regex, diagnosis)], - msg) - - -def _OverloadedFunctionActionDiagnoser(msg): - """Diagnoses the OFA disease, given the error messages by the compiler.""" - - gcc_regex = (_GCC_FILE_LINE_RE + r'error: no matching function for call to ' - r'\'Invoke\(<unresolved overloaded function type>') - clang_regex = (_CLANG_FILE_LINE_RE + r'error: no matching ' - r'function for call to \'Invoke\'\r?\n' - r'(.*\n)*?' - r'.*\bgmock-generated-actions\.h:\d+:\d+:\s+' - r'note: candidate template ignored:\s+' - r'couldn\'t infer template argument \'FunctionImpl\'') - diagnosis = """ -Function you are passing to Invoke is overloaded. Please tell your compiler -which overloaded version you want to use. - -For example, if you want to use the version whose signature is - bool MyFunction(int n, double x); -you should write something like - Invoke(static_cast<bool (*)(int n, double x)>(MyFunction))""" - return _GenericDiagnoser('OFA', 'Overloaded Function Action', - [(gcc_regex, diagnosis), - (clang_regex, diagnosis)], - msg) - - -def _OverloadedMethodActionDiagnoser(msg): - """Diagnoses the OMA disease, given the error messages by the compiler.""" - - gcc_regex = (_GCC_FILE_LINE_RE + r'error: no matching function for ' - r'call to \'Invoke\(.+, <unresolved overloaded function ' - r'type>\)') - clang_regex = (_CLANG_FILE_LINE_RE + r'error: no matching function ' - r'for call to \'Invoke\'\r?\n' - r'(.*\n)*?' - r'.*\bgmock-generated-actions\.h:\d+:\d+: ' - r'note: candidate function template not viable: ' - r'requires .*, but 2 (arguments )?were provided') - diagnosis = """ -The second argument you gave to Invoke() is an overloaded method. Please -tell your compiler which overloaded version you want to use. - -For example, if you want to use the version whose signature is - class Foo { - ... - bool Bar(int n, double x); - }; -you should write something like - Invoke(foo, static_cast<bool (Foo::*)(int n, double x)>(&Foo::Bar))""" - return _GenericDiagnoser('OMA', 'Overloaded Method Action', - [(gcc_regex, diagnosis), - (clang_regex, diagnosis)], - msg) - - -def _MockObjectPointerDiagnoser(msg): - """Diagnoses the MOP disease, given the error messages by the compiler.""" - - gcc_regex = (_GCC_FILE_LINE_RE + r'error: request for member ' - r'\'gmock_(?P<method>.+)\' in \'(?P<mock_object>.+)\', ' - r'which is of non-class type \'(.*::)*(?P<class_name>.+)\*\'') - clang_regex = (_CLANG_FILE_LINE_RE + r'error: member reference type ' - r'\'(?P<class_name>.*?) *\' is a pointer; ' - r'(did you mean|maybe you meant) to use \'->\'\?') - diagnosis = """ -The first argument to ON_CALL() and EXPECT_CALL() must be a mock *object*, -not a *pointer* to it. Please write '*(%(mock_object)s)' instead of -'%(mock_object)s' as your first argument. - -For example, given the mock class: - - class %(class_name)s : public ... { - ... - MOCK_METHOD0(%(method)s, ...); - }; - -and the following mock instance: - - %(class_name)s* mock_ptr = ... - -you should use the EXPECT_CALL like this: - - EXPECT_CALL(*mock_ptr, %(method)s(...));""" - - return _GenericDiagnoser( - 'MOP', - 'Mock Object Pointer', - [(gcc_regex, diagnosis), - (clang_regex, diagnosis % {'mock_object': 'mock_object', - 'method': 'method', - 'class_name': '%(class_name)s'})], - msg) - - -def _NeedToUseSymbolDiagnoser(msg): - """Diagnoses the NUS disease, given the error messages by the compiler.""" - - gcc_regex = (_GCC_FILE_LINE_RE + r'error: \'(?P<symbol>.+)\' ' - r'(was not declared in this scope|has not been declared)') - clang_regex = (_CLANG_FILE_LINE_RE + - r'error: (use of undeclared identifier|unknown type name|' - r'no template named) \'(?P<symbol>[^\']+)\'') - diagnosis = """ -'%(symbol)s' is defined by Google Mock in the testing namespace. -Did you forget to write - using testing::%(symbol)s; -?""" - for m in (list(_FindAllMatches(gcc_regex, msg)) + - list(_FindAllMatches(clang_regex, msg))): - symbol = m.groupdict()['symbol'] - if symbol in _COMMON_GMOCK_SYMBOLS: - yield ('NUS', 'Need to Use Symbol', diagnosis % m.groupdict()) - - -def _NeedToUseReturnNullDiagnoser(msg): - """Diagnoses the NRNULL disease, given the error messages by the compiler.""" - - gcc_regex = ('instantiated from \'testing::internal::ReturnAction<R>' - '::operator testing::Action<Func>\(\) const.*\n' + - _GCC_FILE_LINE_RE + r'instantiated from here\n' - r'.*error: no matching function for call to \'ImplicitCast_\(' - r'(:?long )?int&\)') - clang_regex = (r'\bgmock-actions.h:.* error: no matching function for ' - r'call to \'ImplicitCast_\'\r?\n' - r'(.*\n)*?' + - _CLANG_NON_GMOCK_FILE_LINE_RE + r'note: in instantiation ' - r'of function template specialization ' - r'\'testing::internal::ReturnAction<(int|long)>::operator ' - r'Action<(?P<type>.*)\(\)>\' requested here') - diagnosis = """ -You are probably calling Return(NULL) and the compiler isn't sure how to turn -NULL into %(type)s. Use ReturnNull() instead. -Note: the line number may be off; please fix all instances of Return(NULL).""" - return _GenericDiagnoser( - 'NRNULL', 'Need to use ReturnNull', - [(clang_regex, diagnosis), - (gcc_regex, diagnosis % {'type': 'the right type'})], - msg) - - -def _TypeInTemplatedBaseDiagnoser(msg): - """Diagnoses the TTB disease, given the error messages by the compiler.""" - - # This version works when the type is used as the mock function's return - # type. - gcc_4_3_1_regex_type_in_retval = ( - r'In member function \'int .*\n' + _GCC_FILE_LINE_RE + - r'error: a function call cannot appear in a constant-expression') - gcc_4_4_0_regex_type_in_retval = ( - r'error: a function call cannot appear in a constant-expression' - + _GCC_FILE_LINE_RE + r'error: template argument 1 is invalid\n') - # This version works when the type is used as the mock function's sole - # parameter type. - gcc_regex_type_of_sole_param = ( - _GCC_FILE_LINE_RE + - r'error: \'(?P<type>.+)\' was not declared in this scope\n' - r'.*error: template argument 1 is invalid\n') - # This version works when the type is used as a parameter of a mock - # function that has multiple parameters. - gcc_regex_type_of_a_param = ( - r'error: expected `;\' before \'::\' token\n' - + _GCC_FILE_LINE_RE + - r'error: \'(?P<type>.+)\' was not declared in this scope\n' - r'.*error: template argument 1 is invalid\n' - r'.*error: \'.+\' was not declared in this scope') - clang_regex_type_of_retval_or_sole_param = ( - _CLANG_FILE_LINE_RE + - r'error: use of undeclared identifier \'(?P<type>.*)\'\n' - r'(.*\n)*?' - r'(?P=file):(?P=line):\d+: error: ' - r'non-friend class member \'Result\' cannot have a qualified name' - ) - clang_regex_type_of_a_param = ( - _CLANG_FILE_LINE_RE + - r'error: C\+\+ requires a type specifier for all declarations\n' - r'(.*\n)*?' - r'(?P=file):(?P=line):(?P=column): error: ' - r'C\+\+ requires a type specifier for all declarations' - ) - clang_regex_unknown_type = ( - _CLANG_FILE_LINE_RE + - r'error: unknown type name \'(?P<type>[^\']+)\'' - ) - - diagnosis = """ -In a mock class template, types or typedefs defined in the base class -template are *not* automatically visible. This is how C++ works. Before -you can use a type or typedef named %(type)s defined in base class Base<T>, you -need to make it visible. One way to do it is: - - typedef typename Base<T>::%(type)s %(type)s;""" - - for diag in _GenericDiagnoser( - 'TTB', 'Type in Template Base', - [(gcc_4_3_1_regex_type_in_retval, diagnosis % {'type': 'Foo'}), - (gcc_4_4_0_regex_type_in_retval, diagnosis % {'type': 'Foo'}), - (gcc_regex_type_of_sole_param, diagnosis), - (gcc_regex_type_of_a_param, diagnosis), - (clang_regex_type_of_retval_or_sole_param, diagnosis), - (clang_regex_type_of_a_param, diagnosis % {'type': 'Foo'})], - msg): - yield diag - # Avoid overlap with the NUS pattern. - for m in _FindAllMatches(clang_regex_unknown_type, msg): - type_ = m.groupdict()['type'] - if type_ not in _COMMON_GMOCK_SYMBOLS: - yield ('TTB', 'Type in Template Base', diagnosis % m.groupdict()) - - -def _WrongMockMethodMacroDiagnoser(msg): - """Diagnoses the WMM disease, given the error messages by the compiler.""" - - gcc_regex = (_GCC_FILE_LINE_RE + - r'.*this_method_does_not_take_(?P<wrong_args>\d+)_argument.*\n' - r'.*\n' - r'.*candidates are.*FunctionMocker<[^>]+A(?P<args>\d+)\)>') - clang_regex = (_CLANG_NON_GMOCK_FILE_LINE_RE + - r'error:.*array.*negative.*r?\n' - r'(.*\n)*?' - r'(?P=file):(?P=line):(?P=column): error: too few arguments ' - r'to function call, expected (?P<args>\d+), ' - r'have (?P<wrong_args>\d+)') - clang11_re = (_CLANG_NON_GMOCK_FILE_LINE_RE + - r'.*this_method_does_not_take_' - r'(?P<wrong_args>\d+)_argument.*') - diagnosis = """ -You are using MOCK_METHOD%(wrong_args)s to define a mock method that has -%(args)s arguments. Use MOCK_METHOD%(args)s (or MOCK_CONST_METHOD%(args)s, -MOCK_METHOD%(args)s_T, MOCK_CONST_METHOD%(args)s_T as appropriate) instead.""" - return _GenericDiagnoser('WMM', 'Wrong MOCK_METHODn Macro', - [(gcc_regex, diagnosis), - (clang11_re, diagnosis % {'wrong_args': 'm', - 'args': 'n'}), - (clang_regex, diagnosis)], - msg) - - -def _WrongParenPositionDiagnoser(msg): - """Diagnoses the WPP disease, given the error messages by the compiler.""" - - gcc_regex = (_GCC_FILE_LINE_RE + - r'error:.*testing::internal::MockSpec<.* has no member named \'' - r'(?P<method>\w+)\'') - clang_regex = (_CLANG_NON_GMOCK_FILE_LINE_RE + - r'error: no member named \'(?P<method>\w+)\' in ' - r'\'testing::internal::MockSpec<.*>\'') - diagnosis = """ -The closing parenthesis of ON_CALL or EXPECT_CALL should be *before* -".%(method)s". For example, you should write: - EXPECT_CALL(my_mock, Foo(_)).%(method)s(...); -instead of: - EXPECT_CALL(my_mock, Foo(_).%(method)s(...));""" - return _GenericDiagnoser('WPP', 'Wrong Parenthesis Position', - [(gcc_regex, diagnosis), - (clang_regex, diagnosis)], - msg) - - -_DIAGNOSERS = [ - _IncompleteByReferenceArgumentDiagnoser, - _MockObjectPointerDiagnoser, - _NeedToReturnNothingDiagnoser, - _NeedToReturnReferenceDiagnoser, - _NeedToReturnSomethingDiagnoser, - _NeedToUseReturnNullDiagnoser, - _NeedToUseSymbolDiagnoser, - _OverloadedFunctionActionDiagnoser, - _OverloadedFunctionMatcherDiagnoser, - _OverloadedMethodActionDiagnoser, - _TypeInTemplatedBaseDiagnoser, - _WrongMockMethodMacroDiagnoser, - _WrongParenPositionDiagnoser, - ] - - -def Diagnose(msg): - """Generates all possible diagnoses given the compiler error message.""" - - msg = re.sub(r'\x1b\[[^m]*m', '', msg) # Strips all color formatting. - # Assuming the string is using the UTF-8 encoding, replaces the left and - # the right single quote characters with apostrophes. - msg = re.sub(r'(\xe2\x80\x98|\xe2\x80\x99)', "'", msg) - - diagnoses = [] - for diagnoser in _DIAGNOSERS: - for diag in diagnoser(msg): - diagnosis = '[%s - %s]\n%s' % diag - if not diagnosis in diagnoses: - diagnoses.append(diagnosis) - return diagnoses - - -def main(): - print ('Google Mock Doctor v%s - ' - 'diagnoses problems in code using Google Mock.' % _VERSION) - - if sys.stdin.isatty(): - print ('Please copy and paste the compiler errors here. Press c-D when ' - 'you are done:') - else: - print ('Waiting for compiler errors on stdin . . .') - - msg = sys.stdin.read().strip() - diagnoses = Diagnose(msg) - count = len(diagnoses) - if not count: - print (""" -Your compiler complained: -8<------------------------------------------------------------ -%s ------------------------------------------------------------->8 - -Uh-oh, I'm not smart enough to figure out what the problem is. :-( -However... -If you send your source code and the compiler's error messages to -%s, you can be helped and I can get smarter -- -win-win for us!""" % (msg, _EMAIL)) - else: - print ('------------------------------------------------------------') - print ('Your code appears to have the following',) - if count > 1: - print ('%s diseases:' % (count,)) - else: - print ('disease:') - i = 0 - for d in diagnoses: - i += 1 - if count > 1: - print ('\n#%s:' % (i,)) - print (d) - print (""" -How did I do? If you think I'm wrong or unhelpful, please send your -source code and the compiler's error messages to %s. -Then you can be helped and I can get smarter -- I promise I won't be upset!""" % - _EMAIL) - - -if __name__ == '__main__': - main() diff --git a/contrib/googletest/googlemock/scripts/upload.py b/contrib/googletest/googlemock/scripts/upload.py deleted file mode 100755 index 95239dc2cbed..000000000000 --- a/contrib/googletest/googlemock/scripts/upload.py +++ /dev/null @@ -1,1387 +0,0 @@ -#!/usr/bin/env python -# -# 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. - -"""Tool for uploading diffs from a version control system to the codereview app. - -Usage summary: upload.py [options] [-- diff_options] - -Diff options are passed to the diff command of the underlying system. - -Supported version control systems: - Git - Mercurial - Subversion - -It is important for Git/Mercurial users to specify a tree/node/branch to diff -against by using the '--rev' option. -""" -# This code is derived from appcfg.py in the App Engine SDK (open source), -# and from ASPN recipe #146306. - -import cookielib -import getpass -import logging -import md5 -import mimetypes -import optparse -import os -import re -import socket -import subprocess -import sys -import urllib -import urllib2 -import urlparse - -try: - import readline -except ImportError: - pass - -# The logging verbosity: -# 0: Errors only. -# 1: Status messages. -# 2: Info logs. -# 3: Debug logs. -verbosity = 1 - -# Max size of patch or base file. -MAX_UPLOAD_SIZE = 900 * 1024 - - -def GetEmail(prompt): - """Prompts the user for their email address and returns it. - - The last used email address is saved to a file and offered up as a suggestion - to the user. If the user presses enter without typing in anything the last - used email address is used. If the user enters a new address, it is saved - for next time we prompt. - - """ - last_email_file_name = os.path.expanduser("~/.last_codereview_email_address") - last_email = "" - if os.path.exists(last_email_file_name): - try: - last_email_file = open(last_email_file_name, "r") - last_email = last_email_file.readline().strip("\n") - last_email_file.close() - prompt += " [%s]" % last_email - except IOError, e: - pass - email = raw_input(prompt + ": ").strip() - if email: - try: - last_email_file = open(last_email_file_name, "w") - last_email_file.write(email) - last_email_file.close() - except IOError, e: - pass - else: - email = last_email - return email - - -def StatusUpdate(msg): - """Print a status message to stdout. - - If 'verbosity' is greater than 0, print the message. - - Args: - msg: The string to print. - """ - if verbosity > 0: - print msg - - -def ErrorExit(msg): - """Print an error message to stderr and exit.""" - print >>sys.stderr, msg - sys.exit(1) - - -class ClientLoginError(urllib2.HTTPError): - """Raised to indicate there was an error authenticating with ClientLogin.""" - - def __init__(self, url, code, msg, headers, args): - urllib2.HTTPError.__init__(self, url, code, msg, headers, None) - self.args = args - self.reason = args["Error"] - - -class AbstractRpcServer(object): - """Provides a common interface for a simple RPC server.""" - - def __init__(self, host, auth_function, host_override=None, extra_headers={}, - save_cookies=False): - """Creates a new HttpRpcServer. - - Args: - host: The host to send requests to. - auth_function: A function that takes no arguments and returns an - (email, password) tuple when called. Will be called if authentication - is required. - host_override: The host header to send to the server (defaults to host). - extra_headers: A dict of extra headers to append to every request. - save_cookies: If True, save the authentication cookies to local disk. - If False, use an in-memory cookiejar instead. Subclasses must - implement this functionality. Defaults to False. - """ - self.host = host - self.host_override = host_override - self.auth_function = auth_function - self.authenticated = False - self.extra_headers = extra_headers - self.save_cookies = save_cookies - self.opener = self._GetOpener() - if self.host_override: - logging.info("Server: %s; Host: %s", self.host, self.host_override) - else: - logging.info("Server: %s", self.host) - - def _GetOpener(self): - """Returns an OpenerDirector for making HTTP requests. - - Returns: - A urllib2.OpenerDirector object. - """ - raise NotImplementedError() - - def _CreateRequest(self, url, data=None): - """Creates a new urllib request.""" - logging.debug("Creating request for: '%s' with payload:\n%s", url, data) - req = urllib2.Request(url, data=data) - if self.host_override: - req.add_header("Host", self.host_override) - for key, value in self.extra_headers.iteritems(): - req.add_header(key, value) - return req - - def _GetAuthToken(self, email, password): - """Uses ClientLogin to authenticate the user, returning an auth token. - - Args: - email: The user's email address - password: The user's password - - Raises: - ClientLoginError: If there was an error authenticating with ClientLogin. - HTTPError: If there was some other form of HTTP error. - - Returns: - The authentication token returned by ClientLogin. - """ - account_type = "GOOGLE" - if self.host.endswith(".google.com"): - # Needed for use inside Google. - account_type = "HOSTED" - req = self._CreateRequest( - url="https://www.google.com/accounts/ClientLogin", - data=urllib.urlencode({ - "Email": email, - "Passwd": password, - "service": "ah", - "source": "rietveld-codereview-upload", - "accountType": account_type, - }), - ) - try: - response = self.opener.open(req) - response_body = response.read() - response_dict = dict(x.split("=") - for x in response_body.split("\n") if x) - return response_dict["Auth"] - except urllib2.HTTPError, e: - if e.code == 403: - body = e.read() - response_dict = dict(x.split("=", 1) for x in body.split("\n") if x) - raise ClientLoginError(req.get_full_url(), e.code, e.msg, - e.headers, response_dict) - else: - raise - - def _GetAuthCookie(self, auth_token): - """Fetches authentication cookies for an authentication token. - - Args: - auth_token: The authentication token returned by ClientLogin. - - Raises: - HTTPError: If there was an error fetching the authentication cookies. - """ - # This is a dummy value to allow us to identify when we're successful. - continue_location = "http://localhost/" - args = {"continue": continue_location, "auth": auth_token} - req = self._CreateRequest("http://%s/_ah/login?%s" % - (self.host, urllib.urlencode(args))) - try: - response = self.opener.open(req) - except urllib2.HTTPError, e: - response = e - if (response.code != 302 or - response.info()["location"] != continue_location): - raise urllib2.HTTPError(req.get_full_url(), response.code, response.msg, - response.headers, response.fp) - self.authenticated = True - - def _Authenticate(self): - """Authenticates the user. - - The authentication process works as follows: - 1) We get a username and password from the user - 2) We use ClientLogin to obtain an AUTH token for the user - (see https://developers.google.com/identity/protocols/AuthForInstalledApps). - 3) We pass the auth token to /_ah/login on the server to obtain an - authentication cookie. If login was successful, it tries to redirect - us to the URL we provided. - - If we attempt to access the upload API without first obtaining an - authentication cookie, it returns a 401 response and directs us to - authenticate ourselves with ClientLogin. - """ - for i in range(3): - credentials = self.auth_function() - try: - auth_token = self._GetAuthToken(credentials[0], credentials[1]) - except ClientLoginError, e: - if e.reason == "BadAuthentication": - print >>sys.stderr, "Invalid username or password." - continue - if e.reason == "CaptchaRequired": - print >>sys.stderr, ( - "Please go to\n" - "https://www.google.com/accounts/DisplayUnlockCaptcha\n" - "and verify you are a human. Then try again.") - break - if e.reason == "NotVerified": - print >>sys.stderr, "Account not verified." - break - if e.reason == "TermsNotAgreed": - print >>sys.stderr, "User has not agreed to TOS." - break - if e.reason == "AccountDeleted": - print >>sys.stderr, "The user account has been deleted." - break - if e.reason == "AccountDisabled": - print >>sys.stderr, "The user account has been disabled." - break - if e.reason == "ServiceDisabled": - print >>sys.stderr, ("The user's access to the service has been " - "disabled.") - break - if e.reason == "ServiceUnavailable": - print >>sys.stderr, "The service is not available; try again later." - break - raise - self._GetAuthCookie(auth_token) - return - - def Send(self, request_path, payload=None, - content_type="application/octet-stream", - timeout=None, - **kwargs): - """Sends an RPC and returns the response. - - Args: - request_path: The path to send the request to, eg /api/appversion/create. - payload: The body of the request, or None to send an empty request. - content_type: The Content-Type header to use. - timeout: timeout in seconds; default None i.e. no timeout. - (Note: for large requests on OS X, the timeout doesn't work right.) - kwargs: Any keyword arguments are converted into query string parameters. - - Returns: - The response body, as a string. - """ - # TODO: Don't require authentication. Let the server say - # whether it is necessary. - if not self.authenticated: - self._Authenticate() - - old_timeout = socket.getdefaulttimeout() - socket.setdefaulttimeout(timeout) - try: - tries = 0 - while True: - tries += 1 - args = dict(kwargs) - url = "http://%s%s" % (self.host, request_path) - if args: - url += "?" + urllib.urlencode(args) - req = self._CreateRequest(url=url, data=payload) - req.add_header("Content-Type", content_type) - try: - f = self.opener.open(req) - response = f.read() - f.close() - return response - except urllib2.HTTPError, e: - if tries > 3: - raise - elif e.code == 401: - self._Authenticate() -## elif e.code >= 500 and e.code < 600: -## # Server Error - try again. -## continue - else: - raise - finally: - socket.setdefaulttimeout(old_timeout) - - -class HttpRpcServer(AbstractRpcServer): - """Provides a simplified RPC-style interface for HTTP requests.""" - - def _Authenticate(self): - """Save the cookie jar after authentication.""" - super(HttpRpcServer, self)._Authenticate() - if self.save_cookies: - StatusUpdate("Saving authentication cookies to %s" % self.cookie_file) - self.cookie_jar.save() - - def _GetOpener(self): - """Returns an OpenerDirector that supports cookies and ignores redirects. - - Returns: - A urllib2.OpenerDirector object. - """ - opener = urllib2.OpenerDirector() - opener.add_handler(urllib2.ProxyHandler()) - opener.add_handler(urllib2.UnknownHandler()) - opener.add_handler(urllib2.HTTPHandler()) - opener.add_handler(urllib2.HTTPDefaultErrorHandler()) - opener.add_handler(urllib2.HTTPSHandler()) - opener.add_handler(urllib2.HTTPErrorProcessor()) - if self.save_cookies: - self.cookie_file = os.path.expanduser("~/.codereview_upload_cookies") - self.cookie_jar = cookielib.MozillaCookieJar(self.cookie_file) - if os.path.exists(self.cookie_file): - try: - self.cookie_jar.load() - self.authenticated = True - StatusUpdate("Loaded authentication cookies from %s" % - self.cookie_file) - except (cookielib.LoadError, IOError): - # Failed to load cookies - just ignore them. - pass - else: - # Create an empty cookie file with mode 600 - fd = os.open(self.cookie_file, os.O_CREAT, 0600) - os.close(fd) - # Always chmod the cookie file - os.chmod(self.cookie_file, 0600) - else: - # Don't save cookies across runs of update.py. - self.cookie_jar = cookielib.CookieJar() - opener.add_handler(urllib2.HTTPCookieProcessor(self.cookie_jar)) - return opener - - -parser = optparse.OptionParser(usage="%prog [options] [-- diff_options]") -parser.add_option("-y", "--assume_yes", action="store_true", - dest="assume_yes", default=False, - help="Assume that the answer to yes/no questions is 'yes'.") -# Logging -group = parser.add_option_group("Logging options") -group.add_option("-q", "--quiet", action="store_const", const=0, - dest="verbose", help="Print errors only.") -group.add_option("-v", "--verbose", action="store_const", const=2, - dest="verbose", default=1, - help="Print info level logs (default).") -group.add_option("--noisy", action="store_const", const=3, - dest="verbose", help="Print all logs.") -# Review server -group = parser.add_option_group("Review server options") -group.add_option("-s", "--server", action="store", dest="server", - default="codereview.appspot.com", - metavar="SERVER", - help=("The server to upload to. The format is host[:port]. " - "Defaults to 'codereview.appspot.com'.")) -group.add_option("-e", "--email", action="store", dest="email", - metavar="EMAIL", default=None, - help="The username to use. Will prompt if omitted.") -group.add_option("-H", "--host", action="store", dest="host", - metavar="HOST", default=None, - help="Overrides the Host header sent with all RPCs.") -group.add_option("--no_cookies", action="store_false", - dest="save_cookies", default=True, - help="Do not save authentication cookies to local disk.") -# Issue -group = parser.add_option_group("Issue options") -group.add_option("-d", "--description", action="store", dest="description", - metavar="DESCRIPTION", default=None, - help="Optional description when creating an issue.") -group.add_option("-f", "--description_file", action="store", - dest="description_file", metavar="DESCRIPTION_FILE", - default=None, - help="Optional path of a file that contains " - "the description when creating an issue.") -group.add_option("-r", "--reviewers", action="store", dest="reviewers", - metavar="REVIEWERS", default=None, - help="Add reviewers (comma separated email addresses).") -group.add_option("--cc", action="store", dest="cc", - metavar="CC", default=None, - help="Add CC (comma separated email addresses).") -# Upload options -group = parser.add_option_group("Patch options") -group.add_option("-m", "--message", action="store", dest="message", - metavar="MESSAGE", default=None, - help="A message to identify the patch. " - "Will prompt if omitted.") -group.add_option("-i", "--issue", type="int", action="store", - metavar="ISSUE", default=None, - help="Issue number to which to add. Defaults to new issue.") -group.add_option("--download_base", action="store_true", - dest="download_base", default=False, - help="Base files will be downloaded by the server " - "(side-by-side diffs may not work on files with CRs).") -group.add_option("--rev", action="store", dest="revision", - metavar="REV", default=None, - help="Branch/tree/revision to diff against (used by DVCS).") -group.add_option("--send_mail", action="store_true", - dest="send_mail", default=False, - help="Send notification email to reviewers.") - - -def GetRpcServer(options): - """Returns an instance of an AbstractRpcServer. - - Returns: - A new AbstractRpcServer, on which RPC calls can be made. - """ - - rpc_server_class = HttpRpcServer - - def GetUserCredentials(): - """Prompts the user for a username and password.""" - email = options.email - if email is None: - email = GetEmail("Email (login for uploading to %s)" % options.server) - password = getpass.getpass("Password for %s: " % email) - return (email, password) - - # If this is the dev_appserver, use fake authentication. - host = (options.host or options.server).lower() - if host == "localhost" or host.startswith("localhost:"): - email = options.email - if email is None: - email = "test@example.com" - logging.info("Using debug user %s. Override with --email" % email) - server = rpc_server_class( - options.server, - lambda: (email, "password"), - host_override=options.host, - extra_headers={"Cookie": - 'dev_appserver_login="%s:False"' % email}, - save_cookies=options.save_cookies) - # Don't try to talk to ClientLogin. - server.authenticated = True - return server - - return rpc_server_class(options.server, GetUserCredentials, - host_override=options.host, - save_cookies=options.save_cookies) - - -def EncodeMultipartFormData(fields, files): - """Encode form fields for multipart/form-data. - - Args: - fields: A sequence of (name, value) elements for regular form fields. - files: A sequence of (name, filename, value) elements for data to be - uploaded as files. - Returns: - (content_type, body) ready for httplib.HTTP instance. - - Source: - https://web.archive.org/web/20160116052001/code.activestate.com/recipes/146306 - """ - BOUNDARY = '-M-A-G-I-C---B-O-U-N-D-A-R-Y-' - CRLF = '\r\n' - lines = [] - for (key, value) in fields: - lines.append('--' + BOUNDARY) - lines.append('Content-Disposition: form-data; name="%s"' % key) - lines.append('') - lines.append(value) - for (key, filename, value) in files: - lines.append('--' + BOUNDARY) - lines.append('Content-Disposition: form-data; name="%s"; filename="%s"' % - (key, filename)) - lines.append('Content-Type: %s' % GetContentType(filename)) - lines.append('') - lines.append(value) - lines.append('--' + BOUNDARY + '--') - lines.append('') - body = CRLF.join(lines) - content_type = 'multipart/form-data; boundary=%s' % BOUNDARY - return content_type, body - - -def GetContentType(filename): - """Helper to guess the content-type from the filename.""" - return mimetypes.guess_type(filename)[0] or 'application/octet-stream' - - -# Use a shell for subcommands on Windows to get a PATH search. -use_shell = sys.platform.startswith("win") - -def RunShellWithReturnCode(command, print_output=False, - universal_newlines=True): - """Executes a command and returns the output from stdout and the return code. - - Args: - command: Command to execute. - print_output: If True, the output is printed to stdout. - If False, both stdout and stderr are ignored. - universal_newlines: Use universal_newlines flag (default: True). - - Returns: - Tuple (output, return code) - """ - logging.info("Running %s", command) - p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, - shell=use_shell, universal_newlines=universal_newlines) - if print_output: - output_array = [] - while True: - line = p.stdout.readline() - if not line: - break - print line.strip("\n") - output_array.append(line) - output = "".join(output_array) - else: - output = p.stdout.read() - p.wait() - errout = p.stderr.read() - if print_output and errout: - print >>sys.stderr, errout - p.stdout.close() - p.stderr.close() - return output, p.returncode - - -def RunShell(command, silent_ok=False, universal_newlines=True, - print_output=False): - data, retcode = RunShellWithReturnCode(command, print_output, - universal_newlines) - if retcode: - ErrorExit("Got error status from %s:\n%s" % (command, data)) - if not silent_ok and not data: - ErrorExit("No output from %s" % command) - return data - - -class VersionControlSystem(object): - """Abstract base class providing an interface to the VCS.""" - - def __init__(self, options): - """Constructor. - - Args: - options: Command line options. - """ - self.options = options - - def GenerateDiff(self, args): - """Return the current diff as a string. - - Args: - args: Extra arguments to pass to the diff command. - """ - raise NotImplementedError( - "abstract method -- subclass %s must override" % self.__class__) - - def GetUnknownFiles(self): - """Return a list of files unknown to the VCS.""" - raise NotImplementedError( - "abstract method -- subclass %s must override" % self.__class__) - - def CheckForUnknownFiles(self): - """Show an "are you sure?" prompt if there are unknown files.""" - unknown_files = self.GetUnknownFiles() - if unknown_files: - print "The following files are not added to version control:" - for line in unknown_files: - print line - prompt = "Are you sure to continue?(y/N) " - answer = raw_input(prompt).strip() - if answer != "y": - ErrorExit("User aborted") - - def GetBaseFile(self, filename): - """Get the content of the upstream version of a file. - - Returns: - A tuple (base_content, new_content, is_binary, status) - base_content: The contents of the base file. - new_content: For text files, this is empty. For binary files, this is - the contents of the new file, since the diff output won't contain - information to reconstruct the current file. - is_binary: True iff the file is binary. - status: The status of the file. - """ - - raise NotImplementedError( - "abstract method -- subclass %s must override" % self.__class__) - - - def GetBaseFiles(self, diff): - """Helper that calls GetBase file for each file in the patch. - - Returns: - A dictionary that maps from filename to GetBaseFile's tuple. Filenames - are retrieved based on lines that start with "Index:" or - "Property changes on:". - """ - files = {} - for line in diff.splitlines(True): - if line.startswith('Index:') or line.startswith('Property changes on:'): - unused, filename = line.split(':', 1) - # On Windows if a file has property changes its filename uses '\' - # instead of '/'. - filename = filename.strip().replace('\\', '/') - files[filename] = self.GetBaseFile(filename) - return files - - - def UploadBaseFiles(self, issue, rpc_server, patch_list, patchset, options, - files): - """Uploads the base files (and if necessary, the current ones as well).""" - - def UploadFile(filename, file_id, content, is_binary, status, is_base): - """Uploads a file to the server.""" - file_too_large = False - if is_base: - type = "base" - else: - type = "current" - if len(content) > MAX_UPLOAD_SIZE: - print ("Not uploading the %s file for %s because it's too large." % - (type, filename)) - file_too_large = True - content = "" - checksum = md5.new(content).hexdigest() - if options.verbose > 0 and not file_too_large: - print "Uploading %s file for %s" % (type, filename) - url = "/%d/upload_content/%d/%d" % (int(issue), int(patchset), file_id) - form_fields = [("filename", filename), - ("status", status), - ("checksum", checksum), - ("is_binary", str(is_binary)), - ("is_current", str(not is_base)), - ] - if file_too_large: - form_fields.append(("file_too_large", "1")) - if options.email: - form_fields.append(("user", options.email)) - ctype, body = EncodeMultipartFormData(form_fields, - [("data", filename, content)]) - response_body = rpc_server.Send(url, body, - content_type=ctype) - if not response_body.startswith("OK"): - StatusUpdate(" --> %s" % response_body) - sys.exit(1) - - patches = dict() - [patches.setdefault(v, k) for k, v in patch_list] - for filename in patches.keys(): - base_content, new_content, is_binary, status = files[filename] - file_id_str = patches.get(filename) - if file_id_str.find("nobase") != -1: - base_content = None - file_id_str = file_id_str[file_id_str.rfind("_") + 1:] - file_id = int(file_id_str) - if base_content != None: - UploadFile(filename, file_id, base_content, is_binary, status, True) - if new_content != None: - UploadFile(filename, file_id, new_content, is_binary, status, False) - - def IsImage(self, filename): - """Returns true if the filename has an image extension.""" - mimetype = mimetypes.guess_type(filename)[0] - if not mimetype: - return False - return mimetype.startswith("image/") - - -class SubversionVCS(VersionControlSystem): - """Implementation of the VersionControlSystem interface for Subversion.""" - - def __init__(self, options): - super(SubversionVCS, self).__init__(options) - if self.options.revision: - match = re.match(r"(\d+)(:(\d+))?", self.options.revision) - if not match: - ErrorExit("Invalid Subversion revision %s." % self.options.revision) - self.rev_start = match.group(1) - self.rev_end = match.group(3) - else: - self.rev_start = self.rev_end = None - # Cache output from "svn list -r REVNO dirname". - # Keys: dirname, Values: 2-tuple (ouput for start rev and end rev). - self.svnls_cache = {} - # SVN base URL is required to fetch files deleted in an older revision. - # Result is cached to not guess it over and over again in GetBaseFile(). - required = self.options.download_base or self.options.revision is not None - self.svn_base = self._GuessBase(required) - - def GuessBase(self, required): - """Wrapper for _GuessBase.""" - return self.svn_base - - def _GuessBase(self, required): - """Returns the SVN base URL. - - Args: - required: If true, exits if the url can't be guessed, otherwise None is - returned. - """ - info = RunShell(["svn", "info"]) - for line in info.splitlines(): - words = line.split() - if len(words) == 2 and words[0] == "URL:": - url = words[1] - scheme, netloc, path, params, query, fragment = urlparse.urlparse(url) - username, netloc = urllib.splituser(netloc) - if username: - logging.info("Removed username from base URL") - if netloc.endswith("svn.python.org"): - if netloc == "svn.python.org": - if path.startswith("/projects/"): - path = path[9:] - elif netloc != "pythondev@svn.python.org": - ErrorExit("Unrecognized Python URL: %s" % url) - base = "http://svn.python.org/view/*checkout*%s/" % path - logging.info("Guessed Python base = %s", base) - elif netloc.endswith("svn.collab.net"): - if path.startswith("/repos/"): - path = path[6:] - base = "http://svn.collab.net/viewvc/*checkout*%s/" % path - logging.info("Guessed CollabNet base = %s", base) - elif netloc.endswith(".googlecode.com"): - path = path + "/" - base = urlparse.urlunparse(("http", netloc, path, params, - query, fragment)) - logging.info("Guessed Google Code base = %s", base) - else: - path = path + "/" - base = urlparse.urlunparse((scheme, netloc, path, params, - query, fragment)) - logging.info("Guessed base = %s", base) - return base - if required: - ErrorExit("Can't find URL in output from svn info") - return None - - def GenerateDiff(self, args): - cmd = ["svn", "diff"] - if self.options.revision: - cmd += ["-r", self.options.revision] - cmd.extend(args) - data = RunShell(cmd) - count = 0 - for line in data.splitlines(): - if line.startswith("Index:") or line.startswith("Property changes on:"): - count += 1 - logging.info(line) - if not count: - ErrorExit("No valid patches found in output from svn diff") - return data - - def _CollapseKeywords(self, content, keyword_str): - """Collapses SVN keywords.""" - # svn cat translates keywords but svn diff doesn't. As a result of this - # behavior patching.PatchChunks() fails with a chunk mismatch error. - # This part was originally written by the Review Board development team - # who had the same problem (https://reviews.reviewboard.org/r/276/). - # Mapping of keywords to known aliases - svn_keywords = { - # Standard keywords - 'Date': ['Date', 'LastChangedDate'], - 'Revision': ['Revision', 'LastChangedRevision', 'Rev'], - 'Author': ['Author', 'LastChangedBy'], - 'HeadURL': ['HeadURL', 'URL'], - 'Id': ['Id'], - - # Aliases - 'LastChangedDate': ['LastChangedDate', 'Date'], - 'LastChangedRevision': ['LastChangedRevision', 'Rev', 'Revision'], - 'LastChangedBy': ['LastChangedBy', 'Author'], - 'URL': ['URL', 'HeadURL'], - } - - def repl(m): - if m.group(2): - return "$%s::%s$" % (m.group(1), " " * len(m.group(3))) - return "$%s$" % m.group(1) - keywords = [keyword - for name in keyword_str.split(" ") - for keyword in svn_keywords.get(name, [])] - return re.sub(r"\$(%s):(:?)([^\$]+)\$" % '|'.join(keywords), repl, content) - - def GetUnknownFiles(self): - status = RunShell(["svn", "status", "--ignore-externals"], silent_ok=True) - unknown_files = [] - for line in status.split("\n"): - if line and line[0] == "?": - unknown_files.append(line) - return unknown_files - - def ReadFile(self, filename): - """Returns the contents of a file.""" - file = open(filename, 'rb') - result = "" - try: - result = file.read() - finally: - file.close() - return result - - def GetStatus(self, filename): - """Returns the status of a file.""" - if not self.options.revision: - status = RunShell(["svn", "status", "--ignore-externals", filename]) - if not status: - ErrorExit("svn status returned no output for %s" % filename) - status_lines = status.splitlines() - # If file is in a cl, the output will begin with - # "\n--- Changelist 'cl_name':\n". See - # https://web.archive.org/web/20090918234815/svn.collab.net/repos/svn/trunk/notes/changelist-design.txt - if (len(status_lines) == 3 and - not status_lines[0] and - status_lines[1].startswith("--- Changelist")): - status = status_lines[2] - else: - status = status_lines[0] - # If we have a revision to diff against we need to run "svn list" - # for the old and the new revision and compare the results to get - # the correct status for a file. - else: - dirname, relfilename = os.path.split(filename) - if dirname not in self.svnls_cache: - cmd = ["svn", "list", "-r", self.rev_start, dirname or "."] - out, returncode = RunShellWithReturnCode(cmd) - if returncode: - ErrorExit("Failed to get status for %s." % filename) - old_files = out.splitlines() - args = ["svn", "list"] - if self.rev_end: - args += ["-r", self.rev_end] - cmd = args + [dirname or "."] - out, returncode = RunShellWithReturnCode(cmd) - if returncode: - ErrorExit("Failed to run command %s" % cmd) - self.svnls_cache[dirname] = (old_files, out.splitlines()) - old_files, new_files = self.svnls_cache[dirname] - if relfilename in old_files and relfilename not in new_files: - status = "D " - elif relfilename in old_files and relfilename in new_files: - status = "M " - else: - status = "A " - return status - - def GetBaseFile(self, filename): - status = self.GetStatus(filename) - base_content = None - new_content = None - - # If a file is copied its status will be "A +", which signifies - # "addition-with-history". See "svn st" for more information. We need to - # upload the original file or else diff parsing will fail if the file was - # edited. - if status[0] == "A" and status[3] != "+": - # We'll need to upload the new content if we're adding a binary file - # since diff's output won't contain it. - mimetype = RunShell(["svn", "propget", "svn:mime-type", filename], - silent_ok=True) - base_content = "" - is_binary = mimetype and not mimetype.startswith("text/") - if is_binary and self.IsImage(filename): - new_content = self.ReadFile(filename) - elif (status[0] in ("M", "D", "R") or - (status[0] == "A" and status[3] == "+") or # Copied file. - (status[0] == " " and status[1] == "M")): # Property change. - args = [] - if self.options.revision: - url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) - else: - # Don't change filename, it's needed later. - url = filename - args += ["-r", "BASE"] - cmd = ["svn"] + args + ["propget", "svn:mime-type", url] - mimetype, returncode = RunShellWithReturnCode(cmd) - if returncode: - # File does not exist in the requested revision. - # Reset mimetype, it contains an error message. - mimetype = "" - get_base = False - is_binary = mimetype and not mimetype.startswith("text/") - if status[0] == " ": - # Empty base content just to force an upload. - base_content = "" - elif is_binary: - if self.IsImage(filename): - get_base = True - if status[0] == "M": - if not self.rev_end: - new_content = self.ReadFile(filename) - else: - url = "%s/%s@%s" % (self.svn_base, filename, self.rev_end) - new_content = RunShell(["svn", "cat", url], - universal_newlines=True, silent_ok=True) - else: - base_content = "" - else: - get_base = True - - if get_base: - if is_binary: - universal_newlines = False - else: - universal_newlines = True - if self.rev_start: - # "svn cat -r REV delete_file.txt" doesn't work. cat requires - # the full URL with "@REV" appended instead of using "-r" option. - url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) - base_content = RunShell(["svn", "cat", url], - universal_newlines=universal_newlines, - silent_ok=True) - else: - base_content = RunShell(["svn", "cat", filename], - universal_newlines=universal_newlines, - silent_ok=True) - if not is_binary: - args = [] - if self.rev_start: - url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) - else: - url = filename - args += ["-r", "BASE"] - cmd = ["svn"] + args + ["propget", "svn:keywords", url] - keywords, returncode = RunShellWithReturnCode(cmd) - if keywords and not returncode: - base_content = self._CollapseKeywords(base_content, keywords) - else: - StatusUpdate("svn status returned unexpected output: %s" % status) - sys.exit(1) - return base_content, new_content, is_binary, status[0:5] - - -class GitVCS(VersionControlSystem): - """Implementation of the VersionControlSystem interface for Git.""" - - def __init__(self, options): - super(GitVCS, self).__init__(options) - # Map of filename -> hash of base file. - self.base_hashes = {} - - def GenerateDiff(self, extra_args): - # This is more complicated than svn's GenerateDiff because we must convert - # the diff output to include an svn-style "Index:" line as well as record - # the hashes of the base files, so we can upload them along with our diff. - if self.options.revision: - extra_args = [self.options.revision] + extra_args - gitdiff = RunShell(["git", "diff", "--full-index"] + extra_args) - svndiff = [] - filecount = 0 - filename = None - for line in gitdiff.splitlines(): - match = re.match(r"diff --git a/(.*) b/.*$", line) - if match: - filecount += 1 - filename = match.group(1) - svndiff.append("Index: %s\n" % filename) - else: - # The "index" line in a git diff looks like this (long hashes elided): - # index 82c0d44..b2cee3f 100755 - # We want to save the left hash, as that identifies the base file. - match = re.match(r"index (\w+)\.\.", line) - if match: - self.base_hashes[filename] = match.group(1) - svndiff.append(line + "\n") - if not filecount: - ErrorExit("No valid patches found in output from git diff") - return "".join(svndiff) - - def GetUnknownFiles(self): - status = RunShell(["git", "ls-files", "--exclude-standard", "--others"], - silent_ok=True) - return status.splitlines() - - def GetBaseFile(self, filename): - hash = self.base_hashes[filename] - base_content = None - new_content = None - is_binary = False - if hash == "0" * 40: # All-zero hash indicates no base file. - status = "A" - base_content = "" - else: - status = "M" - base_content, returncode = RunShellWithReturnCode(["git", "show", hash]) - if returncode: - ErrorExit("Got error status from 'git show %s'" % hash) - return (base_content, new_content, is_binary, status) - - -class MercurialVCS(VersionControlSystem): - """Implementation of the VersionControlSystem interface for Mercurial.""" - - def __init__(self, options, repo_dir): - super(MercurialVCS, self).__init__(options) - # Absolute path to repository (we can be in a subdir) - self.repo_dir = os.path.normpath(repo_dir) - # Compute the subdir - cwd = os.path.normpath(os.getcwd()) - assert cwd.startswith(self.repo_dir) - self.subdir = cwd[len(self.repo_dir):].lstrip(r"\/") - if self.options.revision: - self.base_rev = self.options.revision - else: - self.base_rev = RunShell(["hg", "parent", "-q"]).split(':')[1].strip() - - def _GetRelPath(self, filename): - """Get relative path of a file according to the current directory, - given its logical path in the repo.""" - assert filename.startswith(self.subdir), filename - return filename[len(self.subdir):].lstrip(r"\/") - - def GenerateDiff(self, extra_args): - # If no file specified, restrict to the current subdir - extra_args = extra_args or ["."] - cmd = ["hg", "diff", "--git", "-r", self.base_rev] + extra_args - data = RunShell(cmd, silent_ok=True) - svndiff = [] - filecount = 0 - for line in data.splitlines(): - m = re.match("diff --git a/(\S+) b/(\S+)", line) - if m: - # Modify line to make it look like as it comes from svn diff. - # With this modification no changes on the server side are required - # to make upload.py work with Mercurial repos. - # NOTE: for proper handling of moved/copied files, we have to use - # the second filename. - filename = m.group(2) - svndiff.append("Index: %s" % filename) - svndiff.append("=" * 67) - filecount += 1 - logging.info(line) - else: - svndiff.append(line) - if not filecount: - ErrorExit("No valid patches found in output from hg diff") - return "\n".join(svndiff) + "\n" - - def GetUnknownFiles(self): - """Return a list of files unknown to the VCS.""" - args = [] - status = RunShell(["hg", "status", "--rev", self.base_rev, "-u", "."], - silent_ok=True) - unknown_files = [] - for line in status.splitlines(): - st, fn = line.split(" ", 1) - if st == "?": - unknown_files.append(fn) - return unknown_files - - def GetBaseFile(self, filename): - # "hg status" and "hg cat" both take a path relative to the current subdir - # rather than to the repo root, but "hg diff" has given us the full path - # to the repo root. - base_content = "" - new_content = None - is_binary = False - oldrelpath = relpath = self._GetRelPath(filename) - # "hg status -C" returns two lines for moved/copied files, one otherwise - out = RunShell(["hg", "status", "-C", "--rev", self.base_rev, relpath]) - out = out.splitlines() - # HACK: strip error message about missing file/directory if it isn't in - # the working copy - if out[0].startswith('%s: ' % relpath): - out = out[1:] - if len(out) > 1: - # Moved/copied => considered as modified, use old filename to - # retrieve base contents - oldrelpath = out[1].strip() - status = "M" - else: - status, _ = out[0].split(' ', 1) - if status != "A": - base_content = RunShell(["hg", "cat", "-r", self.base_rev, oldrelpath], - silent_ok=True) - is_binary = "\0" in base_content # Mercurial's heuristic - if status != "R": - new_content = open(relpath, "rb").read() - is_binary = is_binary or "\0" in new_content - if is_binary and base_content: - # Fetch again without converting newlines - base_content = RunShell(["hg", "cat", "-r", self.base_rev, oldrelpath], - silent_ok=True, universal_newlines=False) - if not is_binary or not self.IsImage(relpath): - new_content = None - return base_content, new_content, is_binary, status - - -# NOTE: The SplitPatch function is duplicated in engine.py, keep them in sync. -def SplitPatch(data): - """Splits a patch into separate pieces for each file. - - Args: - data: A string containing the output of svn diff. - - Returns: - A list of 2-tuple (filename, text) where text is the svn diff output - pertaining to filename. - """ - patches = [] - filename = None - diff = [] - for line in data.splitlines(True): - new_filename = None - if line.startswith('Index:'): - unused, new_filename = line.split(':', 1) - new_filename = new_filename.strip() - elif line.startswith('Property changes on:'): - unused, temp_filename = line.split(':', 1) - # When a file is modified, paths use '/' between directories, however - # when a property is modified '\' is used on Windows. Make them the same - # otherwise the file shows up twice. - temp_filename = temp_filename.strip().replace('\\', '/') - if temp_filename != filename: - # File has property changes but no modifications, create a new diff. - new_filename = temp_filename - if new_filename: - if filename and diff: - patches.append((filename, ''.join(diff))) - filename = new_filename - diff = [line] - continue - if diff is not None: - diff.append(line) - if filename and diff: - patches.append((filename, ''.join(diff))) - return patches - - -def UploadSeparatePatches(issue, rpc_server, patchset, data, options): - """Uploads a separate patch for each file in the diff output. - - Returns a list of [patch_key, filename] for each file. - """ - patches = SplitPatch(data) - rv = [] - for patch in patches: - if len(patch[1]) > MAX_UPLOAD_SIZE: - print ("Not uploading the patch for " + patch[0] + - " because the file is too large.") - continue - form_fields = [("filename", patch[0])] - if not options.download_base: - form_fields.append(("content_upload", "1")) - files = [("data", "data.diff", patch[1])] - ctype, body = EncodeMultipartFormData(form_fields, files) - url = "/%d/upload_patch/%d" % (int(issue), int(patchset)) - print "Uploading patch for " + patch[0] - response_body = rpc_server.Send(url, body, content_type=ctype) - lines = response_body.splitlines() - if not lines or lines[0] != "OK": - StatusUpdate(" --> %s" % response_body) - sys.exit(1) - rv.append([lines[1], patch[0]]) - return rv - - -def GuessVCS(options): - """Helper to guess the version control system. - - This examines the current directory, guesses which VersionControlSystem - we're using, and returns an instance of the appropriate class. Exit with an - error if we can't figure it out. - - Returns: - A VersionControlSystem instance. Exits if the VCS can't be guessed. - """ - # Mercurial has a command to get the base directory of a repository - # Try running it, but don't die if we don't have hg installed. - # NOTE: we try Mercurial first as it can sit on top of an SVN working copy. - try: - out, returncode = RunShellWithReturnCode(["hg", "root"]) - if returncode == 0: - return MercurialVCS(options, out.strip()) - except OSError, (errno, message): - if errno != 2: # ENOENT -- they don't have hg installed. - raise - - # Subversion has a .svn in all working directories. - if os.path.isdir('.svn'): - logging.info("Guessed VCS = Subversion") - return SubversionVCS(options) - - # Git has a command to test if you're in a git tree. - # Try running it, but don't die if we don't have git installed. - try: - out, returncode = RunShellWithReturnCode(["git", "rev-parse", - "--is-inside-work-tree"]) - if returncode == 0: - return GitVCS(options) - except OSError, (errno, message): - if errno != 2: # ENOENT -- they don't have git installed. - raise - - ErrorExit(("Could not guess version control system. " - "Are you in a working copy directory?")) - - -def RealMain(argv, data=None): - """The real main function. - - Args: - argv: Command line arguments. - data: Diff contents. If None (default) the diff is generated by - the VersionControlSystem implementation returned by GuessVCS(). - - Returns: - A 2-tuple (issue id, patchset id). - The patchset id is None if the base files are not uploaded by this - script (applies only to SVN checkouts). - """ - logging.basicConfig(format=("%(asctime).19s %(levelname)s %(filename)s:" - "%(lineno)s %(message)s ")) - os.environ['LC_ALL'] = 'C' - options, args = parser.parse_args(argv[1:]) - global verbosity - verbosity = options.verbose - if verbosity >= 3: - logging.getLogger().setLevel(logging.DEBUG) - elif verbosity >= 2: - logging.getLogger().setLevel(logging.INFO) - vcs = GuessVCS(options) - if isinstance(vcs, SubversionVCS): - # base field is only allowed for Subversion. - # Note: Fetching base files may become deprecated in future releases. - base = vcs.GuessBase(options.download_base) - else: - base = None - if not base and options.download_base: - options.download_base = True - logging.info("Enabled upload of base file") - if not options.assume_yes: - vcs.CheckForUnknownFiles() - if data is None: - data = vcs.GenerateDiff(args) - files = vcs.GetBaseFiles(data) - if verbosity >= 1: - print "Upload server:", options.server, "(change with -s/--server)" - if options.issue: - prompt = "Message describing this patch set: " - else: - prompt = "New issue subject: " - message = options.message or raw_input(prompt).strip() - if not message: - ErrorExit("A non-empty message is required") - rpc_server = GetRpcServer(options) - form_fields = [("subject", message)] - if base: - form_fields.append(("base", base)) - if options.issue: - form_fields.append(("issue", str(options.issue))) - if options.email: - form_fields.append(("user", options.email)) - if options.reviewers: - for reviewer in options.reviewers.split(','): - if "@" in reviewer and not reviewer.split("@")[1].count(".") == 1: - ErrorExit("Invalid email address: %s" % reviewer) - form_fields.append(("reviewers", options.reviewers)) - if options.cc: - for cc in options.cc.split(','): - if "@" in cc and not cc.split("@")[1].count(".") == 1: - ErrorExit("Invalid email address: %s" % cc) - form_fields.append(("cc", options.cc)) - description = options.description - if options.description_file: - if options.description: - ErrorExit("Can't specify description and description_file") - file = open(options.description_file, 'r') - description = file.read() - file.close() - if description: - form_fields.append(("description", description)) - # Send a hash of all the base file so the server can determine if a copy - # already exists in an earlier patchset. - base_hashes = "" - for file, info in files.iteritems(): - if not info[0] is None: - checksum = md5.new(info[0]).hexdigest() - if base_hashes: - base_hashes += "|" - base_hashes += checksum + ":" + file - form_fields.append(("base_hashes", base_hashes)) - # If we're uploading base files, don't send the email before the uploads, so - # that it contains the file status. - if options.send_mail and options.download_base: - form_fields.append(("send_mail", "1")) - if not options.download_base: - form_fields.append(("content_upload", "1")) - if len(data) > MAX_UPLOAD_SIZE: - print "Patch is large, so uploading file patches separately." - uploaded_diff_file = [] - form_fields.append(("separate_patches", "1")) - else: - uploaded_diff_file = [("data", "data.diff", data)] - ctype, body = EncodeMultipartFormData(form_fields, uploaded_diff_file) - response_body = rpc_server.Send("/upload", body, content_type=ctype) - patchset = None - if not options.download_base or not uploaded_diff_file: - lines = response_body.splitlines() - if len(lines) >= 2: - msg = lines[0] - patchset = lines[1].strip() - patches = [x.split(" ", 1) for x in lines[2:]] - else: - msg = response_body - else: - msg = response_body - StatusUpdate(msg) - if not response_body.startswith("Issue created.") and \ - not response_body.startswith("Issue updated."): - sys.exit(0) - issue = msg[msg.rfind("/")+1:] - - if not uploaded_diff_file: - result = UploadSeparatePatches(issue, rpc_server, patchset, data, options) - if not options.download_base: - patches = result - - if not options.download_base: - vcs.UploadBaseFiles(issue, rpc_server, patches, patchset, options, files) - if options.send_mail: - rpc_server.Send("/" + issue + "/mail", payload="") - return issue, patchset - - -def main(): - try: - RealMain(sys.argv) - except KeyboardInterrupt: - print - StatusUpdate("Interrupted.") - sys.exit(1) - - -if __name__ == "__main__": - main() diff --git a/contrib/googletest/googlemock/scripts/upload_gmock.py b/contrib/googletest/googlemock/scripts/upload_gmock.py deleted file mode 100755 index 5dc484b3912b..000000000000 --- a/contrib/googletest/googlemock/scripts/upload_gmock.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/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. - -"""upload_gmock.py v0.1.0 -- uploads a Google Mock patch for review. - -This simple wrapper passes all command line flags and ---cc=googlemock@googlegroups.com to upload.py. - -USAGE: upload_gmock.py [options for upload.py] -""" - -__author__ = 'wan@google.com (Zhanyong Wan)' - -import os -import sys - -CC_FLAG = '--cc=' -GMOCK_GROUP = 'googlemock@googlegroups.com' - - -def main(): - # Finds the path to upload.py, assuming it is in the same directory - # as this file. - my_dir = os.path.dirname(os.path.abspath(__file__)) - upload_py_path = os.path.join(my_dir, 'upload.py') - - # Adds Google Mock discussion group to the cc line if it's not there - # already. - upload_py_argv = [upload_py_path] - found_cc_flag = False - for arg in sys.argv[1:]: - if arg.startswith(CC_FLAG): - found_cc_flag = True - cc_line = arg[len(CC_FLAG):] - cc_list = [addr for addr in cc_line.split(',') if addr] - if GMOCK_GROUP not in cc_list: - cc_list.append(GMOCK_GROUP) - upload_py_argv.append(CC_FLAG + ','.join(cc_list)) - else: - upload_py_argv.append(arg) - - if not found_cc_flag: - upload_py_argv.append(CC_FLAG + GMOCK_GROUP) - - # Invokes upload.py with the modified command line flags. - os.execv(upload_py_path, upload_py_argv) - - -if __name__ == '__main__': - main() diff --git a/contrib/googletest/googlemock/src/gmock-cardinalities.cc b/contrib/googletest/googlemock/src/gmock-cardinalities.cc index 0549f7276d78..92cde3484abf 100644 --- a/contrib/googletest/googlemock/src/gmock-cardinalities.cc +++ b/contrib/googletest/googlemock/src/gmock-cardinalities.cc @@ -27,7 +27,6 @@ // (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. @@ -35,9 +34,11 @@ #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" @@ -49,8 +50,7 @@ namespace { class BetweenCardinalityImpl : public CardinalityInterface { public: BetweenCardinalityImpl(int min, int max) - : min_(min >= 0 ? min : 0), - max_(max >= min_ ? max : min_) { + : min_(min >= 0 ? min : 0), max_(max >= min_ ? max : min_) { std::stringstream ss; if (min < 0) { ss << "The invocation lower bound must be >= 0, " @@ -62,32 +62,32 @@ class BetweenCardinalityImpl : public CardinalityInterface { internal::Expect(false, __FILE__, __LINE__, ss.str()); } else if (min > max) { ss << "The invocation upper bound (" << max - << ") must be >= the invocation lower bound (" << min - << ")."; + << ") 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. - virtual int ConservativeLowerBound() const { return min_; } - virtual int ConservativeUpperBound() const { return max_; } + int ConservativeLowerBound() const override { return min_; } + int ConservativeUpperBound() const override { return max_; } - virtual bool IsSatisfiedByCallCount(int call_count) const { + bool IsSatisfiedByCallCount(int call_count) const override { return min_ <= call_count && call_count <= max_; } - virtual bool IsSaturatedByCallCount(int call_count) const { + bool IsSaturatedByCallCount(int call_count) const override { return call_count >= max_; } - virtual void DescribeTo(::std::ostream* os) const; + void DescribeTo(::std::ostream* os) const override; private: const int min_; const int max_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(BetweenCardinalityImpl); + BetweenCardinalityImpl(const BetweenCardinalityImpl&) = delete; + BetweenCardinalityImpl& operator=(const BetweenCardinalityImpl&) = delete; }; // Formats "n times" in a human-friendly way. diff --git a/contrib/googletest/googlemock/src/gmock-internal-utils.cc b/contrib/googletest/googlemock/src/gmock-internal-utils.cc index e3a674859a85..5c2ce0d57eb6 100644 --- a/contrib/googletest/googlemock/src/gmock-internal-utils.cc +++ b/contrib/googletest/googlemock/src/gmock-internal-utils.cc @@ -27,7 +27,6 @@ // (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 @@ -37,8 +36,16 @@ #include "gmock/internal/gmock-internal-utils.h" #include <ctype.h> + +#include <array> +#include <cctype> +#include <cstdint> +#include <cstring> +#include <iostream> #include <ostream> // NOLINT #include <string> +#include <vector> + #include "gmock/gmock.h" #include "gmock/internal/gmock-port.h" #include "gtest/gtest.h" @@ -48,21 +55,22 @@ 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; +GTEST_API_ std::string JoinAsKeyValueTuple( + const std::vector<const char*>& names, const Strings& values) { + GTEST_CHECK_(names.size() == values.size()); + if (values.empty()) { + return ""; } + const auto build_one = [&](const size_t i) { + return std::string(names[i]) + ": " + values[i]; + }; + std::string result = "(" + build_one(0); + for (size_t i = 1; i < values.size(); i++) { + result += ", "; + result += build_one(i); + } + result += ")"; + return result; } // Converts an identifier name to a space-separated list of lower-case @@ -76,12 +84,11 @@ GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name) { // 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)); + (!IsAlpha(prev_char) && IsLower(*p)) || + (!IsDigit(prev_char) && IsDigit(*p)); if (IsAlNum(*p)) { - if (starts_new_word && result != "") - result += ' '; + if (starts_new_word && !result.empty()) result += ' '; result += ToLower(*p); } } @@ -93,14 +100,11 @@ GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name) { // use Google Mock with a testing framework other than Google Test. class GoogleTestFailureReporter : public FailureReporterInterface { public: - virtual void ReportFailure(FailureType type, const char* file, int line, - const std::string& message) { - AssertHelper(type == kFatal ? - TestPartResult::kFatalFailure : - TestPartResult::kNonFatalFailure, - file, - line, - message.c_str()) = Message(); + 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(); } @@ -123,13 +127,13 @@ GTEST_API_ FailureReporterInterface* GetFailureReporter() { // Protects global resources (stdout in particular) used by Log(). static GTEST_DEFINE_STATIC_MUTEX_(g_log_mutex); -// Returns true iff a log with the given severity is visible according -// to the --gmock_verbose flag. +// 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) { + if (GMOCK_FLAG_GET(verbose) == kInfoVerbosity) { // Always show the log if --gmock_verbose=info. return true; - } else if (GMOCK_FLAG(verbose) == kErrorVerbosity) { + } else if (GMOCK_FLAG_GET(verbose) == kErrorVerbosity) { // Always hide it if --gmock_verbose=error. return false; } else { @@ -139,7 +143,7 @@ GTEST_API_ bool LogIsVisible(LogSeverity severity) { } } -// Prints the given message to stdout iff 'severity' >= the level +// 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 @@ -148,15 +152,11 @@ GTEST_API_ bool LogIsVisible(LogSeverity severity) { // conservative. GTEST_API_ void Log(LogSeverity severity, const std::string& message, int stack_frames_to_skip) { - if (!LogIsVisible(severity)) - return; + if (!LogIsVisible(severity)) return; // Ensures that logs from different threads don't interleave. MutexLock l(&g_log_mutex); - // "using ::std::cout;" doesn't work with Symbian's STLport, where cout is a - // macro. - if (severity == kWarning) { // Prints a GMOCK WARNING marker to make the warnings easily searchable. std::cout << "\nGMOCK WARNING:"; @@ -181,8 +181,8 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message, std::cout << "\n"; } std::cout << "Stack trace:\n" - << ::testing::internal::GetCurrentOsStackTraceExceptTop( - ::testing::UnitTest::GetInstance(), actual_to_skip); + << ::testing::internal::GetCurrentOsStackTraceExceptTop( + actual_to_skip); } std::cout << ::std::flush; } @@ -199,5 +199,59 @@ GTEST_API_ void IllegalDoDefault(const char* file, int line) { "the variable in various places."); } +constexpr char UndoWebSafeEncoding(char c) { + return c == '-' ? '+' : c == '_' ? '/' : c; +} + +constexpr char UnBase64Impl(char c, const char* const base64, char carry) { + return *base64 == 0 ? static_cast<char>(65) + : *base64 == c + ? carry + : UnBase64Impl(c, base64 + 1, static_cast<char>(carry + 1)); +} + +template <size_t... I> +constexpr std::array<char, 256> UnBase64Impl(IndexSequence<I...>, + const char* const base64) { + return { + {UnBase64Impl(UndoWebSafeEncoding(static_cast<char>(I)), base64, 0)...}}; +} + +constexpr std::array<char, 256> UnBase64(const char* const base64) { + return UnBase64Impl(MakeIndexSequence<256>{}, base64); +} + +static constexpr char kBase64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static constexpr std::array<char, 256> kUnBase64 = UnBase64(kBase64); + +bool Base64Unescape(const std::string& encoded, std::string* decoded) { + decoded->clear(); + size_t encoded_len = encoded.size(); + decoded->reserve(3 * (encoded_len / 4) + (encoded_len % 4)); + int bit_pos = 0; + char dst = 0; + for (int src : encoded) { + if (std::isspace(src) || src == '=') { + continue; + } + char src_bin = kUnBase64[static_cast<size_t>(src)]; + if (src_bin >= 64) { + decoded->clear(); + return false; + } + if (bit_pos == 0) { + dst |= static_cast<char>(src_bin << 2); + bit_pos = 6; + } else { + dst |= static_cast<char>(src_bin >> (bit_pos - 2)); + decoded->push_back(dst); + dst = static_cast<char>(src_bin << (10 - bit_pos)); + bit_pos = (bit_pos + 6) % 8; + } + } + return true; +} + } // namespace internal } // namespace testing diff --git a/contrib/googletest/googlemock/src/gmock-matchers.cc b/contrib/googletest/googlemock/src/gmock-matchers.cc index f8ddff15b5c0..07bba4f0103d 100644 --- a/contrib/googletest/googlemock/src/gmock-matchers.cc +++ b/contrib/googletest/googlemock/src/gmock-matchers.cc @@ -27,131 +27,21 @@ // (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 "gmock/gmock-generated-matchers.h" #include <string.h> + #include <iostream> #include <sstream> #include <string> +#include <vector> namespace testing { - -// Constructs a matcher that matches a const std::string& whose value is -// equal to s. -Matcher<const std::string&>::Matcher(const std::string& s) { *this = Eq(s); } - -#if GTEST_HAS_GLOBAL_STRING -// Constructs a matcher that matches a const std::string& whose value is -// equal to s. -Matcher<const std::string&>::Matcher(const ::string& s) { - *this = Eq(static_cast<std::string>(s)); -} -#endif // GTEST_HAS_GLOBAL_STRING - -// Constructs a matcher that matches a const std::string& whose value is -// equal to s. -Matcher<const std::string&>::Matcher(const char* s) { - *this = Eq(std::string(s)); -} - -// Constructs a matcher that matches a std::string whose value is equal to -// s. -Matcher<std::string>::Matcher(const std::string& s) { *this = Eq(s); } - -#if GTEST_HAS_GLOBAL_STRING -// Constructs a matcher that matches a std::string whose value is equal to -// s. -Matcher<std::string>::Matcher(const ::string& s) { - *this = Eq(static_cast<std::string>(s)); -} -#endif // GTEST_HAS_GLOBAL_STRING - -// Constructs a matcher that matches a std::string whose value is equal to -// s. -Matcher<std::string>::Matcher(const char* s) { *this = Eq(std::string(s)); } - -#if GTEST_HAS_GLOBAL_STRING -// Constructs a matcher that matches a const ::string& whose value is -// equal to s. -Matcher<const ::string&>::Matcher(const std::string& s) { - *this = Eq(static_cast<::string>(s)); -} - -// Constructs a matcher that matches a const ::string& whose value is -// equal to s. -Matcher<const ::string&>::Matcher(const ::string& s) { *this = Eq(s); } - -// Constructs a matcher that matches a const ::string& whose value is -// equal to s. -Matcher<const ::string&>::Matcher(const char* s) { *this = Eq(::string(s)); } - -// Constructs a matcher that matches a ::string whose value is equal to s. -Matcher<::string>::Matcher(const std::string& s) { - *this = Eq(static_cast<::string>(s)); -} - -// Constructs a matcher that matches a ::string whose value is equal to s. -Matcher<::string>::Matcher(const ::string& s) { *this = Eq(s); } - -// Constructs a matcher that matches a string whose value is equal to s. -Matcher<::string>::Matcher(const char* s) { *this = Eq(::string(s)); } -#endif // GTEST_HAS_GLOBAL_STRING - -#if GTEST_HAS_ABSL -// Constructs a matcher that matches a const absl::string_view& whose value is -// equal to s. -Matcher<const absl::string_view&>::Matcher(const std::string& s) { - *this = Eq(s); -} - -#if GTEST_HAS_GLOBAL_STRING -// Constructs a matcher that matches a const absl::string_view& whose value is -// equal to s. -Matcher<const absl::string_view&>::Matcher(const ::string& s) { *this = Eq(s); } -#endif // GTEST_HAS_GLOBAL_STRING - -// Constructs a matcher that matches a const absl::string_view& whose value is -// equal to s. -Matcher<const absl::string_view&>::Matcher(const char* s) { - *this = Eq(std::string(s)); -} - -// Constructs a matcher that matches a const absl::string_view& whose value is -// equal to s. -Matcher<const absl::string_view&>::Matcher(absl::string_view s) { - *this = Eq(std::string(s)); -} - -// Constructs a matcher that matches a absl::string_view whose value is equal to -// s. -Matcher<absl::string_view>::Matcher(const std::string& s) { *this = Eq(s); } - -#if GTEST_HAS_GLOBAL_STRING -// Constructs a matcher that matches a absl::string_view whose value is equal to -// s. -Matcher<absl::string_view>::Matcher(const ::string& s) { *this = Eq(s); } -#endif // GTEST_HAS_GLOBAL_STRING - -// Constructs a matcher that matches a absl::string_view whose value is equal to -// s. -Matcher<absl::string_view>::Matcher(const char* s) { - *this = Eq(std::string(s)); -} - -// Constructs a matcher that matches a absl::string_view whose value is equal to -// s. -Matcher<absl::string_view>::Matcher(absl::string_view s) { - *this = Eq(std::string(s)); -} -#endif // GTEST_HAS_ABSL - namespace internal { // Returns the description for a matcher defined using the MATCHER*() @@ -159,11 +49,13 @@ namespace internal { // '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) { +GTEST_API_ std::string FormatMatcherDescription( + bool negation, const char* matcher_name, + const std::vector<const char*>& param_names, const Strings& param_values) { std::string result = ConvertIdentifierNameToWords(matcher_name); - if (param_values.size() >= 1) result += " " + JoinAsTuple(param_values); + if (!param_values.empty()) { + result += " " + JoinAsKeyValueTuple(param_names, param_values); + } return negation ? "not (" + result + ")" : result; } @@ -329,8 +221,6 @@ class MaxBipartiteMatchState { // right_[left_[i]] = i. ::std::vector<size_t> left_; ::std::vector<size_t> right_; - - GTEST_DISALLOW_ASSIGN_(MaxBipartiteMatchState); }; const size_t MaxBipartiteMatchState::kUnused; @@ -480,6 +370,23 @@ void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl( bool UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix( const ::std::vector<std::string>& element_printouts, const MatchMatrix& matrix, MatchResultListener* listener) const { + 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; + } + } + bool result = true; ::std::vector<char> element_matched(matrix.LhsSize(), 0); ::std::vector<char> matcher_matched(matrix.RhsSize(), 0); diff --git a/contrib/googletest/googlemock/src/gmock-spec-builders.cc b/contrib/googletest/googlemock/src/gmock-spec-builders.cc index b93f4e0ef6b5..de8947163586 100644 --- a/contrib/googletest/googlemock/src/gmock-spec-builders.cc +++ b/contrib/googletest/googlemock/src/gmock-spec-builders.cc @@ -27,7 +27,6 @@ // (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 @@ -36,25 +35,31 @@ #include "gmock/gmock-spec-builders.h" #include <stdlib.h> + #include <iostream> // NOLINT #include <map> +#include <memory> #include <set> +#include <sstream> #include <string> +#include <unordered_map> #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 +#if defined(GTEST_OS_CYGWIN) || defined(GTEST_OS_LINUX) || defined(GTEST_OS_MAC) +#include <unistd.h> // NOLINT +#endif +#ifdef GTEST_OS_QURT +#include <qurt_event.h> #endif // Silence C4800 (C4800: 'int *const ': forcing value -// to bool 'true' or 'false') for MSVC 14,15 -#ifdef _MSC_VER -#if _MSC_VER <= 1900 -# pragma warning(push) -# pragma warning(disable:4800) -#endif +// to bool 'true' or 'false') for MSVC 15 +#if defined(_MSC_VER) && (_MSC_VER == 1900) +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800) #endif namespace testing { @@ -69,7 +74,8 @@ GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity, const char* file, int line, const std::string& message) { ::std::ostringstream s; - s << file << ":" << line << ": " << message << ::std::endl; + s << internal::FormatFileLocation(file, line) << " " << message + << ::std::endl; Log(severity, s.str(), 0); } @@ -90,7 +96,7 @@ ExpectationBase::ExpectationBase(const char* a_file, int a_line, action_count_checked_(false) {} // Destructs an ExpectationBase object. -ExpectationBase::~ExpectationBase() {} +ExpectationBase::~ExpectationBase() = default; // Explicitly specifies the cardinality of this expectation. Used by // the subclasses to implement the .Times() clause. @@ -125,8 +131,8 @@ void ExpectationBase::RetireAllPreRequisites() } } -// Returns true iff all pre-requisites of this expectation have been -// satisfied. +// 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(); @@ -190,11 +196,12 @@ void ExpectationBase::DescribeCallCountTo(::std::ostream* os) const // 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"); + *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 @@ -237,13 +244,12 @@ void ExpectationBase::CheckActionCountIfNotDone() const ::std::stringstream ss; DescribeLocationTo(&ss); - ss << "Too " << (too_many ? "many" : "few") - << " actions specified in " << source_text() << "...\n" + 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"); + ss << ", but has " << (too_many ? "" : "only ") << action_count + << " WillOnce()" << (action_count == 1 ? "" : "s"); if (repeated_action_specified_) { ss << " and a WillRepeatedly()"; } @@ -259,10 +265,10 @@ void ExpectationBase::UntypedTimes(const Cardinality& a_cardinality) { ".Times() cannot appear " "more than once in an EXPECT_CALL()."); } else { - ExpectSpecProperty(last_clause_ < kTimes, - ".Times() cannot appear after " - ".InSequence(), .WillOnce(), .WillRepeatedly(), " - "or .RetiresOnSaturation()."); + ExpectSpecProperty( + last_clause_ < kTimes, + ".Times() may only appear *before* .InSequence(), .WillOnce(), " + ".WillRepeatedly(), or .RetiresOnSaturation(), not after."); } last_clause_ = kTimes; @@ -278,7 +284,7 @@ GTEST_API_ ThreadLocal<Sequence*> g_gmock_implicit_sequence; 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; + GMOCK_FLAG_GET(verbose) == kInfoVerbosity ? 3 : -1; switch (reaction) { case kAllow: Log(kInfo, msg, stack_frames_to_skip); @@ -290,20 +296,20 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg) { "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/CookBook.md#" - "knowing-when-to-expect for details.\n", + "https://github.com/google/googletest/blob/main/docs/" + "gmock_cook_book.md#" + "knowing-when-to-expect-useoncall for details.\n", stack_frames_to_skip); break; default: // FAIL - Expect(false, NULL, -1, msg); + Expect(false, nullptr, -1, msg); } } UntypedFunctionMockerBase::UntypedFunctionMockerBase() - : mock_obj_(NULL), name_("") {} + : mock_obj_(nullptr), name_("") {} -UntypedFunctionMockerBase::~UntypedFunctionMockerBase() {} +UntypedFunctionMockerBase::~UntypedFunctionMockerBase() = default; // Sets the mock object this mock method belongs to, and registers // this information in the global mock registry. Will be called @@ -340,7 +346,7 @@ const void* UntypedFunctionMockerBase::MockObject() const // 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_ != NULL, __FILE__, __LINE__, + Assert(mock_obj_ != nullptr, __FILE__, __LINE__, "MockObject() must not be called before RegisterOwner() or " "SetOwnerAndName() has been called."); mock_obj = mock_obj_; @@ -357,7 +363,7 @@ const char* UntypedFunctionMockerBase::Name() const // 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_ != NULL, __FILE__, __LINE__, + Assert(name_ != nullptr, __FILE__, __LINE__, "Name() must not be called before SetOwnerAndName() has " "been called."); name = name_; @@ -365,129 +371,12 @@ const char* UntypedFunctionMockerBase::Name() const 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 iff 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 != NULL) - 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 = NULL; - - // 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 != NULL; - - // True iff 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 == NULL ? - 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* const result = - untyped_action == NULL ? - this->UntypedPerformDefaultAction(untyped_args, ss.str()) : - this->UntypedPerformAction(untyped_action, untyped_args); - if (result != NULL) - result->PrintAsActionResult(&ss); - ss << "\n" << why.str(); - - if (!found) { - // No expectation matches this call - reports a failure. - Expect(false, NULL, -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); - } - - 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(); + for (UntypedExpectations::const_iterator it = untyped_expectations_.begin(); it != untyped_expectations_.end(); ++it) { if (it->get() == exp) { return Expectation(*it); @@ -507,8 +396,7 @@ 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(); + for (UntypedExpectations::const_iterator it = untyped_expectations_.begin(); it != untyped_expectations_.end(); ++it) { ExpectationBase* const untyped_expectation = it->get(); if (untyped_expectation->IsOverSaturated()) { @@ -519,15 +407,22 @@ bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked() } else if (!untyped_expectation->IsSatisfied()) { expectations_met = false; ::std::stringstream ss; - ss << "Actual function call count doesn't match " - << untyped_expectation->source_text() << "...\n"; + + const ::std::string& expectation_name = + untyped_expectation->GetDescription(); + ss << "Actual function "; + if (!expectation_name.empty()) { + ss << "\"" << expectation_name << "\" "; + } + ss << "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()); + Expect(false, untyped_expectation->file(), untyped_expectation->line(), + ss.str()); } } @@ -548,7 +443,7 @@ bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked() return expectations_met; } -CallReaction intToCallReaction(int mock_behavior) { +static CallReaction intToCallReaction(int mock_behavior) { if (mock_behavior >= kAllow && mock_behavior <= kFail) { return static_cast<internal::CallReaction>(mock_behavior); } @@ -568,15 +463,15 @@ typedef std::set<internal::UntypedFunctionMockerBase*> FunctionMockers; // expectations. struct MockObjectState { MockObjectState() - : first_used_file(NULL), first_used_line(-1), leakable(false) {} + : 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_case; + ::std::string first_used_test_suite; ::std::string first_used_test; - bool leakable; // true iff it's OK to leak the object. + bool leakable; // true if and only if it's OK to leak the object. FunctionMockers function_mockers; // All registered methods of the object. }; @@ -594,11 +489,7 @@ class MockObjectRegistry { // object alive. Therefore we report any living object as test // failure, unless the user explicitly asked us to ignore it. ~MockObjectRegistry() { - // "using ::std::cout;" doesn't work with Symbian's STLport, where cout is - // a macro. - - if (!GMOCK_FLAG(catch_leaked_mocks)) - return; + if (!GMOCK_FLAG_GET(catch_leaked_mocks)) return; int leaked_count = 0; for (StateMap::const_iterator it = states_.begin(); it != states_.end(); @@ -613,18 +504,18 @@ class MockObjectRegistry { 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_case << "." - << state.first_used_test << ")"; + if (!state.first_used_test.empty()) { + 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 << "."; + << 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 is " + << " 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, " @@ -636,8 +527,12 @@ class MockObjectRegistry { // RUN_ALL_TESTS() has already returned when this destructor is // called. Therefore we cannot use the normal Google Test // failure reporting mechanism. +#ifdef GTEST_OS_QURT + qurt_exception_raise_fatal(); +#else _exit(1); // We cannot call exit() as it is not reentrant and // may already have been called. +#endif } } @@ -652,57 +547,63 @@ 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; +std::unordered_map<uintptr_t, internal::CallReaction>& +UninterestingCallReactionMap() { + static auto* map = new std::unordered_map<uintptr_t, internal::CallReaction>; + return *map; +} // Sets the reaction Google Mock should have when an uninteresting // method of the given mock object is called. -void SetReactionOnUninterestingCalls(const void* mock_obj, +void SetReactionOnUninterestingCalls(uintptr_t 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; + UninterestingCallReactionMap()[mock_obj] = reaction; } } // namespace // Tells Google Mock to allow uninteresting calls on the given mock // object. -void Mock::AllowUninterestingCalls(const void* mock_obj) +void Mock::AllowUninterestingCalls(uintptr_t 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) +void Mock::WarnUninterestingCalls(uintptr_t 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) +void Mock::FailUninterestingCalls(uintptr_t 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) +void Mock::UnregisterCallReaction(uintptr_t mock_obj) GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { internal::MutexLock l(&internal::g_gmock_mutex); - g_uninteresting_call_reaction.erase(mock_obj); + UninterestingCallReactionMap().erase(static_cast<uintptr_t>(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) { + 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]; + return (UninterestingCallReactionMap().count( + reinterpret_cast<uintptr_t>(mock_obj)) == 0) + ? internal::intToCallReaction( + GMOCK_FLAG_GET(default_mock_behavior)) + : UninterestingCallReactionMap()[reinterpret_cast<uintptr_t>( + mock_obj)]; } // Tells Google Mock to ignore mock_obj when checking for leaked mock @@ -723,7 +624,7 @@ bool Mock::VerifyAndClearExpectations(void* mock_obj) } // Verifies all expectations on the given mock object and clears its -// default actions and expectations. Returns true iff the +// 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) { @@ -760,6 +661,19 @@ bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj) 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) @@ -776,16 +690,13 @@ void Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj, 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 == NULL) { + 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 != NULL) { - // FIXME: record the test case name when the - // ON_CALL or EXPECT_CALL is invoked from SetUpTestCase() or - // TearDownTestCase(). - state.first_used_test_case = test_info->test_case_name(); + if (test_info != nullptr) { + state.first_used_test_suite = test_info->test_suite_name(); state.first_used_test = test_info->name(); } } @@ -835,20 +746,20 @@ void Mock::ClearDefaultActionsLocked(void* mock_obj) // needed by VerifyAndClearExpectationsLocked(). } -Expectation::Expectation() {} +Expectation::Expectation() = default; Expectation::Expectation( - const internal::linked_ptr<internal::ExpectationBase>& an_expectation_base) + const std::shared_ptr<internal::ExpectationBase>& an_expectation_base) : expectation_base_(an_expectation_base) {} -Expectation::~Expectation() {} +Expectation::~Expectation() = default; // Adds an expectation to a sequence. void Sequence::AddExpectation(const Expectation& expectation) const { if (*last_expectation_ != expectation) { - if (last_expectation_->expectation_base() != NULL) { - expectation.expectation_base()->immediate_prerequisites_ - += *last_expectation_; + if (last_expectation_->expectation_base() != nullptr) { + expectation.expectation_base()->immediate_prerequisites_ += + *last_expectation_; } *last_expectation_ = expectation; } @@ -856,7 +767,7 @@ void Sequence::AddExpectation(const Expectation& expectation) const { // Creates the implicit sequence if there isn't one. InSequence::InSequence() { - if (internal::g_gmock_implicit_sequence.get() == NULL) { + if (internal::g_gmock_implicit_sequence.get() == nullptr) { internal::g_gmock_implicit_sequence.set(new Sequence); sequence_created_ = true; } else { @@ -869,14 +780,12 @@ InSequence::InSequence() { InSequence::~InSequence() { if (sequence_created_) { delete internal::g_gmock_implicit_sequence.get(); - internal::g_gmock_implicit_sequence.set(NULL); + internal::g_gmock_implicit_sequence.set(nullptr); } } } // namespace testing -#ifdef _MSC_VER -#if _MSC_VER <= 1900 -# pragma warning(pop) -#endif +#if defined(_MSC_VER) && (_MSC_VER == 1900) +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4800 #endif diff --git a/contrib/googletest/googlemock/src/gmock.cc b/contrib/googletest/googlemock/src/gmock.cc index 36356c9334ee..b5e714da7d3c 100644 --- a/contrib/googletest/googlemock/src/gmock.cc +++ b/contrib/googletest/googlemock/src/gmock.cc @@ -27,20 +27,17 @@ // (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 { +#include <string> -// FIXME: support using environment variables to -// control the flag values, like what Google Test does. +#include "gmock/internal/gmock-port.h" GMOCK_DEFINE_bool_(catch_leaked_mocks, true, - "true iff Google Mock should report leaked mock objects " - "as failures."); + "true if and only if Google Mock should report leaked " + "mock objects as failures."); -GMOCK_DEFINE_string_(verbose, internal::kWarningVerbosity, +GMOCK_DEFINE_string_(verbose, testing::internal::kWarningVerbosity, "Controls how verbose Google Mock's output is." " Valid values:\n" " info - prints all messages.\n" @@ -54,6 +51,7 @@ GMOCK_DEFINE_int32_(default_mock_behavior, 1, " 1 - by default, mocks act as NaggyMocks.\n" " 2 - by default, mocks act as StrictMocks."); +namespace testing { namespace internal { // Parses a string as a command line flag. The string should have the @@ -62,18 +60,18 @@ namespace internal { // // Returns the value of the flag, or NULL if the parsing failed. static const char* ParseGoogleMockFlagValue(const char* str, - const char* flag, + const char* flag_name, bool def_optional) { // str and flag must not be NULL. - if (str == NULL || flag == NULL) return NULL; + if (str == nullptr || flag_name == 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 NULL; + const std::string flag_name_str = std::string("--gmock_") + flag_name; + const size_t flag_name_len = flag_name_str.length(); + if (strncmp(str, flag_name_str.c_str(), flag_name_len) != 0) return nullptr; // Skips the flag name. - const char* flag_end = str + flag_len; + const char* flag_end = str + flag_name_len; // When def_optional is true, it's OK to not have a "=value" part. if (def_optional && (flag_end[0] == '\0')) { @@ -83,7 +81,7 @@ static const char* ParseGoogleMockFlagValue(const char* str, // 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 NULL; + if (flag_end[0] != '=') return nullptr; // Returns the string after "=". return flag_end + 1; @@ -94,13 +92,13 @@ static const char* ParseGoogleMockFlagValue(const char* str, // // 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) { +static bool ParseGoogleMockFlag(const char* str, const char* flag_name, + bool* value) { // Gets the value of the flag as a string. - const char* const value_str = ParseGoogleMockFlagValue(str, flag, true); + const char* const value_str = ParseGoogleMockFlagValue(str, flag_name, true); // Aborts if the parsing failed. - if (value_str == NULL) return false; + if (value_str == nullptr) return false; // Converts the string value to a bool. *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); @@ -113,30 +111,30 @@ static bool ParseGoogleMockBoolFlag(const char* str, const char* flag, // 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) { +static bool ParseGoogleMockFlag(const char* str, const char* flag_name, + String* value) { // Gets the value of the flag as a string. - const char* const value_str = ParseGoogleMockFlagValue(str, flag, false); + const char* const value_str = ParseGoogleMockFlagValue(str, flag_name, false); // Aborts if the parsing failed. - if (value_str == NULL) return false; + 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, - int* value) { +static bool ParseGoogleMockFlag(const char* str, const char* flag_name, + int32_t* value) { // Gets the value of the flag as a string. - const char* const value_str = ParseGoogleMockFlagValue(str, flag, true); + const char* const value_str = ParseGoogleMockFlagValue(str, flag_name, true); // Aborts if the parsing failed. - if (value_str == NULL) return false; + 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); + return ParseInt32(Message() << "The value of flag --" << flag_name, value_str, + value); } // The internal implementation of InitGoogleMock(). @@ -155,11 +153,22 @@ void InitGoogleMockImpl(int* argc, CharType** argv) { 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))) { + bool found_gmock_flag = false; + +#define GMOCK_INTERNAL_PARSE_FLAG(flag_name) \ + if (!found_gmock_flag) { \ + auto value = GMOCK_FLAG_GET(flag_name); \ + if (ParseGoogleMockFlag(arg, #flag_name, &value)) { \ + GMOCK_FLAG_SET(flag_name, value); \ + found_gmock_flag = true; \ + } \ + } + + GMOCK_INTERNAL_PARSE_FLAG(catch_leaked_mocks) + GMOCK_INTERNAL_PARSE_FLAG(verbose) + GMOCK_INTERNAL_PARSE_FLAG(default_mock_behavior) + + if (found_gmock_flag) { // 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 @@ -201,4 +210,16 @@ 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/contrib/googletest/googlemock/src/gmock_main.cc b/contrib/googletest/googlemock/src/gmock_main.cc index a3a271e68851..6b5541271bfe 100644 --- a/contrib/googletest/googlemock/src/gmock_main.cc +++ b/contrib/googletest/googlemock/src/gmock_main.cc @@ -27,19 +27,37 @@ // (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 defined(GTEST_OS_ESP8266) || defined(GTEST_OS_ESP32) || \ + (defined(GTEST_OS_NRF52) && defined(ARDUINO)) +#ifdef 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(); } +#ifdef 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 +#ifdef GTEST_OS_WINDOWS_MOBILE +#include <tchar.h> // NOLINT GTEST_API_ int _tmain(int argc, TCHAR** argv) { #else @@ -52,3 +70,4 @@ GTEST_API_ int main(int argc, char** argv) { testing::InitGoogleMock(&argc, argv); return RUN_ALL_TESTS(); } +#endif diff --git a/contrib/googletest/googlemock/test/BUILD.bazel b/contrib/googletest/googlemock/test/BUILD.bazel index 0fe72a67798a..d4297c80fe8d 100644 --- a/contrib/googletest/googlemock/test/BUILD.bazel +++ b/contrib/googletest/googlemock/test/BUILD.bazel @@ -28,47 +28,40 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -# Author: misterg@google.com (Gennadiy Civil) -# # Bazel Build for Google C++ Testing Framework(Google Test)-googlemock -licenses(["notice"]) +load("@rules_python//python:defs.bzl", "py_library", "py_test") -""" gmock own tests """ +licenses(["notice"]) +# Tests for GMock itself cc_test( name = "gmock_all_test", size = "small", - srcs = glob( - include = [ - "gmock-*.cc", - ], - ), + srcs = glob(include = ["gmock-*.cc"]) + ["gmock-matchers_test.h"], linkopts = select({ + "//:qnx": [], "//:windows": [], - "//:windows_msvc": [], - "//conditions:default": [ - "-pthread", - ], + "//conditions:default": ["-pthread"], }), deps = ["//:gtest"], ) -# Py tests - +# 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", - ], + deps = ["//:gtest_main"], ) py_test( @@ -79,6 +72,10 @@ py_test( ":gmock_leak_test_", ":gmock_test_utils", ], + tags = [ + "no_test_msvc2015", + "no_test_msvc2017", + ], ) cc_test( @@ -89,17 +86,13 @@ cc_test( "gmock_link_test.cc", "gmock_link_test.h", ], - deps = [ - "//:gtest_main", - ], + deps = ["//:gtest_main"], ) cc_binary( name = "gmock_output_test_", srcs = ["gmock_output_test_.cc"], - deps = [ - "//:gtest", - ], + deps = ["//:gtest"], ) py_test( @@ -110,6 +103,10 @@ py_test( ":gmock_output_test_", ":gmock_output_test_golden.txt", ], + tags = [ + "no_test_msvc2015", + "no_test_msvc2017", + ], deps = [":gmock_test_utils"], ) @@ -117,7 +114,5 @@ cc_test( name = "gmock_test", size = "small", srcs = ["gmock_test.cc"], - deps = [ - "//:gtest_main", - ], + deps = ["//:gtest_main"], ) diff --git a/contrib/googletest/googlemock/test/gmock-actions_test.cc b/contrib/googletest/googlemock/test/gmock-actions_test.cc index 06e29a1e3eda..da1675c525d1 100644 --- a/contrib/googletest/googlemock/test/gmock-actions_test.cc +++ b/contrib/googletest/googlemock/test/gmock-actions_test.cc @@ -27,71 +27,237 @@ // (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 C4800 (C4800: 'int *const ': forcing value -// to bool 'true' or 'false') for MSVC 14,15 -#ifdef _MSC_VER -#if _MSC_VER <= 1900 -# pragma warning(push) -# pragma warning(disable:4800) -#endif -#endif - #include "gmock/gmock-actions.h" + #include <algorithm> +#include <functional> #include <iterator> #include <memory> +#include <sstream> #include <string> +#include <tuple> +#include <type_traits> +#include <utility> +#include <vector> + #include "gmock/gmock.h" #include "gmock/internal/gmock-port.h" -#include "gtest/gtest.h" #include "gtest/gtest-spi.h" +#include "gtest/gtest.h" +#include "gtest/internal/gtest-port.h" + +// Silence C4100 (unreferenced formal parameter) and C4503 (decorated name +// length exceeded) for MSVC. +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100 4503) +#if defined(_MSC_VER) && (_MSC_VER == 1900) +// and silence C4800 (C4800: 'int *const ': forcing value +// to bool 'true' or 'false') for MSVC 15 +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800) +#endif +namespace testing { namespace { -// This list should be kept sorted. -using testing::Action; -using testing::ActionInterface; -using testing::Assign; -using testing::ByMove; -using testing::ByRef; -using testing::DefaultValue; -using testing::DoDefault; -using testing::IgnoreResult; -using testing::Invoke; -using testing::InvokeWithoutArgs; -using testing::MakePolymorphicAction; -using testing::Ne; -using testing::PolymorphicAction; -using testing::Return; -using testing::ReturnNull; -using testing::ReturnRef; -using testing::ReturnRefOfCopy; -using testing::SetArgPointee; -using testing::SetArgumentPointee; -using testing::Unused; -using testing::_; -using testing::get; -using testing::internal::BuiltInDefaultValue; -using testing::internal::Int64; -using testing::internal::UInt64; -using testing::make_tuple; -using testing::tuple; -using testing::tuple_element; - -#if !GTEST_OS_WINDOWS_MOBILE -using testing::SetErrnoAndReturn; -#endif +using ::testing::internal::BuiltInDefaultValue; + +TEST(TypeTraits, Negation) { + // Direct use with std types. + static_assert(std::is_base_of<std::false_type, + internal::negation<std::true_type>>::value, + ""); + + static_assert(std::is_base_of<std::true_type, + internal::negation<std::false_type>>::value, + ""); + + // With other types that fit the requirement of a value member that is + // convertible to bool. + static_assert(std::is_base_of< + std::true_type, + internal::negation<std::integral_constant<int, 0>>>::value, + ""); + + static_assert(std::is_base_of< + std::false_type, + internal::negation<std::integral_constant<int, 1>>>::value, + ""); + + static_assert(std::is_base_of< + std::false_type, + internal::negation<std::integral_constant<int, -1>>>::value, + ""); +} + +// Weird false/true types that aren't actually bool constants (but should still +// be legal according to [meta.logical] because `bool(T::value)` is valid), are +// distinct from std::false_type and std::true_type, and are distinct from other +// instantiations of the same template. +// +// These let us check finicky details mandated by the standard like +// "std::conjunction should evaluate to a type that inherits from the first +// false-y input". +template <int> +struct MyFalse : std::integral_constant<int, 0> {}; + +template <int> +struct MyTrue : std::integral_constant<int, -1> {}; + +TEST(TypeTraits, Conjunction) { + // Base case: always true. + static_assert(std::is_base_of<std::true_type, internal::conjunction<>>::value, + ""); + + // One predicate: inherits from that predicate, regardless of value. + static_assert( + std::is_base_of<MyFalse<0>, internal::conjunction<MyFalse<0>>>::value, + ""); + + static_assert( + std::is_base_of<MyTrue<0>, internal::conjunction<MyTrue<0>>>::value, ""); + + // Multiple predicates, with at least one false: inherits from that one. + static_assert( + std::is_base_of<MyFalse<1>, internal::conjunction<MyTrue<0>, MyFalse<1>, + MyTrue<2>>>::value, + ""); + + static_assert( + std::is_base_of<MyFalse<1>, internal::conjunction<MyTrue<0>, MyFalse<1>, + MyFalse<2>>>::value, + ""); + + // Short circuiting: in the case above, additional predicates need not even + // define a value member. + struct Empty {}; + static_assert( + std::is_base_of<MyFalse<1>, internal::conjunction<MyTrue<0>, MyFalse<1>, + Empty>>::value, + ""); + + // All predicates true: inherits from the last. + static_assert( + std::is_base_of<MyTrue<2>, internal::conjunction<MyTrue<0>, MyTrue<1>, + MyTrue<2>>>::value, + ""); +} + +TEST(TypeTraits, Disjunction) { + // Base case: always false. + static_assert( + std::is_base_of<std::false_type, internal::disjunction<>>::value, ""); + + // One predicate: inherits from that predicate, regardless of value. + static_assert( + std::is_base_of<MyFalse<0>, internal::disjunction<MyFalse<0>>>::value, + ""); + + static_assert( + std::is_base_of<MyTrue<0>, internal::disjunction<MyTrue<0>>>::value, ""); + + // Multiple predicates, with at least one true: inherits from that one. + static_assert( + std::is_base_of<MyTrue<1>, internal::disjunction<MyFalse<0>, MyTrue<1>, + MyFalse<2>>>::value, + ""); + + static_assert( + std::is_base_of<MyTrue<1>, internal::disjunction<MyFalse<0>, MyTrue<1>, + MyTrue<2>>>::value, + ""); + + // Short circuiting: in the case above, additional predicates need not even + // define a value member. + struct Empty {}; + static_assert( + std::is_base_of<MyTrue<1>, internal::disjunction<MyFalse<0>, MyTrue<1>, + Empty>>::value, + ""); + + // All predicates false: inherits from the last. + static_assert( + std::is_base_of<MyFalse<2>, internal::disjunction<MyFalse<0>, MyFalse<1>, + MyFalse<2>>>::value, + ""); +} + +TEST(TypeTraits, IsInvocableRV) { + struct C { + int operator()() const { return 0; } + void operator()(int) & {} + std::string operator()(int) && { return ""; }; + }; + + // The first overload is callable for const and non-const rvalues and lvalues. + // It can be used to obtain an int, cv void, or anything int is convertible + // to. + static_assert(internal::is_callable_r<int, C>::value, ""); + static_assert(internal::is_callable_r<int, C&>::value, ""); + static_assert(internal::is_callable_r<int, const C>::value, ""); + static_assert(internal::is_callable_r<int, const C&>::value, ""); + + static_assert(internal::is_callable_r<void, C>::value, ""); + static_assert(internal::is_callable_r<const volatile void, C>::value, ""); + static_assert(internal::is_callable_r<char, C>::value, ""); + + // It's possible to provide an int. If it's given to an lvalue, the result is + // void. Otherwise it is std::string (which is also treated as allowed for a + // void result type). + static_assert(internal::is_callable_r<void, C&, int>::value, ""); + static_assert(!internal::is_callable_r<int, C&, int>::value, ""); + static_assert(!internal::is_callable_r<std::string, C&, int>::value, ""); + static_assert(!internal::is_callable_r<void, const C&, int>::value, ""); + + static_assert(internal::is_callable_r<std::string, C, int>::value, ""); + static_assert(internal::is_callable_r<void, C, int>::value, ""); + static_assert(!internal::is_callable_r<int, C, int>::value, ""); + + // It's not possible to provide other arguments. + static_assert(!internal::is_callable_r<void, C, std::string>::value, ""); + static_assert(!internal::is_callable_r<void, C, int, int>::value, ""); + + // In C++17 and above, where it's guaranteed that functions can return + // non-moveable objects, everything should work fine for non-moveable rsult + // types too. +#if defined(GTEST_INTERNAL_CPLUSPLUS_LANG) && \ + GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L + { + struct NonMoveable { + NonMoveable() = default; + NonMoveable(NonMoveable&&) = delete; + }; + + static_assert(!std::is_move_constructible_v<NonMoveable>); + + struct Callable { + NonMoveable operator()() { return NonMoveable(); } + }; + + static_assert(internal::is_callable_r<NonMoveable, Callable>::value); + static_assert(internal::is_callable_r<void, Callable>::value); + static_assert( + internal::is_callable_r<const volatile void, Callable>::value); + + static_assert(!internal::is_callable_r<int, Callable>::value); + static_assert(!internal::is_callable_r<NonMoveable, Callable, int>::value); + } +#endif // C++17 and above + + // Nothing should choke when we try to call other arguments besides directly + // callable objects, but they should not show up as callable. + static_assert(!internal::is_callable_r<void, int>::value, ""); + static_assert(!internal::is_callable_r<void, void (C::*)()>::value, ""); + static_assert(!internal::is_callable_r<void, void (C::*)(), C*>::value, ""); +} // Tests that BuiltInDefaultValue<T*>::Get() returns NULL. TEST(BuiltInDefaultValueTest, IsNullForPointerTypes) { - EXPECT_TRUE(BuiltInDefaultValue<int*>::Get() == NULL); - EXPECT_TRUE(BuiltInDefaultValue<const char*>::Get() == NULL); - EXPECT_TRUE(BuiltInDefaultValue<void*>::Get() == NULL); + 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. @@ -107,10 +273,6 @@ TEST(BuiltInDefaultValueTest, IsZeroForNumericTypes) { EXPECT_EQ(0U, BuiltInDefaultValue<unsigned char>::Get()); EXPECT_EQ(0, BuiltInDefaultValue<signed char>::Get()); EXPECT_EQ(0, BuiltInDefaultValue<char>::Get()); -#if GMOCK_HAS_SIGNED_WCHAR_T_ - EXPECT_EQ(0U, BuiltInDefaultValue<unsigned wchar_t>::Get()); - EXPECT_EQ(0, BuiltInDefaultValue<signed wchar_t>::Get()); -#endif #if GMOCK_WCHAR_T_IS_NATIVE_ #if !defined(__WCHAR_UNSIGNED__) EXPECT_EQ(0, BuiltInDefaultValue<wchar_t>::Get()); @@ -119,16 +281,17 @@ TEST(BuiltInDefaultValueTest, IsZeroForNumericTypes) { #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(0, BuiltInDefaultValue<signed short>::Get()); // NOLINT + EXPECT_EQ(0, BuiltInDefaultValue<short>::Get()); // NOLINT EXPECT_EQ(0U, BuiltInDefaultValue<unsigned int>::Get()); EXPECT_EQ(0, BuiltInDefaultValue<signed int>::Get()); EXPECT_EQ(0, BuiltInDefaultValue<int>::Get()); - EXPECT_EQ(0U, BuiltInDefaultValue<unsigned long>::Get()); // NOLINT - EXPECT_EQ(0, BuiltInDefaultValue<signed long>::Get()); // NOLINT - EXPECT_EQ(0, BuiltInDefaultValue<long>::Get()); // NOLINT - EXPECT_EQ(0U, BuiltInDefaultValue<UInt64>::Get()); - EXPECT_EQ(0, BuiltInDefaultValue<Int64>::Get()); + EXPECT_EQ(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()); } @@ -139,24 +302,21 @@ TEST(BuiltInDefaultValueTest, ExistsForNumericTypes) { EXPECT_TRUE(BuiltInDefaultValue<unsigned char>::Exists()); EXPECT_TRUE(BuiltInDefaultValue<signed char>::Exists()); EXPECT_TRUE(BuiltInDefaultValue<char>::Exists()); -#if GMOCK_HAS_SIGNED_WCHAR_T_ - EXPECT_TRUE(BuiltInDefaultValue<unsigned wchar_t>::Exists()); - EXPECT_TRUE(BuiltInDefaultValue<signed wchar_t>::Exists()); -#endif #if GMOCK_WCHAR_T_IS_NATIVE_ EXPECT_TRUE(BuiltInDefaultValue<wchar_t>::Exists()); #endif EXPECT_TRUE(BuiltInDefaultValue<unsigned short>::Exists()); // NOLINT - EXPECT_TRUE(BuiltInDefaultValue<signed short>::Exists()); // NOLINT - EXPECT_TRUE(BuiltInDefaultValue<short>::Exists()); // NOLINT + EXPECT_TRUE(BuiltInDefaultValue<signed short>::Exists()); // NOLINT + EXPECT_TRUE(BuiltInDefaultValue<short>::Exists()); // NOLINT EXPECT_TRUE(BuiltInDefaultValue<unsigned int>::Exists()); EXPECT_TRUE(BuiltInDefaultValue<signed int>::Exists()); EXPECT_TRUE(BuiltInDefaultValue<int>::Exists()); - EXPECT_TRUE(BuiltInDefaultValue<unsigned long>::Exists()); // NOLINT - EXPECT_TRUE(BuiltInDefaultValue<signed long>::Exists()); // NOLINT - EXPECT_TRUE(BuiltInDefaultValue<long>::Exists()); // NOLINT - EXPECT_TRUE(BuiltInDefaultValue<UInt64>::Exists()); - EXPECT_TRUE(BuiltInDefaultValue<Int64>::Exists()); + EXPECT_TRUE(BuiltInDefaultValue<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()); } @@ -174,21 +334,13 @@ TEST(BuiltInDefaultValueTest, BoolExists) { // Tests that BuiltInDefaultValue<T>::Get() returns "" when T is a // string type. TEST(BuiltInDefaultValueTest, IsEmptyStringForString) { -#if GTEST_HAS_GLOBAL_STRING - EXPECT_EQ("", BuiltInDefaultValue< ::string>::Get()); -#endif // GTEST_HAS_GLOBAL_STRING - - EXPECT_EQ("", BuiltInDefaultValue< ::std::string>::Get()); + EXPECT_EQ("", BuiltInDefaultValue<::std::string>::Get()); } // Tests that BuiltInDefaultValue<T>::Exists() returns true when T is a // string type. TEST(BuiltInDefaultValueTest, ExistsForString) { -#if GTEST_HAS_GLOBAL_STRING - EXPECT_TRUE(BuiltInDefaultValue< ::string>::Exists()); -#endif // GTEST_HAS_GLOBAL_STRING - - EXPECT_TRUE(BuiltInDefaultValue< ::std::string>::Exists()); + EXPECT_TRUE(BuiltInDefaultValue<::std::string>::Exists()); } // Tests that BuiltInDefaultValue<const T>::Get() returns the same @@ -196,7 +348,7 @@ TEST(BuiltInDefaultValueTest, ExistsForString) { TEST(BuiltInDefaultValueTest, WorksForConstTypes) { EXPECT_EQ("", BuiltInDefaultValue<const std::string>::Get()); EXPECT_EQ(0, BuiltInDefaultValue<const int>::Get()); - EXPECT_TRUE(BuiltInDefaultValue<char* const>::Get() == NULL); + EXPECT_TRUE(BuiltInDefaultValue<char* const>::Get() == nullptr); EXPECT_FALSE(BuiltInDefaultValue<const bool>::Get()); } @@ -223,8 +375,6 @@ class MyNonDefaultConstructible { int value_; }; -#if GTEST_LANG_CXX11 - TEST(BuiltInDefaultValueTest, ExistsForDefaultConstructibleType) { EXPECT_TRUE(BuiltInDefaultValue<MyDefaultConstructible>::Exists()); } @@ -233,26 +383,19 @@ TEST(BuiltInDefaultValueTest, IsDefaultConstructedForDefaultConstructibleType) { EXPECT_EQ(42, BuiltInDefaultValue<MyDefaultConstructible>::Get().value()); } -#endif // GTEST_LANG_CXX11 - 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(); - }, ""); + 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(); - }, ""); + EXPECT_DEATH_IF_SUPPORTED( + { BuiltInDefaultValue<MyNonDefaultConstructible>::Get(); }, ""); } // Tests that DefaultValue<T>::IsSet() is false initially. @@ -298,28 +441,22 @@ TEST(DefaultValueDeathTest, GetReturnsBuiltInDefaultValueWhenUnset) { EXPECT_EQ(0, DefaultValue<int>::Get()); - EXPECT_DEATH_IF_SUPPORTED({ - DefaultValue<MyNonDefaultConstructible>::Get(); - }, ""); + EXPECT_DEATH_IF_SUPPORTED({ DefaultValue<MyNonDefaultConstructible>::Get(); }, + ""); } -#if GTEST_HAS_STD_UNIQUE_PTR_ TEST(DefaultValueTest, GetWorksForMoveOnlyIfSet) { EXPECT_TRUE(DefaultValue<std::unique_ptr<int>>::Exists()); - EXPECT_TRUE(DefaultValue<std::unique_ptr<int>>::Get() == NULL); - DefaultValue<std::unique_ptr<int>>::SetFactory([] { - return std::unique_ptr<int>(new int(42)); - }); + EXPECT_TRUE(DefaultValue<std::unique_ptr<int>>::Get() == nullptr); + DefaultValue<std::unique_ptr<int>>::SetFactory( + [] { return std::make_unique<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); } -#endif // GTEST_HAS_STD_UNIQUE_PTR_ // Tests that DefaultValue<void>::Get() returns void. -TEST(DefaultValueTest, GetWorksForVoid) { - return DefaultValue<void>::Get(); -} +TEST(DefaultValueTest, GetWorksForVoid) { return DefaultValue<void>::Get(); } // Tests using DefaultValue with a reference type. @@ -330,7 +467,7 @@ TEST(DefaultValueOfReferenceTest, IsInitiallyUnset) { EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible&>::IsSet()); } -// Tests that DefaultValue<T&>::Exists is false initiallly. +// Tests that DefaultValue<T&>::Exists is false initially. TEST(DefaultValueOfReferenceTest, IsInitiallyNotExisting) { EXPECT_FALSE(DefaultValue<int&>::Exists()); EXPECT_FALSE(DefaultValue<MyDefaultConstructible&>::Exists()); @@ -367,12 +504,9 @@ 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(); - }, ""); + EXPECT_DEATH_IF_SUPPORTED({ DefaultValue<int&>::Get(); }, ""); + EXPECT_DEATH_IF_SUPPORTED({ DefaultValue<MyNonDefaultConstructible>::Get(); }, + ""); } // Tests that ActionInterface can be implemented by defining the @@ -382,8 +516,8 @@ typedef int MyGlobalFunction(bool, int); class MyActionImpl : public ActionInterface<MyGlobalFunction> { public: - virtual int Perform(const tuple<bool, int>& args) { - return get<0>(args) ? get<1>(args) : 0; + int Perform(const std::tuple<bool, int>& args) override { + return std::get<0>(args) ? std::get<1>(args) : 0; } }; @@ -399,11 +533,11 @@ TEST(ActionInterfaceTest, MakeAction) { // it a tuple whose size and type are compatible with F's argument // types. For example, if F is int(), then Perform() takes a // 0-tuple; if F is void(bool, int), then Perform() takes a - // tuple<bool, int>, and so on. - EXPECT_EQ(5, action.Perform(make_tuple(true, 5))); + // 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 +// Tests that Action<F> can be constructed from a pointer to // ActionInterface<F>. TEST(ActionTest, CanBeConstructedFromActionInterface) { Action<MyGlobalFunction> action(new MyActionImpl); @@ -413,8 +547,8 @@ TEST(ActionTest, CanBeConstructedFromActionInterface) { TEST(ActionTest, DelegatesWorkToActionInterface) { const Action<MyGlobalFunction> action(new MyActionImpl); - EXPECT_EQ(5, action.Perform(make_tuple(true, 5))); - EXPECT_EQ(0, action.Perform(make_tuple(false, 1))); + 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. @@ -423,22 +557,22 @@ TEST(ActionTest, IsCopyable) { Action<MyGlobalFunction> a2(a1); // Tests the copy constructor. // a1 should continue to work after being copied from. - EXPECT_EQ(5, a1.Perform(make_tuple(true, 5))); - EXPECT_EQ(0, a1.Perform(make_tuple(false, 1))); + 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(make_tuple(true, 5))); - EXPECT_EQ(0, a2.Perform(make_tuple(false, 1))); + 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(make_tuple(true, 5))); - EXPECT_EQ(0, a1.Perform(make_tuple(false, 1))); + 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(make_tuple(true, 5))); - EXPECT_EQ(0, a2.Perform(make_tuple(false, 1))); + 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 @@ -446,24 +580,17 @@ TEST(ActionTest, IsCopyable) { class IsNotZero : public ActionInterface<bool(int)> { // NOLINT public: - virtual bool Perform(const tuple<int>& arg) { - return get<0>(arg) != 0; + bool Perform(const std::tuple<int>& arg) override { + return std::get<0>(arg) != 0; } }; -#if !GTEST_OS_SYMBIAN -// Compiling this test on Nokia's Symbian compiler fails with: -// 'Result' is not a member of class 'testing::internal::Function<int>' -// (point of instantiation: '@unnamed@gmock_actions_test_cc@:: -// ActionTest_CanBeConvertedToOtherActionType_Test::TestBody()') -// with no obvious fix. TEST(ActionTest, CanBeConvertedToOtherActionType) { - const Action<bool(int)> a1(new IsNotZero); // NOLINT + const Action<bool(int)> a1(new IsNotZero); // NOLINT const Action<int(char)> a2 = Action<int(char)>(a1); // NOLINT - EXPECT_EQ(1, a2.Perform(make_tuple('a'))); - EXPECT_EQ(0, a2.Perform(make_tuple('\0'))); + EXPECT_EQ(1, a2.Perform(std::make_tuple('a'))); + EXPECT_EQ(0, a2.Perform(std::make_tuple('\0'))); } -#endif // !GTEST_OS_SYMBIAN // The following two classes are for testing MakePolymorphicAction(). @@ -475,7 +602,9 @@ class ReturnSecondArgumentAction { // polymorphic action whose Perform() method template is either // const or not. This lets us verify the non-const case. template <typename Result, typename ArgumentTuple> - Result Perform(const ArgumentTuple& args) { return get<1>(args); } + Result Perform(const ArgumentTuple& args) { + return std::get<1>(args); + } }; // Implements a polymorphic action that can be used in a nullary @@ -490,7 +619,9 @@ class ReturnZeroFromNullaryFunctionAction { // polymorphic action whose Perform() method template is either // const or not. This lets us verify the const case. template <typename Result> - Result Perform(const tuple<>&) const { return 0; } + Result Perform(const std::tuple<>&) const { + return 0; + } }; // These functions verify that MakePolymorphicAction() returns a @@ -509,65 +640,175 @@ ReturnZeroFromNullaryFunction() { // implementation class into a polymorphic action. TEST(MakePolymorphicActionTest, ConstructsActionFromImpl) { Action<int(bool, int, double)> a1 = ReturnSecondArgument(); // NOLINT - EXPECT_EQ(5, a1.Perform(make_tuple(false, 5, 2.0))); + 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(make_tuple())); + EXPECT_EQ(0, a1.Perform(std::make_tuple())); Action<void*()> a2 = ReturnZeroFromNullaryFunction(); - EXPECT_TRUE(a2.Perform(make_tuple()) == NULL); + 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(make_tuple(1)); + 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(make_tuple())); + EXPECT_EQ(1, ret.Perform(std::make_tuple())); ret = Return(-5); - EXPECT_EQ(-5, ret.Perform(make_tuple())); + 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(make_tuple())); + EXPECT_STREQ("Hello", a1.Perform(std::make_tuple())); Action<std::string()> a2 = Return("world"); - EXPECT_EQ("world", a2.Perform(make_tuple())); + 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 -}; +// Return(x) should work fine when the mock function's return type is a +// reference-like wrapper for decltype(x), as when x is a std::string and the +// mock function returns std::string_view. +TEST(ReturnTest, SupportsReferenceLikeReturnType) { + // A reference wrapper for std::vector<int>, implicitly convertible from it. + struct Result { + const std::vector<int>* v; + Result(const std::vector<int>& vec) : v(&vec) {} // NOLINT + }; + + // Set up an action for a mock function that returns the reference wrapper + // type, initializing it with an actual vector. + // + // The returned wrapper should be initialized with a copy of that vector + // that's embedded within the action itself (which should stay alive as long + // as the mock object is alive), rather than e.g. a reference to the temporary + // we feed to Return. This should work fine both for WillOnce and + // WillRepeatedly. + MockFunction<Result()> mock; + EXPECT_CALL(mock, Call) + .WillOnce(Return(std::vector<int>{17, 19, 23})) + .WillRepeatedly(Return(std::vector<int>{29, 31, 37})); + + EXPECT_THAT(mock.AsStdFunction()(), + Field(&Result::v, Pointee(ElementsAre(17, 19, 23)))); + + EXPECT_THAT(mock.AsStdFunction()(), + Field(&Result::v, Pointee(ElementsAre(29, 31, 37)))); +} + +TEST(ReturnTest, PrefersConversionOperator) { + // Define types In and Out such that: + // + // * In is implicitly convertible to Out. + // * Out also has an explicit constructor from In. + // + struct In; + struct Out { + int x; + + explicit Out(const int val) : x(val) {} + explicit Out(const In&) : x(0) {} + }; + + struct In { + operator Out() const { return Out{19}; } // 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); + // Assumption check: the C++ language rules are such that a function that + // returns Out which uses In a return statement will use the implicit + // conversion path rather than the explicit constructor. + EXPECT_THAT([]() -> Out { return In(); }(), Field(&Out::x, 19)); - // 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(make_tuple()).v); - EXPECT_THAT(result, ::testing::ElementsAre(0, 1, 2, 3, 4)); + // Return should work the same way: if the mock function's return type is Out + // and we feed Return an In value, then the Out should be created through the + // implicit conversion path rather than the explicit constructor. + MockFunction<Out()> mock; + EXPECT_CALL(mock, Call).WillOnce(Return(In())); + EXPECT_THAT(mock.AsStdFunction()(), Field(&Out::x, 19)); +} + +// It should be possible to use Return(R) with a mock function result type U +// that is convertible from const R& but *not* R (such as +// std::reference_wrapper). This should work for both WillOnce and +// WillRepeatedly. +TEST(ReturnTest, ConversionRequiresConstLvalueReference) { + using R = int; + using U = std::reference_wrapper<const int>; + + static_assert(std::is_convertible<const R&, U>::value, ""); + static_assert(!std::is_convertible<R, U>::value, ""); + + MockFunction<U()> mock; + EXPECT_CALL(mock, Call).WillOnce(Return(17)).WillRepeatedly(Return(19)); + + EXPECT_EQ(17, mock.AsStdFunction()()); + EXPECT_EQ(19, mock.AsStdFunction()()); +} + +// Return(x) should not be usable with a mock function result type that's +// implicitly convertible from decltype(x) but requires a non-const lvalue +// reference to the input. It doesn't make sense for the conversion operator to +// modify the input. +TEST(ReturnTest, ConversionRequiresMutableLvalueReference) { + // Set up a type that is implicitly convertible from std::string&, but not + // std::string&& or `const std::string&`. + // + // Avoid asserting about conversion from std::string on MSVC, which seems to + // implement std::is_convertible incorrectly in this case. + struct S { + S(std::string&) {} // NOLINT + }; + + static_assert(std::is_convertible<std::string&, S>::value, ""); +#ifndef _MSC_VER + static_assert(!std::is_convertible<std::string&&, S>::value, ""); +#endif + static_assert(!std::is_convertible<const std::string&, S>::value, ""); + + // It shouldn't be possible to use the result of Return(std::string) in a + // context where an S is needed. + // + // Here too we disable the assertion for MSVC, since its incorrect + // implementation of is_convertible causes our SFINAE to be wrong. + using RA = decltype(Return(std::string())); + + static_assert(!std::is_convertible<RA, Action<S()>>::value, ""); +#ifndef _MSC_VER + static_assert(!std::is_convertible<RA, OnceAction<S()>>::value, ""); +#endif } -// Tests that Return(v) is covaraint. +TEST(ReturnTest, MoveOnlyResultType) { + // Return should support move-only result types when used with WillOnce. + { + MockFunction<std::unique_ptr<int>()> mock; + EXPECT_CALL(mock, Call) + // NOLINTNEXTLINE + .WillOnce(Return(std::unique_ptr<int>(new int(17)))); + + EXPECT_THAT(mock.AsStdFunction()(), Pointee(17)); + } + + // The result of Return should not be convertible to Action (so it can't be + // used with WillRepeatedly). + static_assert(!std::is_convertible<decltype(Return(std::unique_ptr<int>())), + Action<std::unique_ptr<int>()>>::value, + ""); +} + +// Tests that Return(v) is covariant. struct Base { bool operator==(const Base&) { return true; } @@ -581,10 +822,10 @@ TEST(ReturnTest, IsCovariant) { Base base; Derived derived; Action<Base*()> ret = Return(&base); - EXPECT_EQ(&base, ret.Perform(make_tuple())); + EXPECT_EQ(&base, ret.Perform(std::make_tuple())); ret = Return(&derived); - EXPECT_EQ(&derived, ret.Perform(make_tuple())); + EXPECT_EQ(&derived, ret.Perform(std::make_tuple())); } // Tests that the type of the value passed into Return is converted into T @@ -598,8 +839,6 @@ class FromType { private: bool* const converted_; - - GTEST_DISALLOW_ASSIGN_(FromType); }; class ToType { @@ -615,51 +854,36 @@ TEST(ReturnTest, ConvertsArgumentWhenConverted) { EXPECT_TRUE(converted) << "Return must convert its argument in its own " << "conversion operator."; converted = false; - action.Perform(tuple<>()); + 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(make_tuple()) == NULL); + EXPECT_TRUE(a1.Perform(std::make_tuple()) == nullptr); const Action<const char*(bool)> a2 = ReturnNull(); // NOLINT - EXPECT_TRUE(a2.Perform(make_tuple(true)) == NULL); + EXPECT_TRUE(a2.Perform(std::make_tuple(true)) == nullptr); } -#if GTEST_HAS_STD_UNIQUE_PTR_ // 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(make_tuple()) == nullptr); + EXPECT_TRUE(a1.Perform(std::make_tuple()) == nullptr); const Action<std::shared_ptr<int>(std::string)> a2 = ReturnNull(); - EXPECT_TRUE(a2.Perform(make_tuple("foo")) == nullptr); + EXPECT_TRUE(a2.Perform(std::make_tuple("foo")) == nullptr); } -#endif // GTEST_HAS_STD_UNIQUE_PTR_ // Tests that ReturnRef(v) works for reference types. TEST(ReturnRefTest, WorksForReference) { const int n = 0; const Action<const int&(bool)> ret = ReturnRef(n); // NOLINT - EXPECT_EQ(&n, &ret.Perform(make_tuple(true))); + EXPECT_EQ(&n, &ret.Perform(std::make_tuple(true))); } // Tests that ReturnRef(v) is covariant. @@ -667,10 +891,47 @@ TEST(ReturnRefTest, IsCovariant) { Base base; Derived derived; Action<Base&()> a = ReturnRef(base); - EXPECT_EQ(&base, &a.Perform(make_tuple())); + EXPECT_EQ(&base, &a.Perform(std::make_tuple())); a = ReturnRef(derived); - EXPECT_EQ(&derived, &a.Perform(make_tuple())); + 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. @@ -678,12 +939,12 @@ TEST(ReturnRefOfCopyTest, WorksForReference) { int n = 42; const Action<const int&()> ret = ReturnRefOfCopy(n); - EXPECT_NE(&n, &ret.Perform(make_tuple())); - EXPECT_EQ(42, ret.Perform(make_tuple())); + EXPECT_NE(&n, &ret.Perform(std::make_tuple())); + EXPECT_EQ(42, ret.Perform(std::make_tuple())); n = 43; - EXPECT_NE(&n, &ret.Perform(make_tuple())); - EXPECT_EQ(42, ret.Perform(make_tuple())); + EXPECT_NE(&n, &ret.Perform(std::make_tuple())); + EXPECT_EQ(42, ret.Perform(std::make_tuple())); } // Tests that ReturnRefOfCopy(v) is covariant. @@ -691,39 +952,62 @@ TEST(ReturnRefOfCopyTest, IsCovariant) { Base base; Derived derived; Action<Base&()> a = ReturnRefOfCopy(base); - EXPECT_NE(&base, &a.Perform(make_tuple())); + EXPECT_NE(&base, &a.Perform(std::make_tuple())); a = ReturnRefOfCopy(derived); - EXPECT_NE(&derived, &a.Perform(make_tuple())); + 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() {} + MockClass() = default; MOCK_METHOD1(IntFunc, int(bool flag)); // NOLINT MOCK_METHOD0(Foo, MyNonDefaultConstructible()); -#if GTEST_HAS_STD_UNIQUE_PTR_ 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>)); -#endif private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockClass); + MockClass(const MockClass&) = delete; + MockClass& operator=(const MockClass&) = delete; }; // 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_CALL(mock, IntFunc(_)).WillOnce(DoDefault()); EXPECT_EQ(0, mock.IntFunc(true)); } @@ -731,14 +1015,11 @@ TEST(DoDefaultTest, ReturnsBuiltInDefaultValueByDefault) { // the process when there is no built-in default value for the return type. TEST(DoDefaultDeathTest, DiesForUnknowType) { MockClass mock; - EXPECT_CALL(mock, Foo()) - .WillRepeatedly(DoDefault()); + EXPECT_CALL(mock, Foo()).WillRepeatedly(DoDefault()); #if GTEST_HAS_EXCEPTIONS EXPECT_ANY_THROW(mock.Foo()); #else - EXPECT_DEATH_IF_SUPPORTED({ - mock.Foo(); - }, ""); + EXPECT_DEATH_IF_SUPPORTED({ mock.Foo(); }, ""); #endif } @@ -750,25 +1031,21 @@ void VoidFunc(bool /* flag */) {} TEST(DoDefaultDeathTest, DiesIfUsedInCompositeAction) { MockClass mock; EXPECT_CALL(mock, IntFunc(_)) - .WillRepeatedly(DoAll(Invoke(VoidFunc), - DoDefault())); + .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); - }, ""); + 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(). +// DefaultValue<T>::Set() when it's not overridden by an ON_CALL(). TEST(DoDefaultTest, ReturnsUserSpecifiedPerTypeDefaultValueWhenThereIsOne) { DefaultValue<int>::Set(1); MockClass mock; - EXPECT_CALL(mock, IntFunc(_)) - .WillOnce(DoDefault()); + EXPECT_CALL(mock, IntFunc(_)).WillOnce(DoDefault()); EXPECT_EQ(1, mock.IntFunc(false)); DefaultValue<int>::Clear(); } @@ -776,20 +1053,19 @@ TEST(DoDefaultTest, ReturnsUserSpecifiedPerTypeDefaultValueWhenThereIsOne) { // 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()); + 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()"); + 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 @@ -800,33 +1076,31 @@ TEST(SetArgPointeeTest, SetsTheNthPointee) { int n = 0; char ch = '\0'; - a.Perform(make_tuple(true, &n, &ch)); + 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(make_tuple(true, &n, &ch)); + a.Perform(std::make_tuple(true, &n, &ch)); EXPECT_EQ(0, n); EXPECT_EQ('a', ch); } -#if !((GTEST_GCC_VER_ && GTEST_GCC_VER_ < 40000) || GTEST_OS_SYMBIAN) // Tests that SetArgPointee<N>() accepts a string literal. -// GCC prior to v4.0 and the Symbian compiler do not support this. TEST(SetArgPointeeTest, AcceptsStringLiteral) { typedef void MyFunction(std::string*, const char**); Action<MyFunction> a = SetArgPointee<0>("hi"); std::string str; - const char* ptr = NULL; - a.Perform(make_tuple(&str, &ptr)); + const char* ptr = nullptr; + a.Perform(std::make_tuple(&str, &ptr)); EXPECT_EQ("hi", str); - EXPECT_TRUE(ptr == NULL); + EXPECT_TRUE(ptr == nullptr); a = SetArgPointee<1>("world"); str = ""; - a.Perform(make_tuple(&str, &ptr)); + a.Perform(std::make_tuple(&str, &ptr)); EXPECT_EQ("", str); EXPECT_STREQ("world", ptr); } @@ -834,21 +1108,20 @@ TEST(SetArgPointeeTest, AcceptsStringLiteral) { TEST(SetArgPointeeTest, AcceptsWideStringLiteral) { typedef void MyFunction(const wchar_t**); Action<MyFunction> a = SetArgPointee<0>(L"world"); - const wchar_t* ptr = NULL; - a.Perform(make_tuple(&ptr)); + const wchar_t* ptr = nullptr; + a.Perform(std::make_tuple(&ptr)); EXPECT_STREQ(L"world", ptr); -# if GTEST_HAS_STD_WSTRING +#if GTEST_HAS_STD_WSTRING typedef void MyStringFunction(std::wstring*); Action<MyStringFunction> a2 = SetArgPointee<0>(L"world"); std::wstring str = L""; - a2.Perform(make_tuple(&str)); + a2.Perform(std::make_tuple(&str)); EXPECT_EQ(L"world", str); -# endif -} #endif +} // Tests that SetArgPointee<N>() accepts a char pointer. TEST(SetArgPointeeTest, AcceptsCharPointer) { @@ -856,16 +1129,16 @@ TEST(SetArgPointeeTest, AcceptsCharPointer) { const char* const hi = "hi"; Action<MyFunction> a = SetArgPointee<1>(hi); std::string str; - const char* ptr = NULL; - a.Perform(make_tuple(true, &str, &ptr)); + const char* ptr = nullptr; + a.Perform(std::make_tuple(true, &str, &ptr)); EXPECT_EQ("hi", str); - EXPECT_TRUE(ptr == NULL); + EXPECT_TRUE(ptr == nullptr); char world_array[] = "world"; char* const world = world_array; a = SetArgPointee<2>(world); str = ""; - a.Perform(make_tuple(true, &str, &ptr)); + a.Perform(std::make_tuple(true, &str, &ptr)); EXPECT_EQ("", str); EXPECT_EQ(world, ptr); } @@ -874,20 +1147,20 @@ TEST(SetArgPointeeTest, AcceptsWideCharPointer) { typedef void MyFunction(bool, const wchar_t**); const wchar_t* const hi = L"hi"; Action<MyFunction> a = SetArgPointee<1>(hi); - const wchar_t* ptr = NULL; - a.Perform(make_tuple(true, &ptr)); + const wchar_t* ptr = nullptr; + a.Perform(std::make_tuple(true, &ptr)); EXPECT_EQ(hi, ptr); -# if GTEST_HAS_STD_WSTRING +#if GTEST_HAS_STD_WSTRING typedef void MyStringFunction(bool, std::wstring*); wchar_t world_array[] = L"world"; wchar_t* const world = world_array; Action<MyStringFunction> a2 = SetArgPointee<1>(world); std::wstring str; - a2.Perform(make_tuple(true, &str)); + a2.Perform(std::make_tuple(true, &str)); EXPECT_EQ(world_array, str); -# endif +#endif } // Tests that SetArgumentPointee<N>(v) sets the variable pointed to by @@ -898,14 +1171,14 @@ TEST(SetArgumentPointeeTest, SetsTheNthPointee) { int n = 0; char ch = '\0'; - a.Perform(make_tuple(true, &n, &ch)); + 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(make_tuple(true, &n, &ch)); + a.Perform(std::make_tuple(true, &n, &ch)); EXPECT_EQ(0, n); EXPECT_EQ('a', ch); } @@ -926,6 +1199,21 @@ class VoidNullaryFunctor { 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) {} @@ -940,16 +1228,16 @@ class Foo { TEST(InvokeWithoutArgsTest, Function) { // As an action that takes one argument. Action<int(int)> a = InvokeWithoutArgs(Nullary); // NOLINT - EXPECT_EQ(1, a.Perform(make_tuple(2))); + 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(make_tuple(2, 3.5))); + 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(make_tuple(1)); + a3.Perform(std::make_tuple(1)); EXPECT_TRUE(g_done); } @@ -957,17 +1245,17 @@ TEST(InvokeWithoutArgsTest, Function) { TEST(InvokeWithoutArgsTest, Functor) { // As an action that takes no argument. Action<int()> a = InvokeWithoutArgs(NullaryFunctor()); // NOLINT - EXPECT_EQ(2, a.Perform(make_tuple())); + 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(make_tuple(3, 3.5, 'a'))); + 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(make_tuple()); + a3.Perform(std::make_tuple()); EXPECT_TRUE(g_done); } @@ -976,13 +1264,13 @@ TEST(InvokeWithoutArgsTest, Method) { Foo foo; Action<int(bool, char)> a = // NOLINT InvokeWithoutArgs(&foo, &Foo::Nullary); - EXPECT_EQ(123, a.Perform(make_tuple(true, 'a'))); + 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(make_tuple(1)); + a.Perform(std::make_tuple(1)); } // Tests using IgnoreResult() on a monomorphic action. @@ -995,7 +1283,7 @@ int ReturnOne() { TEST(IgnoreResultTest, MonomorphicAction) { g_done = false; Action<void()> a = IgnoreResult(Invoke(ReturnOne)); - a.Perform(make_tuple()); + a.Perform(std::make_tuple()); EXPECT_TRUE(g_done); } @@ -1010,55 +1298,329 @@ TEST(IgnoreResultTest, ActionReturningClass) { g_done = false; Action<void(int)> a = IgnoreResult(Invoke(ReturnMyNonDefaultConstructible)); // NOLINT - a.Perform(make_tuple(2)); + 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(make_tuple(0)); + 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(make_tuple()); + 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(make_tuple(0)); + a.Perform(std::make_tuple(0)); EXPECT_DOUBLE_EQ(5, x); } -#if !GTEST_OS_WINDOWS_MOBILE +// DoAll should support &&-qualified actions when used with WillOnce. +TEST(DoAll, SupportsRefQualifiedActions) { + struct InitialAction { + void operator()(const int arg) && { EXPECT_EQ(17, arg); } + }; + + struct FinalAction { + int operator()() && { return 19; } + }; + + MockFunction<int(int)> mock; + EXPECT_CALL(mock, Call).WillOnce(DoAll(InitialAction{}, FinalAction{})); + EXPECT_EQ(19, mock.AsStdFunction()(17)); +} + +// DoAll should never provide rvalue references to the initial actions. If the +// mock action itself accepts an rvalue reference or a non-scalar object by +// value then the final action should receive an rvalue reference, but initial +// actions should receive only lvalue references. +TEST(DoAll, ProvidesLvalueReferencesToInitialActions) { + struct Obj {}; + + // Mock action accepts by value: the initial action should be fed a const + // lvalue reference, and the final action an rvalue reference. + { + struct InitialAction { + void operator()(Obj&) const { FAIL() << "Unexpected call"; } + void operator()(const Obj&) const {} + void operator()(Obj&&) const { FAIL() << "Unexpected call"; } + void operator()(const Obj&&) const { FAIL() << "Unexpected call"; } + }; + + MockFunction<void(Obj)> mock; + EXPECT_CALL(mock, Call) + .WillOnce(DoAll(InitialAction{}, InitialAction{}, [](Obj&&) {})) + .WillRepeatedly(DoAll(InitialAction{}, InitialAction{}, [](Obj&&) {})); + + mock.AsStdFunction()(Obj{}); + mock.AsStdFunction()(Obj{}); + } + + // Mock action accepts by const lvalue reference: both actions should receive + // a const lvalue reference. + { + struct InitialAction { + void operator()(Obj&) const { FAIL() << "Unexpected call"; } + void operator()(const Obj&) const {} + void operator()(Obj&&) const { FAIL() << "Unexpected call"; } + void operator()(const Obj&&) const { FAIL() << "Unexpected call"; } + }; + + MockFunction<void(const Obj&)> mock; + EXPECT_CALL(mock, Call) + .WillOnce(DoAll(InitialAction{}, InitialAction{}, [](const Obj&) {})) + .WillRepeatedly( + DoAll(InitialAction{}, InitialAction{}, [](const Obj&) {})); + + mock.AsStdFunction()(Obj{}); + mock.AsStdFunction()(Obj{}); + } + + // Mock action accepts by non-const lvalue reference: both actions should get + // a non-const lvalue reference if they want them. + { + struct InitialAction { + void operator()(Obj&) const {} + void operator()(Obj&&) const { FAIL() << "Unexpected call"; } + }; + + MockFunction<void(Obj&)> mock; + EXPECT_CALL(mock, Call) + .WillOnce(DoAll(InitialAction{}, InitialAction{}, [](Obj&) {})) + .WillRepeatedly(DoAll(InitialAction{}, InitialAction{}, [](Obj&) {})); + + Obj obj; + mock.AsStdFunction()(obj); + mock.AsStdFunction()(obj); + } + + // Mock action accepts by rvalue reference: the initial actions should receive + // a non-const lvalue reference if it wants it, and the final action an rvalue + // reference. + { + struct InitialAction { + void operator()(Obj&) const {} + void operator()(Obj&&) const { FAIL() << "Unexpected call"; } + }; + + MockFunction<void(Obj&&)> mock; + EXPECT_CALL(mock, Call) + .WillOnce(DoAll(InitialAction{}, InitialAction{}, [](Obj&&) {})) + .WillRepeatedly(DoAll(InitialAction{}, InitialAction{}, [](Obj&&) {})); + + mock.AsStdFunction()(Obj{}); + mock.AsStdFunction()(Obj{}); + } + + // &&-qualified initial actions should also be allowed with WillOnce. + { + struct InitialAction { + void operator()(Obj&) && {} + }; + + MockFunction<void(Obj&)> mock; + EXPECT_CALL(mock, Call) + .WillOnce(DoAll(InitialAction{}, InitialAction{}, [](Obj&) {})); + + Obj obj; + mock.AsStdFunction()(obj); + } + + { + struct InitialAction { + void operator()(Obj&) && {} + }; + + MockFunction<void(Obj&&)> mock; + EXPECT_CALL(mock, Call) + .WillOnce(DoAll(InitialAction{}, InitialAction{}, [](Obj&&) {})); + + mock.AsStdFunction()(Obj{}); + } +} + +// DoAll should support being used with type-erased Action objects, both through +// WillOnce and WillRepeatedly. +TEST(DoAll, SupportsTypeErasedActions) { + // With only type-erased actions. + const Action<void()> initial_action = [] {}; + const Action<int()> final_action = [] { return 17; }; + + MockFunction<int()> mock; + EXPECT_CALL(mock, Call) + .WillOnce(DoAll(initial_action, initial_action, final_action)) + .WillRepeatedly(DoAll(initial_action, initial_action, final_action)); + + EXPECT_EQ(17, mock.AsStdFunction()()); + + // With &&-qualified and move-only final action. + { + struct FinalAction { + FinalAction() = default; + FinalAction(FinalAction&&) = default; + + int operator()() && { return 17; } + }; + + EXPECT_CALL(mock, Call) + .WillOnce(DoAll(initial_action, initial_action, FinalAction{})); + + EXPECT_EQ(17, mock.AsStdFunction()()); + } +} + +// 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; }; + + MockFunction<Base*(double)> mock; + EXPECT_CALL(mock, Call) + .WillOnce(WithoutArgs(inner)) + .WillRepeatedly(WithoutArgs(inner)); + + EXPECT_EQ(nullptr, mock.AsStdFunction()(1.1)); + EXPECT_EQ(nullptr, mock.AsStdFunction()(1.1)); +} + +// It should be possible to use an &&-qualified inner action as long as the +// whole shebang is used as an rvalue with WillOnce. +TEST(WithArgsTest, RefQualifiedInnerAction) { + struct SomeAction { + int operator()(const int arg) && { + EXPECT_EQ(17, arg); + return 19; + } + }; + + MockFunction<int(int, int)> mock; + EXPECT_CALL(mock, Call).WillOnce(WithArg<1>(SomeAction{})); + EXPECT_EQ(19, mock.AsStdFunction()(0, 17)); +} + +#ifndef GTEST_OS_WINDOWS_MOBILE class SetErrnoAndReturnTest : public testing::Test { protected: - virtual void SetUp() { errno = 0; } - virtual void TearDown() { errno = 0; } + 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(make_tuple())); + 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(make_tuple())); + 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(make_tuple())); + EXPECT_DOUBLE_EQ(5.0, a.Perform(std::make_tuple())); EXPECT_EQ(EINVAL, errno); } @@ -1066,13 +1628,12 @@ TEST_F(SetErrnoAndReturnTest, CompatibleTypes) { // Tests ByRef(). -// Tests that ReferenceWrapper<T> is copyable. +// Tests that the result of ByRef() is copyable. TEST(ByRefTest, IsCopyable) { const std::string s1 = "Hi"; const std::string s2 = "Hello"; - ::testing::internal::ReferenceWrapper<const std::string> ref_wrapper = - ByRef(s1); + auto ref_wrapper = ByRef(s1); const std::string& r1 = ref_wrapper; EXPECT_EQ(&s1, &r1); @@ -1081,8 +1642,7 @@ TEST(ByRefTest, IsCopyable) { const std::string& r2 = ref_wrapper; EXPECT_EQ(&s2, &r2); - ::testing::internal::ReferenceWrapper<const std::string> ref_wrapper1 = - ByRef(s1); + auto ref_wrapper1 = ByRef(s1); // Copies ref_wrapper1 to ref_wrapper. ref_wrapper = ref_wrapper1; const std::string& r3 = ref_wrapper; @@ -1093,7 +1653,7 @@ TEST(ByRefTest, IsCopyable) { TEST(ByRefTest, ConstValue) { const int n = 0; // int& ref = ByRef(n); // This shouldn't compile - we have a - // negative compilation test to catch it. + // negative compilation test to catch it. const int& const_ref = ByRef(n); EXPECT_EQ(&n, &const_ref); } @@ -1118,7 +1678,7 @@ TEST(ByRefTest, ExplicitType) { EXPECT_EQ(&n, &r1); // ByRef<char>(n); // This shouldn't compile - we have a negative - // compilation test to catch it. + // compilation test to catch it. Derived d; Derived& r2 = ByRef<Derived>(d); @@ -1149,12 +1709,55 @@ TEST(ByRefTest, PrintsCorrectly) { EXPECT_EQ(expected.str(), actual.str()); } -#if GTEST_HAS_STD_UNIQUE_PTR_ +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; +} -std::unique_ptr<int> UniquePtrSource() { - return std::unique_ptr<int>(new int(19)); +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::make_unique<int>(19); } + std::vector<std::unique_ptr<int>> VectorUniquePtrSource() { std::vector<std::unique_ptr<int>> out; out.emplace_back(new int(7)); @@ -1188,9 +1791,10 @@ TEST(MockMethodTest, CanReturnMoveOnlyValue_DoAllReturn) { 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))))); + 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); @@ -1200,9 +1804,8 @@ TEST(MockMethodTest, CanReturnMoveOnlyValue_Invoke) { MockClass mock; // Check default value - DefaultValue<std::unique_ptr<int>>::SetFactory([] { - return std::unique_ptr<int>(new int(42)); - }); + DefaultValue<std::unique_ptr<int>>::SetFactory( + [] { return std::make_unique<int>(42); }); EXPECT_EQ(42, *mock.MakeUnique()); EXPECT_CALL(mock, MakeUnique()).WillRepeatedly(Invoke(UniquePtrSource)); @@ -1222,7 +1825,7 @@ TEST(MockMethodTest, CanReturnMoveOnlyValue_Invoke) { TEST(MockMethodTest, CanTakeMoveOnlyValue) { MockClass mock; - auto make = [](int i) { return std::unique_ptr<int>(new int(i)); }; + auto make = [](int i) { return std::make_unique<int>(i); }; EXPECT_CALL(mock, TakeUnique(_)).WillRepeatedly([](std::unique_ptr<int> i) { return *i; @@ -1262,9 +1865,179 @@ TEST(MockMethodTest, CanTakeMoveOnlyValue) { EXPECT_EQ(42, *saved); } -#endif // GTEST_HAS_STD_UNIQUE_PTR_ +// It should be possible to use callables with an &&-qualified call operator +// with WillOnce, since they will be called only once. This allows actions to +// contain and manipulate move-only types. +TEST(MockMethodTest, ActionHasRvalueRefQualifiedCallOperator) { + struct Return17 { + int operator()() && { return 17; } + }; + + // Action is directly compatible with mocked function type. + { + MockFunction<int()> mock; + EXPECT_CALL(mock, Call).WillOnce(Return17()); + + EXPECT_EQ(17, mock.AsStdFunction()()); + } + + // Action doesn't want mocked function arguments. + { + MockFunction<int(int)> mock; + EXPECT_CALL(mock, Call).WillOnce(Return17()); + + EXPECT_EQ(17, mock.AsStdFunction()(0)); + } +} + +// Edge case: if an action has both a const-qualified and an &&-qualified call +// operator, there should be no "ambiguous call" errors. The &&-qualified +// operator should be used by WillOnce (since it doesn't need to retain the +// action beyond one call), and the const-qualified one by WillRepeatedly. +TEST(MockMethodTest, ActionHasMultipleCallOperators) { + struct ReturnInt { + int operator()() && { return 17; } + int operator()() const& { return 19; } + }; + + // Directly compatible with mocked function type. + { + MockFunction<int()> mock; + EXPECT_CALL(mock, Call).WillOnce(ReturnInt()).WillRepeatedly(ReturnInt()); + + EXPECT_EQ(17, mock.AsStdFunction()()); + EXPECT_EQ(19, mock.AsStdFunction()()); + EXPECT_EQ(19, mock.AsStdFunction()()); + } + + // Ignores function arguments. + { + MockFunction<int(int)> mock; + EXPECT_CALL(mock, Call).WillOnce(ReturnInt()).WillRepeatedly(ReturnInt()); + + EXPECT_EQ(17, mock.AsStdFunction()(0)); + EXPECT_EQ(19, mock.AsStdFunction()(0)); + EXPECT_EQ(19, mock.AsStdFunction()(0)); + } +} + +// WillOnce should have no problem coping with a move-only action, whether it is +// &&-qualified or not. +TEST(MockMethodTest, MoveOnlyAction) { + // &&-qualified + { + struct Return17 { + Return17() = default; + Return17(Return17&&) = default; + + Return17(const Return17&) = delete; + Return17 operator=(const Return17&) = delete; + + int operator()() && { return 17; } + }; + + MockFunction<int()> mock; + EXPECT_CALL(mock, Call).WillOnce(Return17()); + EXPECT_EQ(17, mock.AsStdFunction()()); + } + + // Not &&-qualified + { + struct Return17 { + Return17() = default; + Return17(Return17&&) = default; + + Return17(const Return17&) = delete; + Return17 operator=(const Return17&) = delete; + + int operator()() const { return 17; } + }; + + MockFunction<int()> mock; + EXPECT_CALL(mock, Call).WillOnce(Return17()); + EXPECT_EQ(17, mock.AsStdFunction()()); + } +} + +// It should be possible to use an action that returns a value with a mock +// function that doesn't, both through WillOnce and WillRepeatedly. +TEST(MockMethodTest, ActionReturnsIgnoredValue) { + struct ReturnInt { + int operator()() const { return 0; } + }; + + MockFunction<void()> mock; + EXPECT_CALL(mock, Call).WillOnce(ReturnInt()).WillRepeatedly(ReturnInt()); + + mock.AsStdFunction()(); + mock.AsStdFunction()(); +} + +// Despite the fanciness around move-only actions and so on, it should still be +// possible to hand an lvalue reference to a copyable action to WillOnce. +TEST(MockMethodTest, WillOnceCanAcceptLvalueReference) { + MockFunction<int()> mock; + + const auto action = [] { return 17; }; + EXPECT_CALL(mock, Call).WillOnce(action); + + EXPECT_EQ(17, mock.AsStdFunction()()); +} + +// A callable that doesn't use SFINAE to restrict its call operator's overload +// set, but is still picky about which arguments it will accept. +struct StaticAssertSingleArgument { + template <typename... Args> + static constexpr bool CheckArgs() { + static_assert(sizeof...(Args) == 1, ""); + return true; + } + + template <typename... Args, bool = CheckArgs<Args...>()> + int operator()(Args...) const { + return 17; + } +}; + +// WillOnce and WillRepeatedly should both work fine with naïve implementations +// of actions that don't use SFINAE to limit the overload set for their call +// operator. If they are compatible with the actual mocked signature, we +// shouldn't probe them with no arguments and trip a static_assert. +TEST(MockMethodTest, ActionSwallowsAllArguments) { + MockFunction<int(int)> mock; + EXPECT_CALL(mock, Call) + .WillOnce(StaticAssertSingleArgument{}) + .WillRepeatedly(StaticAssertSingleArgument{}); + + EXPECT_EQ(17, mock.AsStdFunction()(0)); + EXPECT_EQ(17, mock.AsStdFunction()(0)); +} + +struct ActionWithTemplatedConversionOperators { + template <typename... Args> + operator OnceAction<int(Args...)>() && { // NOLINT + return [] { return 17; }; + } + + template <typename... Args> + operator Action<int(Args...)>() const { // NOLINT + return [] { return 19; }; + } +}; + +// It should be fine to hand both WillOnce and WillRepeatedly a function that +// defines templated conversion operators to OnceAction and Action. WillOnce +// should prefer the OnceAction version. +TEST(MockMethodTest, ActionHasTemplatedConversionOperators) { + MockFunction<int()> mock; + EXPECT_CALL(mock, Call) + .WillOnce(ActionWithTemplatedConversionOperators{}) + .WillRepeatedly(ActionWithTemplatedConversionOperators{}); + + EXPECT_EQ(17, mock.AsStdFunction()()); + EXPECT_EQ(19, mock.AsStdFunction()()); +} -#if GTEST_LANG_CXX11 // Tests for std::function based action. int Add(int val, int& ref, int* ptr) { // NOLINT @@ -1278,12 +2051,12 @@ int Deref(std::unique_ptr<int> ptr) { return *ptr; } struct Double { template <typename T> - T operator()(T t) { return 2 * t; } + T operator()(T t) { + return 2 * t; + } }; -std::unique_ptr<int> UniqueInt(int i) { - return std::unique_ptr<int>(new int(i)); -} +std::unique_ptr<int> UniqueInt(int i) { return std::make_unique<int>(i); } TEST(FunctorActionTest, ActionFromFunction) { Action<int(int, int&, int*)> a = &Add; @@ -1298,75 +2071,99 @@ TEST(FunctorActionTest, ActionFromFunction) { TEST(FunctorActionTest, ActionFromLambda) { Action<int(bool, int)> a1 = [](bool b, int i) { return b ? i : 0; }; - EXPECT_EQ(5, a1.Perform(make_tuple(true, 5))); - EXPECT_EQ(0, a1.Perform(make_tuple(false, 5))); + 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(make_tuple(UniqueInt(5))); + a2.Perform(std::make_tuple(UniqueInt(5))); EXPECT_EQ(5, *saved); } TEST(FunctorActionTest, PolymorphicFunctor) { Action<int(int)> ai = Double(); - EXPECT_EQ(2, ai.Perform(make_tuple(1))); + EXPECT_EQ(2, ai.Perform(std::make_tuple(1))); Action<double(double)> ad = Double(); // Double? Double double! - EXPECT_EQ(3.0, ad.Perform(make_tuple(1.5))); + 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(make_tuple(42))); - EXPECT_EQ(0, a2.Perform(make_tuple(42))); + 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(make_tuple(""))); - EXPECT_EQ(1, s2.Perform(make_tuple("hello"))); + 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)> x = [](Unused) { return 42; }; - EXPECT_TRUE(x.Perform(make_tuple("hello"))); + 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; }; - tuple<int, double, double> dummy = make_tuple(3, 7.3, 9.44); + 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. -// FIXME: Currently, almost all ActionInterface-based actions will not -// work, even if they only try to use other, copyable arguments. Implement them -// if necessary (but note that DoAll cannot work on non-copyable types anyway - -// so maybe it's better to make users use lambdas instead. TEST(MoveOnlyArgumentsTest, ReturningActions) { Action<int(std::unique_ptr<int>)> a = Return(1); - EXPECT_EQ(1, a.Perform(make_tuple(nullptr))); + EXPECT_EQ(1, a.Perform(std::make_tuple(nullptr))); a = testing::WithoutArgs([]() { return 7; }); - EXPECT_EQ(7, a.Perform(make_tuple(nullptr))); + 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(make_tuple(nullptr, &x)); + a2.Perform(std::make_tuple(nullptr, &x)); EXPECT_EQ(x, 3); } -#endif // GTEST_LANG_CXX11 +ACTION(ReturnArity) { return std::tuple_size<args_type>::value; } -} // Unnamed namespace +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))); +} -#ifdef _MSC_VER -#if _MSC_VER == 1900 -# pragma warning(pop) -#endif -#endif +} // namespace +} // namespace testing +#if defined(_MSC_VER) && (_MSC_VER == 1900) +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4800 +#endif +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100 4503 diff --git a/contrib/googletest/googlemock/test/gmock-cardinalities_test.cc b/contrib/googletest/googlemock/test/gmock-cardinalities_test.cc index 132591bcff50..ad49752e172d 100644 --- a/contrib/googletest/googlemock/test/gmock-cardinalities_test.cc +++ b/contrib/googletest/googlemock/test/gmock-cardinalities_test.cc @@ -27,14 +27,15 @@ // (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 <ostream> + #include "gmock/gmock.h" -#include "gtest/gtest.h" #include "gtest/gtest-spi.h" +#include "gtest/gtest.h" namespace { @@ -51,17 +52,16 @@ using testing::MakeCardinality; class MockFoo { public: - MockFoo() {} + MockFoo() = default; MOCK_METHOD0(Bar, int()); // NOLINT private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo); + MockFoo(const MockFoo&) = delete; + MockFoo& operator=(const MockFoo&) = delete; }; // Tests that Cardinality objects can be default constructed. -TEST(CardinalityTest, IsDefaultConstructable) { - Cardinality c; -} +TEST(CardinalityTest, IsDefaultConstructable) { Cardinality c; } // Tests that Cardinality objects are copyable. TEST(CardinalityTest, IsCopyable) { @@ -119,8 +119,7 @@ TEST(AnyNumber, Works) { stringstream ss; c.DescribeTo(&ss); - EXPECT_PRED_FORMAT2(IsSubstring, "called any number of times", - ss.str()); + EXPECT_PRED_FORMAT2(IsSubstring, "called any number of times", ss.str()); } TEST(AnyNumberTest, HasCorrectBounds) { @@ -132,9 +131,11 @@ TEST(AnyNumberTest, HasCorrectBounds) { // Tests AtLeast(n). TEST(AtLeastTest, OnNegativeNumber) { - EXPECT_NONFATAL_FAILURE({ // NOLINT - AtLeast(-1); - }, "The invocation lower bound must be >= 0"); + EXPECT_NONFATAL_FAILURE( + { // NOLINT + AtLeast(-1); + }, + "The invocation lower bound must be >= 0"); } TEST(AtLeastTest, OnZero) { @@ -147,8 +148,7 @@ TEST(AtLeastTest, OnZero) { stringstream ss; c.DescribeTo(&ss); - EXPECT_PRED_FORMAT2(IsSubstring, "any number of times", - ss.str()); + EXPECT_PRED_FORMAT2(IsSubstring, "any number of times", ss.str()); } TEST(AtLeastTest, OnPositiveNumber) { @@ -164,18 +164,15 @@ TEST(AtLeastTest, OnPositiveNumber) { stringstream ss1; AtLeast(1).DescribeTo(&ss1); - EXPECT_PRED_FORMAT2(IsSubstring, "at least once", - ss1.str()); + EXPECT_PRED_FORMAT2(IsSubstring, "at least once", ss1.str()); stringstream ss2; c.DescribeTo(&ss2); - EXPECT_PRED_FORMAT2(IsSubstring, "at least twice", - ss2.str()); + 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()); + EXPECT_PRED_FORMAT2(IsSubstring, "at least 3 times", ss3.str()); } TEST(AtLeastTest, HasCorrectBounds) { @@ -187,9 +184,11 @@ TEST(AtLeastTest, HasCorrectBounds) { // Tests AtMost(n). TEST(AtMostTest, OnNegativeNumber) { - EXPECT_NONFATAL_FAILURE({ // NOLINT - AtMost(-1); - }, "The invocation upper bound must be >= 0"); + EXPECT_NONFATAL_FAILURE( + { // NOLINT + AtMost(-1); + }, + "The invocation upper bound must be >= 0"); } TEST(AtMostTest, OnZero) { @@ -202,8 +201,7 @@ TEST(AtMostTest, OnZero) { stringstream ss; c.DescribeTo(&ss); - EXPECT_PRED_FORMAT2(IsSubstring, "never called", - ss.str()); + EXPECT_PRED_FORMAT2(IsSubstring, "never called", ss.str()); } TEST(AtMostTest, OnPositiveNumber) { @@ -219,18 +217,15 @@ TEST(AtMostTest, OnPositiveNumber) { stringstream ss1; AtMost(1).DescribeTo(&ss1); - EXPECT_PRED_FORMAT2(IsSubstring, "called at most once", - ss1.str()); + 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()); + 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()); + EXPECT_PRED_FORMAT2(IsSubstring, "called at most 3 times", ss3.str()); } TEST(AtMostTest, HasCorrectBounds) { @@ -242,22 +237,28 @@ TEST(AtMostTest, HasCorrectBounds) { // 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"); + 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"); + 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)"); + EXPECT_NONFATAL_FAILURE( + { // NOLINT + Between(2, 1); + }, + "The invocation upper bound (1) must be >= " + "the invocation lower bound (2)"); } TEST(BetweenTest, OnZeroStartAndZeroEnd) { @@ -271,8 +272,7 @@ TEST(BetweenTest, OnZeroStartAndZeroEnd) { stringstream ss; c.DescribeTo(&ss); - EXPECT_PRED_FORMAT2(IsSubstring, "never called", - ss.str()); + EXPECT_PRED_FORMAT2(IsSubstring, "never called", ss.str()); } TEST(BetweenTest, OnZeroStartAndNonZeroEnd) { @@ -289,8 +289,7 @@ TEST(BetweenTest, OnZeroStartAndNonZeroEnd) { stringstream ss; c.DescribeTo(&ss); - EXPECT_PRED_FORMAT2(IsSubstring, "called at most twice", - ss.str()); + EXPECT_PRED_FORMAT2(IsSubstring, "called at most twice", ss.str()); } TEST(BetweenTest, OnSameStartAndEnd) { @@ -307,8 +306,7 @@ TEST(BetweenTest, OnSameStartAndEnd) { stringstream ss; c.DescribeTo(&ss); - EXPECT_PRED_FORMAT2(IsSubstring, "called 3 times", - ss.str()); + EXPECT_PRED_FORMAT2(IsSubstring, "called 3 times", ss.str()); } TEST(BetweenTest, OnDifferentStartAndEnd) { @@ -328,8 +326,7 @@ TEST(BetweenTest, OnDifferentStartAndEnd) { stringstream ss; c.DescribeTo(&ss); - EXPECT_PRED_FORMAT2(IsSubstring, "called between 3 and 5 times", - ss.str()); + EXPECT_PRED_FORMAT2(IsSubstring, "called between 3 and 5 times", ss.str()); } TEST(BetweenTest, HasCorrectBounds) { @@ -341,9 +338,11 @@ TEST(BetweenTest, HasCorrectBounds) { // Tests Exactly(n). TEST(ExactlyTest, OnNegativeNumber) { - EXPECT_NONFATAL_FAILURE({ // NOLINT - Exactly(-1); - }, "The invocation lower bound must be >= 0"); + EXPECT_NONFATAL_FAILURE( + { // NOLINT + Exactly(-1); + }, + "The invocation lower bound must be >= 0"); } TEST(ExactlyTest, OnZero) { @@ -356,8 +355,7 @@ TEST(ExactlyTest, OnZero) { stringstream ss; c.DescribeTo(&ss); - EXPECT_PRED_FORMAT2(IsSubstring, "never called", - ss.str()); + EXPECT_PRED_FORMAT2(IsSubstring, "never called", ss.str()); } TEST(ExactlyTest, OnPositiveNumber) { @@ -370,18 +368,15 @@ TEST(ExactlyTest, OnPositiveNumber) { stringstream ss1; Exactly(1).DescribeTo(&ss1); - EXPECT_PRED_FORMAT2(IsSubstring, "called once", - ss1.str()); + EXPECT_PRED_FORMAT2(IsSubstring, "called once", ss1.str()); stringstream ss2; c.DescribeTo(&ss2); - EXPECT_PRED_FORMAT2(IsSubstring, "called twice", - ss2.str()); + EXPECT_PRED_FORMAT2(IsSubstring, "called twice", ss2.str()); stringstream ss3; Exactly(3).DescribeTo(&ss3); - EXPECT_PRED_FORMAT2(IsSubstring, "called 3 times", - ss3.str()); + EXPECT_PRED_FORMAT2(IsSubstring, "called 3 times", ss3.str()); } TEST(ExactlyTest, HasCorrectBounds) { @@ -395,18 +390,20 @@ TEST(ExactlyTest, HasCorrectBounds) { class EvenCardinality : public CardinalityInterface { public: - // Returns true iff call_count calls will satisfy this cardinality. - virtual bool IsSatisfiedByCallCount(int call_count) const { + // 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 iff call_count calls will saturate this cardinality. - virtual bool IsSaturatedByCallCount(int /* call_count */) const { + // 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. - virtual void DescribeTo(::std::ostream* ss) const { + void DescribeTo(::std::ostream* ss) const override { *ss << "called even number of times"; } }; diff --git a/contrib/googletest/googlemock/test/gmock-function-mocker_test.cc b/contrib/googletest/googlemock/test/gmock-function-mocker_test.cc new file mode 100644 index 000000000000..f7b31ae33852 --- /dev/null +++ b/contrib/googletest/googlemock/test/gmock-function-mocker_test.cc @@ -0,0 +1,998 @@ +// 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" + +// Silence C4503 (decorated name length exceeded) for MSVC. +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4503) + +#ifdef GTEST_OS_WINDOWS +// MSDN says the header file to be included for STDMETHOD is BaseTyps.h but +// we are getting compiler errors if we use basetyps.h, hence including +// objbase.h for definition of STDMETHOD. +#include <objbase.h> +#endif // GTEST_OS_WINDOWS + +#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() = default; + + template <typename U> + TemplatedCopyable(const U& other) {} // NOLINT +}; + +class FooInterface { + public: + virtual ~FooInterface() = default; + + 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; + +#ifdef GTEST_OS_WINDOWS + STDMETHOD_(int, CTNullary)() = 0; + STDMETHOD_(bool, CTUnary)(int x) = 0; + STDMETHOD_(int, CTDecimal) + (bool b, char c, short d, int e, long f, // NOLINT + float g, double h, unsigned i, char* j, const 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. +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4373) +class MockFoo : public FooInterface { + public: + MockFoo() = default; + + // 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), ()); + +#ifdef 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: + MockFoo(const MockFoo&) = delete; + MockFoo& operator=(const MockFoo&) = delete; +}; + +class LegacyMockFoo : public FooInterface { + public: + LegacyMockFoo() = default; + + // 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)); + +#ifdef 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: + LegacyMockFoo(const LegacyMockFoo&) = delete; + LegacyMockFoo& operator=(const LegacyMockFoo&) = delete; +}; + +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4373 + +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>())); +} + +#ifdef 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() = default; + + MOCK_METHOD(void, DoB, ()); + + private: + MockB(const MockB&) = delete; + MockB& operator=(const MockB&) = delete; +}; + +class LegacyMockB { + public: + LegacyMockB() = default; + + MOCK_METHOD0(DoB, void()); + + private: + LegacyMockB(const LegacyMockB&) = delete; + LegacyMockB& operator=(const LegacyMockB&) = delete; +}; + +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() = default; + + // 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() = default; + + 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: + MockStack(const MockStack&) = delete; + MockStack& operator=(const MockStack&) = delete; +}; + +template <typename T> +class LegacyMockStack : public StackInterface<T> { + public: + LegacyMockStack() = default; + + 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: + LegacyMockStack(const LegacyMockStack&) = delete; + LegacyMockStack& operator=(const LegacyMockStack&) = delete; +}; + +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)); +} + +#ifdef GTEST_OS_WINDOWS +// Tests mocking template interfaces with calltype. + +template <typename T> +class StackInterfaceWithCallType { + public: + virtual ~StackInterfaceWithCallType() {} + + // Template parameter appears in function parameter. + STDMETHOD_(void, Push)(const T& value) = 0; + STDMETHOD_(void, Pop)() = 0; + STDMETHOD_(int, GetSize)() const = 0; + // Template parameter appears in function return type. + STDMETHOD_(const T&, GetTop)() const = 0; +}; + +template <typename T> +class MockStackWithCallType : public StackInterfaceWithCallType<T> { + public: + 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: + MockStackWithCallType(const MockStackWithCallType&) = delete; + MockStackWithCallType& operator=(const MockStackWithCallType&) = delete; +}; + +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: + LegacyMockStackWithCallType(const LegacyMockStackWithCallType&) = delete; + LegacyMockStackWithCallType& operator=(const LegacyMockStackWithCallType&) = + delete; +}; + +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() = default; + + MY_MOCK_METHODS1_; + + private: + MockOverloadedOnArgNumber(const MockOverloadedOnArgNumber&) = delete; + MockOverloadedOnArgNumber& operator=(const MockOverloadedOnArgNumber&) = + delete; +}; + +class LegacyMockOverloadedOnArgNumber { + public: + LegacyMockOverloadedOnArgNumber() = default; + + LEGACY_MY_MOCK_METHODS1_; + + private: + LegacyMockOverloadedOnArgNumber(const LegacyMockOverloadedOnArgNumber&) = + delete; + LegacyMockOverloadedOnArgNumber& operator=( + const LegacyMockOverloadedOnArgNumber&) = delete; +}; + +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() = default; + + MY_MOCK_METHODS2_; + + private: + MockOverloadedOnConstness(const MockOverloadedOnConstness&) = delete; + MockOverloadedOnConstness& operator=(const MockOverloadedOnConstness&) = + delete; +}; + +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 internal::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<TypeParam>(foo)); +} + +TYPED_TEST(MockMethodMockFunctionSignatureTest, + IsMockFunctionTemplateArgumentDeducedForStdFunction) { + using Argument = std::function<TypeParam>; + MockFunction<Argument> foo; + EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<TypeParam>(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)); +} + +template <typename F> +struct AlternateCallable {}; + +TYPED_TEST(MockMethodMockFunctionSignatureTest, + IsMockFunctionTemplateArgumentDeducedForAlternateCallable) { + using Argument = AlternateCallable<TypeParam>; + MockFunction<Argument> foo; + EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<TypeParam>(foo)); +} + +TYPED_TEST(MockMethodMockFunctionSignatureTest, + IsMockFunctionCallMethodSignatureTheSameForAlternateCallable) { + using ForRawSignature = decltype(&MockFunction<TypeParam>::Call); + using ForStdFunction = + decltype(&MockFunction<std::function<TypeParam>>::Call); + 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)); +} + +TEST(MockMethodMockFunctionTest, EnsureNoUnusedMemberFunction) { +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic error "-Wunused-member-function" +#endif + // https://github.com/google/googletest/issues/4052 + struct Foo { + MOCK_METHOD(void, foo, ()); + }; + EXPECT_CALL(Foo(), foo()).Times(0); +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +} + +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 + +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4503 diff --git a/contrib/googletest/googlemock/test/gmock-generated-actions_test.cc b/contrib/googletest/googlemock/test/gmock-generated-actions_test.cc deleted file mode 100644 index a4602806d53e..000000000000 --- a/contrib/googletest/googlemock/test/gmock-generated-actions_test.cc +++ /dev/null @@ -1,1229 +0,0 @@ -// 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 <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::get; -using testing::make_tuple; -using testing::tuple; -using testing::tuple_element; -using testing::_; -using testing::Action; -using testing::ActionInterface; -using testing::ByRef; -using testing::DoAll; -using testing::Invoke; -using testing::Return; -using testing::ReturnNew; -using testing::SetArgPointee; -using testing::StaticAssertTypeEq; -using testing::Unused; -using testing::WithArgs; - -// For suppressing compiler warnings on conversion possibly losing precision. -inline short Short(short n) { return n; } // NOLINT -inline char Char(char ch) { return ch; } - -// Sample functions and functors for testing various actions. -int Nullary() { return 1; } - -class NullaryFunctor { - public: - int operator()() { return 2; } -}; - -bool g_done = false; - -bool Unary(int x) { return x < 0; } - -const char* Plus1(const char* s) { return s + 1; } - -bool ByConstRef(const 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; } - -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; -} - -// A helper that turns the type of a C-string literal from const -// char[N] to const char*. -inline const char* CharPtr(const char* s) { return s; } - -// Tests InvokeArgument<N>(...). - -// Tests using InvokeArgument with a nullary function. -TEST(InvokeArgumentTest, Function0) { - Action<int(int, int(*)())> a = InvokeArgument<1>(); // NOLINT - EXPECT_EQ(1, a.Perform(make_tuple(2, &Nullary))); -} - -// Tests using InvokeArgument with a unary function. -TEST(InvokeArgumentTest, Functor1) { - Action<int(UnaryFunctor)> a = InvokeArgument<0>(true); // NOLINT - EXPECT_EQ(1, a.Perform(make_tuple(UnaryFunctor()))); -} - -// Tests using InvokeArgument with a 5-ary function. -TEST(InvokeArgumentTest, Function5) { - Action<int(int(*)(int, int, int, int, int))> a = // NOLINT - InvokeArgument<0>(10000, 2000, 300, 40, 5); - EXPECT_EQ(12345, a.Perform(make_tuple(&SumOf5))); -} - -// Tests using InvokeArgument with a 5-ary functor. -TEST(InvokeArgumentTest, Functor5) { - Action<int(SumOf5Functor)> a = // NOLINT - InvokeArgument<0>(10000, 2000, 300, 40, 5); - EXPECT_EQ(12345, a.Perform(make_tuple(SumOf5Functor()))); -} - -// Tests using InvokeArgument with a 6-ary function. -TEST(InvokeArgumentTest, Function6) { - Action<int(int(*)(int, int, int, int, int, int))> a = // NOLINT - InvokeArgument<0>(100000, 20000, 3000, 400, 50, 6); - EXPECT_EQ(123456, a.Perform(make_tuple(&SumOf6))); -} - -// Tests using InvokeArgument with a 6-ary functor. -TEST(InvokeArgumentTest, Functor6) { - Action<int(SumOf6Functor)> a = // NOLINT - InvokeArgument<0>(100000, 20000, 3000, 400, 50, 6); - EXPECT_EQ(123456, a.Perform(make_tuple(SumOf6Functor()))); -} - -// Tests using InvokeArgument with a 7-ary function. -TEST(InvokeArgumentTest, Function7) { - Action<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(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(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(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(make_tuple(&Concat10))); -} - -// Tests using InvokeArgument with a function that takes a pointer argument. -TEST(InvokeArgumentTest, ByPointerFunction) { - Action<const char*(const char*(*)(const char* input, short n))> a = // NOLINT - InvokeArgument<0>(static_cast<const char*>("Hi"), Short(1)); - EXPECT_STREQ("i", a.Perform(make_tuple(&Binary))); -} - -// Tests using InvokeArgument with a function that takes a const char* -// by passing it a C-string literal. -TEST(InvokeArgumentTest, FunctionWithCStringLiteral) { - Action<const char*(const char*(*)(const char* input, short n))> a = // NOLINT - InvokeArgument<0>("Hi", Short(1)); - EXPECT_STREQ("i", a.Perform(make_tuple(&Binary))); -} - -// Tests using InvokeArgument with a function that takes a const reference. -TEST(InvokeArgumentTest, ByConstReferenceFunction) { - Action<bool(bool (*function)(const 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(make_tuple(&ByConstRef))); -} - -// Tests using InvokeArgument with ByRef() and a function that takes a -// const reference. -TEST(InvokeArgumentTest, ByExplicitConstReferenceFunction) { - Action<bool(bool(*)(const double& x))> a = // NOLINT - InvokeArgument<0>(ByRef(g_double)); - // The above line calls ByRef() on a const value. - EXPECT_TRUE(a.Perform(make_tuple(&ReferencesGlobalDouble))); - - double x = 0; - a = InvokeArgument<0>(ByRef(x)); // This calls ByRef() on a non-const. - EXPECT_FALSE(a.Perform(make_tuple(&ReferencesGlobalDouble))); -} - -// Tests using WithArgs and with an action that takes 1 argument. -TEST(WithArgsTest, OneArg) { - Action<bool(double x, int n)> a = WithArgs<1>(Invoke(Unary)); // NOLINT - EXPECT_TRUE(a.Perform(make_tuple(1.5, -1))); - EXPECT_FALSE(a.Perform(make_tuple(1.5, 1))); -} - -// Tests using WithArgs with an action that takes 2 arguments. -TEST(WithArgsTest, TwoArgs) { - Action<const char*(const char* s, double x, short n)> a = - WithArgs<0, 2>(Invoke(Binary)); - const char s[] = "Hello"; - EXPECT_EQ(s + 2, a.Perform(make_tuple(CharPtr(s), 0.5, Short(2)))); -} - -// Tests using WithArgs with an action that takes 3 arguments. -TEST(WithArgsTest, ThreeArgs) { - Action<int(int, double, char, short)> a = // NOLINT - WithArgs<0, 2, 3>(Invoke(Ternary)); - EXPECT_EQ(123, a.Perform(make_tuple(100, 6.5, Char(20), Short(3)))); -} - -// Tests using WithArgs with an action that takes 4 arguments. -TEST(WithArgsTest, FourArgs) { - Action<std::string(const char*, const char*, double, const char*, - const char*)> - a = WithArgs<4, 3, 1, 0>(Invoke(Concat4)); - EXPECT_EQ("4310", a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), 2.5, - CharPtr("3"), CharPtr("4")))); -} - -// Tests using WithArgs with an action that takes 5 arguments. -TEST(WithArgsTest, FiveArgs) { - Action<std::string(const char*, const char*, const char*, const char*, - const char*)> - a = WithArgs<4, 3, 2, 1, 0>(Invoke(Concat5)); - EXPECT_EQ("43210", - a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"), - CharPtr("3"), CharPtr("4")))); -} - -// Tests using WithArgs with an action that takes 6 arguments. -TEST(WithArgsTest, SixArgs) { - Action<std::string(const char*, const char*, const char*)> a = - WithArgs<0, 1, 2, 2, 1, 0>(Invoke(Concat6)); - EXPECT_EQ("012210", - a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2")))); -} - -// Tests using WithArgs with an action that takes 7 arguments. -TEST(WithArgsTest, SevenArgs) { - Action<std::string(const char*, const char*, const char*, const char*)> a = - WithArgs<0, 1, 2, 3, 2, 1, 0>(Invoke(Concat7)); - EXPECT_EQ("0123210", - a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"), - CharPtr("3")))); -} - -// Tests using WithArgs with an action that takes 8 arguments. -TEST(WithArgsTest, EightArgs) { - Action<std::string(const char*, const char*, const char*, const char*)> a = - WithArgs<0, 1, 2, 3, 0, 1, 2, 3>(Invoke(Concat8)); - EXPECT_EQ("01230123", - a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"), - CharPtr("3")))); -} - -// Tests using WithArgs with an action that takes 9 arguments. -TEST(WithArgsTest, NineArgs) { - Action<std::string(const char*, const char*, const char*, const char*)> a = - WithArgs<0, 1, 2, 3, 1, 2, 3, 2, 3>(Invoke(Concat9)); - EXPECT_EQ("012312323", - a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"), - CharPtr("3")))); -} - -// Tests using WithArgs with an action that takes 10 arguments. -TEST(WithArgsTest, TenArgs) { - Action<std::string(const char*, const char*, const char*, const char*)> a = - WithArgs<0, 1, 2, 3, 2, 1, 0, 1, 2, 3>(Invoke(Concat10)); - EXPECT_EQ("0123210123", - a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"), - CharPtr("3")))); -} - -// Tests using WithArgs with an action that is not Invoke(). -class SubstractAction : public ActionInterface<int(int, int)> { // NOLINT - public: - virtual int Perform(const tuple<int, int>& args) { - return get<0>(args) - get<1>(args); - } -}; - -TEST(WithArgsTest, NonInvokeAction) { - Action<int(const std::string&, int, int)> a = // NOLINT - WithArgs<2, 1>(MakeAction(new SubstractAction)); - tuple<std::string, int, int> dummy = 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(make_tuple(100, Char(20), Short(3)))); -} - -// Tests using WithArgs with repeated arguments. -TEST(WithArgsTest, RepeatedArguments) { - Action<int(bool, int m, int n)> a = // NOLINT - WithArgs<1, 1, 1, 1>(Invoke(SumOf4)); - EXPECT_EQ(4, a.Perform(make_tuple(false, 1, 10))); -} - -// Tests using WithArgs with reversed argument order. -TEST(WithArgsTest, ReversedArgumentOrder) { - Action<const char*(short n, const char* input)> a = // NOLINT - WithArgs<1, 0>(Invoke(Binary)); - const char s[] = "Hello"; - EXPECT_EQ(s + 2, a.Perform(make_tuple(Short(2), CharPtr(s)))); -} - -// Tests using WithArgs with compatible, but not identical, argument types. -TEST(WithArgsTest, ArgsOfCompatibleTypes) { - Action<long(short x, char y, double z, char c)> a = // NOLINT - WithArgs<0, 1, 3>(Invoke(Ternary)); - EXPECT_EQ(123, a.Perform(make_tuple(Short(100), Char(20), 5.6, Char(3)))); -} - -// Tests using WithArgs with an action that returns void. -TEST(WithArgsTest, VoidAction) { - Action<void(double x, char c, int n)> a = WithArgs<2, 1>(Invoke(VoidBinary)); - g_done = false; - a.Perform(make_tuple(1.5, 'a', 3)); - EXPECT_TRUE(g_done); -} - -// Tests DoAll(a1, a2). -TEST(DoAllTest, TwoActions) { - int n = 0; - Action<int(int*)> a = DoAll(SetArgPointee<0>(1), // NOLINT - Return(2)); - EXPECT_EQ(2, a.Perform(make_tuple(&n))); - EXPECT_EQ(1, n); -} - -// Tests DoAll(a1, a2, a3). -TEST(DoAllTest, ThreeActions) { - int m = 0, n = 0; - Action<int(int*, int*)> a = DoAll(SetArgPointee<0>(1), // NOLINT - SetArgPointee<1>(2), - Return(3)); - EXPECT_EQ(3, a.Perform(make_tuple(&m, &n))); - EXPECT_EQ(1, m); - EXPECT_EQ(2, n); -} - -// Tests DoAll(a1, a2, a3, a4). -TEST(DoAllTest, FourActions) { - int m = 0, n = 0; - char ch = '\0'; - Action<int(int*, int*, char*)> a = // NOLINT - DoAll(SetArgPointee<0>(1), - SetArgPointee<1>(2), - SetArgPointee<2>('a'), - Return(3)); - EXPECT_EQ(3, a.Perform(make_tuple(&m, &n, &ch))); - EXPECT_EQ(1, m); - EXPECT_EQ(2, n); - EXPECT_EQ('a', ch); -} - -// Tests DoAll(a1, a2, a3, a4, a5). -TEST(DoAllTest, FiveActions) { - int m = 0, n = 0; - char a = '\0', b = '\0'; - Action<int(int*, int*, char*, char*)> action = // NOLINT - DoAll(SetArgPointee<0>(1), - SetArgPointee<1>(2), - SetArgPointee<2>('a'), - SetArgPointee<3>('b'), - Return(3)); - EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b))); - EXPECT_EQ(1, m); - EXPECT_EQ(2, n); - EXPECT_EQ('a', a); - EXPECT_EQ('b', b); -} - -// Tests DoAll(a1, a2, ..., a6). -TEST(DoAllTest, SixActions) { - int m = 0, n = 0; - char a = '\0', b = '\0', c = '\0'; - Action<int(int*, int*, char*, char*, char*)> action = // NOLINT - DoAll(SetArgPointee<0>(1), - SetArgPointee<1>(2), - SetArgPointee<2>('a'), - SetArgPointee<3>('b'), - SetArgPointee<4>('c'), - Return(3)); - EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c))); - EXPECT_EQ(1, m); - EXPECT_EQ(2, n); - EXPECT_EQ('a', a); - EXPECT_EQ('b', b); - EXPECT_EQ('c', c); -} - -// Tests DoAll(a1, a2, ..., a7). -TEST(DoAllTest, SevenActions) { - int m = 0, n = 0; - char a = '\0', b = '\0', c = '\0', d = '\0'; - Action<int(int*, int*, char*, char*, char*, char*)> action = // NOLINT - DoAll(SetArgPointee<0>(1), - SetArgPointee<1>(2), - SetArgPointee<2>('a'), - SetArgPointee<3>('b'), - SetArgPointee<4>('c'), - SetArgPointee<5>('d'), - Return(3)); - EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d))); - EXPECT_EQ(1, m); - EXPECT_EQ(2, n); - EXPECT_EQ('a', a); - EXPECT_EQ('b', b); - EXPECT_EQ('c', c); - EXPECT_EQ('d', d); -} - -// Tests DoAll(a1, a2, ..., a8). -TEST(DoAllTest, EightActions) { - int m = 0, n = 0; - char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0'; - Action<int(int*, int*, char*, char*, char*, char*, // NOLINT - char*)> action = - DoAll(SetArgPointee<0>(1), - SetArgPointee<1>(2), - SetArgPointee<2>('a'), - SetArgPointee<3>('b'), - SetArgPointee<4>('c'), - SetArgPointee<5>('d'), - SetArgPointee<6>('e'), - Return(3)); - EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e))); - EXPECT_EQ(1, m); - EXPECT_EQ(2, n); - EXPECT_EQ('a', a); - EXPECT_EQ('b', b); - EXPECT_EQ('c', c); - EXPECT_EQ('d', d); - EXPECT_EQ('e', e); -} - -// Tests DoAll(a1, a2, ..., a9). -TEST(DoAllTest, NineActions) { - int m = 0, n = 0; - char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0', f = '\0'; - Action<int(int*, int*, char*, char*, char*, char*, // NOLINT - char*, char*)> action = - DoAll(SetArgPointee<0>(1), - SetArgPointee<1>(2), - SetArgPointee<2>('a'), - SetArgPointee<3>('b'), - SetArgPointee<4>('c'), - SetArgPointee<5>('d'), - SetArgPointee<6>('e'), - SetArgPointee<7>('f'), - Return(3)); - EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e, &f))); - EXPECT_EQ(1, m); - EXPECT_EQ(2, n); - EXPECT_EQ('a', a); - EXPECT_EQ('b', b); - EXPECT_EQ('c', c); - EXPECT_EQ('d', d); - EXPECT_EQ('e', e); - EXPECT_EQ('f', f); -} - -// Tests DoAll(a1, a2, ..., a10). -TEST(DoAllTest, TenActions) { - int m = 0, n = 0; - char a = '\0', b = '\0', c = '\0', d = '\0'; - char e = '\0', f = '\0', g = '\0'; - Action<int(int*, int*, char*, char*, char*, char*, // NOLINT - char*, char*, char*)> action = - DoAll(SetArgPointee<0>(1), - SetArgPointee<1>(2), - SetArgPointee<2>('a'), - SetArgPointee<3>('b'), - SetArgPointee<4>('c'), - SetArgPointee<5>('d'), - SetArgPointee<6>('e'), - SetArgPointee<7>('f'), - SetArgPointee<8>('g'), - Return(3)); - EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e, &f, &g))); - EXPECT_EQ(1, m); - EXPECT_EQ(2, n); - EXPECT_EQ('a', a); - EXPECT_EQ('b', b); - EXPECT_EQ('c', c); - EXPECT_EQ('d', d); - EXPECT_EQ('e', e); - EXPECT_EQ('f', f); - EXPECT_EQ('g', g); -} - -// The ACTION*() macros trigger warning C4100 (unreferenced formal -// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in -// the macro definition, as the warnings are generated when the macro -// is expanded and macro expansion cannot contain #pragma. Therefore -// we suppress them here. -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable:4100) -#endif - -// Tests the ACTION*() macro family. - -// Tests that ACTION() can define an action that doesn't reference the -// mock function arguments. -ACTION(Return5) { return 5; } - -TEST(ActionMacroTest, WorksWhenNotReferencingArguments) { - Action<double()> a1 = Return5(); - EXPECT_DOUBLE_EQ(5, a1.Perform(make_tuple())); - - Action<int(double, bool)> a2 = Return5(); - EXPECT_EQ(5, a2.Perform(make_tuple(1, true))); -} - -// Tests that ACTION() can define an action that returns void. -ACTION(IncrementArg1) { (*arg1)++; } - -TEST(ActionMacroTest, WorksWhenReturningVoid) { - Action<void(int, int*)> a1 = IncrementArg1(); - int n = 0; - a1.Perform(make_tuple(5, &n)); - EXPECT_EQ(1, n); -} - -// Tests that the body of ACTION() can reference the type of the -// argument. -ACTION(IncrementArg2) { - StaticAssertTypeEq<int*, arg2_type>(); - arg2_type temp = arg2; - (*temp)++; -} - -TEST(ActionMacroTest, CanReferenceArgumentType) { - Action<void(int, bool, int*)> a1 = IncrementArg2(); - int n = 0; - a1.Perform(make_tuple(5, false, &n)); - EXPECT_EQ(1, n); -} - -// Tests that the body of ACTION() can reference the argument tuple -// via args_type and args. -ACTION(Sum2) { - StaticAssertTypeEq<tuple<int, char, int*>, args_type>(); - args_type args_copy = args; - return get<0>(args_copy) + get<1>(args_copy); -} - -TEST(ActionMacroTest, CanReferenceArgumentTuple) { - Action<int(int, char, int*)> a1 = Sum2(); - int dummy = 0; - EXPECT_EQ(11, a1.Perform(make_tuple(5, Char(6), &dummy))); -} - -// Tests that the body of ACTION() can reference the mock function -// type. -int Dummy(bool flag) { return flag? 1 : 0; } - -ACTION(InvokeDummy) { - StaticAssertTypeEq<int(bool), function_type>(); - function_type* fp = &Dummy; - return (*fp)(true); -} - -TEST(ActionMacroTest, CanReferenceMockFunctionType) { - Action<int(bool)> a1 = InvokeDummy(); - EXPECT_EQ(1, a1.Perform(make_tuple(true))); - EXPECT_EQ(1, a1.Perform(make_tuple(false))); -} - -// Tests that the body of ACTION() can reference the mock function's -// return type. -ACTION(InvokeDummy2) { - StaticAssertTypeEq<int, return_type>(); - return_type result = Dummy(true); - return result; -} - -TEST(ActionMacroTest, CanReferenceMockFunctionReturnType) { - Action<int(bool)> a1 = InvokeDummy2(); - EXPECT_EQ(1, a1.Perform(make_tuple(true))); - EXPECT_EQ(1, a1.Perform(make_tuple(false))); -} - -// Tests that ACTION() works for arguments passed by const reference. -ACTION(ReturnAddrOfConstBoolReferenceArg) { - StaticAssertTypeEq<const bool&, arg1_type>(); - return &arg1; -} - -TEST(ActionMacroTest, WorksForConstReferenceArg) { - Action<const bool*(int, const bool&)> a = ReturnAddrOfConstBoolReferenceArg(); - const bool b = false; - EXPECT_EQ(&b, a.Perform(tuple<int, const bool&>(0, b))); -} - -// Tests that ACTION() works for arguments passed by non-const reference. -ACTION(ReturnAddrOfIntReferenceArg) { - StaticAssertTypeEq<int&, arg0_type>(); - return &arg0; -} - -TEST(ActionMacroTest, WorksForNonConstReferenceArg) { - Action<int*(int&, bool, int)> a = ReturnAddrOfIntReferenceArg(); - int n = 0; - EXPECT_EQ(&n, a.Perform(tuple<int&, bool, int>(n, true, 1))); -} - -// Tests that ACTION() can be used in a namespace. -namespace action_test { -ACTION(Sum) { return arg0 + arg1; } -} // namespace action_test - -TEST(ActionMacroTest, WorksInNamespace) { - Action<int(int, int)> a1 = action_test::Sum(); - EXPECT_EQ(3, a1.Perform(make_tuple(1, 2))); -} - -// Tests that the same ACTION definition works for mock functions with -// different argument numbers. -ACTION(PlusTwo) { return arg0 + 2; } - -TEST(ActionMacroTest, WorksForDifferentArgumentNumbers) { - Action<int(int)> a1 = PlusTwo(); - EXPECT_EQ(4, a1.Perform(make_tuple(2))); - - Action<double(float, void*)> a2 = PlusTwo(); - int dummy; - EXPECT_DOUBLE_EQ(6, a2.Perform(make_tuple(4.0f, &dummy))); -} - -// Tests that ACTION_P can define a parameterized action. -ACTION_P(Plus, n) { return arg0 + n; } - -TEST(ActionPMacroTest, DefinesParameterizedAction) { - Action<int(int m, bool t)> a1 = Plus(9); - EXPECT_EQ(10, a1.Perform(make_tuple(1, true))); -} - -// Tests that the body of ACTION_P can reference the argument types -// and the parameter type. -ACTION_P(TypedPlus, n) { - arg0_type t1 = arg0; - n_type t2 = n; - return t1 + t2; -} - -TEST(ActionPMacroTest, CanReferenceArgumentAndParameterTypes) { - Action<int(char m, bool t)> a1 = TypedPlus(9); - EXPECT_EQ(10, a1.Perform(make_tuple(Char(1), true))); -} - -// Tests that a parameterized action can be used in any mock function -// whose type is compatible. -TEST(ActionPMacroTest, WorksInCompatibleMockFunction) { - Action<std::string(const std::string& s)> a1 = Plus("tail"); - const std::string re = "re"; - tuple<const std::string> dummy = 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(make_tuple(false, CharPtr("world")))); - EXPECT_STREQ("world", a1.Perform(make_tuple(true, CharPtr("world")))); - - const MyAction a2 = OverloadedAction("hi"); - EXPECT_STREQ("hi", a2.Perform(make_tuple(false, CharPtr("world")))); - EXPECT_STREQ("world", a2.Perform(make_tuple(true, CharPtr("world")))); - - const MyAction a3 = OverloadedAction("hi", "you"); - EXPECT_STREQ("hi", a3.Perform(make_tuple(true, CharPtr("world")))); - EXPECT_STREQ("you", a3.Perform(make_tuple(false, CharPtr("world")))); -} - -// Tests ACTION_Pn where n >= 3. - -ACTION_P3(Plus, m, n, k) { return arg0 + m + n + k; } - -TEST(ActionPnMacroTest, WorksFor3Parameters) { - Action<double(int m, bool t)> a1 = Plus(100, 20, 3.4); - EXPECT_DOUBLE_EQ(3123.4, a1.Perform(make_tuple(3000, true))); - - Action<std::string(const std::string& s)> a2 = Plus("tail", "-", ">"); - const std::string re = "re"; - tuple<const std::string> dummy = 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(make_tuple(10))); -} - -ACTION_P5(Plus, p0, p1, p2, p3, p4) { return arg0 + p0 + p1 + p2 + p3 + p4; } - -TEST(ActionPnMacroTest, WorksFor5Parameters) { - Action<int(int)> a1 = Plus(1, 2, 3, 4, 5); - EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5, a1.Perform(make_tuple(10))); -} - -ACTION_P6(Plus, p0, p1, p2, p3, p4, p5) { - return arg0 + p0 + p1 + p2 + p3 + p4 + p5; -} - -TEST(ActionPnMacroTest, WorksFor6Parameters) { - Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6); - EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6, a1.Perform(make_tuple(10))); -} - -ACTION_P7(Plus, p0, p1, p2, p3, p4, p5, p6) { - return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6; -} - -TEST(ActionPnMacroTest, WorksFor7Parameters) { - Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7); - EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7, a1.Perform(make_tuple(10))); -} - -ACTION_P8(Plus, p0, p1, p2, p3, p4, p5, p6, p7) { - return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7; -} - -TEST(ActionPnMacroTest, WorksFor8Parameters) { - Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8); - EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8, a1.Perform(make_tuple(10))); -} - -ACTION_P9(Plus, p0, p1, p2, p3, p4, p5, p6, p7, p8) { - return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8; -} - -TEST(ActionPnMacroTest, WorksFor9Parameters) { - Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8, 9); - EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9, a1.Perform(make_tuple(10))); -} - -ACTION_P10(Plus, p0, p1, p2, p3, p4, p5, p6, p7, p8, last_param) { - arg0_type t0 = arg0; - last_param_type t9 = last_param; - return t0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + t9; -} - -TEST(ActionPnMacroTest, WorksFor10Parameters) { - Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); - EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10, - a1.Perform(make_tuple(10))); -} - -// Tests that the action body can promote the parameter types. - -ACTION_P2(PadArgument, prefix, suffix) { - // The following lines promote the two parameters to desired types. - std::string prefix_str(prefix); - char suffix_char = static_cast<char>(suffix); - return prefix_str + arg0 + suffix_char; -} - -TEST(ActionPnMacroTest, SimpleTypePromotion) { - Action<std::string(const char*)> no_promo = - PadArgument(std::string("foo"), 'r'); - Action<std::string(const char*)> promo = - PadArgument("foo", static_cast<int>('r')); - EXPECT_EQ("foobar", no_promo.Perform(make_tuple(CharPtr("ba")))); - EXPECT_EQ("foobar", promo.Perform(make_tuple(CharPtr("ba")))); -} - -// Tests that we can partially restrict parameter types using a -// straight-forward pattern. - -// Defines a generic action that doesn't restrict the types of its -// parameters. -ACTION_P3(ConcatImpl, a, b, c) { - std::stringstream ss; - ss << a << b << c; - return ss.str(); -} - -// Next, we try to restrict that either the first parameter is a -// string, or the second parameter is an int. - -// Defines a partially specialized wrapper that restricts the first -// parameter to std::string. -template <typename T1, typename T2> -// ConcatImplActionP3 is the class template ACTION_P3 uses to -// implement ConcatImpl. We shouldn't change the name as this -// pattern requires the user to use it directly. -ConcatImplActionP3<std::string, T1, T2> -Concat(const std::string& a, T1 b, T2 c) { - 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(make_tuple())); - - a1 = Concat(1, 2, 3); - EXPECT_EQ("123", a1.Perform(make_tuple())); -} - -// Verifies the type of an ACTION*. - -ACTION(DoFoo) {} -ACTION_P(DoFoo, p) {} -ACTION_P2(DoFoo, p0, p1) {} - -TEST(ActionPnMacroTest, TypesAreCorrect) { - // DoFoo() must be assignable to a DoFooAction variable. - DoFooAction a0 = DoFoo(); - - // DoFoo(1) must be assignable to a DoFooActionP variable. - DoFooActionP<int> a1 = DoFoo(1); - - // DoFoo(p1, ..., pk) must be assignable to a DoFooActionPk - // variable, and so on. - DoFooActionP2<int, char> a2 = DoFoo(1, '2'); - PlusActionP3<int, int, char> a3 = Plus(1, 2, '3'); - PlusActionP4<int, int, int, char> a4 = Plus(1, 2, 3, '4'); - PlusActionP5<int, int, int, int, char> a5 = Plus(1, 2, 3, 4, '5'); - PlusActionP6<int, int, int, int, int, char> a6 = Plus(1, 2, 3, 4, 5, '6'); - PlusActionP7<int, int, int, int, int, int, char> a7 = - Plus(1, 2, 3, 4, 5, 6, '7'); - PlusActionP8<int, int, int, int, int, int, int, char> a8 = - Plus(1, 2, 3, 4, 5, 6, 7, '8'); - PlusActionP9<int, int, int, int, int, int, int, int, char> a9 = - Plus(1, 2, 3, 4, 5, 6, 7, 8, '9'); - PlusActionP10<int, int, int, int, int, int, int, int, int, char> a10 = - Plus(1, 2, 3, 4, 5, 6, 7, 8, 9, '0'); - - // Avoid "unused variable" warnings. - (void)a0; - (void)a1; - (void)a2; - (void)a3; - (void)a4; - (void)a5; - (void)a6; - (void)a7; - (void)a8; - (void)a9; - (void)a10; -} - -// Tests that an ACTION_P*() action can be explicitly instantiated -// with reference-typed parameters. - -ACTION_P(Plus1, x) { return x; } -ACTION_P2(Plus2, x, y) { return x + y; } -ACTION_P3(Plus3, x, y, z) { return x + y + z; } -ACTION_P10(Plus10, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) { - return a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9; -} - -TEST(ActionPnMacroTest, CanExplicitlyInstantiateWithReferenceTypes) { - int x = 1, y = 2, z = 3; - const tuple<> empty = make_tuple(); - - Action<int()> a = Plus1<int&>(x); - EXPECT_EQ(1, a.Perform(empty)); - - a = Plus2<const int&, int&>(x, y); - EXPECT_EQ(3, a.Perform(empty)); - - a = Plus3<int&, const int&, int&>(x, y, z); - EXPECT_EQ(6, a.Perform(empty)); - - int n[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; - a = Plus10<const int&, int&, const int&, int&, const int&, int&, const int&, - int&, const int&, int&>(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], - n[8], n[9]); - EXPECT_EQ(55, a.Perform(empty)); -} - -class NullaryConstructorClass { - public: - NullaryConstructorClass() : value_(123) {} - int value_; -}; - -// Tests using ReturnNew() with a nullary constructor. -TEST(ReturnNewTest, NoArgs) { - Action<NullaryConstructorClass*()> a = ReturnNew<NullaryConstructorClass>(); - NullaryConstructorClass* c = a.Perform(make_tuple()); - EXPECT_EQ(123, c->value_); - delete c; -} - -class UnaryConstructorClass { - public: - explicit UnaryConstructorClass(int value) : value_(value) {} - int value_; -}; - -// Tests using ReturnNew() with a unary constructor. -TEST(ReturnNewTest, Unary) { - Action<UnaryConstructorClass*()> a = ReturnNew<UnaryConstructorClass>(4000); - UnaryConstructorClass* c = a.Perform(make_tuple()); - EXPECT_EQ(4000, c->value_); - delete c; -} - -TEST(ReturnNewTest, UnaryWorksWhenMockMethodHasArgs) { - Action<UnaryConstructorClass*(bool, int)> a = - ReturnNew<UnaryConstructorClass>(4000); - UnaryConstructorClass* c = a.Perform(make_tuple(false, 5)); - EXPECT_EQ(4000, c->value_); - delete c; -} - -TEST(ReturnNewTest, UnaryWorksWhenMockMethodReturnsPointerToConst) { - Action<const UnaryConstructorClass*()> a = - ReturnNew<UnaryConstructorClass>(4000); - const UnaryConstructorClass* c = a.Perform(make_tuple()); - EXPECT_EQ(4000, c->value_); - delete c; -} - -class TenArgConstructorClass { - public: - TenArgConstructorClass(int a1, int a2, int a3, int a4, int a5, - int a6, int a7, int a8, int a9, int a10) - : value_(a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10) { - } - int value_; -}; - -// Tests using ReturnNew() with a 10-argument constructor. -TEST(ReturnNewTest, ConstructorThatTakes10Arguments) { - Action<TenArgConstructorClass*()> a = - ReturnNew<TenArgConstructorClass>(1000000000, 200000000, 30000000, - 4000000, 500000, 60000, - 7000, 800, 90, 0); - TenArgConstructorClass* c = a.Perform(make_tuple()); - EXPECT_EQ(1234567890, c->value_); - delete c; -} - -// Tests that ACTION_TEMPLATE works when there is no value parameter. -ACTION_TEMPLATE(CreateNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_0_VALUE_PARAMS()) { - return new T; -} - -TEST(ActionTemplateTest, WorksWithoutValueParam) { - const Action<int*()> a = CreateNew<int>(); - int* p = a.Perform(make_tuple()); - delete p; -} - -// Tests that ACTION_TEMPLATE works when there are value parameters. -ACTION_TEMPLATE(CreateNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_1_VALUE_PARAMS(a0)) { - return new T(a0); -} - -TEST(ActionTemplateTest, WorksWithValueParams) { - const Action<int*()> a = CreateNew<int>(42); - int* p = a.Perform(make_tuple()); - EXPECT_EQ(42, *p); - delete p; -} - -// Tests that ACTION_TEMPLATE works for integral template parameters. -ACTION_TEMPLATE(MyDeleteArg, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_0_VALUE_PARAMS()) { - delete get<k>(args); -} - -// Resets a bool variable in the destructor. -class BoolResetter { - public: - explicit BoolResetter(bool* value) : value_(value) {} - ~BoolResetter() { *value_ = false; } - private: - bool* value_; -}; - -TEST(ActionTemplateTest, WorksForIntegralTemplateParams) { - const Action<void(int*, BoolResetter*)> a = MyDeleteArg<1>(); - int n = 0; - bool b = true; - BoolResetter* resetter = new BoolResetter(&b); - a.Perform(make_tuple(&n, resetter)); - EXPECT_FALSE(b); // Verifies that resetter is deleted. -} - -// Tests that ACTION_TEMPLATES works for template template parameters. -ACTION_TEMPLATE(ReturnSmartPointer, - HAS_1_TEMPLATE_PARAMS(template <typename Pointee> class, - Pointer), - AND_1_VALUE_PARAMS(pointee)) { - return Pointer<pointee_type>(new pointee_type(pointee)); -} - -TEST(ActionTemplateTest, WorksForTemplateTemplateParameters) { - using ::testing::internal::linked_ptr; - const Action<linked_ptr<int>()> a = ReturnSmartPointer<linked_ptr>(42); - linked_ptr<int> p = a.Perform(make_tuple()); - EXPECT_EQ(42, *p); -} - -// Tests that ACTION_TEMPLATE works for 10 template parameters. -template <typename T1, typename T2, typename T3, int k4, bool k5, - unsigned int k6, typename T7, typename T8, typename T9> -struct GiantTemplate { - public: - explicit GiantTemplate(int a_value) : value(a_value) {} - int value; -}; - -ACTION_TEMPLATE(ReturnGiant, - HAS_10_TEMPLATE_PARAMS( - typename, T1, - typename, T2, - typename, T3, - int, k4, - bool, k5, - unsigned int, k6, - class, T7, - class, T8, - class, T9, - template <typename T> class, T10), - AND_1_VALUE_PARAMS(value)) { - return GiantTemplate<T10<T1>, T2, T3, k4, k5, k6, T7, T8, T9>(value); -} - -TEST(ActionTemplateTest, WorksFor10TemplateParameters) { - using ::testing::internal::linked_ptr; - typedef GiantTemplate<linked_ptr<int>, bool, double, 5, - true, 6, char, unsigned, int> Giant; - const Action<Giant()> a = ReturnGiant< - int, bool, double, 5, true, 6, char, unsigned, int, linked_ptr>(42); - Giant giant = a.Perform(make_tuple()); - EXPECT_EQ(42, giant.value); -} - -// Tests that ACTION_TEMPLATE works for 10 value parameters. -ACTION_TEMPLATE(ReturnSum, - HAS_1_TEMPLATE_PARAMS(typename, Number), - AND_10_VALUE_PARAMS(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10)) { - return static_cast<Number>(v1) + v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9 + v10; -} - -TEST(ActionTemplateTest, WorksFor10ValueParameters) { - const Action<int()> a = ReturnSum<int>(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); - EXPECT_EQ(55, a.Perform(make_tuple())); -} - -// Tests that ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded -// on the number of value parameters. - -ACTION(ReturnSum) { return 0; } - -ACTION_P(ReturnSum, x) { return x; } - -ACTION_TEMPLATE(ReturnSum, - HAS_1_TEMPLATE_PARAMS(typename, Number), - AND_2_VALUE_PARAMS(v1, v2)) { - return static_cast<Number>(v1) + v2; -} - -ACTION_TEMPLATE(ReturnSum, - HAS_1_TEMPLATE_PARAMS(typename, Number), - AND_3_VALUE_PARAMS(v1, v2, v3)) { - return static_cast<Number>(v1) + v2 + v3; -} - -ACTION_TEMPLATE(ReturnSum, - HAS_2_TEMPLATE_PARAMS(typename, Number, int, k), - AND_4_VALUE_PARAMS(v1, v2, v3, v4)) { - return static_cast<Number>(v1) + v2 + v3 + v4 + k; -} - -TEST(ActionTemplateTest, CanBeOverloadedOnNumberOfValueParameters) { - const Action<int()> a0 = ReturnSum(); - const Action<int()> a1 = ReturnSum(1); - const Action<int()> a2 = ReturnSum<int>(1, 2); - const Action<int()> a3 = ReturnSum<int>(1, 2, 3); - const Action<int()> a4 = ReturnSum<int, 10000>(2000, 300, 40, 5); - EXPECT_EQ(0, a0.Perform(make_tuple())); - EXPECT_EQ(1, a1.Perform(make_tuple())); - EXPECT_EQ(3, a2.Perform(make_tuple())); - EXPECT_EQ(6, a3.Perform(make_tuple())); - EXPECT_EQ(12345, a4.Perform(make_tuple())); -} - -#ifdef _MSC_VER -# pragma warning(pop) -#endif - -} // namespace gmock_generated_actions_test -} // namespace testing diff --git a/contrib/googletest/googlemock/test/gmock-generated-function-mockers_test.cc b/contrib/googletest/googlemock/test/gmock-generated-function-mockers_test.cc deleted file mode 100644 index f16833b280e4..000000000000 --- a/contrib/googletest/googlemock/test/gmock-generated-function-mockers_test.cc +++ /dev/null @@ -1,646 +0,0 @@ -// 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-generated-function-mockers.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 <map> -#include <string> -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -// There is a bug in MSVC (fixed in VS 2008) that prevents creating a -// mock for a function with const arguments, so we don't test such -// cases for MSVC versions older than 2008. -#if !GTEST_OS_WINDOWS || (_MSC_VER >= 1500) -# define GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS -#endif // !GTEST_OS_WINDOWS || (_MSC_VER >= 1500) - -namespace testing { -namespace gmock_generated_function_mockers_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; - -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; -#ifdef GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS - virtual bool TakesConst(const int x) = 0; -#endif // GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS - - virtual int OverloadedOnArgumentNumber() = 0; - virtual int OverloadedOnArgumentNumber(int n) = 0; - - virtual int OverloadedOnArgumentType(int n) = 0; - virtual char OverloadedOnArgumentType(char c) = 0; - - virtual int OverloadedOnConstness() = 0; - virtual char OverloadedOnConstness() const = 0; - - virtual int TypeWithHole(int (*func)()) = 0; - virtual int TypeWithComma(const std::map<int, std::string>& a_map) = 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_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&)); - -#ifdef GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS - MOCK_METHOD1(TakesConst, bool(const int)); // NOLINT -#endif - - // 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 - -#if GTEST_OS_WINDOWS - MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTNullary, int()); - MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTUnary, bool(int)); - MOCK_METHOD10_WITH_CALLTYPE(STDMETHODCALLTYPE, CTDecimal, - int(bool b, char c, short d, int e, long f, - float g, double h, unsigned i, char* j, - const std::string& k)); - MOCK_CONST_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTConst, char(int)); - - // 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 - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo); -}; -#ifdef _MSC_VER -# pragma warning(pop) -#endif - -class FunctionMockerTest : public testing::Test { - protected: - FunctionMockerTest() : foo_(&mock_foo_) {} - - FooInterface* const foo_; - MockFoo mock_foo_; -}; - -// Tests mocking a void-returning function. -TEST_F(FunctionMockerTest, MocksVoidFunction) { - EXPECT_CALL(mock_foo_, VoidReturning(Lt(100))); - foo_->VoidReturning(0); -} - -// Tests mocking a nullary function. -TEST_F(FunctionMockerTest, MocksNullaryFunction) { - EXPECT_CALL(mock_foo_, Nullary()) - .WillOnce(DoDefault()) - .WillOnce(Return(1)); - - EXPECT_EQ(0, foo_->Nullary()); - EXPECT_EQ(1, foo_->Nullary()); -} - -// Tests mocking a unary function. -TEST_F(FunctionMockerTest, MocksUnaryFunction) { - EXPECT_CALL(mock_foo_, Unary(Eq(2))) - .Times(2) - .WillOnce(Return(true)); - - EXPECT_TRUE(foo_->Unary(2)); - EXPECT_FALSE(foo_->Unary(2)); -} - -// Tests mocking a binary function. -TEST_F(FunctionMockerTest, MocksBinaryFunction) { - EXPECT_CALL(mock_foo_, Binary(2, _)) - .WillOnce(Return(3)); - - EXPECT_EQ(3, foo_->Binary(2, 1)); -} - -// Tests mocking a decimal function. -TEST_F(FunctionMockerTest, MocksDecimalFunction) { - EXPECT_CALL(mock_foo_, Decimal(true, 'a', 0, 0, 1L, A<float>(), - Lt(100), 5U, NULL, "hi")) - .WillOnce(Return(5)); - - EXPECT_EQ(5, foo_->Decimal(true, 'a', 0, 0, 1, 0, 0, 5, NULL, "hi")); -} - -// Tests mocking a function that takes a non-const reference. -TEST_F(FunctionMockerTest, MocksFunctionWithNonConstReferenceArgument) { - int a = 0; - EXPECT_CALL(mock_foo_, TakesNonConstReference(Ref(a))) - .WillOnce(Return(true)); - - EXPECT_TRUE(foo_->TakesNonConstReference(a)); -} - -// Tests mocking a function that takes a const reference. -TEST_F(FunctionMockerTest, MocksFunctionWithConstReferenceArgument) { - int a = 0; - EXPECT_CALL(mock_foo_, TakesConstReference(Ref(a))) - .WillOnce(Return("Hello")); - - EXPECT_EQ("Hello", foo_->TakesConstReference(a)); -} - -#ifdef GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS -// Tests mocking a function that takes a const variable. -TEST_F(FunctionMockerTest, MocksFunctionWithConstArgument) { - EXPECT_CALL(mock_foo_, TakesConst(Lt(10))) - .WillOnce(DoDefault()); - - EXPECT_FALSE(foo_->TakesConst(5)); -} -#endif // GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS - -// Tests mocking functions overloaded on the number of arguments. -TEST_F(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentNumber) { - EXPECT_CALL(mock_foo_, OverloadedOnArgumentNumber()) - .WillOnce(Return(1)); - EXPECT_CALL(mock_foo_, OverloadedOnArgumentNumber(_)) - .WillOnce(Return(2)); - - EXPECT_EQ(2, foo_->OverloadedOnArgumentNumber(1)); - EXPECT_EQ(1, foo_->OverloadedOnArgumentNumber()); -} - -// Tests mocking functions overloaded on the types of argument. -TEST_F(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentType) { - EXPECT_CALL(mock_foo_, OverloadedOnArgumentType(An<int>())) - .WillOnce(Return(1)); - EXPECT_CALL(mock_foo_, OverloadedOnArgumentType(TypedEq<char>('a'))) - .WillOnce(Return('b')); - - EXPECT_EQ(1, foo_->OverloadedOnArgumentType(0)); - EXPECT_EQ('b', foo_->OverloadedOnArgumentType('a')); -} - -// Tests mocking functions overloaded on the const-ness of this object. -TEST_F(FunctionMockerTest, MocksFunctionsOverloadedOnConstnessOfThis) { - EXPECT_CALL(mock_foo_, OverloadedOnConstness()); - EXPECT_CALL(Const(mock_foo_), OverloadedOnConstness()) - .WillOnce(Return('a')); - - EXPECT_EQ(0, foo_->OverloadedOnConstness()); - EXPECT_EQ('a', Const(*foo_).OverloadedOnConstness()); -} - -TEST_F(FunctionMockerTest, MocksReturnTypeWithComma) { - const std::map<int, std::string> a_map; - EXPECT_CALL(mock_foo_, ReturnTypeWithComma()) - .WillOnce(Return(a_map)); - EXPECT_CALL(mock_foo_, ReturnTypeWithComma(42)) - .WillOnce(Return(a_map)); - - EXPECT_EQ(a_map, mock_foo_.ReturnTypeWithComma()); - EXPECT_EQ(a_map, mock_foo_.ReturnTypeWithComma(42)); -} - -#if GTEST_OS_WINDOWS -// Tests mocking a nullary function with calltype. -TEST_F(FunctionMockerTest, MocksNullaryFunctionWithCallType) { - EXPECT_CALL(mock_foo_, CTNullary()) - .WillOnce(Return(-1)) - .WillOnce(Return(0)); - - EXPECT_EQ(-1, foo_->CTNullary()); - EXPECT_EQ(0, foo_->CTNullary()); -} - -// Tests mocking a unary function with calltype. -TEST_F(FunctionMockerTest, MocksUnaryFunctionWithCallType) { - EXPECT_CALL(mock_foo_, CTUnary(Eq(2))) - .Times(2) - .WillOnce(Return(true)) - .WillOnce(Return(false)); - - EXPECT_TRUE(foo_->CTUnary(2)); - EXPECT_FALSE(foo_->CTUnary(2)); -} - -// Tests mocking a decimal function with calltype. -TEST_F(FunctionMockerTest, MocksDecimalFunctionWithCallType) { - EXPECT_CALL(mock_foo_, CTDecimal(true, 'a', 0, 0, 1L, A<float>(), - Lt(100), 5U, NULL, "hi")) - .WillOnce(Return(10)); - - EXPECT_EQ(10, foo_->CTDecimal(true, 'a', 0, 0, 1, 0, 0, 5, NULL, "hi")); -} - -// Tests mocking functions overloaded on the const-ness of this object. -TEST_F(FunctionMockerTest, MocksFunctionsConstFunctionWithCallType) { - EXPECT_CALL(Const(mock_foo_), CTConst(_)) - .WillOnce(Return('a')); - - EXPECT_EQ('a', Const(*foo_).CTConst(0)); -} - -TEST_F(FunctionMockerTest, MocksReturnTypeWithCommaAndCallType) { - const std::map<int, std::string> a_map; - EXPECT_CALL(mock_foo_, CTReturnTypeWithComma()) - .WillOnce(Return(a_map)); - - EXPECT_EQ(a_map, mock_foo_.CTReturnTypeWithComma()); -} - -#endif // GTEST_OS_WINDOWS - -class MockB { - public: - MockB() {} - - MOCK_METHOD0(DoB, void()); - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockB); -}; - -// Tests that functions with no EXPECT_CALL() ruls can be called any -// number of times. -TEST(ExpectCallTest, UnmentionedFunctionCanBeCalledAnyNumberOfTimes) { - { - MockB b; - } - - { - MockB b; - b.DoB(); - } - - { - MockB b; - b.DoB(); - b.DoB(); - } -} - -// Tests mocking template interfaces. - -template <typename T> -class StackInterface { - public: - virtual ~StackInterface() {} - - // Template parameter appears in function parameter. - virtual void Push(const T& value) = 0; - virtual void Pop() = 0; - virtual int GetSize() const = 0; - // Template parameter appears in function return type. - virtual const T& GetTop() const = 0; -}; - -template <typename T> -class MockStack : public StackInterface<T> { - public: - MockStack() {} - - 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_(MockStack); -}; - -// Tests that template mock works. -TEST(TemplateMockTest, Works) { - MockStack<int> mock; - - EXPECT_CALL(mock, GetSize()) - .WillOnce(Return(0)) - .WillOnce(Return(1)) - .WillOnce(Return(0)); - EXPECT_CALL(mock, Push(_)); - int n = 5; - EXPECT_CALL(mock, GetTop()) - .WillOnce(ReturnRef(n)); - EXPECT_CALL(mock, Pop()) - .Times(AnyNumber()); - - EXPECT_EQ(0, mock.GetSize()); - mock.Push(5); - EXPECT_EQ(1, mock.GetSize()); - EXPECT_EQ(5, mock.GetTop()); - mock.Pop(); - EXPECT_EQ(0, mock.GetSize()); -} - -TEST(TemplateMockTest, MethodWithCommaInReturnTypeWorks) { - MockStack<int> 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_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_(MockStackWithCallType); -}; - -// Tests that template mock with calltype works. -TEST(TemplateMockTestWithCallType, Works) { - MockStackWithCallType<int> mock; - - EXPECT_CALL(mock, GetSize()) - .WillOnce(Return(0)) - .WillOnce(Return(1)) - .WillOnce(Return(0)); - EXPECT_CALL(mock, Push(_)); - int n = 5; - EXPECT_CALL(mock, GetTop()) - .WillOnce(ReturnRef(n)); - EXPECT_CALL(mock, Pop()) - .Times(AnyNumber()); - - EXPECT_EQ(0, mock.GetSize()); - mock.Push(5); - EXPECT_EQ(1, mock.GetSize()); - EXPECT_EQ(5, mock.GetTop()); - mock.Pop(); - EXPECT_EQ(0, mock.GetSize()); -} -#endif // GTEST_OS_WINDOWS - -#define 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); -}; - -TEST(OverloadedMockMethodTest, CanOverloadOnArgNumberInMacroBody) { - MockOverloadedOnArgNumber 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(OverloadedMockMethodTest, 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(MockFunctionTest, WorksForVoidNullary) { - MockFunction<void()> foo; - EXPECT_CALL(foo, Call()); - foo.Call(); -} - -TEST(MockFunctionTest, 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(MockFunctionTest, WorksForVoidUnary) { - MockFunction<void(int)> foo; - EXPECT_CALL(foo, Call(1)); - foo.Call(1); -} - -TEST(MockFunctionTest, 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(MockFunctionTest, 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)); -} - -#if GTEST_HAS_STD_FUNCTION_ -TEST(MockFunctionTest, 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(MockFunctionTest, 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); -} -#endif // GTEST_HAS_STD_FUNCTION_ - -struct MockMethodSizes0 { - MOCK_METHOD0(func, void()); -}; -struct MockMethodSizes1 { - MOCK_METHOD1(func, void(int)); -}; -struct MockMethodSizes2 { - MOCK_METHOD2(func, void(int, int)); -}; -struct MockMethodSizes3 { - MOCK_METHOD3(func, void(int, int, int)); -}; -struct MockMethodSizes4 { - MOCK_METHOD4(func, void(int, int, int, int)); -}; - -TEST(MockFunctionTest, 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)); -} - -} // namespace gmock_generated_function_mockers_test -} // namespace testing diff --git a/contrib/googletest/googlemock/test/gmock-generated-internal-utils_test.cc b/contrib/googletest/googlemock/test/gmock-generated-internal-utils_test.cc deleted file mode 100644 index ae0280fc314d..000000000000 --- a/contrib/googletest/googlemock/test/gmock-generated-internal-utils_test.cc +++ /dev/null @@ -1,128 +0,0 @@ -// 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-generated-internal-utils.h" -#include "gmock/internal/gmock-internal-utils.h" -#include "gtest/gtest.h" - -namespace { - -using ::testing::tuple; -using ::testing::Matcher; -using ::testing::internal::CompileAssertTypesEqual; -using ::testing::internal::MatcherTuple; -using ::testing::internal::Function; -using ::testing::internal::IgnoredValue; - -// Tests the MatcherTuple template struct. - -TEST(MatcherTupleTest, ForSize0) { - CompileAssertTypesEqual<tuple<>, MatcherTuple<tuple<> >::type>(); -} - -TEST(MatcherTupleTest, ForSize1) { - CompileAssertTypesEqual<tuple<Matcher<int> >, - MatcherTuple<tuple<int> >::type>(); -} - -TEST(MatcherTupleTest, ForSize2) { - CompileAssertTypesEqual<tuple<Matcher<int>, Matcher<char> >, - MatcherTuple<tuple<int, char> >::type>(); -} - -TEST(MatcherTupleTest, ForSize5) { - CompileAssertTypesEqual< - tuple<Matcher<int>, Matcher<char>, Matcher<bool>, Matcher<double>, - Matcher<char*> >, - MatcherTuple<tuple<int, char, bool, double, char*> >::type>(); -} - -// Tests the Function template struct. - -TEST(FunctionTest, Nullary) { - typedef Function<int()> F; // NOLINT - CompileAssertTypesEqual<int, F::Result>(); - CompileAssertTypesEqual<tuple<>, F::ArgumentTuple>(); - CompileAssertTypesEqual<tuple<>, F::ArgumentMatcherTuple>(); - CompileAssertTypesEqual<void(), F::MakeResultVoid>(); - CompileAssertTypesEqual<IgnoredValue(), F::MakeResultIgnoredValue>(); -} - -TEST(FunctionTest, Unary) { - typedef Function<int(bool)> F; // NOLINT - CompileAssertTypesEqual<int, F::Result>(); - CompileAssertTypesEqual<bool, F::Argument1>(); - CompileAssertTypesEqual<tuple<bool>, F::ArgumentTuple>(); - CompileAssertTypesEqual<tuple<Matcher<bool> >, F::ArgumentMatcherTuple>(); - CompileAssertTypesEqual<void(bool), F::MakeResultVoid>(); // NOLINT - CompileAssertTypesEqual<IgnoredValue(bool), // NOLINT - F::MakeResultIgnoredValue>(); -} - -TEST(FunctionTest, Binary) { - typedef Function<int(bool, const long&)> F; // NOLINT - CompileAssertTypesEqual<int, F::Result>(); - CompileAssertTypesEqual<bool, F::Argument1>(); - CompileAssertTypesEqual<const long&, F::Argument2>(); // NOLINT - CompileAssertTypesEqual<tuple<bool, const long&>, F::ArgumentTuple>(); // NOLINT - CompileAssertTypesEqual< - tuple<Matcher<bool>, Matcher<const long&> >, // NOLINT - F::ArgumentMatcherTuple>(); - CompileAssertTypesEqual<void(bool, const long&), F::MakeResultVoid>(); // NOLINT - CompileAssertTypesEqual<IgnoredValue(bool, const long&), // NOLINT - F::MakeResultIgnoredValue>(); -} - -TEST(FunctionTest, LongArgumentList) { - typedef Function<char(bool, int, char*, int&, const long&)> F; // NOLINT - CompileAssertTypesEqual<char, F::Result>(); - CompileAssertTypesEqual<bool, F::Argument1>(); - CompileAssertTypesEqual<int, F::Argument2>(); - CompileAssertTypesEqual<char*, F::Argument3>(); - CompileAssertTypesEqual<int&, F::Argument4>(); - CompileAssertTypesEqual<const long&, F::Argument5>(); // NOLINT - CompileAssertTypesEqual<tuple<bool, int, char*, int&, const long&>, // NOLINT - F::ArgumentTuple>(); - CompileAssertTypesEqual< - tuple<Matcher<bool>, Matcher<int>, Matcher<char*>, Matcher<int&>, - Matcher<const long&> >, // NOLINT - F::ArgumentMatcherTuple>(); - CompileAssertTypesEqual<void(bool, int, char*, int&, const long&), // NOLINT - F::MakeResultVoid>(); - CompileAssertTypesEqual< - IgnoredValue(bool, int, char*, int&, const long&), // NOLINT - F::MakeResultIgnoredValue>(); -} - -} // Unnamed namespace diff --git a/contrib/googletest/googlemock/test/gmock-generated-matchers_test.cc b/contrib/googletest/googlemock/test/gmock-generated-matchers_test.cc deleted file mode 100644 index 0ebd47014fb6..000000000000 --- a/contrib/googletest/googlemock/test/gmock-generated-matchers_test.cc +++ /dev/null @@ -1,1341 +0,0 @@ -// Copyright 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Google Mock - a framework for writing C++ mock classes. -// -// This file tests the built-in matchers generated by a script. - -// 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-generated-matchers.h" - -#include <list> -#include <map> -#include <memory> -#include <set> -#include <sstream> -#include <string> -#include <utility> -#include <vector> - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "gtest/gtest-spi.h" - -namespace { - -using std::list; -using std::map; -using std::pair; -using std::set; -using std::stringstream; -using std::vector; -using testing::get; -using testing::make_tuple; -using testing::tuple; -using testing::_; -using testing::AllOf; -using testing::AnyOf; -using testing::Args; -using testing::Contains; -using testing::ElementsAre; -using testing::ElementsAreArray; -using testing::Eq; -using testing::Ge; -using testing::Gt; -using testing::Le; -using testing::Lt; -using testing::MakeMatcher; -using testing::Matcher; -using testing::MatcherInterface; -using testing::MatchResultListener; -using testing::Ne; -using testing::Not; -using testing::Pointee; -using testing::PrintToString; -using testing::Ref; -using testing::StaticAssertTypeEq; -using testing::StrEq; -using testing::Value; -using testing::internal::ElementsAreArrayMatcher; - -// Returns the description of the given matcher. -template <typename T> -std::string Describe(const Matcher<T>& m) { - stringstream ss; - m.DescribeTo(&ss); - return ss.str(); -} - -// Returns the description of the negation of the given matcher. -template <typename T> -std::string DescribeNegation(const Matcher<T>& m) { - stringstream ss; - m.DescribeNegationTo(&ss); - return ss.str(); -} - -// Returns the reason why x matches, or doesn't match, m. -template <typename MatcherType, typename Value> -std::string Explain(const MatcherType& m, const Value& x) { - stringstream ss; - m.ExplainMatchResultTo(x, &ss); - return ss.str(); -} - -// Tests Args<k0, ..., kn>(m). - -TEST(ArgsTest, AcceptsZeroTemplateArg) { - const tuple<int, bool> t(5, true); - EXPECT_THAT(t, Args<>(Eq(tuple<>()))); - EXPECT_THAT(t, Not(Args<>(Ne(tuple<>())))); -} - -TEST(ArgsTest, AcceptsOneTemplateArg) { - const tuple<int, bool> t(5, true); - EXPECT_THAT(t, Args<0>(Eq(make_tuple(5)))); - EXPECT_THAT(t, Args<1>(Eq(make_tuple(true)))); - EXPECT_THAT(t, Not(Args<1>(Eq(make_tuple(false))))); -} - -TEST(ArgsTest, AcceptsTwoTemplateArgs) { - const tuple<short, int, long> t(4, 5, 6L); // NOLINT - - EXPECT_THAT(t, (Args<0, 1>(Lt()))); - EXPECT_THAT(t, (Args<1, 2>(Lt()))); - EXPECT_THAT(t, Not(Args<0, 2>(Gt()))); -} - -TEST(ArgsTest, AcceptsRepeatedTemplateArgs) { - const tuple<short, int, long> t(4, 5, 6L); // NOLINT - EXPECT_THAT(t, (Args<0, 0>(Eq()))); - EXPECT_THAT(t, Not(Args<1, 1>(Ne()))); -} - -TEST(ArgsTest, AcceptsDecreasingTemplateArgs) { - const tuple<short, int, long> t(4, 5, 6L); // NOLINT - EXPECT_THAT(t, (Args<2, 0>(Gt()))); - EXPECT_THAT(t, Not(Args<2, 1>(Lt()))); -} - -// The MATCHER*() macros trigger warning C4100 (unreferenced formal -// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in -// the macro definition, as the warnings are generated when the macro -// is expanded and macro expansion cannot contain #pragma. Therefore -// we suppress them here. -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable:4100) -#endif - -MATCHER(SumIsZero, "") { - return get<0>(arg) + get<1>(arg) + get<2>(arg) == 0; -} - -TEST(ArgsTest, AcceptsMoreTemplateArgsThanArityOfOriginalTuple) { - EXPECT_THAT(make_tuple(-1, 2), (Args<0, 0, 1>(SumIsZero()))); - EXPECT_THAT(make_tuple(1, 2), Not(Args<0, 0, 1>(SumIsZero()))); -} - -TEST(ArgsTest, CanBeNested) { - const tuple<short, int, long, int> t(4, 5, 6L, 6); // NOLINT - EXPECT_THAT(t, (Args<1, 2, 3>(Args<1, 2>(Eq())))); - EXPECT_THAT(t, (Args<0, 1, 3>(Args<0, 2>(Lt())))); -} - -TEST(ArgsTest, CanMatchTupleByValue) { - typedef tuple<char, int, int> Tuple3; - const Matcher<Tuple3> m = Args<1, 2>(Lt()); - EXPECT_TRUE(m.Matches(Tuple3('a', 1, 2))); - EXPECT_FALSE(m.Matches(Tuple3('b', 2, 2))); -} - -TEST(ArgsTest, CanMatchTupleByReference) { - typedef tuple<char, char, int> Tuple3; - const Matcher<const Tuple3&> m = Args<0, 1>(Lt()); - EXPECT_TRUE(m.Matches(Tuple3('a', 'b', 2))); - EXPECT_FALSE(m.Matches(Tuple3('b', 'b', 2))); -} - -// Validates that arg is printed as str. -MATCHER_P(PrintsAs, str, "") { - return testing::PrintToString(arg) == str; -} - -TEST(ArgsTest, AcceptsTenTemplateArgs) { - EXPECT_THAT(make_tuple(0, 1L, 2, 3L, 4, 5, 6, 7, 8, 9), - (Args<9, 8, 7, 6, 5, 4, 3, 2, 1, 0>( - PrintsAs("(9, 8, 7, 6, 5, 4, 3, 2, 1, 0)")))); - EXPECT_THAT(make_tuple(0, 1L, 2, 3L, 4, 5, 6, 7, 8, 9), - Not(Args<9, 8, 7, 6, 5, 4, 3, 2, 1, 0>( - PrintsAs("(0, 8, 7, 6, 5, 4, 3, 2, 1, 0)")))); -} - -TEST(ArgsTest, DescirbesSelfCorrectly) { - const Matcher<tuple<int, bool, char> > m = Args<2, 0>(Lt()); - EXPECT_EQ("are a tuple whose fields (#2, #0) are a pair where " - "the first < the second", - Describe(m)); -} - -TEST(ArgsTest, DescirbesNestedArgsCorrectly) { - const Matcher<const tuple<int, bool, char, int>&> m = - Args<0, 2, 3>(Args<2, 0>(Lt())); - EXPECT_EQ("are a tuple whose fields (#0, #2, #3) are a tuple " - "whose fields (#2, #0) are a pair where the first < the second", - Describe(m)); -} - -TEST(ArgsTest, DescribesNegationCorrectly) { - const Matcher<tuple<int, char> > m = Args<1, 0>(Gt()); - EXPECT_EQ("are a tuple whose fields (#1, #0) aren't a pair " - "where the first > the second", - DescribeNegation(m)); -} - -TEST(ArgsTest, ExplainsMatchResultWithoutInnerExplanation) { - const Matcher<tuple<bool, int, int> > m = Args<1, 2>(Eq()); - EXPECT_EQ("whose fields (#1, #2) are (42, 42)", - Explain(m, make_tuple(false, 42, 42))); - EXPECT_EQ("whose fields (#1, #2) are (42, 43)", - Explain(m, make_tuple(false, 42, 43))); -} - -// For testing Args<>'s explanation. -class LessThanMatcher : public MatcherInterface<tuple<char, int> > { - public: - virtual void DescribeTo(::std::ostream* os) const {} - - virtual bool MatchAndExplain(tuple<char, int> value, - MatchResultListener* listener) const { - const int diff = get<0>(value) - get<1>(value); - if (diff > 0) { - *listener << "where the first value is " << diff - << " more than the second"; - } - return diff < 0; - } -}; - -Matcher<tuple<char, int> > LessThan() { - return MakeMatcher(new LessThanMatcher); -} - -TEST(ArgsTest, ExplainsMatchResultWithInnerExplanation) { - const Matcher<tuple<char, int, int> > m = Args<0, 2>(LessThan()); - EXPECT_EQ("whose fields (#0, #2) are ('a' (97, 0x61), 42), " - "where the first value is 55 more than the second", - Explain(m, make_tuple('a', 42, 42))); - EXPECT_EQ("whose fields (#0, #2) are ('\\0', 43)", - Explain(m, make_tuple('\0', 42, 43))); -} - -// For testing ExplainMatchResultTo(). -class GreaterThanMatcher : public MatcherInterface<int> { - public: - explicit GreaterThanMatcher(int rhs) : rhs_(rhs) {} - - virtual void DescribeTo(::std::ostream* os) const { - *os << "is greater than " << rhs_; - } - - virtual bool MatchAndExplain(int lhs, - MatchResultListener* listener) const { - const int diff = lhs - rhs_; - if (diff > 0) { - *listener << "which is " << diff << " more than " << rhs_; - } else if (diff == 0) { - *listener << "which is the same as " << rhs_; - } else { - *listener << "which is " << -diff << " less than " << rhs_; - } - - return lhs > rhs_; - } - - private: - int rhs_; -}; - -Matcher<int> GreaterThan(int n) { - return MakeMatcher(new GreaterThanMatcher(n)); -} - -// Tests for ElementsAre(). - -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(a, a + GTEST_ARRAY_SIZE_(a)); - EXPECT_EQ("whose element #0 matches, which is 9 more than 1,\n" - "and whose element #2 matches, which is 98 more than 2", - Explain(m, test_vector)); -} - -TEST(ElementsAreTest, CanExplainMismatchWrongSize) { - Matcher<const list<int>& > m = ElementsAre(1, 3); - - list<int> test_list; - // No need to explain when the container is empty. - EXPECT_EQ("", Explain(m, test_list)); - - test_list.push_back(1); - EXPECT_EQ("which has 1 element", Explain(m, test_list)); -} - -TEST(ElementsAreTest, CanExplainMismatchRightSize) { - Matcher<const vector<int>& > m = ElementsAre(1, GreaterThan(5)); - - vector<int> v; - v.push_back(2); - v.push_back(1); - EXPECT_EQ("whose element #0 doesn't match", Explain(m, v)); - - v[0] = 1; - EXPECT_EQ("whose element #1 doesn't match, which is 4 less than 5", - Explain(m, v)); -} - -TEST(ElementsAreTest, MatchesOneElementVector) { - vector<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(a, a + GTEST_ARRAY_SIZE_(a)); - - EXPECT_THAT(test_vector, - // The element list can contain values and/or matchers - // of different types. - ElementsAre(0, Ge(0), _, 3, 4, Ne(2), Eq(6), 7, 8, _)); -} - -TEST(ElementsAreTest, DoesNotMatchWrongSize) { - vector<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) { - const char* strings[] = { - "Hi", - "world" - }; - - vector<list<char> > nested; - for (size_t i = 0; i < GTEST_ARRAY_SIZE_(strings); i++) { - nested.push_back(list<char>(strings[i], strings[i] + strlen(strings[i]))); - } - - EXPECT_THAT(nested, ElementsAre(ElementsAre('H', Ne('e')), - ElementsAre('w', 'o', _, _, 'd'))); - EXPECT_THAT(nested, Not(ElementsAre(ElementsAre('H', 'e'), - ElementsAre('w', 'o', _, _, 'd')))); -} - -TEST(ElementsAreTest, WorksWithByRefElementMatchers) { - int a[] = { 0, 1, 2 }; - vector<int> v(a, a + GTEST_ARRAY_SIZE_(a)); - - EXPECT_THAT(v, ElementsAre(Ref(v[0]), Ref(v[1]), Ref(v[2]))); - EXPECT_THAT(v, Not(ElementsAre(Ref(v[0]), Ref(v[1]), Ref(a[2])))); -} - -TEST(ElementsAreTest, WorksWithContainerPointerUsingPointee) { - int a[] = { 0, 1, 2 }; - vector<int> v(a, a + GTEST_ARRAY_SIZE_(a)); - - EXPECT_THAT(&v, Pointee(ElementsAre(0, 1, _))); - EXPECT_THAT(&v, Not(Pointee(ElementsAre(0, _, 3)))); -} - -TEST(ElementsAreTest, WorksWithNativeArrayPassedByReference) { - int array[] = { 0, 1, 2 }; - EXPECT_THAT(array, ElementsAre(0, 1, _)); - EXPECT_THAT(array, Not(ElementsAre(1, _, _))); - EXPECT_THAT(array, Not(ElementsAre(0, _))); -} - -class NativeArrayPassedAsPointerAndSize { - public: - NativeArrayPassedAsPointerAndSize() {} - - MOCK_METHOD2(Helper, void(int* array, int size)); - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(NativeArrayPassedAsPointerAndSize); -}; - -TEST(ElementsAreTest, WorksWithNativeArrayPassedAsPointerAndSize) { - int array[] = { 0, 1 }; - ::testing::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"))); -} - -#ifndef _MSC_VER - -// The following test passes a value of type const char[] to a -// function template that expects const T&. Some versions of MSVC -// generates a compiler error C2665 for that. We believe it's a bug -// in MSVC. Therefore this test is #if-ed out for MSVC. - -// Declared here with the size unknown. Defined AFTER the following test. -extern const char kHi[]; - -TEST(ElementsAreTest, AcceptsArrayWithUnknownSize) { - // The size of kHi is not known in this test, but ElementsAre() should - // still accept it. - - std::string array1[] = {"hi"}; - EXPECT_THAT(array1, ElementsAre(kHi)); - - std::string array2[] = {"ho"}; - EXPECT_THAT(array2, Not(ElementsAre(kHi))); -} - -const char kHi[] = "hi"; - -#endif // _MSC_VER - -TEST(ElementsAreTest, MakesCopyOfArguments) { - int x = 1; - int y = 2; - // This should make a copy of x and y. - ::testing::internal::ElementsAreMatcher<testing::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(a, a + GTEST_ARRAY_SIZE_(a)); - EXPECT_THAT(test_vector, ElementsAreArray(a)); - - test_vector[2] = 0; - EXPECT_THAT(test_vector, Not(ElementsAreArray(a))); -} - -TEST(ElementsAreArrayTest, CanBeCreatedWithArraySize) { - const char* a[] = { "one", "two", "three" }; - - vector<std::string> test_vector(a, a + GTEST_ARRAY_SIZE_(a)); - EXPECT_THAT(test_vector, ElementsAreArray(a, GTEST_ARRAY_SIZE_(a))); - - const char** p = a; - test_vector[0] = "1"; - EXPECT_THAT(test_vector, Not(ElementsAreArray(p, GTEST_ARRAY_SIZE_(a)))); -} - -TEST(ElementsAreArrayTest, CanBeCreatedWithoutArraySize) { - const char* a[] = { "one", "two", "three" }; - - vector<std::string> test_vector(a, a + GTEST_ARRAY_SIZE_(a)); - EXPECT_THAT(test_vector, ElementsAreArray(a)); - - test_vector[0] = "1"; - EXPECT_THAT(test_vector, Not(ElementsAreArray(a))); -} - -TEST(ElementsAreArrayTest, CanBeCreatedWithMatcherArray) { - const Matcher<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(a, a + GTEST_ARRAY_SIZE_(a)); - const vector<int> expected(a, a + GTEST_ARRAY_SIZE_(a)); - EXPECT_THAT(test_vector, ElementsAreArray(expected)); - test_vector.push_back(4); - EXPECT_THAT(test_vector, Not(ElementsAreArray(expected))); -} - -#if GTEST_HAS_STD_INITIALIZER_LIST_ - -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) }))); -} - -#endif // GTEST_HAS_STD_INITIALIZER_LIST_ - -TEST(ElementsAreArrayTest, CanBeCreatedWithMatcherVector) { - const int a[] = { 1, 2, 3 }; - const Matcher<int> kMatchers[] = { Eq(1), Eq(2), Eq(3) }; - vector<int> test_vector(a, a + GTEST_ARRAY_SIZE_(a)); - const vector<Matcher<int> > expected( - kMatchers, kMatchers + GTEST_ARRAY_SIZE_(kMatchers)); - EXPECT_THAT(test_vector, ElementsAreArray(expected)); - test_vector.push_back(4); - EXPECT_THAT(test_vector, Not(ElementsAreArray(expected))); -} - -TEST(ElementsAreArrayTest, CanBeCreatedWithIteratorRange) { - const int a[] = { 1, 2, 3 }; - const vector<int> test_vector(a, a + GTEST_ARRAY_SIZE_(a)); - const vector<int> expected(a, a + GTEST_ARRAY_SIZE_(a)); - EXPECT_THAT(test_vector, ElementsAreArray(expected.begin(), expected.end())); - // Pointers are iterators, too. - EXPECT_THAT(test_vector, ElementsAreArray(a, a + GTEST_ARRAY_SIZE_(a))); - // The empty range of NULL pointers should also be okay. - int* const null_int = NULL; - EXPECT_THAT(test_vector, Not(ElementsAreArray(null_int, null_int))); - EXPECT_THAT((vector<int>()), ElementsAreArray(null_int, null_int)); -} - -// Since ElementsAre() and ElementsAreArray() share much of the -// implementation, we only do a sanity test for native arrays here. -TEST(ElementsAreArrayTest, WorksWithNativeArray) { - ::std::string a[] = { "hi", "ho" }; - ::std::string b[] = { "hi", "ho" }; - - EXPECT_THAT(a, ElementsAreArray(b)); - EXPECT_THAT(a, ElementsAreArray(b, 2)); - EXPECT_THAT(a, Not(ElementsAreArray(b, 1))); -} - -TEST(ElementsAreArrayTest, SourceLifeSpan) { - const int a[] = { 1, 2, 3 }; - vector<int> test_vector(a, a + GTEST_ARRAY_SIZE_(a)); - vector<int> expect(a, a + GTEST_ARRAY_SIZE_(a)); - ElementsAreArrayMatcher<int> matcher_maker = - ElementsAreArray(expect.begin(), expect.end()); - EXPECT_THAT(test_vector, matcher_maker); - // Changing in place the values that initialized matcher_maker should not - // affect matcher_maker anymore. It should have made its own copy of them. - typedef vector<int>::iterator Iter; - for (Iter it = expect.begin(); it != expect.end(); ++it) { *it += 10; } - EXPECT_THAT(test_vector, matcher_maker); - test_vector.push_back(3); - EXPECT_THAT(test_vector, Not(matcher_maker)); -} - -// Tests for the MATCHER*() macro family. - -// Tests that a simple MATCHER() definition works. - -MATCHER(IsEven, "") { return (arg % 2) == 0; } - -TEST(MatcherMacroTest, Works) { - const Matcher<int> m = IsEven(); - EXPECT_TRUE(m.Matches(6)); - EXPECT_FALSE(m.Matches(7)); - - EXPECT_EQ("is even", Describe(m)); - EXPECT_EQ("not (is even)", DescribeNegation(m)); - EXPECT_EQ("", Explain(m, 6)); - EXPECT_EQ("", Explain(m, 7)); -} - -// This also tests that the description string can reference 'negation'. -MATCHER(IsEven2, negation ? "is odd" : "is even") { - if ((arg % 2) == 0) { - // Verifies that we can stream to result_listener, a listener - // supplied by the MATCHER macro implicitly. - *result_listener << "OK"; - return true; - } else { - *result_listener << "% 2 == " << (arg % 2); - return false; - } -} - -// This also tests that the description string can reference matcher -// parameters. -MATCHER_P2(EqSumOf, x, y, 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() != NULL) { - *result_listener->stream() << "diff == " << (x + y - arg); - } - return false; - } -} - -// Tests that the matcher description can reference 'negation' and the -// matcher parameters. -TEST(MatcherMacroTest, DescriptionCanReferenceNegationAndParameters) { - const Matcher<int> m1 = IsEven2(); - EXPECT_EQ("is even", Describe(m1)); - EXPECT_EQ("is odd", DescribeNegation(m1)); - - const Matcher<int> m2 = EqSumOf(5, 9); - EXPECT_EQ("equals the sum of 5 and 9", Describe(m2)); - EXPECT_EQ("doesn't equal the sum of 5 and 9", DescribeNegation(m2)); -} - -// Tests explaining match result in a MATCHER* macro. -TEST(MatcherMacroTest, CanExplainMatchResult) { - const Matcher<int> m1 = IsEven2(); - EXPECT_EQ("OK", Explain(m1, 4)); - EXPECT_EQ("% 2 == 1", Explain(m1, 5)); - - const Matcher<int> m2 = EqSumOf(1, 2); - EXPECT_EQ("OK", Explain(m2, 3)); - EXPECT_EQ("diff == -1", Explain(m2, 4)); -} - -// Tests that the body of MATCHER() can reference the type of the -// value being matched. - -MATCHER(IsEmptyString, "") { - StaticAssertTypeEq< ::std::string, arg_type>(); - return arg == ""; -} - -MATCHER(IsEmptyStringByRef, "") { - StaticAssertTypeEq<const ::std::string&, arg_type>(); - return arg == ""; -} - -TEST(MatcherMacroTest, CanReferenceArgType) { - const Matcher< ::std::string> m1 = IsEmptyString(); - EXPECT_TRUE(m1.Matches("")); - - const Matcher<const ::std::string&> m2 = IsEmptyStringByRef(); - EXPECT_TRUE(m2.Matches("")); -} - -// Tests that MATCHER() can be used in a namespace. - -namespace matcher_test { -MATCHER(IsOdd, "") { return (arg % 2) != 0; } -} // namespace matcher_test - -TEST(MatcherMacroTest, WorksInNamespace) { - Matcher<int> m = matcher_test::IsOdd(); - EXPECT_FALSE(m.Matches(4)); - EXPECT_TRUE(m.Matches(5)); -} - -// Tests that Value() can be used to compose matchers. -MATCHER(IsPositiveOdd, "") { - return Value(arg, matcher_test::IsOdd()) && arg > 0; -} - -TEST(MatcherMacroTest, CanBeComposedUsingValue) { - EXPECT_THAT(3, IsPositiveOdd()); - EXPECT_THAT(4, Not(IsPositiveOdd())); - EXPECT_THAT(-1, Not(IsPositiveOdd())); -} - -// Tests that a simple MATCHER_P() definition works. - -MATCHER_P(IsGreaterThan32And, n, "") { return arg > 32 && arg > n; } - -TEST(MatcherPMacroTest, Works) { - const Matcher<int> m = IsGreaterThan32And(5); - EXPECT_TRUE(m.Matches(36)); - EXPECT_FALSE(m.Matches(5)); - - EXPECT_EQ("is greater than 32 and 5", Describe(m)); - EXPECT_EQ("not (is greater than 32 and 5)", DescribeNegation(m)); - EXPECT_EQ("", Explain(m, 36)); - EXPECT_EQ("", Explain(m, 5)); -} - -// Tests that the description is calculated correctly from the matcher name. -MATCHER_P(_is_Greater_Than32and_, n, "") { return arg > 32 && arg > n; } - -TEST(MatcherPMacroTest, GeneratesCorrectDescription) { - const Matcher<int> m = _is_Greater_Than32and_(5); - - EXPECT_EQ("is greater than 32 and 5", Describe(m)); - EXPECT_EQ("not (is greater than 32 and 5)", DescribeNegation(m)); - EXPECT_EQ("", Explain(m, 36)); - EXPECT_EQ("", Explain(m, 5)); -} - -// Tests that a MATCHER_P matcher can be explicitly instantiated with -// a reference parameter type. - -class UncopyableFoo { - public: - explicit UncopyableFoo(char value) : value_(value) {} - private: - UncopyableFoo(const UncopyableFoo&); - void operator=(const UncopyableFoo&); - - char value_; -}; - -MATCHER_P(ReferencesUncopyable, variable, "") { return &arg == &variable; } - -TEST(MatcherPMacroTest, WorksWhenExplicitlyInstantiatedWithReference) { - UncopyableFoo foo1('1'), foo2('2'); - const Matcher<const UncopyableFoo&> m = - ReferencesUncopyable<const UncopyableFoo&>(foo1); - - EXPECT_TRUE(m.Matches(foo1)); - EXPECT_FALSE(m.Matches(foo2)); - - // We don't want the address of the parameter printed, as most - // likely it will just annoy the user. If the address is - // interesting, the user should consider passing the parameter by - // pointer instead. - EXPECT_EQ("references uncopyable 1-byte object <31>", Describe(m)); -} - - -// Tests that the body of MATCHER_Pn() can reference the parameter -// types. - -MATCHER_P3(ParamTypesAreIntLongAndChar, foo, bar, baz, "") { - StaticAssertTypeEq<int, foo_type>(); - StaticAssertTypeEq<long, bar_type>(); // NOLINT - StaticAssertTypeEq<char, baz_type>(); - return arg == 0; -} - -TEST(MatcherPnMacroTest, CanReferenceParamTypes) { - EXPECT_THAT(0, ParamTypesAreIntLongAndChar(10, 20L, 'a')); -} - -// Tests that a MATCHER_Pn matcher can be explicitly instantiated with -// reference parameter types. - -MATCHER_P2(ReferencesAnyOf, variable1, variable2, "") { - return &arg == &variable1 || &arg == &variable2; -} - -TEST(MatcherPnMacroTest, WorksWhenExplicitlyInstantiatedWithReferences) { - UncopyableFoo foo1('1'), foo2('2'), foo3('3'); - const Matcher<const UncopyableFoo&> m = - ReferencesAnyOf<const UncopyableFoo&, const UncopyableFoo&>(foo1, foo2); - - EXPECT_TRUE(m.Matches(foo1)); - EXPECT_TRUE(m.Matches(foo2)); - EXPECT_FALSE(m.Matches(foo3)); -} - -TEST(MatcherPnMacroTest, - GeneratesCorretDescriptionWhenExplicitlyInstantiatedWithReferences) { - UncopyableFoo foo1('1'), foo2('2'); - const Matcher<const UncopyableFoo&> m = - ReferencesAnyOf<const UncopyableFoo&, const UncopyableFoo&>(foo1, foo2); - - // We don't want the addresses of the parameters printed, as most - // likely they will just annoy the user. If the addresses are - // interesting, the user should consider passing the parameters by - // pointers instead. - EXPECT_EQ("references any of (1-byte object <31>, 1-byte object <32>)", - Describe(m)); -} - -// Tests that a simple MATCHER_P2() definition works. - -MATCHER_P2(IsNotInClosedRange, low, hi, "") { return arg < low || arg > hi; } - -TEST(MatcherPnMacroTest, Works) { - const Matcher<const long&> m = IsNotInClosedRange(10, 20); // NOLINT - EXPECT_TRUE(m.Matches(36L)); - EXPECT_FALSE(m.Matches(15L)); - - EXPECT_EQ("is not in closed range (10, 20)", Describe(m)); - EXPECT_EQ("not (is not in closed range (10, 20))", DescribeNegation(m)); - EXPECT_EQ("", Explain(m, 36L)); - EXPECT_EQ("", Explain(m, 15L)); -} - -// Tests that MATCHER*() definitions can be overloaded on the number -// of parameters; also tests MATCHER_Pn() where n >= 3. - -MATCHER(EqualsSumOf, "") { return arg == 0; } -MATCHER_P(EqualsSumOf, a, "") { return arg == a; } -MATCHER_P2(EqualsSumOf, a, b, "") { return arg == a + b; } -MATCHER_P3(EqualsSumOf, a, b, c, "") { return arg == a + b + c; } -MATCHER_P4(EqualsSumOf, a, b, c, d, "") { return arg == a + b + c + d; } -MATCHER_P5(EqualsSumOf, a, b, c, d, e, "") { return arg == a + b + c + d + e; } -MATCHER_P6(EqualsSumOf, a, b, c, d, e, f, "") { - return arg == a + b + c + d + e + f; -} -MATCHER_P7(EqualsSumOf, a, b, c, d, e, f, g, "") { - return arg == a + b + c + d + e + f + g; -} -MATCHER_P8(EqualsSumOf, a, b, c, d, e, f, g, h, "") { - return arg == a + b + c + d + e + f + g + h; -} -MATCHER_P9(EqualsSumOf, a, b, c, d, e, f, g, h, i, "") { - return arg == a + b + c + d + e + f + g + h + i; -} -MATCHER_P10(EqualsSumOf, a, b, c, d, e, f, g, h, i, j, "") { - return arg == a + b + c + d + e + f + g + h + i + j; -} - -TEST(MatcherPnMacroTest, CanBeOverloadedOnNumberOfParameters) { - EXPECT_THAT(0, EqualsSumOf()); - EXPECT_THAT(1, EqualsSumOf(1)); - EXPECT_THAT(12, EqualsSumOf(10, 2)); - EXPECT_THAT(123, EqualsSumOf(100, 20, 3)); - EXPECT_THAT(1234, EqualsSumOf(1000, 200, 30, 4)); - EXPECT_THAT(12345, EqualsSumOf(10000, 2000, 300, 40, 5)); - EXPECT_THAT("abcdef", - EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f')); - EXPECT_THAT("abcdefg", - EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g')); - EXPECT_THAT("abcdefgh", - EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g', - "h")); - EXPECT_THAT("abcdefghi", - EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g', - "h", 'i')); - EXPECT_THAT("abcdefghij", - EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g', - "h", 'i', ::std::string("j"))); - - EXPECT_THAT(1, Not(EqualsSumOf())); - EXPECT_THAT(-1, Not(EqualsSumOf(1))); - EXPECT_THAT(-12, Not(EqualsSumOf(10, 2))); - EXPECT_THAT(-123, Not(EqualsSumOf(100, 20, 3))); - EXPECT_THAT(-1234, Not(EqualsSumOf(1000, 200, 30, 4))); - EXPECT_THAT(-12345, Not(EqualsSumOf(10000, 2000, 300, 40, 5))); - EXPECT_THAT("abcdef ", - Not(EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f'))); - EXPECT_THAT("abcdefg ", - Not(EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', - 'g'))); - EXPECT_THAT("abcdefgh ", - Not(EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g', - "h"))); - EXPECT_THAT("abcdefghi ", - Not(EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g', - "h", 'i'))); - EXPECT_THAT("abcdefghij ", - Not(EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g', - "h", 'i', ::std::string("j")))); -} - -// Tests that a MATCHER_Pn() definition can be instantiated with any -// compatible parameter types. -TEST(MatcherPnMacroTest, WorksForDifferentParameterTypes) { - EXPECT_THAT(123, EqualsSumOf(100L, 20, static_cast<char>(3))); - EXPECT_THAT("abcd", EqualsSumOf(::std::string("a"), "b", 'c', "d")); - - EXPECT_THAT(124, Not(EqualsSumOf(100L, 20, static_cast<char>(3)))); - EXPECT_THAT("abcde", Not(EqualsSumOf(::std::string("a"), "b", 'c', "d"))); -} - -// Tests that the matcher body can promote the parameter types. - -MATCHER_P2(EqConcat, prefix, suffix, "") { - // The following lines promote the two parameters to desired types. - std::string prefix_str(prefix); - char suffix_char = static_cast<char>(suffix); - return arg == prefix_str + suffix_char; -} - -TEST(MatcherPnMacroTest, SimpleTypePromotion) { - Matcher<std::string> no_promo = - EqConcat(std::string("foo"), 't'); - Matcher<const std::string&> promo = - EqConcat("foo", static_cast<int>('t')); - EXPECT_FALSE(no_promo.Matches("fool")); - EXPECT_FALSE(promo.Matches("fool")); - EXPECT_TRUE(no_promo.Matches("foot")); - EXPECT_TRUE(promo.Matches("foot")); -} - -// Verifies the type of a MATCHER*. - -TEST(MatcherPnMacroTest, TypesAreCorrect) { - // EqualsSumOf() must be assignable to a EqualsSumOfMatcher variable. - EqualsSumOfMatcher a0 = EqualsSumOf(); - - // EqualsSumOf(1) must be assignable to a EqualsSumOfMatcherP variable. - EqualsSumOfMatcherP<int> a1 = EqualsSumOf(1); - - // EqualsSumOf(p1, ..., pk) must be assignable to a EqualsSumOfMatcherPk - // variable, and so on. - EqualsSumOfMatcherP2<int, char> a2 = EqualsSumOf(1, '2'); - EqualsSumOfMatcherP3<int, int, char> a3 = EqualsSumOf(1, 2, '3'); - EqualsSumOfMatcherP4<int, int, int, char> a4 = EqualsSumOf(1, 2, 3, '4'); - EqualsSumOfMatcherP5<int, int, int, int, char> a5 = - EqualsSumOf(1, 2, 3, 4, '5'); - EqualsSumOfMatcherP6<int, int, int, int, int, char> a6 = - EqualsSumOf(1, 2, 3, 4, 5, '6'); - EqualsSumOfMatcherP7<int, int, int, int, int, int, char> a7 = - EqualsSumOf(1, 2, 3, 4, 5, 6, '7'); - EqualsSumOfMatcherP8<int, int, int, int, int, int, int, char> a8 = - EqualsSumOf(1, 2, 3, 4, 5, 6, 7, '8'); - EqualsSumOfMatcherP9<int, int, int, int, int, int, int, int, char> a9 = - EqualsSumOf(1, 2, 3, 4, 5, 6, 7, 8, '9'); - EqualsSumOfMatcherP10<int, int, int, int, int, int, int, int, int, char> a10 = - EqualsSumOf(1, 2, 3, 4, 5, 6, 7, 8, 9, '0'); - - // Avoid "unused variable" warnings. - (void)a0; - (void)a1; - (void)a2; - (void)a3; - (void)a4; - (void)a5; - (void)a6; - (void)a7; - (void)a8; - (void)a9; - (void)a10; -} - -// Tests that matcher-typed parameters can be used in Value() inside a -// MATCHER_Pn definition. - -// Succeeds if arg matches exactly 2 of the 3 matchers. -MATCHER_P3(TwoOf, m1, m2, m3, "") { - const int count = static_cast<int>(Value(arg, m1)) - + static_cast<int>(Value(arg, m2)) + static_cast<int>(Value(arg, m3)); - return count == 2; -} - -TEST(MatcherPnMacroTest, CanUseMatcherTypedParameterInValue) { - EXPECT_THAT(42, TwoOf(Gt(0), Lt(50), Eq(10))); - EXPECT_THAT(0, Not(TwoOf(Gt(-1), Lt(1), Eq(0)))); -} - -// Tests Contains(). - -TEST(ContainsTest, ListMatchesWhenElementIsInContainer) { - list<int> some_list; - some_list.push_back(3); - some_list.push_back(1); - some_list.push_back(2); - EXPECT_THAT(some_list, Contains(1)); - EXPECT_THAT(some_list, Contains(Gt(2.5))); - EXPECT_THAT(some_list, Contains(Eq(2.0f))); - - list<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<const char*> another_set; - another_set.insert("fee"); - another_set.insert("fie"); - another_set.insert("foe"); - another_set.insert("fum"); - EXPECT_THAT(another_set, Contains(Eq(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<const char*> c_string_set; - c_string_set.insert("hello"); - EXPECT_THAT(c_string_set, Not(Contains(std::string("hello").c_str()))); -} - -TEST(ContainsTest, ExplainsMatchResultCorrectly) { - const int a[2] = { 1, 2 }; - Matcher<const int (&)[2]> m = Contains(2); - EXPECT_EQ("whose element #1 matches", Explain(m, a)); - - m = Contains(3); - EXPECT_EQ("", Explain(m, a)); - - m = Contains(GreaterThan(0)); - EXPECT_EQ("whose element #0 matches, which is 1 more than 0", Explain(m, a)); - - m = Contains(GreaterThan(10)); - EXPECT_EQ("", Explain(m, a)); -} - -TEST(ContainsTest, DescribesItselfCorrectly) { - Matcher<vector<int> > m = Contains(1); - EXPECT_EQ("contains at least one element that is equal to 1", Describe(m)); - - Matcher<vector<int> > m2 = Not(m); - EXPECT_EQ("doesn't contain any element that is equal to 1", Describe(m2)); -} - -TEST(ContainsTest, MapMatchesWhenElementIsInContainer) { - map<const char*, int> my_map; - const char* bar = "a string"; - my_map[bar] = 2; - EXPECT_THAT(my_map, Contains(pair<const char* const, int>(bar, 2))); - - map<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(make_tuple(pointer, 2), Contains(1)); - EXPECT_THAT(make_tuple(pointer, 2), Not(Contains(Gt(3)))); -} - -TEST(ContainsTest, WorksForTwoDimensionalNativeArray) { - int a[][3] = { { 1, 2, 3 }, { 4, 5, 6 } }; - EXPECT_THAT(a, Contains(ElementsAre(4, 5, 6))); - EXPECT_THAT(a, Contains(Contains(5))); - EXPECT_THAT(a, Not(Contains(ElementsAre(3, 4, 5)))); - EXPECT_THAT(a, Contains(Not(Contains(5)))); -} - -TEST(AllOfTest, HugeMatcher) { - // Verify that using AllOf with many arguments doesn't cause - // the compiler to exceed template instantiation depth limit. - EXPECT_THAT(0, testing::AllOf(_, _, _, _, _, _, _, _, _, - testing::AllOf(_, _, _, _, _, _, _, _, _, _))); -} - -TEST(AnyOfTest, HugeMatcher) { - // Verify that using AnyOf with many arguments doesn't cause - // the compiler to exceed template instantiation depth limit. - EXPECT_THAT(0, testing::AnyOf(_, _, _, _, _, _, _, _, _, - testing::AnyOf(_, _, _, _, _, _, _, _, _, _))); -} - -namespace adl_test { - -// Verifies that the implementation of ::testing::AllOf and ::testing::AnyOf -// don't issue unqualified recursive calls. If they do, the argument dependent -// name lookup will cause AllOf/AnyOf in the 'adl_test' namespace to be found -// as a candidate and the compilation will break due to an ambiguous overload. - -// The matcher must be in the same namespace as AllOf/AnyOf to make argument -// dependent lookup find those. -MATCHER(M, "") { return true; } - -template <typename T1, typename T2> -bool AllOf(const T1& t1, const T2& t2) { return true; } - -TEST(AllOfTest, DoesNotCallAllOfUnqualified) { - EXPECT_THAT(42, testing::AllOf( - M(), M(), M(), M(), M(), M(), M(), M(), M(), M())); -} - -template <typename T1, typename T2> bool -AnyOf(const T1& t1, const T2& t2) { return true; } - -TEST(AnyOfTest, DoesNotCallAnyOfUnqualified) { - EXPECT_THAT(42, testing::AnyOf( - M(), M(), M(), M(), M(), M(), M(), M(), M(), M())); -} - -} // namespace adl_test - -#ifdef _MSC_VER -# pragma warning(pop) -#endif - -#if GTEST_LANG_CXX11 - -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))); -} - -#endif // GTEST_LASNG_CXX11 - -} // namespace - -#ifdef _MSC_VER -# pragma warning(pop) -#endif diff --git a/contrib/googletest/googlemock/test/gmock-internal-utils_test.cc b/contrib/googletest/googlemock/test/gmock-internal-utils_test.cc index 5f53077c3fa5..6c769a882a69 100644 --- a/contrib/googletest/googlemock/test/gmock-internal-utils_test.cc +++ b/contrib/googletest/googlemock/test/gmock-internal-utils_test.cc @@ -27,22 +27,26 @@ // (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 <string> #include <sstream> +#include <string> +#include <tuple> #include <vector> + #include "gmock/gmock.h" #include "gmock/internal/gmock-port.h" -#include "gtest/gtest.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 @@ -53,12 +57,10 @@ #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ -#if GTEST_OS_CYGWIN -# include <sys/types.h> // For ssize_t. NOLINT +#ifdef GTEST_OS_CYGWIN +#include <sys/types.h> // For ssize_t. NOLINT #endif -class ProtocolMessage; - namespace proto2 { class Message; } // namespace proto2 @@ -68,24 +70,23 @@ namespace internal { namespace { -TEST(JoinAsTupleTest, JoinsEmptyTuple) { - EXPECT_EQ("", JoinAsTuple(Strings())); +TEST(JoinAsKeyValueTupleTest, JoinsEmptyTuple) { + EXPECT_EQ("", JoinAsKeyValueTuple({}, Strings())); } -TEST(JoinAsTupleTest, JoinsOneTuple) { - const char* fields[] = {"1"}; - EXPECT_EQ("1", JoinAsTuple(Strings(fields, fields + 1))); +TEST(JoinAsKeyValueTupleTest, JoinsOneTuple) { + EXPECT_EQ("(a: 1)", JoinAsKeyValueTuple({"a"}, {"1"})); } -TEST(JoinAsTupleTest, JoinsTwoTuple) { - const char* fields[] = {"1", "a"}; - EXPECT_EQ("(1, a)", JoinAsTuple(Strings(fields, fields + 2))); +TEST(JoinAsKeyValueTupleTest, JoinsTwoTuple) { + EXPECT_EQ("(a: 1, b: 2)", JoinAsKeyValueTuple({"a", "b"}, {"1", "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(JoinAsKeyValueTupleTest, JoinsTenTuple) { + EXPECT_EQ( + "(a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10)", + JoinAsKeyValueTuple({"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"}, + {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"})); } TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameContainsNoWord) { @@ -122,49 +123,28 @@ TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameIsMixture) { ConvertIdentifierNameToWords("_Chapter11Section_1_")); } -TEST(PointeeOfTest, WorksForSmartPointers) { - CompileAssertTypesEqual<const char, - PointeeOf<internal::linked_ptr<const char> >::type>(); -#if GTEST_HAS_STD_UNIQUE_PTR_ - CompileAssertTypesEqual<int, PointeeOf<std::unique_ptr<int> >::type>(); -#endif // GTEST_HAS_STD_UNIQUE_PTR_ -#if GTEST_HAS_STD_SHARED_PTR_ - CompileAssertTypesEqual<std::string, - PointeeOf<std::shared_ptr<std::string> >::type>(); -#endif // GTEST_HAS_STD_SHARED_PTR_ -} - -TEST(PointeeOfTest, WorksForRawPointers) { - CompileAssertTypesEqual<int, PointeeOf<int*>::type>(); - CompileAssertTypesEqual<const char, PointeeOf<const char*>::type>(); - CompileAssertTypesEqual<void, PointeeOf<void*>::type>(); -} - TEST(GetRawPointerTest, WorksForSmartPointers) { -#if GTEST_HAS_STD_UNIQUE_PTR_ 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)); -#endif // GTEST_HAS_STD_UNIQUE_PTR_ -#if GTEST_HAS_STD_SHARED_PTR_ double* const raw_p2 = new double(2.5); // NOLINT const std::shared_ptr<double> p2(raw_p2); EXPECT_EQ(raw_p2, GetRawPointer(p2)); -#endif // GTEST_HAS_STD_SHARED_PTR_ - - const char* const raw_p4 = new const char('a'); // NOLINT - const internal::linked_ptr<const char> p4(raw_p4); - EXPECT_EQ(raw_p4, GetRawPointer(p4)); } TEST(GetRawPointerTest, WorksForRawPointers) { - int* p = NULL; - // Don't use EXPECT_EQ as no NULL-testing magic on Symbian. - EXPECT_TRUE(NULL == GetRawPointer(p)); + int* p = nullptr; + EXPECT_TRUE(nullptr == GetRawPointer(p)); int n = 1; EXPECT_EQ(&n, GetRawPointer(&n)); } +TEST(GetRawPointerTest, WorksForStdReferenceWrapper) { + int n = 1; + EXPECT_EQ(&n, GetRawPointer(std::ref(n))); + EXPECT_EQ(&n, GetRawPointer(std::cref(n))); +} + // Tests KindOf<T>. class Base {}; @@ -175,35 +155,35 @@ TEST(KindOfTest, Bool) { } 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_(wchar_t)); // NOLINT - EXPECT_EQ(kInteger, GMOCK_KIND_OF_(Int64)); // NOLINT - EXPECT_EQ(kInteger, GMOCK_KIND_OF_(UInt64)); // NOLINT - EXPECT_EQ(kInteger, GMOCK_KIND_OF_(size_t)); // NOLINT -#if GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN + 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 defined(GTEST_OS_LINUX) || defined(GTEST_OS_MAC) || defined(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_(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_(void*)); // NOLINT EXPECT_EQ(kOther, GMOCK_KIND_OF_(char**)); // NOLINT - EXPECT_EQ(kOther, GMOCK_KIND_OF_(Base)); // NOLINT + EXPECT_EQ(kOther, GMOCK_KIND_OF_(Base)); // NOLINT } // Tests LosslessArithmeticConvertible<T, U>. @@ -234,32 +214,33 @@ TEST(LosslessArithmeticConvertibleTest, IntegerToInteger) { EXPECT_TRUE((LosslessArithmeticConvertible<unsigned char, int>::value)); // Unsigned => larger unsigned is fine. - EXPECT_TRUE( - (LosslessArithmeticConvertible<unsigned short, UInt64>::value)); // NOLINT + EXPECT_TRUE((LosslessArithmeticConvertible<unsigned short, + uint64_t>::value)); // NOLINT // Signed => unsigned is not fine. - EXPECT_FALSE((LosslessArithmeticConvertible<short, UInt64>::value)); // NOLINT - EXPECT_FALSE((LosslessArithmeticConvertible< - signed char, unsigned int>::value)); // NOLINT + 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<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 + 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<unsigned char, signed char>::value)); EXPECT_FALSE((LosslessArithmeticConvertible<int, unsigned int>::value)); - EXPECT_FALSE((LosslessArithmeticConvertible<UInt64, Int64>::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, unsigned int>::value)); + EXPECT_FALSE((LosslessArithmeticConvertible<int64_t, unsigned int>::value)); } TEST(LosslessArithmeticConvertibleTest, IntegerToFloatingPoint) { @@ -267,8 +248,8 @@ TEST(LosslessArithmeticConvertibleTest, IntegerToFloatingPoint) { // 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 + EXPECT_FALSE( + (LosslessArithmeticConvertible<short, long double>::value)); // NOLINT } TEST(LosslessArithmeticConvertibleTest, FloatingPointToBool) { @@ -278,7 +259,7 @@ TEST(LosslessArithmeticConvertibleTest, FloatingPointToBool) { TEST(LosslessArithmeticConvertibleTest, FloatingPointToInteger) { EXPECT_FALSE((LosslessArithmeticConvertible<float, long>::value)); // NOLINT - EXPECT_FALSE((LosslessArithmeticConvertible<double, Int64>::value)); + EXPECT_FALSE((LosslessArithmeticConvertible<double, int64_t>::value)); EXPECT_FALSE((LosslessArithmeticConvertible<long double, int>::value)); } @@ -296,7 +277,7 @@ TEST(LosslessArithmeticConvertibleTest, FloatingPointToFloatingPoint) { EXPECT_FALSE((LosslessArithmeticConvertible<double, float>::value)); GTEST_INTENTIONAL_CONST_COND_PUSH_() if (sizeof(double) == sizeof(long double)) { // NOLINT - GTEST_INTENTIONAL_CONST_COND_POP_() + 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)); @@ -308,26 +289,23 @@ TEST(LosslessArithmeticConvertibleTest, FloatingPointToFloatingPoint) { // Tests the TupleMatches() template function. TEST(TupleMatchesTest, WorksForSize0) { - tuple<> matchers; - tuple<> values; + std::tuple<> matchers; + std::tuple<> values; EXPECT_TRUE(TupleMatches(matchers, values)); } TEST(TupleMatchesTest, WorksForSize1) { - tuple<Matcher<int> > matchers(Eq(1)); - tuple<int> values1(1), - values2(2); + 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) { - tuple<Matcher<int>, Matcher<char> > matchers(Eq(1), Eq('a')); - tuple<int, char> values1(1, 'a'), - values2(1, 'b'), - values3(2, 'a'), + 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)); @@ -337,10 +315,11 @@ TEST(TupleMatchesTest, WorksForSize2) { } TEST(TupleMatchesTest, WorksForSize5) { - tuple<Matcher<int>, Matcher<char>, Matcher<bool>, Matcher<long>, // NOLINT - Matcher<std::string> > + 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")); - tuple<int, char, bool, long, std::string> // NOLINT + 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"); @@ -357,13 +336,10 @@ TEST(AssertTest, SucceedsOnTrue) { // 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__, "This should fail."); }, ""); - EXPECT_DEATH_IF_SUPPORTED({ - Assert(false, __FILE__, __LINE__); - }, ""); + EXPECT_DEATH_IF_SUPPORTED({ Assert(false, __FILE__, __LINE__); }, ""); } // Tests that Expect(true, ...) succeeds. @@ -374,42 +350,44 @@ TEST(ExpectTest, SucceedsOnTrue) { // 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__, "This should fail."); + }, + "This should fail"); - EXPECT_NONFATAL_FAILURE({ // NOLINT - Expect(false, __FILE__, __LINE__); - }, "Expectation failed"); + EXPECT_NONFATAL_FAILURE( + { // NOLINT + Expect(false, __FILE__, __LINE__); + }, + "Expectation failed"); } // Tests LogIsVisible(). class LogIsVisibleTest : public ::testing::Test { protected: - virtual void SetUp() { - original_verbose_ = GMOCK_FLAG(verbose); - } + void SetUp() override { original_verbose_ = GMOCK_FLAG_GET(verbose); } - virtual void TearDown() { GMOCK_FLAG(verbose) = original_verbose_; } + void TearDown() override { GMOCK_FLAG_SET(verbose, original_verbose_); } std::string original_verbose_; }; TEST_F(LogIsVisibleTest, AlwaysReturnsTrueIfVerbosityIsInfo) { - GMOCK_FLAG(verbose) = kInfoVerbosity; + GMOCK_FLAG_SET(verbose, kInfoVerbosity); EXPECT_TRUE(LogIsVisible(kInfo)); EXPECT_TRUE(LogIsVisible(kWarning)); } TEST_F(LogIsVisibleTest, AlwaysReturnsFalseIfVerbosityIsError) { - GMOCK_FLAG(verbose) = kErrorVerbosity; + GMOCK_FLAG_SET(verbose, kErrorVerbosity); EXPECT_FALSE(LogIsVisible(kInfo)); EXPECT_FALSE(LogIsVisible(kWarning)); } TEST_F(LogIsVisibleTest, WorksWhenVerbosityIsWarning) { - GMOCK_FLAG(verbose) = kWarningVerbosity; + GMOCK_FLAG_SET(verbose, kWarningVerbosity); EXPECT_FALSE(LogIsVisible(kInfo)); EXPECT_TRUE(LogIsVisible(kWarning)); } @@ -422,39 +400,39 @@ TEST_F(LogIsVisibleTest, WorksWhenVerbosityIsWarning) { // 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; + const std::string old_flag = GMOCK_FLAG_GET(verbose); + GMOCK_FLAG_SET(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")); + 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; + GMOCK_FLAG_SET(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; + const std::string saved_flag = GMOCK_FLAG_GET(verbose); + GMOCK_FLAG_SET(verbose, kInfoVerbosity); CaptureStdout(); Log(kInfo, "Test log.\n", -1); EXPECT_STREQ("\nTest log.\n", GetCapturedStdout().c_str()); - GMOCK_FLAG(verbose) = saved_flag; + GMOCK_FLAG_SET(verbose, saved_flag); } struct MockStackTraceGetter : testing::internal::OsStackTraceGetterInterface { - virtual std::string CurrentStackTrace(int max_depth, int skip_count) { + std::string CurrentStackTrace(int max_depth, int skip_count) override { return (testing::Message() << max_depth << "::" << skip_count << "\n") .GetString(); } - virtual void UponLeavingGTest() {} + void UponLeavingGTest() override {} }; // Tests that in opt mode, a positive stack_frames_to_skip argument is @@ -468,7 +446,8 @@ TEST(LogTest, NoSkippingStackFrameInOptMode) { const std::string log = GetCapturedStdout(); std::string expected_trace = - (testing::Message() << GTEST_FLAG(stack_trace_depth) << "::").GetString(); + (testing::Message() << GTEST_FLAG_GET(stack_trace_depth) << "::") + .GetString(); std::string expected_message = "\nGMOCK WARNING:\n" "Test log.\n" @@ -477,13 +456,13 @@ TEST(LogTest, NoSkippingStackFrameInOptMode) { EXPECT_THAT(log, HasSubstr(expected_message)); int skip_count = atoi(log.substr(expected_message.size()).c_str()); -# if defined(NDEBUG) +#if defined(NDEBUG) // In opt mode, no stack frame should be skipped. const int expected_skip_count = 0; -# else +#else // In dbg mode, the stack frames should be skipped. const int expected_skip_count = 100; -# endif +#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 @@ -492,7 +471,7 @@ TEST(LogTest, NoSkippingStackFrameInOptMode) { AllOf(Ge(expected_skip_count), Le(expected_skip_count + 10))); // Restores the default OS stack trace getter. - GetUnitTestImpl()->set_os_stack_trace_getter(NULL); + GetUnitTestImpl()->set_os_stack_trace_getter(nullptr); } // Tests that all logs are printed when the value of the @@ -523,53 +502,14 @@ TEST(LogTest, OnlyWarningsArePrintedWhenVerbosityIsInvalid) { TestLogWithSeverity("invalid", kWarning, true); } -#endif // GTEST_HAS_STREAM_REDIRECTION - -TEST(TypeTraitsTest, true_type) { - EXPECT_TRUE(true_type::value); -} - -TEST(TypeTraitsTest, false_type) { - EXPECT_FALSE(false_type::value); -} - -TEST(TypeTraitsTest, is_reference) { - EXPECT_FALSE(is_reference<int>::value); - EXPECT_FALSE(is_reference<char*>::value); - EXPECT_TRUE(is_reference<const int&>::value); -} - -TEST(TypeTraitsTest, is_pointer) { - EXPECT_FALSE(is_pointer<int>::value); - EXPECT_FALSE(is_pointer<char&>::value); - EXPECT_TRUE(is_pointer<const int*>::value); -} - -TEST(TypeTraitsTest, type_equals) { - EXPECT_FALSE((type_equals<int, const int>::value)); - EXPECT_FALSE((type_equals<int, int&>::value)); - EXPECT_FALSE((type_equals<int, double>::value)); - EXPECT_TRUE((type_equals<char, char>::value)); -} - -TEST(TypeTraitsTest, remove_reference) { - EXPECT_TRUE((type_equals<char, remove_reference<char&>::type>::value)); - EXPECT_TRUE((type_equals<const int, - remove_reference<const int&>::type>::value)); - EXPECT_TRUE((type_equals<int, remove_reference<int>::type>::value)); - EXPECT_TRUE((type_equals<double*, remove_reference<double*>::type>::value)); -} - -#if GTEST_HAS_STREAM_REDIRECTION - // 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; +std::string GrabOutput(void (*logger)(), const char* verbosity) { + const std::string saved_flag = GMOCK_FLAG_GET(verbose); + GMOCK_FLAG_SET(verbose, verbosity); CaptureStdout(); logger(); - GMOCK_FLAG(verbose) = saved_flag; + GMOCK_FLAG_SET(verbose, saved_flag); return GetCapturedStdout(); } @@ -583,7 +523,7 @@ 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) { @@ -599,14 +539,14 @@ TEST(ExpectCallTest, DoesNotLogWhenVerbosityIsWarning) { // Verifies that EXPECT_CALL doesn't log // if the --gmock_verbose flag is set to "error". -TEST(ExpectCallTest, DoesNotLogWhenVerbosityIsError) { +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) { @@ -643,9 +583,9 @@ TEST(OnCallTest, LogsAnythingArgument) { TEST(StlContainerViewTest, WorksForStlContainer) { StaticAssertTypeEq<std::vector<int>, - StlContainerView<std::vector<int> >::type>(); + StlContainerView<std::vector<int>>::type>(); StaticAssertTypeEq<const std::vector<double>&, - StlContainerView<std::vector<double> >::const_reference>(); + StlContainerView<std::vector<double>>::const_reference>(); typedef std::vector<char> Chars; Chars v1; @@ -658,17 +598,16 @@ TEST(StlContainerViewTest, WorksForStlContainer) { } TEST(StlContainerViewTest, WorksForStaticNativeArray) { - StaticAssertTypeEq<NativeArray<int>, - StlContainerView<int[3]>::type>(); + StaticAssertTypeEq<NativeArray<int>, StlContainerView<int[3]>::type>(); StaticAssertTypeEq<NativeArray<double>, - StlContainerView<const double[4]>::type>(); + StlContainerView<const double[4]>::type>(); StaticAssertTypeEq<NativeArray<char[3]>, - StlContainerView<const char[2][3]>::type>(); + StlContainerView<const char[2][3]>::type>(); StaticAssertTypeEq<const NativeArray<int>, - StlContainerView<int[2]>::const_reference>(); + StlContainerView<int[2]>::const_reference>(); - int a1[3] = { 0, 1, 2 }; + int a1[3] = {0, 1, 2}; NativeArray<int> a2 = StlContainerView<int[3]>::ConstReference(a1); EXPECT_EQ(3U, a2.size()); EXPECT_EQ(a1, a2.begin()); @@ -686,22 +625,25 @@ TEST(StlContainerViewTest, WorksForStaticNativeArray) { TEST(StlContainerViewTest, WorksForDynamicNativeArray) { StaticAssertTypeEq<NativeArray<int>, - StlContainerView<tuple<const int*, size_t> >::type>(); - StaticAssertTypeEq<NativeArray<double>, - StlContainerView<tuple<linked_ptr<double>, int> >::type>(); + 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<tuple<const int*, int> >::const_reference>(); + StaticAssertTypeEq< + const NativeArray<int>, + StlContainerView<std::tuple<const int*, int>>::const_reference>(); - int a1[3] = { 0, 1, 2 }; + int a1[3] = {0, 1, 2}; const int* const p1 = a1; - NativeArray<int> a2 = StlContainerView<tuple<const int*, int> >:: - ConstReference(make_tuple(p1, 3)); + 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<tuple<int*, size_t> >:: - Copy(make_tuple(static_cast<int*>(a1), 3)); + 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]); @@ -712,6 +654,113 @@ TEST(StlContainerViewTest, WorksForDynamicNativeArray) { 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)); +} + +TEST(Base64Unescape, InvalidString) { + std::string unescaped; + EXPECT_FALSE(Base64Unescape("(invalid)", &unescaped)); +} + +TEST(Base64Unescape, ShortString) { + std::string unescaped; + EXPECT_TRUE(Base64Unescape("SGVsbG8gd29ybGQh", &unescaped)); + EXPECT_EQ("Hello world!", unescaped); +} + +TEST(Base64Unescape, ShortStringWithPadding) { + std::string unescaped; + EXPECT_TRUE(Base64Unescape("SGVsbG8gd29ybGQ=", &unescaped)); + EXPECT_EQ("Hello world", unescaped); +} + +TEST(Base64Unescape, ShortStringWithoutPadding) { + std::string unescaped; + EXPECT_TRUE(Base64Unescape("SGVsbG8gd29ybGQ", &unescaped)); + EXPECT_EQ("Hello world", unescaped); +} + +TEST(Base64Unescape, LongStringWithWhiteSpaces) { + std::string escaped = + R"(TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz + IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg + dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu + dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo + ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=)"; + std::string expected = + "Man is distinguished, not only by his reason, but by this singular " + "passion from other animals, which is a lust of the mind, that by a " + "perseverance of delight in the continued and indefatigable generation " + "of knowledge, exceeds the short vehemence of any carnal pleasure."; + std::string unescaped; + EXPECT_TRUE(Base64Unescape(escaped, &unescaped)); + EXPECT_EQ(expected, unescaped); +} + } // namespace } // namespace internal } // namespace testing diff --git a/contrib/googletest/googlemock/test/gmock-matchers-arithmetic_test.cc b/contrib/googletest/googlemock/test/gmock-matchers-arithmetic_test.cc new file mode 100644 index 000000000000..f176962855ea --- /dev/null +++ b/contrib/googletest/googlemock/test/gmock-matchers-arithmetic_test.cc @@ -0,0 +1,1516 @@ +// 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. + +#include <cmath> +#include <limits> +#include <memory> +#include <string> + +#include "test/gmock-matchers_test.h" + +// Silence warning C4244: 'initializing': conversion from 'int' to 'short', +// possible loss of data and C4100, unreferenced local parameter +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4244 4100) + +namespace testing { +namespace gmock_matchers_test { +namespace { + +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)); +} + +INSTANTIATE_GTEST_MATCHER_TEST_P(AllOfTest); + +// 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_P(AllOfTestP, 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))); +} + +INSTANTIATE_GTEST_MATCHER_TEST_P(AnyOfTest); + +// 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")); +} + +TEST(ConditionalTest, MatchesFirstIfCondition) { + Matcher<std::string> eq_red = Eq("red"); + Matcher<std::string> ne_red = Ne("red"); + Matcher<std::string> m = Conditional(true, eq_red, ne_red); + EXPECT_TRUE(m.Matches("red")); + EXPECT_FALSE(m.Matches("green")); + + StringMatchResultListener listener; + StringMatchResultListener expected; + EXPECT_FALSE(m.MatchAndExplain("green", &listener)); + EXPECT_FALSE(eq_red.MatchAndExplain("green", &expected)); + EXPECT_THAT(listener.str(), Eq(expected.str())); +} + +TEST(ConditionalTest, MatchesSecondIfCondition) { + Matcher<std::string> eq_red = Eq("red"); + Matcher<std::string> ne_red = Ne("red"); + Matcher<std::string> m = Conditional(false, eq_red, ne_red); + EXPECT_FALSE(m.Matches("red")); + EXPECT_TRUE(m.Matches("green")); + + StringMatchResultListener listener; + StringMatchResultListener expected; + EXPECT_FALSE(m.MatchAndExplain("red", &listener)); + EXPECT_FALSE(ne_red.MatchAndExplain("red", &expected)); + EXPECT_THAT(listener.str(), Eq(expected.str())); +} + +// 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_P(AnyOfTestP, 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(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() = default; + + MOCK_METHOD2(Helper, int(char x, int y)); + + private: + AllArgsHelper(const AllArgsHelper&) = delete; + AllArgsHelper& operator=(const AllArgsHelper&) = delete; +}; + +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() = default; + + 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: + OptionalMatchersHelper(const OptionalMatchersHelper&) = delete; + OptionalMatchersHelper& operator=(const OptionalMatchersHelper&) = delete; +}; + +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 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_(std::numeric_limits<RawType>::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(NotTest, WorksOnMoveOnlyType) { + std::unique_ptr<int> p(new int(3)); + EXPECT_THAT(p, Pointee(Eq(3))); + EXPECT_THAT(p, Not(Pointee(Eq(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))))); +} + +} // namespace +} // namespace gmock_matchers_test +} // namespace testing + +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4244 4100 diff --git a/contrib/googletest/googlemock/test/gmock-matchers-comparisons_test.cc b/contrib/googletest/googlemock/test/gmock-matchers-comparisons_test.cc new file mode 100644 index 000000000000..fe7e1811ef0b --- /dev/null +++ b/contrib/googletest/googlemock/test/gmock-matchers-comparisons_test.cc @@ -0,0 +1,2371 @@ +// 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. + +#include <functional> +#include <memory> +#include <string> +#include <tuple> +#include <vector> + +#include "test/gmock-matchers_test.h" + +// Silence warning C4244: 'initializing': conversion from 'int' to 'short', +// possible loss of data and C4100, unreferenced local parameter +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4244 4100) + + +namespace testing { +namespace gmock_matchers_test { +namespace { + +INSTANTIATE_GTEST_MATCHER_TEST_P(MonotonicMatcherTest); + +TEST_P(MonotonicMatcherTestP, 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)); +} + +INSTANTIATE_GTEST_MATCHER_TEST_P(MatcherTest); + +// 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_P(MatcherTestP, 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 = new EvenMatcherImpl; + 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')); +} + +INSTANTIATE_GTEST_MATCHER_TEST_P(MatcherCastTest); + +// Tests that MatcherCast<T>(m) works when m is a polymorphic matcher. +TEST_P(MatcherCastTestP, FromPolymorphicMatcher) { + Matcher<int16_t> m; + if (use_gtest_matcher_) { + m = MatcherCast<int16_t>(GtestGreaterThan(int64_t{5})); + } else { + m = MatcherCast<int16_t>(Gt(int64_t{5})); + } + EXPECT_TRUE(m.Matches(6)); + EXPECT_FALSE(m.Matches(4)); +} + +// 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() = default; + Base() = default; + + private: + Base(const Base&) = delete; + Base& operator=(const Base&) = delete; +}; + +class Derived : public Base { + public: + Derived() : Base() {} + int i; +}; + +class OtherDerived : public Base {}; + +INSTANTIATE_GTEST_MATCHER_TEST_P(SafeMatcherCastTest); + +// Tests that SafeMatcherCast<T>(m) works when m is a polymorphic matcher. +TEST_P(SafeMatcherCastTestP, FromPolymorphicMatcher) { + Matcher<char> m2; + if (use_gtest_matcher_) { + m2 = SafeMatcherCast<char>(GtestGreaterThan(32)); + } else { + m2 = SafeMatcherCast<char>(Gt(32)); + } + EXPECT_TRUE(m2.Matches('A')); + 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) { + // Verifies 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)); +} + +TEST(IsEmptyTest, MatchesContainer) { + const Matcher<std::vector<int>> m = IsEmpty(); + std::vector<int> a = {}; + std::vector<int> b = {1}; + EXPECT_TRUE(m.Matches(a)); + EXPECT_FALSE(m.Matches(b)); +} + +TEST(IsEmptyTest, MatchesStdString) { + const Matcher<std::string> m = IsEmpty(); + std::string a = "z"; + std::string b = ""; + EXPECT_FALSE(m.Matches(a)); + EXPECT_TRUE(m.Matches(b)); +} + +TEST(IsEmptyTest, MatchesCString) { + const Matcher<const char*> m = IsEmpty(); + const char a[] = ""; + const char b[] = "x"; + EXPECT_TRUE(m.Matches(a)); + EXPECT_FALSE(m.Matches(b)); +} + +// 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)); +} + +INSTANTIATE_GTEST_MATCHER_TEST_P(KeyTest); + +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_P(KeyTestP, 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))); +} + +INSTANTIATE_GTEST_MATCHER_TEST_P(PairTest); + +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_P(PairTestP, 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' doesn't 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 = std::make_unique<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, _)))); +} + +INSTANTIATE_GTEST_MATCHER_TEST_P(FieldsAreTest); + +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_P(FieldsAreTestP, 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)); + struct MyVarType17 { + int a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q; + }; + EXPECT_THAT(MyVarType17{}, + FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + struct MyVarType18 { + int a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r; + }; + EXPECT_THAT(MyVarType18{}, + FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + struct MyVarType19 { + int a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s; + }; + EXPECT_THAT(MyVarType19{}, FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0)); +} +#endif + +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 WhenBase64Unescaped. + +TEST(WhenBase64UnescapedTest, MatchesUnescapedBase64Strings) { + const Matcher<const char*> m1 = WhenBase64Unescaped(EndsWith("!")); + EXPECT_FALSE(m1.Matches("invalid base64")); + EXPECT_FALSE(m1.Matches("aGVsbG8gd29ybGQ=")); // hello world + EXPECT_TRUE(m1.Matches("aGVsbG8gd29ybGQh")); // hello world! + EXPECT_TRUE(m1.Matches("+/-_IQ")); // \xfb\xff\xbf! + + const Matcher<const std::string&> m2 = WhenBase64Unescaped(EndsWith("!")); + EXPECT_FALSE(m2.Matches("invalid base64")); + EXPECT_FALSE(m2.Matches("aGVsbG8gd29ybGQ=")); // hello world + EXPECT_TRUE(m2.Matches("aGVsbG8gd29ybGQh")); // hello world! + EXPECT_TRUE(m2.Matches("+/-_IQ")); // \xfb\xff\xbf! + +#if GTEST_INTERNAL_HAS_STRING_VIEW + const Matcher<const internal::StringView&> m3 = + WhenBase64Unescaped(EndsWith("!")); + EXPECT_FALSE(m3.Matches("invalid base64")); + EXPECT_FALSE(m3.Matches("aGVsbG8gd29ybGQ=")); // hello world + EXPECT_TRUE(m3.Matches("aGVsbG8gd29ybGQh")); // hello world! + EXPECT_TRUE(m3.Matches("+/-_IQ")); // \xfb\xff\xbf! +#endif // GTEST_INTERNAL_HAS_STRING_VIEW +} + +TEST(WhenBase64UnescapedTest, CanDescribeSelf) { + const Matcher<const char*> m = WhenBase64Unescaped(EndsWith("!")); + EXPECT_EQ("matches after Base64Unescape ends with \"!\"", 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 + +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)); +} + +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; + + // This testcase fails on FreeBSD. See this GitHub issue for more details: + // https://github.com/google/googletest/issues/2172 +#ifdef __FreeBSD__ + EXPECT_NONFATAL_FAILURE({ +#endif + // 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()))); +#ifdef __FreeBSD__ + }, ""); +#endif +} + +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 + +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)); +} + +INSTANTIATE_GTEST_MATCHER_TEST_P(ExplainmatcherResultTest); + +TEST_P(ExplainmatcherResultTestP, MonomorphicMatcher) { + const Matcher<int> m = GreaterThan(5); + EXPECT_EQ("which is 1 more than 5", Explain(m, 6)); +} + +// 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()); +} + +} // namespace +} // namespace gmock_matchers_test +} // namespace testing + +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4244 4100 diff --git a/contrib/googletest/googlemock/test/gmock-matchers-containers_test.cc b/contrib/googletest/googlemock/test/gmock-matchers-containers_test.cc new file mode 100644 index 000000000000..38fd9a5dd76f --- /dev/null +++ b/contrib/googletest/googlemock/test/gmock-matchers-containers_test.cc @@ -0,0 +1,3137 @@ +// 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. + +#include <algorithm> +#include <array> +#include <deque> +#include <forward_list> +#include <iterator> +#include <list> +#include <memory> +#include <ostream> +#include <string> +#include <tuple> +#include <vector> + +#include "gtest/gtest.h" + +// Silence warning C4244: 'initializing': conversion from 'int' to 'short', +// possible loss of data and C4100, unreferenced local parameter +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4244 4100) + +#include "test/gmock-matchers_test.h" + +namespace testing { +namespace gmock_matchers_test { +namespace { + +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; +} + +std::string OfType(const std::string& type_name) { +#if GTEST_HAS_RTTI + return IsReadableTypeName(type_name) ? " (of type " + type_name + ")" : ""; +#else + return ""; +#endif +} + +TEST(ContainsTest, WorksWithMoveOnly) { + ContainerHelper helper; + EXPECT_CALL(helper, Call(Contains(Pointee(2)))); + helper.Call(MakeUniquePtrs({1, 2})); +} + +INSTANTIATE_GTEST_MATCHER_TEST_P(ElementsAreTest); + +// 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 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")); +} + +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)); +} + +// 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_; +}; + +INSTANTIATE_GTEST_MATCHER_TEST_P(PointeeTest); + +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_P(PointeeTestP, 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_; + Uncopyable(const Uncopyable&) = delete; + Uncopyable& operator=(const Uncopyable&) = delete; +}; + +// 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; +}; + +INSTANTIATE_GTEST_MATCHER_TEST_P(FieldTest); + +// 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_P(FieldTestP, 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_P(FieldTestP, 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)); +} + +INSTANTIATE_GTEST_MATCHER_TEST_P(FieldForPointerTest); + +// 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_P(FieldForPointerTestP, 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_P(FieldForPointerTestP, 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_; +}; + +INSTANTIATE_GTEST_MATCHER_TEST_P(PropertyTest); + +// 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_P(PropertyTestP, 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_P(PropertyTestP, 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)); +} + +INSTANTIATE_GTEST_MATCHER_TEST_P(PropertyForPointerTest); + +// 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_P(PropertyForPointerTestP, 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_P(PropertyForPointerTestP, 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"; +} + +INSTANTIATE_GTEST_MATCHER_TEST_P(ResultOfTest); + +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 describe itself when provided a result description. +TEST(ResultOfTest, CanDescribeItselfWithResultDescription) { + Matcher<int> matcher = + ResultOf("string conversion", &IntToStringFunction, StrEq("foo")); + + EXPECT_EQ("whose string conversion is equal to \"foo\"", Describe(matcher)); + EXPECT_EQ("whose string conversion 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_P(ResultOfTestP, 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)); +} + +TEST_P(ResultOfTestP, CanExplainMatchResultWithResultDescription) { + Matcher<int> matcher = ResultOf("magic int conversion", &IntFunction, Ge(85)); + EXPECT_EQ("whose magic int conversion is 90" + OfType("int"), + Explain(matcher, 36)); + + matcher = ResultOf("magic int conversion", &IntFunction, GreaterThan(85)); + EXPECT_EQ("whose magic int conversion is 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)); +} + +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("has a size that is equal to 2", Describe(m)); + EXPECT_EQ("has a size that 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)); +} + +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: + using iterator_category = std::input_iterator_tag; + using value_type = T; + using difference_type = ptrdiff_t; + using pointer = const value_type*; + using reference = const value_type&; + + 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++); + } +} + +INSTANTIATE_GTEST_MATCHER_TEST_P(BeginEndDistanceIsTest); + +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_P(BeginEndDistanceIsTestP, 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[] = {false, true, false, true, true}; + const bool b[] = {true, false, true, true, false}; + 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")); +} + +// Tests Each(). + +INSTANTIATE_GTEST_MATCHER_TEST_P(EachTest); + +TEST_P(EachTestP, 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})); +} + +TEST(PointeeTest, WorksOnMoveOnlyType) { + std::unique_ptr<int> p(new int(3)); + EXPECT_THAT(p, Pointee(Eq(3))); + EXPECT_THAT(p, Not(Pointee(Eq(2)))); +} + +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, CanDescribeNegationOfExpectingOneElement) { + 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_P(ElementsAreTestP, 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_P(ElementsAreTestP, 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() = default; + + MOCK_METHOD(void, Helper, (int* array, int size)); + + private: + NativeArrayPassedAsPointerAndSize(const NativeArrayPassedAsPointerAndSize&) = + delete; + NativeArrayPassedAsPointerAndSize& operator=( + const NativeArrayPassedAsPointerAndSize&) = delete; +}; + +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 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 Contains(). + +INSTANTIATE_GTEST_MATCHER_TEST_P(ContainsTest); + +TEST(ContainsTest, ListMatchesWhenElementIsInContainer) { + list<int> some_list; + some_list.push_back(3); + some_list.push_back(1); + some_list.push_back(2); + some_list.push_back(3); + 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_P(ContainsTestP, 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)))); +} + +} // namespace +} // namespace gmock_matchers_test +} // namespace testing + +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4244 4100 diff --git a/contrib/googletest/googlemock/test/gmock-matchers-misc_test.cc b/contrib/googletest/googlemock/test/gmock-matchers-misc_test.cc new file mode 100644 index 000000000000..b8f64587db14 --- /dev/null +++ b/contrib/googletest/googlemock/test/gmock-matchers-misc_test.cc @@ -0,0 +1,1823 @@ +// 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. + +#include <array> +#include <memory> +#include <ostream> +#include <string> +#include <tuple> +#include <utility> +#include <vector> + +#include "gtest/gtest.h" + +// Silence warning C4244: 'initializing': conversion from 'int' to 'short', +// possible loss of data and C4100, unreferenced local parameter +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4244 4100) + +#include "test/gmock-matchers_test.h" + +namespace testing { +namespace gmock_matchers_test { +namespace { + +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)); +} + +// 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_; + + NotCopyable(const NotCopyable&) = delete; + NotCopyable& operator=(const NotCopyable&) = delete; +}; + +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())); +} + +#ifdef 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); +} + +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_GET(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())); + + EXPECT_EQ("equals (a: 5)", + FormatMatcherDescription(false, "Equals", {"a"}, {"5"})); + + EXPECT_EQ( + "is in range (a: 5, b: 8)", + FormatMatcherDescription(false, "IsInRange", {"a", "b"}, {"5", "8"})); +} + +INSTANTIATE_GTEST_MATCHER_TEST_P(MatcherTupleTest); + +TEST_P(MatcherTupleTestP, 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. +} + +// 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"); +} + +// 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(short{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(short{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(short{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(short{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))); +} + +// 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 (n: 5)", Describe(m)); + EXPECT_EQ("not (is greater than 32 and (n: 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 (n: 5)", Describe(m)); + EXPECT_EQ("not (is greater than 32 and (n: 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 (variable: 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 (variable1: 1-byte object <31>, variable2: 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 (low: 10, hi: 20)", Describe(m)); + EXPECT_EQ("not (is not in closed range (low: 10, hi: 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().Times(). + +INSTANTIATE_GTEST_MATCHER_TEST_P(ContainsTimes); + +TEST(ContainsTimes, ListMatchesWhenElementQuantityMatches) { + list<int> some_list; + some_list.push_back(3); + some_list.push_back(1); + some_list.push_back(2); + some_list.push_back(3); + EXPECT_THAT(some_list, Contains(3).Times(2)); + EXPECT_THAT(some_list, Contains(2).Times(1)); + EXPECT_THAT(some_list, Contains(Ge(2)).Times(3)); + EXPECT_THAT(some_list, Contains(Ge(2)).Times(Gt(2))); + EXPECT_THAT(some_list, Contains(4).Times(0)); + EXPECT_THAT(some_list, Contains(_).Times(4)); + EXPECT_THAT(some_list, Not(Contains(5).Times(1))); + EXPECT_THAT(some_list, Contains(5).Times(_)); // Times(_) always matches + EXPECT_THAT(some_list, Not(Contains(3).Times(1))); + EXPECT_THAT(some_list, Contains(3).Times(Not(1))); + EXPECT_THAT(list<int>{}, Not(Contains(_))); +} + +TEST_P(ContainsTimesP, ExplainsMatchResultCorrectly) { + const int a[2] = {1, 2}; + Matcher<const int(&)[2]> m = Contains(2).Times(3); + EXPECT_EQ( + "whose element #1 matches but whose match quantity of 1 does not match", + Explain(m, a)); + + m = Contains(3).Times(0); + EXPECT_EQ("has no element that matches and whose match quantity of 0 matches", + Explain(m, a)); + + m = Contains(3).Times(4); + EXPECT_EQ( + "has no element that matches and whose match quantity of 0 does not " + "match", + Explain(m, a)); + + m = Contains(2).Times(4); + EXPECT_EQ( + "whose element #1 matches but whose match quantity of 1 does not " + "match", + Explain(m, a)); + + m = Contains(GreaterThan(0)).Times(2); + EXPECT_EQ("whose elements (0, 1) match and whose match quantity of 2 matches", + Explain(m, a)); + + m = Contains(GreaterThan(10)).Times(Gt(1)); + EXPECT_EQ( + "has no element that matches and whose match quantity of 0 does not " + "match", + Explain(m, a)); + + m = Contains(GreaterThan(0)).Times(GreaterThan<size_t>(5)); + EXPECT_EQ( + "whose elements (0, 1) match but whose match quantity of 2 does not " + "match, which is 3 less than 5", + Explain(m, a)); +} + +TEST(ContainsTimes, DescribesItselfCorrectly) { + Matcher<vector<int>> m = Contains(1).Times(2); + EXPECT_EQ("quantity of elements that match is equal to 1 is equal to 2", + Describe(m)); + + Matcher<vector<int>> m2 = Not(m); + EXPECT_EQ("quantity of elements that match is equal to 1 isn't equal to 2", + Describe(m2)); +} + +// Tests AllOfArray() + +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)})); +} + +INSTANTIATE_GTEST_MATCHER_TEST_P(AnyOfArrayTest); + +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_P(AnyOfArrayTestP, ExplainsMatchResultCorrectly) { + // AnyOfArray and AllOfArray 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 positive 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)); +} + +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))); +} + +MATCHER(EnsureNoUnusedButMarkedUnusedWarning, "") { return (arg % 2) == 0; } + +TEST(MockMethodMockFunctionTest, EnsureNoUnusedButMarkedUnusedWarning) { +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic error "-Wused-but-marked-unused" +#endif + // https://github.com/google/googletest/issues/4055 + EXPECT_THAT(0, EnsureNoUnusedButMarkedUnusedWarning()); +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +} + +#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, PrintsExceptionWhat) { + EXPECT_THAT( + std::function<void()>([]() { throw std::runtime_error("ABC123XYZ"); }), + ThrowsMessage<std::runtime_error>(HasSubstr("ABC123XYZ"))); +} + +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, 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 + +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4244 4100 diff --git a/contrib/googletest/googlemock/test/gmock-matchers_test.cc b/contrib/googletest/googlemock/test/gmock-matchers_test.cc deleted file mode 100644 index 0ded4c445bd3..000000000000 --- a/contrib/googletest/googlemock/test/gmock-matchers_test.cc +++ /dev/null @@ -1,6814 +0,0 @@ -// 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. - -#include "gmock/gmock-matchers.h" -#include "gmock/gmock-more-matchers.h" - -#include <string.h> -#include <time.h> -#include <deque> -#include <functional> -#include <iostream> -#include <iterator> -#include <limits> -#include <list> -#include <map> -#include <memory> -#include <set> -#include <sstream> -#include <string> -#include <utility> -#include <vector> -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "gtest/gtest-spi.h" - -#if GTEST_HAS_STD_FORWARD_LIST_ -# include <forward_list> // NOLINT -#endif - -#if GTEST_LANG_CXX11 -# include <type_traits> -#endif - -namespace testing { -namespace gmock_matchers_test { - -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::A; -using testing::AllArgs; -using testing::AllOf; -using testing::An; -using testing::AnyOf; -using testing::ByRef; -using testing::ContainsRegex; -using testing::DoubleEq; -using testing::DoubleNear; -using testing::EndsWith; -using testing::Eq; -using testing::ExplainMatchResult; -using testing::Field; -using testing::FloatEq; -using testing::FloatNear; -using testing::Ge; -using testing::Gt; -using testing::HasSubstr; -using testing::IsEmpty; -using testing::IsNull; -using testing::Key; -using testing::Le; -using testing::Lt; -using testing::MakeMatcher; -using testing::MakePolymorphicMatcher; -using testing::MatchResultListener; -using testing::Matcher; -using testing::MatcherCast; -using testing::MatcherInterface; -using testing::Matches; -using testing::MatchesRegex; -using testing::NanSensitiveDoubleEq; -using testing::NanSensitiveDoubleNear; -using testing::NanSensitiveFloatEq; -using testing::NanSensitiveFloatNear; -using testing::Ne; -using testing::Not; -using testing::NotNull; -using testing::Pair; -using testing::Pointee; -using testing::Pointwise; -using testing::PolymorphicMatcher; -using testing::Property; -using testing::Ref; -using testing::ResultOf; -using testing::SizeIs; -using testing::StartsWith; -using testing::StrCaseEq; -using testing::StrCaseNe; -using testing::StrEq; -using testing::StrNe; -using testing::StringMatchResultListener; -using testing::Truly; -using testing::TypedEq; -using testing::UnorderedPointwise; -using testing::Value; -using testing::WhenSorted; -using testing::WhenSortedBy; -using testing::_; -using testing::get; -using testing::internal::DummyMatchResultListener; -using testing::internal::ElementMatcherPair; -using testing::internal::ElementMatcherPairs; -using testing::internal::ExplainMatchFailureTupleTo; -using testing::internal::FloatingEqMatcher; -using testing::internal::FormatMatcherDescription; -using testing::internal::IsReadableTypeName; -using testing::internal::linked_ptr; -using testing::internal::MatchMatrix; -using testing::internal::RE; -using testing::internal::scoped_ptr; -using testing::internal::StreamMatchResultListener; -using testing::internal::Strings; -using testing::internal::linked_ptr; -using testing::internal::scoped_ptr; -using testing::internal::string; -using testing::make_tuple; -using testing::tuple; - -// For testing ExplainMatchResultTo(). -class GreaterThanMatcher : public MatcherInterface<int> { - public: - explicit GreaterThanMatcher(int rhs) : rhs_(rhs) {} - - virtual void DescribeTo(ostream* os) const { - *os << "is > " << rhs_; - } - - virtual bool MatchAndExplain(int lhs, - MatchResultListener* listener) const { - const int diff = lhs - rhs_; - if (diff > 0) { - *listener << "which is " << diff << " more than " << rhs_; - } else if (diff == 0) { - *listener << "which is the same as " << rhs_; - } else { - *listener << "which is " << -diff << " less than " << rhs_; - } - - return lhs > rhs_; - } - - private: - int rhs_; -}; - -Matcher<int> GreaterThan(int n) { - return MakeMatcher(new GreaterThanMatcher(n)); -} - -std::string OfType(const std::string& type_name) { -#if GTEST_HAS_RTTI - return " (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() == NULL); - EXPECT_TRUE(StreamMatchResultListener(NULL).stream() == NULL); - - 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(NULL).IsInterested()); -} - -// Makes sure that the MatcherInterface<T> interface doesn't -// change. -class EvenMatcherImpl : public MatcherInterface<int> { - public: - virtual bool MatchAndExplain(int x, - MatchResultListener* /* listener */) const { - return x % 2 == 0; - } - - virtual void DescribeTo(ostream* os) const { - *os << "is an even number"; - } - - // We deliberately don't define DescribeNegationTo() and - // ExplainMatchResultTo() here, to make sure the definition of these - // two methods is optional. -}; - -// 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: - virtual bool MatchAndExplain(int x, MatchResultListener* listener) const { - const bool match = x % 2 == 0; - // Verifies that we can stream to a listener directly. - *listener << "value % " << 2; - if (listener->stream() != NULL) { - // Verifies that we can stream to a listener's underlying stream - // too. - *listener->stream() << " == " << (x % 2); - } - return match; - } - - virtual void DescribeTo(ostream* os) const { - *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 = NULL; - EXPECT_TRUE(m1.Matches(NULL)); - 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_HAS_GLOBAL_STRING -// Tests that a ::string object can be implicitly converted to a -// Matcher<std::string> or Matcher<const std::string&>. -TEST(StringMatcherTest, CanBeImplicitlyConstructedFromGlobalString) { - Matcher<std::string> m1 = ::string("hi"); - EXPECT_TRUE(m1.Matches("hi")); - EXPECT_FALSE(m1.Matches("hello")); - - Matcher<const std::string&> m2 = ::string("hi"); - EXPECT_TRUE(m2.Matches("hi")); - EXPECT_FALSE(m2.Matches("hello")); -} -#endif // GTEST_HAS_GLOBAL_STRING - -#if GTEST_HAS_GLOBAL_STRING -// Tests that a C-string literal can be implicitly converted to a -// Matcher<::string> or Matcher<const ::string&>. -TEST(GlobalStringMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) { - Matcher< ::string> m1 = "hi"; - EXPECT_TRUE(m1.Matches("hi")); - EXPECT_FALSE(m1.Matches("hello")); - - Matcher<const ::string&> m2 = "hi"; - EXPECT_TRUE(m2.Matches("hi")); - EXPECT_FALSE(m2.Matches("hello")); -} - -// Tests that a std::string object can be implicitly converted to a -// Matcher<::string> or Matcher<const ::string&>. -TEST(GlobalStringMatcherTest, CanBeImplicitlyConstructedFromString) { - Matcher< ::string> m1 = std::string("hi"); - EXPECT_TRUE(m1.Matches("hi")); - EXPECT_FALSE(m1.Matches("hello")); - - Matcher<const ::string&> m2 = std::string("hi"); - EXPECT_TRUE(m2.Matches("hi")); - EXPECT_FALSE(m2.Matches("hello")); -} - -// Tests that a ::string object can be implicitly converted to a -// Matcher<::string> or Matcher<const ::string&>. -TEST(GlobalStringMatcherTest, CanBeImplicitlyConstructedFromGlobalString) { - Matcher< ::string> m1 = ::string("hi"); - EXPECT_TRUE(m1.Matches("hi")); - EXPECT_FALSE(m1.Matches("hello")); - - Matcher<const ::string&> m2 = ::string("hi"); - EXPECT_TRUE(m2.Matches("hi")); - EXPECT_FALSE(m2.Matches("hello")); -} -#endif // GTEST_HAS_GLOBAL_STRING - -#if GTEST_HAS_ABSL -// Tests that a C-string literal can be implicitly converted to a -// Matcher<absl::string_view> or Matcher<const absl::string_view&>. -TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) { - Matcher<absl::string_view> m1 = "cats"; - EXPECT_TRUE(m1.Matches("cats")); - EXPECT_FALSE(m1.Matches("dogs")); - - Matcher<const absl::string_view&> 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<absl::string_view> or Matcher<const absl::string_view&>. -TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromString) { - Matcher<absl::string_view> m1 = std::string("cats"); - EXPECT_TRUE(m1.Matches("cats")); - EXPECT_FALSE(m1.Matches("dogs")); - - Matcher<const absl::string_view&> m2 = std::string("cats"); - EXPECT_TRUE(m2.Matches("cats")); - EXPECT_FALSE(m2.Matches("dogs")); -} - -#if GTEST_HAS_GLOBAL_STRING -// Tests that a ::string object can be implicitly converted to a -// Matcher<absl::string_view> or Matcher<const absl::string_view&>. -TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromGlobalString) { - Matcher<absl::string_view> m1 = ::string("cats"); - EXPECT_TRUE(m1.Matches("cats")); - EXPECT_FALSE(m1.Matches("dogs")); - - Matcher<const absl::string_view&> m2 = ::string("cats"); - EXPECT_TRUE(m2.Matches("cats")); - EXPECT_FALSE(m2.Matches("dogs")); -} -#endif // GTEST_HAS_GLOBAL_STRING - -// Tests that a absl::string_view object can be implicitly converted to a -// Matcher<absl::string_view> or Matcher<const absl::string_view&>. -TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromStringView) { - Matcher<absl::string_view> m1 = absl::string_view("cats"); - EXPECT_TRUE(m1.Matches("cats")); - EXPECT_FALSE(m1.Matches("dogs")); - - Matcher<const absl::string_view&> m2 = absl::string_view("cats"); - EXPECT_TRUE(m2.Matches("cats")); - EXPECT_FALSE(m2.Matches("dogs")); -} -#endif // GTEST_HAS_ABSL - -// Tests that MakeMatcher() constructs a Matcher<T> from a -// MatcherInterface* without requiring the user to explicitly -// write the type. -TEST(MakeMatcherTest, ConstructsMatcherFromMatcherInterface) { - const MatcherInterface<int>* dummy_impl = NULL; - Matcher<int> m = MakeMatcher(dummy_impl); -} - -// Tests that MakePolymorphicMatcher() 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() != NULL) { - // 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<int> m1 = Eq(0); - Matcher<const int&> m2 = SafeMatcherCast<const int&>(m1); - EXPECT_TRUE(m2.Matches(0)); - EXPECT_FALSE(m2.Matches(1)); -} - -// 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; } - private: - char c_; -}; - -TEST(EqTest, CanDescribeSelf) { - Matcher<Unprintable> m = Eq(Unprintable()); - EXPECT_EQ("is equal to 1-byte object <61>", Describe(m)); -} - -// Tests that Eq(v) can be used to match any type that supports -// comparing with type T, where T is v's type. -TEST(EqTest, IsPolymorphic) { - Matcher<int> m1 = Eq(1); - EXPECT_TRUE(m1.Matches(1)); - EXPECT_FALSE(m1.Matches(2)); - - Matcher<char> m2 = Eq(1); - EXPECT_TRUE(m2.Matches('\1')); - EXPECT_FALSE(m2.Matches('a')); -} - -// Tests that TypedEq<T>(v) matches values of type T that's equal to v. -TEST(TypedEqTest, ChecksEqualityForGivenType) { - Matcher<char> m1 = TypedEq<char>('a'); - EXPECT_TRUE(m1.Matches('a')); - EXPECT_FALSE(m1.Matches('b')); - - Matcher<int> m2 = TypedEq<int>(6); - EXPECT_TRUE(m2.Matches(6)); - EXPECT_FALSE(m2.Matches(7)); -} - -// Tests that TypedEq(v) describes itself properly. -TEST(TypedEqTest, CanDescribeSelf) { - EXPECT_EQ("is equal to 2", Describe(TypedEq<int>(2))); -} - -// Tests that TypedEq<T>(v) has type Matcher<T>. - -// Type<T>::IsTypeOf(v) compiles iff the type of value v is T, where T -// is a "bare" type (i.e. not in the form of const U or U&). If v's -// type is not T, the compiler will generate a message about -// "undefined 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)); -} - -// Tests that IsNull() matches any NULL pointer of any type. -TEST(IsNullTest, MatchesNullPointer) { - Matcher<int*> m1 = IsNull(); - int* p1 = NULL; - int n = 0; - EXPECT_TRUE(m1.Matches(p1)); - EXPECT_FALSE(m1.Matches(&n)); - - Matcher<const char*> m2 = IsNull(); - const char* p2 = NULL; - EXPECT_TRUE(m2.Matches(p2)); - EXPECT_FALSE(m2.Matches("hi")); - -#if !GTEST_OS_SYMBIAN - // Nokia's Symbian compiler generates: - // gmock-matchers.h: ambiguous access to overloaded function - // gmock-matchers.h: 'testing::Matcher<void *>::Matcher(void *)' - // gmock-matchers.h: 'testing::Matcher<void *>::Matcher(const testing:: - // MatcherInterface<void *> *)' - // gmock-matchers.h: (point of instantiation: 'testing:: - // gmock_matchers_test::IsNullTest_MatchesNullPointer_Test::TestBody()') - // gmock-matchers.h: (instantiating: 'testing::PolymorphicMatc - Matcher<void*> m3 = IsNull(); - void* p3 = NULL; - EXPECT_TRUE(m3.Matches(p3)); - EXPECT_FALSE(m3.Matches(reinterpret_cast<void*>(0xbeef))); -#endif -} - -TEST(IsNullTest, LinkedPtr) { - const Matcher<linked_ptr<int> > m = IsNull(); - const linked_ptr<int> null_p; - const linked_ptr<int> non_null_p(new int); - - EXPECT_TRUE(m.Matches(null_p)); - EXPECT_FALSE(m.Matches(non_null_p)); -} - -TEST(IsNullTest, ReferenceToConstLinkedPtr) { - const Matcher<const linked_ptr<double>&> m = IsNull(); - const linked_ptr<double> null_p; - const linked_ptr<double> non_null_p(new double); - - EXPECT_TRUE(m.Matches(null_p)); - EXPECT_FALSE(m.Matches(non_null_p)); -} - -#if GTEST_LANG_CXX11 -TEST(IsNullTest, StdFunction) { - const Matcher<std::function<void()>> m = IsNull(); - - EXPECT_TRUE(m.Matches(std::function<void()>())); - EXPECT_FALSE(m.Matches([]{})); -} -#endif // GTEST_LANG_CXX11 - -// 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 = NULL; - int n = 0; - EXPECT_FALSE(m1.Matches(p1)); - EXPECT_TRUE(m1.Matches(&n)); - - Matcher<const char*> m2 = NotNull(); - const char* p2 = NULL; - EXPECT_FALSE(m2.Matches(p2)); - EXPECT_TRUE(m2.Matches("hi")); -} - -TEST(NotNullTest, LinkedPtr) { - const Matcher<linked_ptr<int> > m = NotNull(); - const linked_ptr<int> null_p; - const linked_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 linked_ptr<double>&> m = NotNull(); - const linked_ptr<double> null_p; - const linked_ptr<double> non_null_p(new double); - - EXPECT_FALSE(m.Matches(null_p)); - EXPECT_TRUE(m.Matches(non_null_p)); -} - -#if GTEST_LANG_CXX11 -TEST(NotNullTest, StdFunction) { - const Matcher<std::function<void()>> m = NotNull(); - - EXPECT_TRUE(m.Matches([]{})); - EXPECT_FALSE(m.Matches(std::function<void()>())); -} -#endif // GTEST_LANG_CXX11 - -// 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. - -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(NULL)); - - Matcher<const std::string&> m2 = StrEq("Hello"); - EXPECT_TRUE(m2.Matches("Hello")); - EXPECT_FALSE(m2.Matches("Hi")); - -#if GTEST_HAS_ABSL - Matcher<const absl::string_view&> m3 = StrEq("Hello"); - EXPECT_TRUE(m3.Matches(absl::string_view("Hello"))); - EXPECT_FALSE(m3.Matches(absl::string_view("hello"))); - EXPECT_FALSE(m3.Matches(absl::string_view())); -#endif // GTEST_HAS_ABSL -} - -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(NULL)); - 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_HAS_ABSL - Matcher<const absl::string_view> m3 = StrNe("Hello"); - EXPECT_TRUE(m3.Matches(absl::string_view(""))); - EXPECT_TRUE(m3.Matches(absl::string_view())); - EXPECT_FALSE(m3.Matches(absl::string_view("Hello"))); -#endif // GTEST_HAS_ABSL -} - -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(NULL)); - - Matcher<const std::string&> m2 = StrCaseEq("Hello"); - EXPECT_TRUE(m2.Matches("hello")); - EXPECT_FALSE(m2.Matches("Hi")); - -#if GTEST_HAS_ABSL - Matcher<const absl::string_view&> m3 = StrCaseEq(std::string("Hello")); - EXPECT_TRUE(m3.Matches(absl::string_view("Hello"))); - EXPECT_TRUE(m3.Matches(absl::string_view("hello"))); - EXPECT_FALSE(m3.Matches(absl::string_view("Hi"))); - EXPECT_FALSE(m3.Matches(absl::string_view())); -#endif // GTEST_HAS_ABSL -} - -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(NULL)); - 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_HAS_ABSL - Matcher<const absl::string_view> m3 = StrCaseNe("Hello"); - EXPECT_TRUE(m3.Matches(absl::string_view("Hi"))); - EXPECT_TRUE(m3.Matches(absl::string_view())); - EXPECT_FALSE(m3.Matches(absl::string_view("Hello"))); - EXPECT_FALSE(m3.Matches(absl::string_view("hello"))); -#endif // GTEST_HAS_ABSL -} - -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"))); -} - -// Tests that HasSubstr() works for matching C-string-typed values. -TEST(HasSubstrTest, WorksForCStrings) { - const Matcher<char*> m1 = HasSubstr("foo"); - EXPECT_TRUE(m1.Matches(const_cast<char*>("I love food."))); - EXPECT_FALSE(m1.Matches(const_cast<char*>("tofo"))); - EXPECT_FALSE(m1.Matches(NULL)); - - const Matcher<const char*> m2 = HasSubstr("foo"); - EXPECT_TRUE(m2.Matches("I love food.")); - EXPECT_FALSE(m2.Matches("tofo")); - EXPECT_FALSE(m2.Matches(NULL)); -} - -#if GTEST_HAS_ABSL -// Tests that HasSubstr() works for matching absl::string_view-typed values. -TEST(HasSubstrTest, WorksForStringViewClasses) { - const Matcher<absl::string_view> m1 = HasSubstr("foo"); - EXPECT_TRUE(m1.Matches(absl::string_view("I love food."))); - EXPECT_FALSE(m1.Matches(absl::string_view("tofo"))); - EXPECT_FALSE(m1.Matches(absl::string_view())); - - const Matcher<const absl::string_view&> m2 = HasSubstr("foo"); - EXPECT_TRUE(m2.Matches(absl::string_view("I love food."))); - EXPECT_FALSE(m2.Matches(absl::string_view("tofo"))); - EXPECT_FALSE(m2.Matches(absl::string_view())); - - const Matcher<const absl::string_view&> m3 = HasSubstr(""); - EXPECT_TRUE(m3.Matches(absl::string_view("foo"))); - EXPECT_FALSE(m3.Matches(absl::string_view())); -} -#endif // GTEST_HAS_ABSL - -// 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)))); -} - -#if GTEST_LANG_CXX11 -template <size_t I> -struct Tag {}; - -struct PairWithGet { - int member_1; - string member_2; - using first_type = int; - using second_type = string; - - const int& GetImpl(Tag<0>) const { return member_1; } - const 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))); -} -#endif // GTEST_LANG_CXX11 - -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, 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, _)))); -} - -#if GTEST_LANG_CXX11 -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, string("Foo")), Pair(Ge(10), Not("")))); -} -#endif // GTEST_LANG_CXX11 - -// 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(NULL)); - - 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")); -} - -TEST(StartsWithTest, CanDescribeSelf) { - Matcher<const std::string> m = StartsWith("Hi"); - EXPECT_EQ("starts with \"Hi\"", Describe(m)); -} - -// Tests EndsWith(s). - -TEST(EndsWithTest, MatchesStringWithGivenSuffix) { - const Matcher<const char*> m1 = EndsWith(""); - EXPECT_TRUE(m1.Matches("Hi")); - EXPECT_TRUE(m1.Matches("")); - EXPECT_FALSE(m1.Matches(NULL)); - - const Matcher<const 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_HAS_GLOBAL_STRING - const Matcher<const ::string&> m3 = EndsWith(::string("Hi")); - EXPECT_TRUE(m3.Matches("Hi")); - EXPECT_TRUE(m3.Matches("Wow Hi Hi")); - EXPECT_TRUE(m3.Matches("Super Hi")); - EXPECT_FALSE(m3.Matches("i")); - EXPECT_FALSE(m3.Matches("Hi ")); -#endif // GTEST_HAS_GLOBAL_STRING - -#if GTEST_HAS_ABSL - const Matcher<const absl::string_view&> m4 = EndsWith(""); - EXPECT_TRUE(m4.Matches("Hi")); - EXPECT_TRUE(m4.Matches("")); - // Default-constructed absl::string_view should not match anything, in order - // to distinguish it from an empty string. - EXPECT_FALSE(m4.Matches(absl::string_view())); -#endif // GTEST_HAS_ABSL -} - -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(NULL)); - - 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_HAS_ABSL - const Matcher<const absl::string_view&> m3 = MatchesRegex("a.*z"); - EXPECT_TRUE(m3.Matches(absl::string_view("az"))); - EXPECT_TRUE(m3.Matches(absl::string_view("abcz"))); - EXPECT_FALSE(m3.Matches(absl::string_view("1az"))); - // Default-constructed absl::string_view should not match anything, in order - // to distinguish it from an empty string. - EXPECT_FALSE(m3.Matches(absl::string_view())); - const Matcher<const absl::string_view&> m4 = MatchesRegex(""); - EXPECT_FALSE(m4.Matches(absl::string_view())); -#endif // GTEST_HAS_ABSL -} - -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_HAS_ABSL - Matcher<const absl::string_view> m3 = MatchesRegex(new RE("0.*")); - EXPECT_EQ("matches regular expression \"0.*\"", Describe(m3)); -#endif // GTEST_HAS_ABSL -} - -// 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(NULL)); - - 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_HAS_ABSL - const Matcher<const absl::string_view&> m3 = ContainsRegex(new RE("a.*z")); - EXPECT_TRUE(m3.Matches(absl::string_view("azbz"))); - EXPECT_TRUE(m3.Matches(absl::string_view("az1"))); - EXPECT_FALSE(m3.Matches(absl::string_view("1a"))); - // Default-constructed absl::string_view should not match anything, in order - // to distinguish it from an empty string. - EXPECT_FALSE(m3.Matches(absl::string_view())); - const Matcher<const absl::string_view&> m4 = ContainsRegex(""); - EXPECT_FALSE(m4.Matches(absl::string_view())); -#endif // GTEST_HAS_ABSL -} - -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_HAS_ABSL - Matcher<const absl::string_view> m3 = ContainsRegex(new RE("0.*")); - EXPECT_EQ("contains regular expression \"0.*\"", Describe(m3)); -#endif // GTEST_HAS_ABSL -} - -// Tests for wide strings. -#if GTEST_HAS_STD_WSTRING -TEST(StdWideStrEqTest, MatchesEqual) { - Matcher<const wchar_t*> m = StrEq(::std::wstring(L"Hello")); - EXPECT_TRUE(m.Matches(L"Hello")); - EXPECT_FALSE(m.Matches(L"hello")); - EXPECT_FALSE(m.Matches(NULL)); - - Matcher<const ::std::wstring&> m2 = StrEq(L"Hello"); - EXPECT_TRUE(m2.Matches(L"Hello")); - EXPECT_FALSE(m2.Matches(L"Hi")); - - Matcher<const ::std::wstring&> m3 = StrEq(L"\xD3\x576\x8D3\xC74D"); - EXPECT_TRUE(m3.Matches(L"\xD3\x576\x8D3\xC74D")); - EXPECT_FALSE(m3.Matches(L"\xD3\x576\x8D3\xC74E")); - - ::std::wstring str(L"01204500800"); - str[3] = L'\0'; - Matcher<const ::std::wstring&> m4 = StrEq(str); - EXPECT_TRUE(m4.Matches(str)); - str[0] = str[6] = str[7] = str[9] = str[10] = L'\0'; - Matcher<const ::std::wstring&> m5 = StrEq(str); - EXPECT_TRUE(m5.Matches(str)); -} - -TEST(StdWideStrEqTest, CanDescribeSelf) { - Matcher< ::std::wstring> m = StrEq(L"Hi-\'\"?\\\a\b\f\n\r\t\v"); - EXPECT_EQ("is equal to L\"Hi-\'\\\"?\\\\\\a\\b\\f\\n\\r\\t\\v\"", - Describe(m)); - - Matcher< ::std::wstring> m2 = StrEq(L"\xD3\x576\x8D3\xC74D"); - EXPECT_EQ("is equal to L\"\\xD3\\x576\\x8D3\\xC74D\"", - Describe(m2)); - - ::std::wstring str(L"01204500800"); - str[3] = L'\0'; - Matcher<const ::std::wstring&> m4 = StrEq(str); - EXPECT_EQ("is equal to L\"012\\04500800\"", Describe(m4)); - str[0] = str[6] = str[7] = str[9] = str[10] = L'\0'; - Matcher<const ::std::wstring&> m5 = StrEq(str); - EXPECT_EQ("is equal to L\"\\012\\045\\0\\08\\0\\0\"", Describe(m5)); -} - -TEST(StdWideStrNeTest, MatchesUnequalString) { - Matcher<const wchar_t*> m = StrNe(L"Hello"); - EXPECT_TRUE(m.Matches(L"")); - EXPECT_TRUE(m.Matches(NULL)); - EXPECT_FALSE(m.Matches(L"Hello")); - - Matcher< ::std::wstring> m2 = StrNe(::std::wstring(L"Hello")); - EXPECT_TRUE(m2.Matches(L"hello")); - EXPECT_FALSE(m2.Matches(L"Hello")); -} - -TEST(StdWideStrNeTest, CanDescribeSelf) { - Matcher<const wchar_t*> m = StrNe(L"Hi"); - EXPECT_EQ("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(NULL)); - - Matcher<const ::std::wstring&> m2 = StrCaseEq(L"Hello"); - EXPECT_TRUE(m2.Matches(L"hello")); - EXPECT_FALSE(m2.Matches(L"Hi")); -} - -TEST(StdWideStrCaseEqTest, MatchesEqualStringWith0IgnoringCase) { - ::std::wstring str1(L"oabocdooeoo"); - ::std::wstring str2(L"OABOCDOOEOO"); - Matcher<const ::std::wstring&> m0 = StrCaseEq(str1); - EXPECT_FALSE(m0.Matches(str2 + ::std::wstring(1, L'\0'))); - - str1[3] = str2[3] = L'\0'; - Matcher<const ::std::wstring&> m1 = StrCaseEq(str1); - EXPECT_TRUE(m1.Matches(str2)); - - str1[0] = str1[6] = str1[7] = str1[10] = L'\0'; - str2[0] = str2[6] = str2[7] = str2[10] = L'\0'; - Matcher<const ::std::wstring&> m2 = StrCaseEq(str1); - str1[9] = str2[9] = L'\0'; - EXPECT_FALSE(m2.Matches(str2)); - - Matcher<const ::std::wstring&> m3 = StrCaseEq(str1); - EXPECT_TRUE(m3.Matches(str2)); - - EXPECT_FALSE(m3.Matches(str2 + L"x")); - str2.append(1, L'\0'); - EXPECT_FALSE(m3.Matches(str2)); - EXPECT_FALSE(m3.Matches(::std::wstring(str2, 0, 9))); -} - -TEST(StdWideStrCaseEqTest, CanDescribeSelf) { - Matcher< ::std::wstring> m = StrCaseEq(L"Hi"); - EXPECT_EQ("is equal to (ignoring case) L\"Hi\"", Describe(m)); -} - -TEST(StdWideStrCaseNeTest, MatchesUnequalStringIgnoringCase) { - Matcher<const wchar_t*> m = StrCaseNe(L"Hello"); - EXPECT_TRUE(m.Matches(L"Hi")); - EXPECT_TRUE(m.Matches(NULL)); - EXPECT_FALSE(m.Matches(L"Hello")); - EXPECT_FALSE(m.Matches(L"hello")); - - Matcher< ::std::wstring> m2 = StrCaseNe(::std::wstring(L"Hello")); - EXPECT_TRUE(m2.Matches(L"")); - EXPECT_FALSE(m2.Matches(L"Hello")); -} - -TEST(StdWideStrCaseNeTest, CanDescribeSelf) { - Matcher<const wchar_t*> m = StrCaseNe(L"Hi"); - EXPECT_EQ("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(NULL)); - - const Matcher<const wchar_t*> m2 = HasSubstr(L"foo"); - EXPECT_TRUE(m2.Matches(L"I love food.")); - EXPECT_FALSE(m2.Matches(L"tofo")); - EXPECT_FALSE(m2.Matches(NULL)); -} - -// Tests that HasSubstr(s) describes itself properly. -TEST(StdWideHasSubstrTest, CanDescribeSelf) { - Matcher< ::std::wstring> m = HasSubstr(L"foo\n\""); - EXPECT_EQ("has substring L\"foo\\n\\\"\"", Describe(m)); -} - -// Tests StartsWith(s). - -TEST(StdWideStartsWithTest, MatchesStringWithGivenPrefix) { - const Matcher<const wchar_t*> m1 = StartsWith(::std::wstring(L"")); - EXPECT_TRUE(m1.Matches(L"Hi")); - EXPECT_TRUE(m1.Matches(L"")); - EXPECT_FALSE(m1.Matches(NULL)); - - const Matcher<const ::std::wstring&> m2 = StartsWith(L"Hi"); - EXPECT_TRUE(m2.Matches(L"Hi")); - EXPECT_TRUE(m2.Matches(L"Hi Hi!")); - EXPECT_TRUE(m2.Matches(L"High")); - EXPECT_FALSE(m2.Matches(L"H")); - EXPECT_FALSE(m2.Matches(L" Hi")); -} - -TEST(StdWideStartsWithTest, CanDescribeSelf) { - Matcher<const ::std::wstring> m = StartsWith(L"Hi"); - EXPECT_EQ("starts with L\"Hi\"", Describe(m)); -} - -// Tests EndsWith(s). - -TEST(StdWideEndsWithTest, MatchesStringWithGivenSuffix) { - const Matcher<const wchar_t*> m1 = EndsWith(L""); - EXPECT_TRUE(m1.Matches(L"Hi")); - EXPECT_TRUE(m1.Matches(L"")); - EXPECT_FALSE(m1.Matches(NULL)); - - const Matcher<const ::std::wstring&> m2 = EndsWith(::std::wstring(L"Hi")); - EXPECT_TRUE(m2.Matches(L"Hi")); - EXPECT_TRUE(m2.Matches(L"Wow Hi Hi")); - EXPECT_TRUE(m2.Matches(L"Super Hi")); - EXPECT_FALSE(m2.Matches(L"i")); - EXPECT_FALSE(m2.Matches(L"Hi ")); -} - -TEST(StdWideEndsWithTest, CanDescribeSelf) { - Matcher<const ::std::wstring> m = EndsWith(L"Hi"); - EXPECT_EQ("ends with L\"Hi\"", Describe(m)); -} - -#endif // GTEST_HAS_STD_WSTRING - -#if GTEST_HAS_GLOBAL_WSTRING -TEST(GlobalWideStrEqTest, MatchesEqual) { - Matcher<const wchar_t*> m = StrEq(::wstring(L"Hello")); - EXPECT_TRUE(m.Matches(L"Hello")); - EXPECT_FALSE(m.Matches(L"hello")); - EXPECT_FALSE(m.Matches(NULL)); - - Matcher<const ::wstring&> m2 = StrEq(L"Hello"); - EXPECT_TRUE(m2.Matches(L"Hello")); - EXPECT_FALSE(m2.Matches(L"Hi")); - - Matcher<const ::wstring&> m3 = StrEq(L"\xD3\x576\x8D3\xC74D"); - EXPECT_TRUE(m3.Matches(L"\xD3\x576\x8D3\xC74D")); - EXPECT_FALSE(m3.Matches(L"\xD3\x576\x8D3\xC74E")); - - ::wstring str(L"01204500800"); - str[3] = L'\0'; - Matcher<const ::wstring&> m4 = StrEq(str); - EXPECT_TRUE(m4.Matches(str)); - str[0] = str[6] = str[7] = str[9] = str[10] = L'\0'; - Matcher<const ::wstring&> m5 = StrEq(str); - EXPECT_TRUE(m5.Matches(str)); -} - -TEST(GlobalWideStrEqTest, CanDescribeSelf) { - Matcher< ::wstring> m = StrEq(L"Hi-\'\"?\\\a\b\f\n\r\t\v"); - EXPECT_EQ("is equal to L\"Hi-\'\\\"?\\\\\\a\\b\\f\\n\\r\\t\\v\"", - Describe(m)); - - Matcher< ::wstring> m2 = StrEq(L"\xD3\x576\x8D3\xC74D"); - EXPECT_EQ("is equal to L\"\\xD3\\x576\\x8D3\\xC74D\"", - Describe(m2)); - - ::wstring str(L"01204500800"); - str[3] = L'\0'; - Matcher<const ::wstring&> m4 = StrEq(str); - EXPECT_EQ("is equal to L\"012\\04500800\"", Describe(m4)); - str[0] = str[6] = str[7] = str[9] = str[10] = L'\0'; - Matcher<const ::wstring&> m5 = StrEq(str); - EXPECT_EQ("is equal to L\"\\012\\045\\0\\08\\0\\0\"", Describe(m5)); -} - -TEST(GlobalWideStrNeTest, MatchesUnequalString) { - Matcher<const wchar_t*> m = StrNe(L"Hello"); - EXPECT_TRUE(m.Matches(L"")); - EXPECT_TRUE(m.Matches(NULL)); - EXPECT_FALSE(m.Matches(L"Hello")); - - Matcher< ::wstring> m2 = StrNe(::wstring(L"Hello")); - EXPECT_TRUE(m2.Matches(L"hello")); - EXPECT_FALSE(m2.Matches(L"Hello")); -} - -TEST(GlobalWideStrNeTest, CanDescribeSelf) { - Matcher<const wchar_t*> m = StrNe(L"Hi"); - EXPECT_EQ("isn't equal to L\"Hi\"", Describe(m)); -} - -TEST(GlobalWideStrCaseEqTest, MatchesEqualStringIgnoringCase) { - Matcher<const wchar_t*> m = StrCaseEq(::wstring(L"Hello")); - EXPECT_TRUE(m.Matches(L"Hello")); - EXPECT_TRUE(m.Matches(L"hello")); - EXPECT_FALSE(m.Matches(L"Hi")); - EXPECT_FALSE(m.Matches(NULL)); - - Matcher<const ::wstring&> m2 = StrCaseEq(L"Hello"); - EXPECT_TRUE(m2.Matches(L"hello")); - EXPECT_FALSE(m2.Matches(L"Hi")); -} - -TEST(GlobalWideStrCaseEqTest, MatchesEqualStringWith0IgnoringCase) { - ::wstring str1(L"oabocdooeoo"); - ::wstring str2(L"OABOCDOOEOO"); - Matcher<const ::wstring&> m0 = StrCaseEq(str1); - EXPECT_FALSE(m0.Matches(str2 + ::wstring(1, L'\0'))); - - str1[3] = str2[3] = L'\0'; - Matcher<const ::wstring&> m1 = StrCaseEq(str1); - EXPECT_TRUE(m1.Matches(str2)); - - str1[0] = str1[6] = str1[7] = str1[10] = L'\0'; - str2[0] = str2[6] = str2[7] = str2[10] = L'\0'; - Matcher<const ::wstring&> m2 = StrCaseEq(str1); - str1[9] = str2[9] = L'\0'; - EXPECT_FALSE(m2.Matches(str2)); - - Matcher<const ::wstring&> m3 = StrCaseEq(str1); - EXPECT_TRUE(m3.Matches(str2)); - - EXPECT_FALSE(m3.Matches(str2 + L"x")); - str2.append(1, L'\0'); - EXPECT_FALSE(m3.Matches(str2)); - EXPECT_FALSE(m3.Matches(::wstring(str2, 0, 9))); -} - -TEST(GlobalWideStrCaseEqTest, CanDescribeSelf) { - Matcher< ::wstring> m = StrCaseEq(L"Hi"); - EXPECT_EQ("is equal to (ignoring case) L\"Hi\"", Describe(m)); -} - -TEST(GlobalWideStrCaseNeTest, MatchesUnequalStringIgnoringCase) { - Matcher<const wchar_t*> m = StrCaseNe(L"Hello"); - EXPECT_TRUE(m.Matches(L"Hi")); - EXPECT_TRUE(m.Matches(NULL)); - EXPECT_FALSE(m.Matches(L"Hello")); - EXPECT_FALSE(m.Matches(L"hello")); - - Matcher< ::wstring> m2 = StrCaseNe(::wstring(L"Hello")); - EXPECT_TRUE(m2.Matches(L"")); - EXPECT_FALSE(m2.Matches(L"Hello")); -} - -TEST(GlobalWideStrCaseNeTest, CanDescribeSelf) { - Matcher<const wchar_t*> m = StrCaseNe(L"Hi"); - EXPECT_EQ("isn't equal to (ignoring case) L\"Hi\"", Describe(m)); -} - -// Tests that HasSubstr() works for matching wstring-typed values. -TEST(GlobalWideHasSubstrTest, WorksForStringClasses) { - const Matcher< ::wstring> m1 = HasSubstr(L"foo"); - EXPECT_TRUE(m1.Matches(::wstring(L"I love food."))); - EXPECT_FALSE(m1.Matches(::wstring(L"tofo"))); - - const Matcher<const ::wstring&> m2 = HasSubstr(L"foo"); - EXPECT_TRUE(m2.Matches(::wstring(L"I love food."))); - EXPECT_FALSE(m2.Matches(::wstring(L"tofo"))); -} - -// Tests that HasSubstr() works for matching C-wide-string-typed values. -TEST(GlobalWideHasSubstrTest, WorksForCStrings) { - const Matcher<wchar_t*> m1 = HasSubstr(L"foo"); - EXPECT_TRUE(m1.Matches(const_cast<wchar_t*>(L"I love food."))); - EXPECT_FALSE(m1.Matches(const_cast<wchar_t*>(L"tofo"))); - EXPECT_FALSE(m1.Matches(NULL)); - - const Matcher<const wchar_t*> m2 = HasSubstr(L"foo"); - EXPECT_TRUE(m2.Matches(L"I love food.")); - EXPECT_FALSE(m2.Matches(L"tofo")); - EXPECT_FALSE(m2.Matches(NULL)); -} - -// Tests that HasSubstr(s) describes itself properly. -TEST(GlobalWideHasSubstrTest, CanDescribeSelf) { - Matcher< ::wstring> m = HasSubstr(L"foo\n\""); - EXPECT_EQ("has substring L\"foo\\n\\\"\"", Describe(m)); -} - -// Tests StartsWith(s). - -TEST(GlobalWideStartsWithTest, MatchesStringWithGivenPrefix) { - const Matcher<const wchar_t*> m1 = StartsWith(::wstring(L"")); - EXPECT_TRUE(m1.Matches(L"Hi")); - EXPECT_TRUE(m1.Matches(L"")); - EXPECT_FALSE(m1.Matches(NULL)); - - const Matcher<const ::wstring&> m2 = StartsWith(L"Hi"); - EXPECT_TRUE(m2.Matches(L"Hi")); - EXPECT_TRUE(m2.Matches(L"Hi Hi!")); - EXPECT_TRUE(m2.Matches(L"High")); - EXPECT_FALSE(m2.Matches(L"H")); - EXPECT_FALSE(m2.Matches(L" Hi")); -} - -TEST(GlobalWideStartsWithTest, CanDescribeSelf) { - Matcher<const ::wstring> m = StartsWith(L"Hi"); - EXPECT_EQ("starts with L\"Hi\"", Describe(m)); -} - -// Tests EndsWith(s). - -TEST(GlobalWideEndsWithTest, MatchesStringWithGivenSuffix) { - const Matcher<const wchar_t*> m1 = EndsWith(L""); - EXPECT_TRUE(m1.Matches(L"Hi")); - EXPECT_TRUE(m1.Matches(L"")); - EXPECT_FALSE(m1.Matches(NULL)); - - const Matcher<const ::wstring&> m2 = EndsWith(::wstring(L"Hi")); - EXPECT_TRUE(m2.Matches(L"Hi")); - EXPECT_TRUE(m2.Matches(L"Wow Hi Hi")); - EXPECT_TRUE(m2.Matches(L"Super Hi")); - EXPECT_FALSE(m2.Matches(L"i")); - EXPECT_FALSE(m2.Matches(L"Hi ")); -} - -TEST(GlobalWideEndsWithTest, CanDescribeSelf) { - Matcher<const ::wstring> m = EndsWith(L"Hi"); - EXPECT_EQ("ends with L\"Hi\"", Describe(m)); -} - -#endif // GTEST_HAS_GLOBAL_WSTRING - - -typedef ::testing::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)); -} - -// Tests that FloatEq() matches a 2-tuple where -// FloatEq(first field) matches the second field. -TEST(FloatEq2Test, MatchesEqualArguments) { - typedef ::testing::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 ::testing::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 ::testing::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 ::testing::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 ::testing::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 ::testing::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 ::testing::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 ::testing::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 ::testing::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 ::testing::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 ::testing::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 ::testing::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 ::testing::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 ::testing::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 ::testing::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 ::testing::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))); -} - -#if GTEST_LANG_CXX11 -// Tests the variadic version of the AllOfMatcher. -TEST(AllOfTest, VariadicMatchesWhenAllMatch) { - // Make sure AllOf is defined in the right namespace and does not depend on - // ADL. - ::testing::AllOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); - Matcher<int> m = AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5), Ne(6), Ne(7), Ne(8), - Ne(9), Ne(10), Ne(11)); - EXPECT_THAT(Describe(m), EndsWith("and (isn't equal to 11)")); - AllOfMatches(11, m); - 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))); -} - -#endif // GTEST_LANG_CXX11 - -// 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)); - EXPECT_EQ("(is > 0) and " - "((isn't equal to 1) and " - "(isn't equal to 2))", - Describe(m)); - - - m = AllOf(Gt(0), Ne(1), Ne(2), Ne(3)); - EXPECT_EQ("((is > 0) and " - "(isn't equal to 1)) and " - "((isn't equal to 2) and " - "(isn't equal to 3))", - Describe(m)); - - - m = AllOf(Ge(0), Lt(10), Ne(3), Ne(5), Ne(7)); - EXPECT_EQ("((is >= 0) and " - "(is < 10)) and " - "((isn't equal to 3) and " - "((isn't equal to 5) and " - "(isn't equal to 7)))", - Describe(m)); -} - -// Tests that AllOf(m1, ..., mn) describes its negation properly. -TEST(AllOfTest, CanDescribeNegation) { - Matcher<int> m; - m = AllOf(Le(2), Ge(1)); - EXPECT_EQ("(isn't <= 2) or " - "(isn't >= 1)", - DescribeNegation(m)); - - m = AllOf(Gt(0), Ne(1), Ne(2)); - EXPECT_EQ("(isn't > 0) or " - "((is equal to 1) or " - "(is equal to 2))", - DescribeNegation(m)); - - - m = AllOf(Gt(0), Ne(1), Ne(2), Ne(3)); - EXPECT_EQ("((isn't > 0) or " - "(is equal to 1)) or " - "((is equal to 2) or " - "(is equal to 3))", - DescribeNegation(m)); - - - m = AllOf(Ge(0), Lt(10), Ne(3), Ne(5), Ne(7)); - EXPECT_EQ("((isn't >= 0) or " - "(isn't < 10)) or " - "((is equal to 3) or " - "((is equal to 5) or " - "(is equal to 7)))", - DescribeNegation(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)); -} - -#if GTEST_LANG_CXX11 -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))); -} -#endif - -// 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)); -} - -#if GTEST_LANG_CXX11 -// 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<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))); -} - -#endif // GTEST_LANG_CXX11 - -// 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 iff the argument references foo and has -// a zero value. -bool ReferencesFooAndIsZero(const int& n) { - return (&n == &foo) && (n == 0); -} - -// Tests that Truly(predicate) matches what satisfies the given -// predicate. -TEST(TrulyTest, MatchesWhatSatisfiesThePredicate) { - Matcher<double> m = Truly(IsPositive); - EXPECT_TRUE(m.Matches(2.0)); - EXPECT_FALSE(m.Matches(-1.5)); -} - -// Tests that Truly(predicate_functor) works too. -TEST(TrulyTest, CanBeUsedWithFunctor) { - Matcher<int> m = Truly(IsGreaterThan(5)); - EXPECT_TRUE(m.Matches(6)); - EXPECT_FALSE(m.Matches(4)); -} - -// 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 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_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(make_tuple(1, 2L), AllArgs(Lt())); - EXPECT_THAT(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; - - // VC++ prior to version 8.0 SP1 has a bug where it will not see any - // functions declared in the namespace scope from within nested classes. - // EXPECT/ASSERT_(NON)FATAL_FAILURE macros use nested classes so that all - // namespace-level functions invoked inside them need to be explicitly - // resolved. - EXPECT_FATAL_FAILURE(ASSERT_THAT(n, ::testing::Gt(10)), - "Value of: n\n" - "Expected: is > 10\n" - " Actual: 5" + OfType("unsigned short")); - n = 0; - EXPECT_NONFATAL_FAILURE( - EXPECT_THAT(n, ::testing::AllOf(::testing::Le(7), ::testing::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, ::testing::Not(::testing::Ref(n))), - "Value of: n\n" - "Expected: does not reference the variable @"); - // Tests the "Actual" part. - EXPECT_FATAL_FAILURE(ASSERT_THAT(n, ::testing::Not(::testing::Ref(n))), - "Actual: 0" + OfType("int") + ", which is located @"); -} - -#if !GTEST_OS_SYMBIAN -// Tests that ASSERT_THAT() and EXPECT_THAT() work when the matcher is -// monomorphic. - -// ASSERT_THAT("hello", starts_with_he) fails to compile with Nokia's -// Symbian compiler: it tries to compile -// template<T, U> class MatcherCastImpl { ... -// virtual bool MatchAndExplain(T x, ...) const { -// return source_matcher_.MatchAndExplain(static_cast<U>(x), ...); -// with U == string and T == const char* -// With ASSERT_THAT("hello"...) changed to ASSERT_THAT(string("hello") ... ) -// the compiler silently crashes with no output. -// If MatcherCastImpl is changed to use U(x) instead of static_cast<U>(x) -// the code compiles but the converted string is bogus. -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")); -} -#endif // !GTEST_OS_SYMBIAN - -// 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(NULL)); -} - -TEST(PointeeTest, RawPointerToConst) { - const Matcher<const double*> m = Pointee(Ge(0)); - - double x = 1; - EXPECT_TRUE(m.Matches(&x)); - x = -1; - EXPECT_FALSE(m.Matches(&x)); - EXPECT_FALSE(m.Matches(NULL)); -} - -TEST(PointeeTest, ReferenceToConstRawPointer) { - const Matcher<int* const &> m = Pointee(Ge(0)); - - int n = 1; - EXPECT_TRUE(m.Matches(&n)); - n = -1; - EXPECT_FALSE(m.Matches(&n)); - EXPECT_FALSE(m.Matches(NULL)); -} - -TEST(PointeeTest, ReferenceToNonConstRawPointer) { - const Matcher<double* &> m = Pointee(Ge(0)); - - double x = 1.0; - double* p = &x; - EXPECT_TRUE(m.Matches(p)); - x = -1; - EXPECT_FALSE(m.Matches(p)); - p = NULL; - EXPECT_FALSE(m.Matches(p)); -} - -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 = NULL; - 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. - - // This testcase fails on FreeBSD. See this GitHub issue for more details: - // https://github.com/google/googletest/issues/2172 -#ifdef __FreeBSD__ - EXPECT_NONFATAL_FAILURE({ -#endif - 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()))); -#ifdef __FreeBSD__ - }, ""); -#endif -} - -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 = NULL; - 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(NULL)); -} - -// Tests that we can write Pointee(value) instead of Pointee(Eq(value)). -TEST(PointeeTest, MatchesAgainstAValue) { - const Matcher<int*> m = Pointee(5); - - int n = 5; - EXPECT_TRUE(m.Matches(&n)); - n = -1; - EXPECT_FALSE(m.Matches(&n)); - EXPECT_FALSE(m.Matches(NULL)); -} - -TEST(PointeeTest, CanDescribeSelf) { - const Matcher<int*> m = Pointee(Gt(3)); - EXPECT_EQ("points to a value that is > 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*>(NULL))); - - 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 iff 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(NULL) {} - AStruct(const AStruct& rhs) - : x(rhs.x), y(rhs.y), z(rhs.z.value()), p(rhs.p) {} - - int x; // A non-const field. - const double y; // A const field. - Uncopyable z; // An uncopyable field. - const char* p; // A pointer field. - - private: - GTEST_DISALLOW_ASSIGN_(AStruct); -}; - -// A derived struct for testing Field(). -struct DerivedStruct : public AStruct { - char ch; - - private: - GTEST_DISALLOW_ASSIGN_(DerivedStruct); -}; - -// 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*>(NULL)); - AStruct a; - EXPECT_TRUE(m.Matches(a)); - a.p = "hi"; - EXPECT_FALSE(m.Matches(a)); - - // Matching a pointer that is not NULL. - m = Field(&AStruct::p, StartsWith("hi")); - a.p = "hill"; - EXPECT_TRUE(m.Matches(a)); - a.p = "hole"; - EXPECT_FALSE(m.Matches(a)); -} - -// Tests that Field() works when the object is passed by reference. -TEST(FieldTest, WorksForByRefArgument) { - Matcher<const AStruct&> m = Field(&AStruct::x, Ge(0)); - - AStruct a; - EXPECT_TRUE(m.Matches(a)); - a.x = -1; - EXPECT_FALSE(m.Matches(a)); -} - -// Tests that Field(&Foo::field, ...) works when the argument's type -// is a sub-type of Foo. -TEST(FieldTest, WorksForArgumentOfSubType) { - // Note that the matcher expects DerivedStruct but we say AStruct - // inside Field(). - Matcher<const DerivedStruct&> m = Field(&AStruct::x, Ge(0)); - - DerivedStruct d; - EXPECT_TRUE(m.Matches(d)); - d.x = -1; - EXPECT_FALSE(m.Matches(d)); -} - -// Tests that Field(&Foo::field, m) works when field's type and m's -// argument type are compatible but not the same. -TEST(FieldTest, WorksForCompatibleMatcherType) { - // The field is an int, but the inner matcher expects a signed char. - Matcher<const AStruct&> m = Field(&AStruct::x, - Matcher<signed char>(Ge(0))); - - AStruct a; - EXPECT_TRUE(m.Matches(a)); - a.x = -1; - EXPECT_FALSE(m.Matches(a)); -} - -// Tests that Field() can describe itself. -TEST(FieldTest, CanDescribeSelf) { - Matcher<const AStruct&> m = Field(&AStruct::x, Ge(0)); - - EXPECT_EQ("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(NULL)); -} - -// Tests that Field(&Foo::field, ...) works when the argument's type -// is a sub-type of const Foo*. -TEST(FieldForPointerTest, WorksForArgumentOfSubType) { - // Note that the matcher expects DerivedStruct but we say AStruct - // inside Field(). - Matcher<DerivedStruct*> m = Field(&AStruct::x, Ge(0)); - - DerivedStruct d; - EXPECT_TRUE(m.Matches(&d)); - d.x = -1; - EXPECT_FALSE(m.Matches(&d)); -} - -// Tests that Field() can describe itself when used to match a pointer. -TEST(FieldForPointerTest, CanDescribeSelf) { - Matcher<const AStruct*> m = Field(&AStruct::x, Ge(0)); - - EXPECT_EQ("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*>(NULL))); - 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*>(NULL))); - 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_; } - -#if GTEST_LANG_CXX11 - const std::string& s_ref() const & { return s_; } -#endif - - 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)); -} - -#if GTEST_LANG_CXX11 -// 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)); -} -#endif - -// 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(NULL)); -} - -// Tests that Property(&Foo::property, ...) works when the argument's -// type is a sub-type of const Foo*. -TEST(PropertyForPointerTest, WorksForArgumentOfSubType) { - // The matcher expects a DerivedClass, but inside the Property() we - // say AClass. - Matcher<const DerivedClass*> m = Property(&AClass::n, Ge(0)); - - DerivedClass d; - d.set_n(1); - EXPECT_TRUE(m.Matches(&d)); - - d.set_n(-1); - EXPECT_FALSE(m.Matches(&d)); -} - -// Tests that Property() can describe itself when used to match a pointer. -TEST(PropertyForPointerTest, CanDescribeSelf) { - Matcher<const AClass*> m = Property(&AClass::n, Ge(0)); - - EXPECT_EQ("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*>(NULL))); - 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*>(NULL))); - 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)>(NULL), - 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 : public ::std::unary_function<int, std::string> { - result_type operator()(argument_type 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")); -} - -#if GTEST_LANG_CXX11 -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(str_len, 'x'); }, "xxx"); - EXPECT_TRUE(matcher.Matches(3)); - EXPECT_FALSE(matcher.Matches(1)); -} -#endif - -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(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(NULL, Not(IsTrue())); - EXPECT_THAT(NULL, 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())); -#if GTEST_LANG_CXX11 - 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())); -#endif // GTEST_LANG_CXX11 -} - -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, 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(GreaterThan(1)); - 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, which is 1 less than 1", - 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, which is 1 more than 1", - 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_CASE(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 mutliple 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(make_tuple(p1, 3), ContainerEq(a2)); - EXPECT_THAT(make_tuple(p1, 3), Not(ContainerEq(b))); - - const int c[] = {1, 3, 2}; - EXPECT_THAT(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++); - } -} - -#if GTEST_HAS_STD_FORWARD_LIST_ -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)); -} -#endif // GTEST_HAS_STD_FORWARD_LIST_ - -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, 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(a, a + GTEST_ARRAY_SIZE_(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(a, a + GTEST_ARRAY_SIZE_(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(a, a + GTEST_ARRAY_SIZE_(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")); -} - -#if GTEST_HAS_STD_INITIALIZER_LIST_ -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}))); -} -#endif - -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(a, a + GTEST_ARRAY_SIZE_(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")); -} - -#if GTEST_HAS_STD_INITIALIZER_LIST_ -TEST(IsSubsetOfTest, WorksForRhsInitializerList) { - const int numbers[] = {1, 2, 3}; - EXPECT_THAT(numbers, IsSubsetOf({1, 2, 3, 4})); - EXPECT_THAT(numbers, Not(IsSubsetOf({1, 2}))); -} -#endif - -// Tests using ElementsAre() and ElementsAreArray() with stream-like -// "containers". - -TEST(ElemensAreStreamTest, WorksForStreamlike) { - const int a[5] = {1, 2, 3, 4, 5}; - Streamlike<int> s(a, a + GTEST_ARRAY_SIZE_(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(a, a + GTEST_ARRAY_SIZE_(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, 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(a, a + GTEST_ARRAY_SIZE_(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(a, a + GTEST_ARRAY_SIZE_(a)); - std::vector<bool> actual(b, b + GTEST_ARRAY_SIZE_(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(a, a + GTEST_ARRAY_SIZE_(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))); -} - -#if GTEST_HAS_STD_INITIALIZER_LIST_ - -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)}))); -} - -#endif // GTEST_HAS_STD_INITIALIZER_LIST_ - -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(a, a + GTEST_ARRAY_SIZE_(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(a, a + GTEST_ARRAY_SIZE_(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(a, a + GTEST_ARRAY_SIZE_(a)); - - EXPECT_THAT(s, UnorderedElementsAre(1, 2, 3, 4, 5)); - EXPECT_THAT(s, Not(UnorderedElementsAre(2, 2, 3, 4, 5))); -} - -// 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<int> { }; - -// Verify all match graphs up to some moderate number of edges. -TEST_P(BipartiteTest, Exhaustive) { - int 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_CASE_P(AllGraphs, BipartiteTest, - ::testing::Range(0, 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); - static const int kEdges[][2] = {{0, 2}, {1, 1}, {2, 1}, {3, 0}}; - for (size_t i = 0; i < GTEST_ARRAY_SIZE_(kEdges); ++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_CASE_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(nodes, nodes); - - testing::internal::Int32 seed = GTEST_FLAG(random_seed); - if (seed == 0) { - seed = static_cast<testing::internal::Int32>(time(NULL)); - } - - for (; iters > 0; --iters, ++seed) { - srand(static_cast<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_CASE_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(make_tuple(Matcher<char>(Eq('a')), GreaterThan(5)), - make_tuple('a', 10), &ss1); - EXPECT_EQ("", ss1.str()); // Successful match. - - stringstream ss2; - ExplainMatchFailureTupleTo(make_tuple(GreaterThan(5), Matcher<char>(Eq('a'))), - 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(make_tuple(GreaterThan(5), Matcher<char>(Eq('a'))), - 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(make_tuple(pointer, 2), Each(Gt(0))); - EXPECT_THAT(make_tuple(pointer, 2), Not(Each(Gt(1)))); -} - -// For testing Pointwise(). -class IsHalfOfMatcher { - public: - template <typename T1, typename T2> - bool MatchAndExplain(const tuple<T1, T2>& a_pair, - MatchResultListener* listener) const { - if (get<0>(a_pair) == get<1>(a_pair)/2) { - *listener << "where the second is " << get<1>(a_pair); - return true; - } else { - *listener << "where the second/2 is " << 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))); -} - -#if GTEST_HAS_STD_INITIALIZER_LIST_ - -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}))); -} - -#endif // GTEST_HAS_STD_INITIALIZER_LIST_ - -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<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 tuple<const double&, const int&> can be - // implicitly cast to tuple<double, int>. - const Matcher<tuple<double, int> > m2 = IsHalfOf(); - EXPECT_THAT(lhs, Pointwise(m2, rhs)); - EXPECT_EQ("", Explain(Pointwise(m2, rhs), lhs)); -} - -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))); -} - -#if GTEST_HAS_STD_INITIALIZER_LIST_ - -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}))); -} - -#endif // GTEST_HAS_STD_INITIALIZER_LIST_ - -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<tuple<const double&, const int&> > m1 = IsHalfOf(); - EXPECT_THAT(lhs, UnorderedPointwise(m1, rhs)); - - // This type works as a tuple<const double&, const int&> can be - // implicitly cast to tuple<double, int>. - const Matcher<tuple<double, int> > m2 = IsHalfOf(); - EXPECT_THAT(lhs, UnorderedPointwise(m2, rhs)); -} - -// Sample optional type implementation with minimal requirements for use with -// Optional matcher. -class SampleOptionalInt { - public: - typedef int value_type; - explicit SampleOptionalInt(int value) : value_(value), has_value_(true) {} - SampleOptionalInt() : value_(0), has_value_(false) {} - operator bool() const { - return has_value_; - } - const int& operator*() const { - return value_; - } - private: - int value_; - bool has_value_; -}; - -TEST(OptionalTest, DescribesSelf) { - const Matcher<SampleOptionalInt> m = Optional(Eq(1)); - EXPECT_EQ("value is equal to 1", Describe(m)); -} - -TEST(OptionalTest, ExplainsSelf) { - const Matcher<SampleOptionalInt> m = Optional(Eq(1)); - EXPECT_EQ("whose value 1 matches", Explain(m, SampleOptionalInt(1))); - EXPECT_EQ("whose value 2 doesn't match", Explain(m, SampleOptionalInt(2))); -} - -TEST(OptionalTest, MatchesNonEmptyOptional) { - const Matcher<SampleOptionalInt> m1 = Optional(1); - const Matcher<SampleOptionalInt> m2 = Optional(Eq(2)); - const Matcher<SampleOptionalInt> m3 = Optional(Lt(3)); - SampleOptionalInt opt(1); - EXPECT_TRUE(m1.Matches(opt)); - EXPECT_FALSE(m2.Matches(opt)); - EXPECT_TRUE(m3.Matches(opt)); -} - -TEST(OptionalTest, DoesNotMatchNullopt) { - const Matcher<SampleOptionalInt> m = Optional(1); - SampleOptionalInt empty; - EXPECT_FALSE(m.Matches(empty)); -} - -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_ == internal::IsSame<T, int>::value; - } - - template <typename T> - friend const T& get(const SampleVariantIntString& value) { - return value.get_impl(static_cast<T*>(NULL)); - } - - 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*>(NULL)); - } - - private: - int index_; - int i_; - std::string s_; - - const int* get_impl(int*) const { return index_ == 0 ? &i_ : NULL; } - const std::string* get_impl(std::string*) const { - return index_ == 1 ? &s_ : NULL; - } -}; - -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))); -} - -#if GTEST_LANG_CXX11 -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")})); -} -#endif // GTEST_LANG_CXX11 -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"); -} - -#if GTEST_LANG_CXX11 - -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)))); -} - -#endif // GTEST_LANG_CXX11 - -} // namespace gmock_matchers_test -} // namespace testing diff --git a/contrib/googletest/googlemock/test/gmock-matchers_test.h b/contrib/googletest/googlemock/test/gmock-matchers_test.h new file mode 100644 index 000000000000..56956076dae0 --- /dev/null +++ b/contrib/googletest/googlemock/test/gmock-matchers_test.h @@ -0,0 +1,192 @@ +// 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. + +#ifndef GOOGLEMOCK_TEST_GMOCK_MATCHERS_TEST_H_ +#define GOOGLEMOCK_TEST_GMOCK_MATCHERS_TEST_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-matchers.h" +#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 { + +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>>)); +}; + +// For testing ExplainMatchResultTo(). +template <typename T> +struct GtestGreaterThanMatcher { + using is_gtest_matcher = void; + + void DescribeTo(ostream* os) const { *os << "is > " << rhs; } + void DescribeNegationTo(ostream* os) const { *os << "is <= " << rhs; } + + bool MatchAndExplain(T lhs, MatchResultListener* listener) const { + if (lhs > rhs) { + *listener << "which is " << (lhs - rhs) << " more than " << rhs; + } else if (lhs == rhs) { + *listener << "which is the same as " << rhs; + } else { + *listener << "which is " << (rhs - lhs) << " less than " << rhs; + } + + return lhs > rhs; + } + + T rhs; +}; + +template <typename T> +GtestGreaterThanMatcher<typename std::decay<T>::type> GtestGreaterThan( + T&& rhs) { + return {rhs}; +} + +// As the matcher above, but using the base class with virtual functions. +template <typename T> +class GreaterThanMatcher : public MatcherInterface<T> { + public: + explicit GreaterThanMatcher(T rhs) : impl_{rhs} {} + + void DescribeTo(ostream* os) const override { impl_.DescribeTo(os); } + void DescribeNegationTo(ostream* os) const override { + impl_.DescribeNegationTo(os); + } + + bool MatchAndExplain(T lhs, MatchResultListener* listener) const override { + return impl_.MatchAndExplain(lhs, listener); + } + + private: + const GtestGreaterThanMatcher<T> impl_; +}; + +// Names and instantiates a new instance of GTestMatcherTestP. +#define INSTANTIATE_GTEST_MATCHER_TEST_P(TestSuite) \ + using TestSuite##P = GTestMatcherTestP; \ + INSTANTIATE_TEST_SUITE_P(MatcherInterface, TestSuite##P, Values(false)); \ + INSTANTIATE_TEST_SUITE_P(GtestMatcher, TestSuite##P, Values(true)) + +class GTestMatcherTestP : public testing::TestWithParam<bool> { + public: + template <typename T> + Matcher<T> GreaterThan(T n) { + if (use_gtest_matcher_) { + return GtestGreaterThan(n); + } else { + return MakeMatcher(new GreaterThanMatcher<T>(n)); + } + } + const bool use_gtest_matcher_ = GetParam(); +}; + +// 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(); +} + +} // namespace gmock_matchers_test +} // namespace testing + +#endif // GOOGLEMOCK_TEST_GMOCK_MATCHERS_TEST_H_ diff --git a/contrib/googletest/googlemock/test/gmock-more-actions_test.cc b/contrib/googletest/googlemock/test/gmock-more-actions_test.cc index 08a2df099d98..9980f3bc4567 100644 --- a/contrib/googletest/googlemock/test/gmock-more-actions_test.cc +++ b/contrib/googletest/googlemock/test/gmock-more-actions_test.cc @@ -27,45 +27,43 @@ // (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-more-actions.h. +// This file tests the built-in actions in gmock-actions.h. #include "gmock/gmock-more-actions.h" +#include <algorithm> #include <functional> +#include <iterator> +#include <memory> #include <sstream> #include <string> +#include <tuple> +#include <vector> + #include "gmock/gmock.h" +#include "gtest/gtest-spi.h" #include "gtest/gtest.h" -#include "gtest/internal/gtest-linked_ptr.h" + +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4577) namespace testing { namespace gmock_more_actions_test { using ::std::plus; using ::std::string; -using testing::get; -using testing::make_tuple; -using testing::tuple; -using testing::tuple_element; -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::StaticAssertTypeEq; using testing::Unused; using testing::WithArg; using testing::WithoutArgs; -using testing::internal::linked_ptr; // For suppressing compiler warnings on conversion possibly losing precision. inline short Short(short n) { return n; } // NOLINT @@ -74,55 +72,27 @@ 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 { @@ -131,11 +101,6 @@ struct SumOf5Functor { } }; -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; } @@ -146,11 +111,6 @@ struct SumOf6Functor { } }; -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) { @@ -186,7 +146,7 @@ class Foo { 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 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_; @@ -232,45 +192,46 @@ class Foo { // Tests using Invoke() with a nullary function. TEST(InvokeTest, Nullary) { Action<int()> a = Invoke(Nullary); // NOLINT - EXPECT_EQ(1, a.Perform(make_tuple())); + 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(make_tuple(1))); - EXPECT_TRUE(a.Perform(make_tuple(-1))); + 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(make_tuple(p, Short(2)))); + 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(make_tuple(1, '\2', Short(3)))); + 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(make_tuple(1000, 200, 30, 4))); + 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(make_tuple(10000, 2000, 300, 40, 5))); + 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(make_tuple(100000, 20000, 3000, 400, 50, 6))); + 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 @@ -283,9 +244,9 @@ TEST(InvokeTest, FunctionThatTakes7Arguments) { const char*, const char*, const char*)> a = Invoke(Concat7); EXPECT_EQ("1234567", - a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"), - CharPtr("4"), CharPtr("5"), CharPtr("6"), - CharPtr("7")))); + 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. @@ -294,9 +255,9 @@ TEST(InvokeTest, FunctionThatTakes8Arguments) { const char*, const char*, const char*, const char*)> a = Invoke(Concat8); EXPECT_EQ("12345678", - a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"), - CharPtr("4"), CharPtr("5"), CharPtr("6"), - CharPtr("7"), CharPtr("8")))); + 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. @@ -305,10 +266,10 @@ TEST(InvokeTest, FunctionThatTakes9Arguments) { const char*, const char*, const char*, const char*, const char*)> a = Invoke(Concat9); - EXPECT_EQ("123456789", - a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"), - CharPtr("4"), CharPtr("5"), CharPtr("6"), - CharPtr("7"), CharPtr("8"), CharPtr("9")))); + 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. @@ -318,45 +279,44 @@ TEST(InvokeTest, FunctionThatTakes10Arguments) { const char*, const char*)> a = Invoke(Concat10); EXPECT_EQ("1234567890", - a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"), - CharPtr("4"), CharPtr("5"), CharPtr("6"), - CharPtr("7"), CharPtr("8"), CharPtr("9"), - CharPtr("0")))); + 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); - tuple<int, int, double, std::string> dummy = - make_tuple(10, 2, 5.6, std::string("hi")); + 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(make_tuple(20, 3, true, static_cast<int*>(NULL)))); + 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(make_tuple(CharPtr("hi"), true, 10, 2))); + 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(make_tuple('a', 2.5, 20, 3))); + 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(make_tuple(1, 2))); + 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(make_tuple(4000, Short(300), Char(20), true))); + 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. @@ -365,14 +325,14 @@ TEST(InvokeTest, FunctionWithCompatibleType) { TEST(InvokeMethodTest, Nullary) { Foo foo; Action<int()> a = Invoke(&foo, &Foo::Nullary); // NOLINT - EXPECT_EQ(123, a.Perform(make_tuple())); + 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(make_tuple(4000))); + EXPECT_EQ(4123, a.Perform(std::make_tuple(4000))); } // Tests using Invoke() with a binary method. @@ -380,7 +340,7 @@ TEST(InvokeMethodTest, Binary) { Foo foo; Action<std::string(const std::string&, char)> a = Invoke(&foo, &Foo::Binary); std::string s("Hell"); - tuple<std::string, char> dummy = make_tuple(s, 'o'); + std::tuple<std::string, char> dummy = std::make_tuple(s, 'o'); EXPECT_EQ("Hello", a.Perform(dummy)); } @@ -388,21 +348,22 @@ TEST(InvokeMethodTest, Binary) { TEST(InvokeMethodTest, Ternary) { Foo foo; Action<int(int, bool, char)> a = Invoke(&foo, &Foo::Ternary); // NOLINT - EXPECT_EQ(1124, a.Perform(make_tuple(1000, true, Char(1)))); + 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(make_tuple(1000, 200, 30, 4))); + 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(make_tuple(10000, 2000, 300, 40, 5))); + 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. @@ -410,7 +371,8 @@ TEST(InvokeMethodTest, MethodThatTakes6Arguments) { Foo foo; Action<int(int, int, int, int, int, int)> a = // NOLINT Invoke(&foo, &Foo::SumOf6); - EXPECT_EQ(123456, a.Perform(make_tuple(100000, 20000, 3000, 400, 50, 6))); + EXPECT_EQ(123456, + a.Perform(std::make_tuple(100000, 20000, 3000, 400, 50, 6))); } // Tests using Invoke() with a 7-argument method. @@ -420,9 +382,9 @@ TEST(InvokeMethodTest, MethodThatTakes7Arguments) { const char*, const char*, const char*)> a = Invoke(&foo, &Foo::Concat7); EXPECT_EQ("1234567", - a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"), - CharPtr("4"), CharPtr("5"), CharPtr("6"), - CharPtr("7")))); + 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. @@ -432,9 +394,9 @@ TEST(InvokeMethodTest, MethodThatTakes8Arguments) { const char*, const char*, const char*, const char*)> a = Invoke(&foo, &Foo::Concat8); EXPECT_EQ("12345678", - a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"), - CharPtr("4"), CharPtr("5"), CharPtr("6"), - CharPtr("7"), CharPtr("8")))); + 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. @@ -444,10 +406,10 @@ TEST(InvokeMethodTest, MethodThatTakes9Arguments) { const char*, const char*, const char*, const char*, const char*)> a = Invoke(&foo, &Foo::Concat9); - EXPECT_EQ("123456789", - a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"), - CharPtr("4"), CharPtr("5"), CharPtr("6"), - CharPtr("7"), CharPtr("8"), CharPtr("9")))); + 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. @@ -458,10 +420,10 @@ TEST(InvokeMethodTest, MethodThatTakes10Arguments) { const char*, const char*)> a = Invoke(&foo, &Foo::Concat10); EXPECT_EQ("1234567890", - a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"), - CharPtr("4"), CharPtr("5"), CharPtr("6"), - CharPtr("7"), CharPtr("8"), CharPtr("9"), - CharPtr("0")))); + 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. @@ -469,48 +431,54 @@ TEST(InvokeMethodTest, MethodWithCompatibleType) { Foo foo; Action<long(int, short, char, bool)> a = // NOLINT Invoke(&foo, &Foo::SumOf4); - EXPECT_EQ(4444, a.Perform(make_tuple(4000, Short(300), Char(20), true))); + 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(make_tuple(2))); + 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(make_tuple(1.5, -1))); - EXPECT_FALSE(b.Perform(make_tuple(1.5, 1))); + 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(make_tuple(5))); + 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(make_tuple(true, false, false))); + 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(make_tuple(5, 6, std::string("seven"), 8))); + EXPECT_EQ("seven", a.Perform(std::make_tuple(5, 6, std::string("seven"), 8))); +} + +TEST(ReturnArgActionTest, WorksForNonConstRefArg0) { + const Action<std::string&(std::string&)> a = ReturnArg<0>(); + std::string s = "12345"; + EXPECT_EQ(&s, &a.Perform(std::forward_as_tuple(s))); } TEST(SaveArgActionTest, WorksForSameType) { int result = 0; const Action<void(int n)> a1 = SaveArg<0>(&result); - a1.Perform(make_tuple(5)); + 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(make_tuple(true, 'a')); + a1.Perform(std::make_tuple(true, 'a')); EXPECT_EQ('a', result); } @@ -518,7 +486,7 @@ TEST(SaveArgPointeeActionTest, WorksForSameType) { int result = 0; const int value = 5; const Action<void(const int*)> a1 = SaveArgPointee<0>(&result); - a1.Perform(make_tuple(&value)); + a1.Perform(std::make_tuple(&value)); EXPECT_EQ(5, result); } @@ -526,36 +494,28 @@ TEST(SaveArgPointeeActionTest, WorksForCompatibleType) { int result = 0; char value = 'a'; const Action<void(bool, char*)> a1 = SaveArgPointee<1>(&result); - a1.Perform(make_tuple(true, &value)); + a1.Perform(std::make_tuple(true, &value)); EXPECT_EQ('a', result); } -TEST(SaveArgPointeeActionTest, WorksForLinkedPtr) { - int result = 0; - linked_ptr<int> value(new int(5)); - const Action<void(linked_ptr<int>)> a1 = SaveArgPointee<0>(&result); - a1.Perform(make_tuple(value)); - EXPECT_EQ(5, result); -} - TEST(SetArgRefereeActionTest, WorksForSameType) { int value = 0; const Action<void(int&)> a1 = SetArgReferee<0>(1); - a1.Perform(tuple<int&>(value)); + 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(tuple<int, int&>(0, value)); + 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(tuple<bool, int, int&, const char*>(true, 0, value, "hi")); + a1.Perform(std::tuple<bool, int, int&, const char*>(true, 0, value, "hi")); EXPECT_EQ('a', value); } @@ -563,15 +523,12 @@ TEST(SetArgRefereeActionTest, WorksWithExtraArguments) { // the bool provided to the constructor to true when destroyed. class DeletionTester { public: - explicit DeletionTester(bool* is_deleted) - : is_deleted_(is_deleted) { + explicit DeletionTester(bool* is_deleted) : is_deleted_(is_deleted) { // Make sure the bit is set to false. *is_deleted_ = false; } - ~DeletionTester() { - *is_deleted_ = true; - } + ~DeletionTester() { *is_deleted_ = true; } private: bool* is_deleted_; @@ -580,19 +537,20 @@ class DeletionTester { TEST(DeleteArgActionTest, OneArg) { bool is_deleted = false; DeletionTester* t = new DeletionTester(&is_deleted); - const Action<void(DeletionTester*)> a1 = DeleteArg<0>(); // NOLINT + const Action<void(DeletionTester*)> a1 = DeleteArg<0>(); // NOLINT EXPECT_FALSE(is_deleted); - a1.Perform(make_tuple(t)); + 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>(); + const Action<void(bool, int, int, const char*, bool, int, int, int, int, + DeletionTester*)> + a1 = DeleteArg<9>(); EXPECT_FALSE(is_deleted); - a1.Perform(make_tuple(true, 5, 6, CharPtr("hi"), false, 7, 8, 9, 10, t)); + a1.Perform(std::make_tuple(true, 5, 6, CharPtr("hi"), false, 7, 8, 9, 10, t)); EXPECT_TRUE(is_deleted); } @@ -600,19 +558,46 @@ TEST(DeleteArgActionTest, TenArgs) { TEST(ThrowActionTest, ThrowsGivenExceptionInVoidFunction) { const Action<void(int n)> a = Throw('a'); - EXPECT_THROW(a.Perform(make_tuple(0)), char); + 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(make_tuple('0')), MyException); + EXPECT_THROW(a.Perform(std::make_tuple('0')), MyException); } TEST(ThrowActionTest, ThrowsGivenExceptionInNullaryFunction) { const Action<double()> a = Throw(MyException()); - EXPECT_THROW(a.Perform(make_tuple()), 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 @@ -620,15 +605,15 @@ TEST(ThrowActionTest, ThrowsGivenExceptionInNullaryFunction) { // 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 }; + using MyFunction = void(bool, int*, char*); + int numbers[] = {1, 2, 3}; Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers + 3); int n[4] = {}; int* pn = n; char ch[4] = {}; char* pch = ch; - a.Perform(make_tuple(true, pn, pch)); + a.Perform(std::make_tuple(true, pn, pch)); EXPECT_EQ(1, n[0]); EXPECT_EQ(2, n[1]); EXPECT_EQ(3, n[2]); @@ -643,7 +628,7 @@ TEST(SetArrayArgumentTest, SetsTheNthArray) { a = SetArrayArgument<2>(letters.begin(), letters.end()); std::fill_n(n, 4, 0); std::fill_n(ch, 4, '\0'); - a.Perform(make_tuple(true, pn, pch)); + a.Perform(std::make_tuple(true, pn, pch)); EXPECT_EQ(0, n[0]); EXPECT_EQ(0, n[1]); EXPECT_EQ(0, n[2]); @@ -656,13 +641,13 @@ TEST(SetArrayArgumentTest, SetsTheNthArray) { // Tests SetArrayArgument<N>(first, last) where first == last. TEST(SetArrayArgumentTest, SetsTheNthArrayWithEmptyRange) { - typedef void MyFunction(bool, int*); - int numbers[] = { 1, 2, 3 }; + using MyFunction = void(bool, int*); + int numbers[] = {1, 2, 3}; Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers); int n[4] = {}; int* pn = n; - a.Perform(make_tuple(true, pn)); + a.Perform(std::make_tuple(true, pn)); EXPECT_EQ(0, n[0]); EXPECT_EQ(0, n[1]); EXPECT_EQ(0, n[2]); @@ -672,13 +657,13 @@ TEST(SetArrayArgumentTest, SetsTheNthArrayWithEmptyRange) { // 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 }; + using MyFunction = void(bool, int*); + char chars[] = {97, 98, 99}; Action<MyFunction> a = SetArrayArgument<1>(chars, chars + 3); - int codes[4] = { 111, 222, 333, 444 }; + int codes[4] = {111, 222, 333, 444}; int* pcodes = codes; - a.Perform(make_tuple(true, pcodes)); + a.Perform(std::make_tuple(true, pcodes)); EXPECT_EQ(97, codes[0]); EXPECT_EQ(98, codes[1]); EXPECT_EQ(99, codes[2]); @@ -687,23 +672,879 @@ TEST(SetArrayArgumentTest, SetsTheNthArrayWithConvertibleType) { // Test SetArrayArgument<N>(first, last) with iterator as argument. TEST(SetArrayArgumentTest, SetsTheNthArrayWithIteratorArgument) { - typedef void MyFunction(bool, std::back_insert_iterator<std::string>); + using MyFunction = void(bool, std::back_insert_iterator<std::string>); std::string letters = "abc"; Action<MyFunction> a = SetArrayArgument<1>(letters.begin(), letters.end()); std::string s; - a.Perform(make_tuple(true, back_inserter(s))); + a.Perform(std::make_tuple(true, std::back_inserter(s))); EXPECT_EQ(letters, s); } TEST(ReturnPointeeTest, Works) { int n = 42; const Action<int()> a = ReturnPointee(&n); - EXPECT_EQ(42, a.Perform(make_tuple())); + EXPECT_EQ(42, a.Perform(std::make_tuple())); n = 43; - EXPECT_EQ(43, a.Perform(make_tuple())); + EXPECT_EQ(43, a.Perform(std::make_tuple())); +} + +// 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))> // NOLINT + a = 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))> // NOLINT + a = 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 +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100 4503) +// 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))); +} + +namespace { + +// Tests that the body of ACTION() can reference the mock function +// type. +int Dummy(bool flag) { return flag ? 1 : 0; } + +} // namespace + +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) { + using MyAction = Action<const char*(bool, const char*)>; + + 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))); } -} // namespace gmock_generated_actions_test +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; + auto* 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_more_actions_test } // namespace testing + +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100 4503 +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4577 diff --git a/contrib/googletest/googlemock/test/gmock-nice-strict_test.cc b/contrib/googletest/googlemock/test/gmock-nice-strict_test.cc index dce6642325ff..95f096903583 100644 --- a/contrib/googletest/googlemock/test/gmock-nice-strict_test.cc +++ b/contrib/googletest/googlemock/test/gmock-nice-strict_test.cc @@ -27,11 +27,11 @@ // (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-generated-nice-strict.h" +#include "gmock/gmock-nice-strict.h" #include <string> #include <utility> + #include "gmock/gmock.h" #include "gtest/gtest-spi.h" #include "gtest/gtest.h" @@ -40,18 +40,18 @@ // clash with ::testing::Mock. class Mock { public: - Mock() {} + Mock() = default; MOCK_METHOD0(DoThis, void()); private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(Mock); + Mock(const Mock&) = delete; + Mock& operator=(const Mock&) = delete; }; namespace testing { namespace gmock_nice_strict_test { -using testing::GMOCK_FLAG(verbose); using testing::HasSubstr; using testing::NaggyMock; using testing::NiceMock; @@ -68,11 +68,17 @@ class NotDefaultConstructible { 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 ~Foo() = default; virtual void DoThis() = 0; virtual int DoThat(bool flag) = 0; @@ -80,7 +86,7 @@ class Foo { class MockFoo : public Foo { public: - MockFoo() {} + MockFoo() = default; void Delete() { delete this; } MOCK_METHOD0(DoThis, void()); @@ -88,7 +94,8 @@ class MockFoo : public Foo { MOCK_METHOD0(ReturnNonDefaultConstructible, NotDefaultConstructible()); private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo); + MockFoo(const MockFoo&) = delete; + MockFoo& operator=(const MockFoo&) = delete; }; class MockBar { @@ -98,10 +105,11 @@ class MockBar { 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'); + static_cast<char>(a6) + a7 + a8 + (a9 ? 'T' : 'F') + + (a10 ? 'T' : 'F'); } - virtual ~MockBar() {} + virtual ~MockBar() = default; const std::string& str() const { return str_; } @@ -111,33 +119,32 @@ class MockBar { private: std::string str_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockBar); + MockBar(const MockBar&) = delete; + MockBar& operator=(const MockBar&) = delete; }; -#if GTEST_GTEST_LANG_CXX11 - class MockBaz { public: class MoveOnly { + public: MoveOnly() = default; MoveOnly(const MoveOnly&) = delete; - operator=(const MoveOnly&) = delete; + MoveOnly& operator=(const MoveOnly&) = delete; MoveOnly(MoveOnly&&) = default; - operator=(MoveOnly&&) = default; + MoveOnly& operator=(MoveOnly&&) = default; }; MockBaz(MoveOnly) {} -} -#endif // GTEST_GTEST_LANG_CXX11 && GTEST_HAS_STD_MOVE_ +}; #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"; + const std::string saved_flag = GMOCK_FLAG_GET(verbose); + GMOCK_FLAG_SET(verbose, "warning"); MockFoo raw_foo; @@ -147,26 +154,25 @@ TEST(RawMockTest, WarningForUninterestingCall) { EXPECT_THAT(GetCapturedStdout(), HasSubstr("Uninteresting mock function call")); - GMOCK_FLAG(verbose) = saved_flag; + GMOCK_FLAG_SET(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"; + const std::string saved_flag = GMOCK_FLAG_GET(verbose); + GMOCK_FLAG_SET(verbose, "warning"); MockFoo* const raw_foo = new MockFoo; - ON_CALL(*raw_foo, DoThis()) - .WillByDefault(Invoke(raw_foo, &MockFoo::Delete)); + 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; + GMOCK_FLAG_SET(verbose, saved_flag); } // Tests that a raw mock generates informational logs for @@ -174,14 +180,21 @@ TEST(RawMockTest, WarningForUninterestingCallAfterDeath) { TEST(RawMockTest, InfoForUninterestingCall) { MockFoo raw_foo; - const std::string saved_flag = GMOCK_FLAG(verbose); - GMOCK_FLAG(verbose) = "info"; + const std::string saved_flag = GMOCK_FLAG_GET(verbose); + GMOCK_FLAG_SET(verbose, "info"); CaptureStdout(); raw_foo.DoThis(); EXPECT_THAT(GetCapturedStdout(), HasSubstr("Uninteresting mock function call")); - GMOCK_FLAG(verbose) = saved_flag; + GMOCK_FLAG_SET(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. @@ -212,14 +225,14 @@ TEST(NiceMockTest, NoWarningForUninterestingCallAfterDeath) { TEST(NiceMockTest, InfoForUninterestingCall) { NiceMock<MockFoo> nice_foo; - const std::string saved_flag = GMOCK_FLAG(verbose); - GMOCK_FLAG(verbose) = "info"; + const std::string saved_flag = GMOCK_FLAG_GET(verbose); + GMOCK_FLAG_SET(verbose, "info"); CaptureStdout(); nice_foo.DoThis(); EXPECT_THAT(GetCapturedStdout(), HasSubstr("Uninteresting mock function call")); - GMOCK_FLAG(verbose) = saved_flag; + GMOCK_FLAG_SET(verbose, saved_flag); } #endif // GTEST_HAS_STREAM_REDIRECTION @@ -270,8 +283,8 @@ TEST(NiceMockTest, NonDefaultConstructor) { // 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); + NiceMock<MockBar> nice_bar('a', 'b', "c", "d", 'e', 'f', "g", "h", true, + false); EXPECT_EQ("abcdefghTF", nice_bar.str()); nice_bar.This(); @@ -285,36 +298,38 @@ TEST(NiceMockTest, AllowLeak) { leaked->DoThis(); } -#if GTEST_GTEST_LANG_CXX11 && GTEST_HAS_STD_MOVE_ - TEST(NiceMockTest, MoveOnlyConstructor) { - NiceMock<MockBaz> nice_baz(MockBaz::MoveOnly()); + NiceMock<MockBaz> nice_baz(MockBaz::MoveOnly{}); } -#endif // GTEST_LANG_CXX11 && GTEST_HAS_STD_MOVE_ - -#if !GTEST_OS_SYMBIAN && !GTEST_OS_WINDOWS_MOBILE // Tests that NiceMock<Mock> compiles where Mock is a user-defined -// class (as opposed to ::testing::Mock). We had to work around an -// MSVC 8.0 bug that caused the symbol Mock used in the definition of -// NiceMock to be looked up in the wrong context, and this test -// ensures that our fix works. -// -// We have to skip this test on Symbian and Windows Mobile, as it -// causes the program to crash there, for reasons unclear to us yet. +// class (as opposed to ::testing::Mock). TEST(NiceMockTest, AcceptsClassNamedMock) { NiceMock< ::Mock> nice; EXPECT_CALL(nice, DoThis()); nice.DoThis(); } -#endif // !GTEST_OS_SYMBIAN && !GTEST_OS_WINDOWS_MOBILE + +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"; + const std::string saved_flag = GMOCK_FLAG_GET(verbose); + GMOCK_FLAG_SET(verbose, "warning"); NaggyMock<MockFoo> naggy_foo; @@ -324,14 +339,14 @@ TEST(NaggyMockTest, WarningForUninterestingCall) { EXPECT_THAT(GetCapturedStdout(), HasSubstr("Uninteresting mock function call")); - GMOCK_FLAG(verbose) = saved_flag; + GMOCK_FLAG_SET(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"; + const std::string saved_flag = GMOCK_FLAG_GET(verbose); + GMOCK_FLAG_SET(verbose, "warning"); NaggyMock<MockFoo>* const naggy_foo = new NaggyMock<MockFoo>; @@ -343,7 +358,7 @@ TEST(NaggyMockTest, WarningForUninterestingCallAfterDeath) { EXPECT_THAT(GetCapturedStdout(), HasSubstr("Uninteresting mock function call")); - GMOCK_FLAG(verbose) = saved_flag; + GMOCK_FLAG_SET(verbose, saved_flag); } #endif // GTEST_HAS_STREAM_REDIRECTION @@ -378,8 +393,8 @@ TEST(NaggyMockTest, NonDefaultConstructor) { // 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); + NaggyMock<MockBar> naggy_bar('0', '1', "2", "3", '4', '5', "6", "7", true, + false); EXPECT_EQ("01234567TF", naggy_bar.str()); naggy_bar.This(); @@ -393,29 +408,40 @@ TEST(NaggyMockTest, AllowLeak) { leaked->DoThis(); } -#if GTEST_GTEST_LANG_CXX11 && GTEST_HAS_STD_MOVE_ - TEST(NaggyMockTest, MoveOnlyConstructor) { - NaggyMock<MockBaz> naggy_baz(MockBaz::MoveOnly()); + NaggyMock<MockBaz> naggy_baz(MockBaz::MoveOnly{}); } -#endif // GTEST_LANG_CXX11 && GTEST_HAS_STD_MOVE_ - -#if !GTEST_OS_SYMBIAN && !GTEST_OS_WINDOWS_MOBILE // Tests that NaggyMock<Mock> compiles where Mock is a user-defined -// class (as opposed to ::testing::Mock). We had to work around an -// MSVC 8.0 bug that caused the symbol Mock used in the definition of -// NaggyMock to be looked up in the wrong context, and this test -// ensures that our fix works. -// -// We have to skip this test on Symbian and Windows Mobile, as it -// causes the program to crash there, for reasons unclear to us yet. +// class (as opposed to ::testing::Mock). TEST(NaggyMockTest, AcceptsClassNamedMock) { NaggyMock< ::Mock> naggy; EXPECT_CALL(naggy, DoThis()); naggy.DoThis(); } -#endif // !GTEST_OS_SYMBIAN && !GTEST_OS_WINDOWS_MOBILE + +TEST(NaggyMockTest, IsNaggyInDestructor) { + const std::string saved_flag = GMOCK_FLAG_GET(verbose); + GMOCK_FLAG_SET(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_SET(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) { @@ -467,8 +493,8 @@ TEST(StrictMockTest, NonDefaultConstructor) { // 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); + 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), @@ -482,29 +508,34 @@ TEST(StrictMockTest, AllowLeak) { leaked->DoThis(); } -#if GTEST_GTEST_LANG_CXX11 && GTEST_HAS_STD_MOVE_ - TEST(StrictMockTest, MoveOnlyConstructor) { - StrictMock<MockBaz> strict_baz(MockBaz::MoveOnly()); + StrictMock<MockBaz> strict_baz(MockBaz::MoveOnly{}); } -#endif // GTEST_LANG_CXX11 && GTEST_HAS_STD_MOVE_ - -#if !GTEST_OS_SYMBIAN && !GTEST_OS_WINDOWS_MOBILE // Tests that StrictMock<Mock> compiles where Mock is a user-defined -// class (as opposed to ::testing::Mock). We had to work around an -// MSVC 8.0 bug that caused the symbol Mock used in the definition of -// StrictMock to be looked up in the wrong context, and this test -// ensures that our fix works. -// -// We have to skip this test on Symbian and Windows Mobile, as it -// causes the program to crash there, for reasons unclear to us yet. +// class (as opposed to ::testing::Mock). TEST(StrictMockTest, AcceptsClassNamedMock) { StrictMock< ::Mock> strict; EXPECT_CALL(strict, DoThis()); strict.DoThis(); } -#endif // !GTEST_OS_SYMBIAN && !GTEST_OS_WINDOWS_MOBILE + +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/contrib/googletest/googlemock/test/gmock-port_test.cc b/contrib/googletest/googlemock/test/gmock-port_test.cc index a2c2be248864..c31af821559b 100644 --- a/contrib/googletest/googlemock/test/gmock-port_test.cc +++ b/contrib/googletest/googlemock/test/gmock-port_test.cc @@ -27,12 +27,12 @@ // (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 diff --git a/contrib/googletest/googlemock/test/gmock-pp-string_test.cc b/contrib/googletest/googlemock/test/gmock-pp-string_test.cc new file mode 100644 index 000000000000..53c80f4e3d2f --- /dev/null +++ b/contrib/googletest/googlemock/test/gmock-pp-string_test.cc @@ -0,0 +1,205 @@ +// 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 <string> + +#include "gmock/gmock.h" +#include "gmock/internal/gmock-pp.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/contrib/googletest/googlemock/test/gmock-pp_test.cc b/contrib/googletest/googlemock/test/gmock-pp_test.cc new file mode 100644 index 000000000000..5d1566e38853 --- /dev/null +++ b/contrib/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/contrib/googletest/googlemock/test/gmock-spec-builders_test.cc b/contrib/googletest/googlemock/test/gmock-spec-builders_test.cc index 160218051dd5..f01bc24fc44d 100644 --- a/contrib/googletest/googlemock/test/gmock-spec-builders_test.cc +++ b/contrib/googletest/googlemock/test/gmock-spec-builders_test.cc @@ -27,84 +27,38 @@ // (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 <type_traits> #include "gmock/gmock.h" #include "gmock/internal/gmock-port.h" -#include "gtest/gtest.h" #include "gtest/gtest-spi.h" +#include "gtest/gtest.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::ContainsRegex; -using testing::Const; -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::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; -using testing::internal::linked_ptr; +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; +using ::testing::internal::CaptureStdout; +using ::testing::internal::GetCapturedStdout; #endif class Incomplete { @@ -126,8 +80,7 @@ TEST(MockMethodTest, CanInstantiateWithIncompleteArgType) { // use the mock, as long as Google Mock knows how to print the // argument. MockIncomplete incomplete; - EXPECT_CALL(incomplete, ByRefFunc(_)) - .Times(AnyNumber()); + EXPECT_CALL(incomplete, ByRefFunc(_)).Times(AnyNumber()); } // The definition of the printer for the argument type doesn't have to @@ -146,7 +99,7 @@ class NonDefaultConstructible { class MockA { public: - MockA() {} + MockA() = default; MOCK_METHOD1(DoA, void(int n)); MOCK_METHOD1(ReturnResult, Result(int n)); @@ -155,28 +108,31 @@ class MockA { MOCK_METHOD2(ReturnInt, int(int x, int y)); private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockA); + MockA(const MockA&) = delete; + MockA& operator=(const MockA&) = delete; }; class MockB { public: - MockB() {} + MockB() = default; MOCK_CONST_METHOD0(DoB, int()); // NOLINT - MOCK_METHOD1(DoB, int(int n)); // NOLINT + MOCK_METHOD1(DoB, int(int n)); // NOLINT private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockB); + MockB(const MockB&) = delete; + MockB& operator=(const MockB&) = delete; }; class ReferenceHoldingMock { public: - ReferenceHoldingMock() {} + ReferenceHoldingMock() = default; - MOCK_METHOD1(AcceptReference, void(linked_ptr<MockA>*)); + MOCK_METHOD1(AcceptReference, void(std::shared_ptr<MockA>*)); private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(ReferenceHoldingMock); + ReferenceHoldingMock(const ReferenceHoldingMock&) = delete; + ReferenceHoldingMock& operator=(const ReferenceHoldingMock&) = delete; }; // Tests that EXPECT_CALL and ON_CALL compile in a presence of macro @@ -188,17 +144,18 @@ class ReferenceHoldingMock { class CC { public: - virtual ~CC() {} + virtual ~CC() = default; virtual int Method() = 0; }; class MockCC : public CC { public: - MockCC() {} + MockCC() = default; MOCK_METHOD0(Method, int()); private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockCC); + MockCC(const MockCC&) = delete; + MockCC& operator=(const MockCC&) = delete; }; // Tests that a method with expanded name compiles. @@ -254,41 +211,42 @@ TEST(OnCallSyntaxTest, EvaluatesSecondArgumentOnce) { TEST(OnCallSyntaxTest, WithIsOptional) { MockA a; - ON_CALL(a, DoA(5)) - .WillByDefault(Return()); - ON_CALL(a, DoA(_)) - .With(_) - .WillByDefault(Return()); + 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()"); + 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); - }, ""); + 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()"); + 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 @@ -316,21 +274,18 @@ TEST(ExpectCallSyntaxTest, EvaluatesSecondArgumentOnce) { TEST(ExpectCallSyntaxTest, WithIsOptional) { MockA a; - EXPECT_CALL(a, DoA(5)) - .Times(0); - EXPECT_CALL(a, DoA(6)) - .With(_) - .Times(0); + 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()"); + EXPECT_NONFATAL_FAILURE( + { // NOLINT + EXPECT_CALL(a, DoA(6)).With(_).With(_); + }, + ".With() cannot appear more than once in an EXPECT_CALL()"); a.DoA(6); } @@ -338,19 +293,19 @@ TEST(ExpectCallSyntaxTest, WithCanAppearAtMostOnce) { 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()"); + 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()"); + 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); } @@ -358,12 +313,9 @@ TEST(ExpectCallSyntaxTest, WithMustBeFirstClause) { TEST(ExpectCallSyntaxTest, TimesCanBeInferred) { MockA a; - EXPECT_CALL(a, DoA(1)) - .WillOnce(Return()); + EXPECT_CALL(a, DoA(1)).WillOnce(Return()); - EXPECT_CALL(a, DoA(2)) - .WillOnce(Return()) - .WillRepeatedly(Return()); + EXPECT_CALL(a, DoA(2)).WillOnce(Return()).WillRepeatedly(Return()); a.DoA(1); a.DoA(2); @@ -373,11 +325,11 @@ TEST(ExpectCallSyntaxTest, TimesCanBeInferred) { 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()"); + 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); @@ -387,11 +339,11 @@ TEST(ExpectCallSyntaxTest, TimesMustBeBeforeInSequence) { MockA a; Sequence s; - EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_CALL(a, DoA(1)) - .InSequence(s) - .Times(1); - }, ".Times() cannot appear after "); + EXPECT_NONFATAL_FAILURE( + { // NOLINT + EXPECT_CALL(a, DoA(1)).InSequence(s).Times(1); + }, + ".Times() may only appear *before* "); a.DoA(1); } @@ -401,8 +353,7 @@ TEST(ExpectCallSyntaxTest, InSequenceIsOptional) { Sequence s; EXPECT_CALL(a, DoA(1)); - EXPECT_CALL(a, DoA(2)) - .InSequence(s); + EXPECT_CALL(a, DoA(2)).InSequence(s); a.DoA(1); a.DoA(2); @@ -412,9 +363,7 @@ TEST(ExpectCallSyntaxTest, InSequenceCanAppearMultipleTimes) { MockA a; Sequence s1, s2; - EXPECT_CALL(a, DoA(1)) - .InSequence(s1, s2) - .InSequence(s1); + EXPECT_CALL(a, DoA(1)).InSequence(s1, s2).InSequence(s1); a.DoA(1); } @@ -423,13 +372,12 @@ 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 "); + 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); } @@ -438,11 +386,11 @@ TEST(ExpectCallSyntaxTest, InSequenceMustBeBeforeWillOnce) { MockA a; Sequence s; - EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_CALL(a, DoA(1)) - .WillOnce(Return()) - .InSequence(s); - }, ".InSequence() cannot appear after "); + EXPECT_NONFATAL_FAILURE( + { // NOLINT + EXPECT_CALL(a, DoA(1)).WillOnce(Return()).InSequence(s); + }, + ".InSequence() cannot appear after "); a.DoA(1); } @@ -451,11 +399,9 @@ 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 "); + EXPECT_NONFATAL_FAILURE( + { EXPECT_CALL(a, DoA(2)).WillOnce(Return()).After(e); }, + ".After() cannot appear after "); a.DoA(1); a.DoA(2); @@ -465,8 +411,7 @@ TEST(ExpectCallSyntaxTest, WillIsOptional) { MockA a; EXPECT_CALL(a, DoA(1)); - EXPECT_CALL(a, DoA(2)) - .WillOnce(Return()); + EXPECT_CALL(a, DoA(2)).WillOnce(Return()); a.DoA(1); a.DoA(2); @@ -485,11 +430,11 @@ TEST(ExpectCallSyntaxTest, WillCanAppearMultipleTimes) { TEST(ExpectCallSyntaxTest, WillMustBeBeforeWillRepeatedly) { MockA a; - EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_CALL(a, DoA(1)) - .WillRepeatedly(Return()) - .WillOnce(Return()); - }, ".WillOnce() cannot appear after "); + EXPECT_NONFATAL_FAILURE( + { // NOLINT + EXPECT_CALL(a, DoA(1)).WillRepeatedly(Return()).WillOnce(Return()); + }, + ".WillOnce() cannot appear after "); a.DoA(1); } @@ -497,11 +442,8 @@ TEST(ExpectCallSyntaxTest, WillMustBeBeforeWillRepeatedly) { TEST(ExpectCallSyntaxTest, WillRepeatedlyIsOptional) { MockA a; - EXPECT_CALL(a, DoA(1)) - .WillOnce(Return()); - EXPECT_CALL(a, DoA(2)) - .WillOnce(Return()) - .WillRepeatedly(Return()); + EXPECT_CALL(a, DoA(1)).WillOnce(Return()); + EXPECT_CALL(a, DoA(2)).WillOnce(Return()).WillRepeatedly(Return()); a.DoA(1); a.DoA(2); @@ -511,30 +453,30 @@ TEST(ExpectCallSyntaxTest, WillRepeatedlyIsOptional) { 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()"); + 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 "); + 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(); + EXPECT_CALL(a, DoA(1)).RetiresOnSaturation(); a.DoA(1); a.DoA(1); @@ -543,11 +485,11 @@ TEST(ExpectCallSyntaxTest, RetiresOnSaturationIsOptional) { TEST(ExpectCallSyntaxTest, RetiresOnSaturationCannotAppearMultipleTimes) { MockA a; - EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_CALL(a, DoA(1)) - .RetiresOnSaturation() - .RetiresOnSaturation(); - }, ".RetiresOnSaturation() cannot appear more than once"); + EXPECT_NONFATAL_FAILURE( + { // NOLINT + EXPECT_CALL(a, DoA(1)).RetiresOnSaturation().RetiresOnSaturation(); + }, + ".RetiresOnSaturation() cannot appear more than once"); a.DoA(1); } @@ -558,16 +500,20 @@ TEST(ExpectCallSyntaxTest, DefaultCardinalityIsOnce) { 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"); + 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 @@ -580,13 +526,9 @@ TEST(ExpectCallSyntaxTest, DoesNotWarnOnAdequateActionCount) { 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)); + 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)) @@ -596,10 +538,8 @@ TEST(ExpectCallSyntaxTest, DoesNotWarnOnAdequateActionCount) { // 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)); + EXPECT_CALL(b, DoB(4)).Times(AtMost(3)).WillOnce(Return(1)).WillRepeatedly( + Return(2)); // Satisfies the above expectations. b.DoB(2); @@ -616,13 +556,9 @@ TEST(ExpectCallSyntaxTest, WarnsOnTooManyActions) { 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()).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)) @@ -631,41 +567,34 @@ TEST(ExpectCallSyntaxTest, WarnsOnTooManyActions) { // 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 + 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())...\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())...\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" @@ -679,26 +608,23 @@ TEST(ExpectCallSyntaxTest, WarnsOnTooManyActions) { TEST(ExpectCallSyntaxTest, WarnsOnTooFewActions) { MockB b; - EXPECT_CALL(b, DoB()) - .Times(Between(2, 3)) - .WillOnce(Return(1)); + 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); + 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); + int original_behavior = GMOCK_FLAG_GET(default_mock_behavior); - testing::GMOCK_FLAG(default_mock_behavior) = kAllow; + GMOCK_FLAG_SET(default_mock_behavior, kAllow); CaptureStdout(); { MockA a; @@ -707,7 +633,7 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) { std::string output = GetCapturedStdout(); EXPECT_TRUE(output.empty()) << output; - testing::GMOCK_FLAG(default_mock_behavior) = kWarn; + GMOCK_FLAG_SET(default_mock_behavior, kWarn); CaptureStdout(); { MockA a; @@ -718,14 +644,16 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) { 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"); + GMOCK_FLAG_SET(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; + GMOCK_FLAG_SET(default_mock_behavior, -1); CaptureStdout(); { MockA a; @@ -735,7 +663,7 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) { 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; + GMOCK_FLAG_SET(default_mock_behavior, 3); CaptureStdout(); { MockA a; @@ -746,7 +674,7 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) { EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call", warning_output); - testing::GMOCK_FLAG(default_mock_behavior) = original_behavior; + GMOCK_FLAG_SET(default_mock_behavior, original_behavior); } #endif // GTEST_HAS_STREAM_REDIRECTION @@ -766,8 +694,7 @@ TEST(OnCallTest, TakesBuiltInDefaultActionWhenNoOnCall) { // matches the invocation. TEST(OnCallTest, TakesBuiltInDefaultActionWhenNoOnCallMatches) { MockB b; - ON_CALL(b, DoB(1)) - .WillByDefault(Return(1)); + ON_CALL(b, DoB(1)).WillByDefault(Return(1)); EXPECT_CALL(b, DoB(_)); EXPECT_EQ(0, b.DoB(2)); @@ -776,12 +703,9 @@ TEST(OnCallTest, TakesBuiltInDefaultActionWhenNoOnCallMatches) { // 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)); + 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)); @@ -805,25 +729,25 @@ TEST(ExpectCallTest, AllowsAnyCallWhenNoSpec) { // 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_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)); + EXPECT_NONFATAL_FAILURE( + { // NOLINT + MockB b; + EXPECT_CALL(b, DoB(5)).Description("DoB Method").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"); + b.DoB(5); + }, + "Actual function \"DoB Method\" 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 @@ -831,28 +755,24 @@ TEST(ExpectCallTest, CatchesTooFewCalls) { TEST(ExpectCallTest, InfersCardinalityWhenThereIsNoWillRepeatedly) { { MockB b; - EXPECT_CALL(b, DoB()) - .WillOnce(Return(1)) - .WillOnce(Return(2)); + 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_NONFATAL_FAILURE( + { // NOLINT + MockB b; + EXPECT_CALL(b, DoB()).WillOnce(Return(1)).WillOnce(Return(2)); - EXPECT_EQ(1, b.DoB()); - }, "to be called twice"); + EXPECT_EQ(1, b.DoB()); + }, + "to be called twice"); { // NOLINT MockB b; - EXPECT_CALL(b, DoB()) - .WillOnce(Return(1)) - .WillOnce(Return(2)); + EXPECT_CALL(b, DoB()).WillOnce(Return(1)).WillOnce(Return(2)); EXPECT_EQ(1, b.DoB()); EXPECT_EQ(2, b.DoB()); @@ -863,40 +783,79 @@ TEST(ExpectCallTest, InfersCardinalityWhenThereIsNoWillRepeatedly) { TEST(ExpectCallTest, InfersCardinality1WhenThereIsWillRepeatedly) { { MockB b; - EXPECT_CALL(b, DoB()) - .WillOnce(Return(1)) - .WillRepeatedly(Return(2)); + 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_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"); + EXPECT_NONFATAL_FAILURE( + { // NOLINT + MockB b; + EXPECT_CALL(b, DoB()).WillOnce(Return(1)).WillRepeatedly(Return(2)); + }, + "to be called at least once"); } +#if defined(GTEST_INTERNAL_CPLUSPLUS_LANG) && \ + GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L + +// It should be possible to return a non-moveable type from a mock action in +// C++17 and above, where it's guaranteed that such a type can be initialized +// from a prvalue returned from a function. +TEST(ExpectCallTest, NonMoveableType) { + // Define a non-moveable result type. + struct NonMoveableStruct { + explicit NonMoveableStruct(int x_in) : x(x_in) {} + NonMoveableStruct(NonMoveableStruct&&) = delete; + + int x; + }; + + static_assert(!std::is_move_constructible_v<NonMoveableStruct>); + static_assert(!std::is_copy_constructible_v<NonMoveableStruct>); + + static_assert(!std::is_move_assignable_v<NonMoveableStruct>); + static_assert(!std::is_copy_assignable_v<NonMoveableStruct>); + + // We should be able to use a callable that returns that result as both a + // OnceAction and an Action, whether the callable ignores arguments or not. + const auto return_17 = [] { return NonMoveableStruct(17); }; + + static_cast<void>(OnceAction<NonMoveableStruct()>{return_17}); + static_cast<void>(Action<NonMoveableStruct()>{return_17}); + + static_cast<void>(OnceAction<NonMoveableStruct(int)>{return_17}); + static_cast<void>(Action<NonMoveableStruct(int)>{return_17}); + + // It should be possible to return the result end to end through an + // EXPECT_CALL statement, with both WillOnce and WillRepeatedly. + MockFunction<NonMoveableStruct()> mock; + EXPECT_CALL(mock, Call) // + .WillOnce(return_17) // + .WillRepeatedly(return_17); + + EXPECT_EQ(17, mock.AsStdFunction()().x); + EXPECT_EQ(17, mock.AsStdFunction()().x); + EXPECT_EQ(17, mock.AsStdFunction()().x); +} + +#endif // C++17 and above + // 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_CALL(b, DoB()).WillOnce(Return(1)).WillOnce(Return(2)).WillOnce( + Return(3)); EXPECT_EQ(1, b.DoB()); EXPECT_EQ(2, b.DoB()); @@ -907,9 +866,7 @@ TEST(ExpectCallTest, NthMatchTakesNthAction) { // list is exhausted. TEST(ExpectCallTest, TakesRepeatedActionWhenWillListIsExhausted) { MockB b; - EXPECT_CALL(b, DoB()) - .WillOnce(Return(1)) - .WillRepeatedly(Return(2)); + EXPECT_CALL(b, DoB()).WillOnce(Return(1)).WillRepeatedly(Return(2)); EXPECT_EQ(1, b.DoB()); EXPECT_EQ(2, b.DoB()); @@ -922,8 +879,7 @@ TEST(ExpectCallTest, TakesRepeatedActionWhenWillListIsExhausted) { // exhausted and there is no WillRepeatedly(). TEST(ExpectCallTest, TakesDefaultActionWhenWillListIsExhausted) { MockB b; - EXPECT_CALL(b, DoB(_)) - .Times(1); + EXPECT_CALL(b, DoB(_)).Times(1); EXPECT_CALL(b, DoB()) .Times(AnyNumber()) .WillOnce(Return(1)) @@ -985,8 +941,7 @@ 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)); + 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 @@ -1000,8 +955,7 @@ 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)); + ON_CALL(a, Binary(_, _)).WillByDefault(Return(true)); EXPECT_CALL(a, Binary(0, 0)); a.Binary(0, 0); bool result = false; @@ -1012,11 +966,9 @@ TEST(UnexpectedCallTest, DoesDefaultAction) { // 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); + EXPECT_CALL(b, DoB(0)).Times(0); int n = -1; - EXPECT_NONFATAL_FAILURE(n = b.DoB(1), - "Unexpected mock function call"); + EXPECT_NONFATAL_FAILURE(n = b.DoB(1), "Unexpected mock function call"); EXPECT_EQ(0, n); } @@ -1093,14 +1045,12 @@ TEST(UnexpectedCallTest, GeneartesFailureForNonVoidFunction) { // match the call. TEST(UnexpectedCallTest, RetiredExpectation) { MockB b; - EXPECT_CALL(b, DoB(1)) - .RetiresOnSaturation(); + 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"); + 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 @@ -1109,27 +1059,21 @@ 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"); + 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) { +TEST(UnexpectedCallTest, UnsatisfiedPrerequisites) { 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); + 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; { @@ -1146,27 +1090,22 @@ TEST(UnexpectedCallTest, UnsatisifiedPrerequisites) { // 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")); +#ifdef 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( + "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 +#endif // GTEST_USES_POSIX_RE b.DoB(1); b.DoB(3); @@ -1192,8 +1131,7 @@ 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)); + ON_CALL(a, Binary(_, _)).WillByDefault(Return(true)); EXPECT_CALL(a, Binary(0, 0)); a.Binary(0, 0); bool result = false; @@ -1204,11 +1142,11 @@ TEST(ExcessiveCallTest, DoesDefaultAction) { // 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); + EXPECT_CALL(b, DoB(0)).Description("DoB Method").Times(0); int n = -1; - EXPECT_NONFATAL_FAILURE(n = b.DoB(0), - "Mock function called more times than expected"); + EXPECT_NONFATAL_FAILURE( + n = b.DoB(0), + "Mock function \"DoB Method\" called more times than expected"); EXPECT_EQ(0, n); } @@ -1216,11 +1154,11 @@ TEST(ExcessiveCallTest, DoesDefaultAction) { // the failure message contains the argument values. TEST(ExcessiveCallTest, GeneratesFailureForVoidFunction) { MockA a; - EXPECT_CALL(a, DoA(_)) - .Times(0); + EXPECT_CALL(a, DoA(_)).Description("DoA Method").Times(0); EXPECT_NONFATAL_FAILURE( a.DoA(9), - "Mock function called more times than expected - returning directly.\n" + "Mock function \"DoA Method\" 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"); @@ -1253,9 +1191,11 @@ TEST(InSequenceTest, AllExpectationInScopeAreInSequence) { EXPECT_CALL(a, DoA(2)); } - EXPECT_NONFATAL_FAILURE({ // NOLINT - a.DoA(2); - }, "Unexpected mock function call"); + EXPECT_NONFATAL_FAILURE( + { // NOLINT + a.DoA(2); + }, + "Unexpected mock function call"); a.DoA(1); a.DoA(2); @@ -1275,10 +1215,12 @@ TEST(InSequenceTest, NestedInSequence) { } } - EXPECT_NONFATAL_FAILURE({ // NOLINT - a.DoA(1); - a.DoA(3); - }, "Unexpected mock function call"); + EXPECT_NONFATAL_FAILURE( + { // NOLINT + a.DoA(1); + a.DoA(3); + }, + "Unexpected mock function call"); a.DoA(2); a.DoA(3); @@ -1294,9 +1236,11 @@ TEST(InSequenceTest, ExpectationsOutOfScopeAreNotAffected) { } EXPECT_CALL(a, DoA(3)); - EXPECT_NONFATAL_FAILURE({ // NOLINT - a.DoA(2); - }, "Unexpected mock function call"); + EXPECT_NONFATAL_FAILURE( + { // NOLINT + a.DoA(2); + }, + "Unexpected mock function call"); a.DoA(3); a.DoA(1); @@ -1310,8 +1254,7 @@ TEST(SequenceTest, AnyOrderIsOkByDefault) { MockB b; EXPECT_CALL(a, DoA(1)); - EXPECT_CALL(b, DoB()) - .Times(AnyNumber()); + EXPECT_CALL(b, DoB()).Times(AnyNumber()); a.DoA(1); b.DoB(); @@ -1322,8 +1265,7 @@ TEST(SequenceTest, AnyOrderIsOkByDefault) { MockB b; EXPECT_CALL(a, DoA(1)); - EXPECT_CALL(b, DoB()) - .Times(AnyNumber()); + EXPECT_CALL(b, DoB()).Times(AnyNumber()); b.DoB(); a.DoA(1); @@ -1334,16 +1276,12 @@ TEST(SequenceTest, AnyOrderIsOkByDefault) { // is specified. TEST(SequenceTest, CallsMustBeInStrictOrderWhenSaidSo1) { MockA a; - ON_CALL(a, ReturnResult(_)) - .WillByDefault(Return(Result())); + 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); + EXPECT_CALL(a, ReturnResult(1)).InSequence(s); + EXPECT_CALL(a, ReturnResult(2)).InSequence(s); + EXPECT_CALL(a, ReturnResult(3)).InSequence(s); a.ReturnResult(1); @@ -1358,14 +1296,11 @@ TEST(SequenceTest, CallsMustBeInStrictOrderWhenSaidSo1) { // is specified. TEST(SequenceTest, CallsMustBeInStrictOrderWhenSaidSo2) { MockA a; - ON_CALL(a, ReturnResult(_)) - .WillByDefault(Return(Result())); + 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(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"); @@ -1378,8 +1313,7 @@ TEST(SequenceTest, CallsMustBeInStrictOrderWhenSaidSo2) { class PartialOrderTest : public testing::Test { protected: PartialOrderTest() { - ON_CALL(a_, ReturnResult(_)) - .WillByDefault(Return(Result())); + ON_CALL(a_, ReturnResult(_)).WillByDefault(Return(Result())); // Specifies this partial ordering: // @@ -1387,16 +1321,10 @@ class PartialOrderTest : public testing::Test { // 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); + 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_; @@ -1448,13 +1376,9 @@ 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); + 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); @@ -1519,12 +1443,12 @@ TEST(ExpectationSetTest, ConstructorsWork) { Expectation e1; const Expectation e2; - ExpectationSet es1; // Default ctor. + 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 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()); @@ -1596,7 +1520,7 @@ TEST(ExpectationSetTest, IsEnumerable) { EXPECT_TRUE(it != es.end()); EXPECT_THAT(*it, Eq(Expectation())); ++it; - EXPECT_TRUE(it== es.end()); + EXPECT_TRUE(it == es.end()); } // Tests the .After() clause. @@ -1606,8 +1530,7 @@ TEST(AfterTest, SucceedsWhenPartialOrderIsSatisfied) { ExpectationSet es; es += EXPECT_CALL(a, DoA(1)); es += EXPECT_CALL(a, DoA(2)); - EXPECT_CALL(a, DoA(3)) - .After(es); + EXPECT_CALL(a, DoA(3)).After(es); a.DoA(1); a.DoA(2); @@ -1620,9 +1543,7 @@ TEST(AfterTest, SucceedsWhenTotalOrderIsSatisfied) { // 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); + const Expectation e2 = EXPECT_CALL(b, DoB()).Times(2).After(e1); EXPECT_CALL(a, DoA(2)).After(e2); a.DoA(1); @@ -1639,10 +1560,8 @@ TEST(AfterTest, CallsMustBeInStrictOrderWhenSpecifiedSo1) { // 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); + Expectation e2 = EXPECT_CALL(b, DoB()).After(e1); + EXPECT_CALL(a, DoA(2)).After(e2); a.DoA(1); @@ -1661,11 +1580,8 @@ TEST(AfterTest, CallsMustBeInStrictOrderWhenSpecifiedSo2) { // 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); + Expectation e2 = EXPECT_CALL(b, DoB()).Times(2).After(e1); + EXPECT_CALL(a, DoA(2)).After(e2); a.DoA(1); b.DoB(); @@ -1680,16 +1596,14 @@ TEST(AfterTest, CallsMustBeInStrictOrderWhenSpecifiedSo2) { // Calls must satisfy the partial order when specified so. TEST(AfterTest, CallsMustSatisfyPartialOrderWhenSpecifiedSo) { MockA a; - ON_CALL(a, ReturnResult(_)) - .WillByDefault(Return(Result())); + 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); + EXPECT_CALL(a, ReturnResult(3)).After(e, es); // May only be called last. EXPECT_NONFATAL_FAILURE(a.ReturnResult(3), "Unexpected mock function call"); @@ -1708,8 +1622,7 @@ TEST(AfterTest, CallsMustSatisfyPartialOrderWhenSpecifiedSo2) { // 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); + EXPECT_CALL(a, DoA(3)).After(e, es); a.DoA(2); @@ -1726,9 +1639,7 @@ TEST(AfterTest, CanBeUsedWithInSequence) { 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); + EXPECT_CALL(a, DoA(3)).InSequence(s).After(e); a.DoA(1); @@ -1745,10 +1656,7 @@ TEST(AfterTest, CanBeCalledManyTimes) { 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); + EXPECT_CALL(a, DoA(4)).After(e1).After(e2).After(e3); a.DoA(3); a.DoA(1); @@ -1764,8 +1672,7 @@ TEST(AfterTest, AcceptsUpToFiveArguments) { 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); + EXPECT_CALL(a, DoA(6)).After(e1, e2, e3, es1, es2); a.DoA(5); a.DoA(2); @@ -1778,8 +1685,7 @@ TEST(AfterTest, AcceptsUpToFiveArguments) { // .After() allows input to contain duplicated Expectations. TEST(AfterTest, AcceptsDuplicatedInput) { MockA a; - ON_CALL(a, ReturnResult(_)) - .WillByDefault(Return(Result())); + ON_CALL(a, ReturnResult(_)).WillByDefault(Return(Result())); // Define ordering: // DoA(1) ==> @@ -1789,8 +1695,7 @@ TEST(AfterTest, AcceptsDuplicatedInput) { ExpectationSet es; es += e1; es += e2; - EXPECT_CALL(a, ReturnResult(3)) - .After(e1, e2, es, e1); + EXPECT_CALL(a, ReturnResult(3)).After(e1, e2, es, e1); a.DoA(1); @@ -1807,8 +1712,7 @@ 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); + EXPECT_CALL(a, DoA(3)).After(es1); es1 += e2; a.DoA(1); @@ -1827,14 +1731,11 @@ TEST(DeletingMockEarlyTest, Success1) { { InSequence dummy; - EXPECT_CALL(*b1, DoB(_)) - .WillOnce(Return(1)); + 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_CALL(*b2, DoB(_)).Times(AnyNumber()).WillRepeatedly(Return(2)); } EXPECT_EQ(1, b1->DoB(1)); @@ -1855,13 +1756,9 @@ TEST(DeletingMockEarlyTest, Success2) { { InSequence dummy; - EXPECT_CALL(*b1, DoB(_)) - .WillOnce(Return(1)); - EXPECT_CALL(*a, Binary(_, _)) - .Times(AnyNumber()); - EXPECT_CALL(*b2, DoB(_)) - .Times(AnyNumber()) - .WillRepeatedly(Return(2)); + 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. @@ -1875,16 +1772,11 @@ TEST(DeletingMockEarlyTest, Success2) { // Suppresses warning on unreferenced formal parameter in MSVC with // -W4. -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable:4100) -#endif +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100) ACTION_P(Delete, ptr) { delete ptr; } -#ifdef _MSC_VER -# pragma warning(pop) -#endif +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100 TEST(DeletingMockEarlyTest, CanDeleteSelfInActionReturningVoid) { MockA* const a = new MockA; @@ -1894,8 +1786,7 @@ TEST(DeletingMockEarlyTest, CanDeleteSelfInActionReturningVoid) { TEST(DeletingMockEarlyTest, CanDeleteSelfInActionReturningValue) { MockA* const a = new MockA; - EXPECT_CALL(*a, ReturnResult(_)) - .WillOnce(DoAll(Delete(a), Return(Result()))); + EXPECT_CALL(*a, ReturnResult(_)).WillOnce(DoAll(Delete(a), Return(Result()))); a->ReturnResult(42); // This will cause a to be deleted. } @@ -1907,19 +1798,13 @@ TEST(DeletingMockEarlyTest, Failure1) { { InSequence dummy; - EXPECT_CALL(*b1, DoB(_)) - .WillOnce(Return(1)); - EXPECT_CALL(*a, Binary(_, _)) - .Times(AnyNumber()); - EXPECT_CALL(*b2, DoB(_)) - .Times(AnyNumber()) - .WillRepeatedly(Return(2)); + 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_NONFATAL_FAILURE({ b2->DoB(2); }, "Unexpected mock function call"); EXPECT_EQ(1, b1->DoB(1)); delete b1; delete b2; @@ -1934,57 +1819,47 @@ TEST(DeletingMockEarlyTest, Failure2) { { InSequence dummy; EXPECT_CALL(*b1, DoB(_)); - EXPECT_CALL(*a, Binary(_, _)) - .Times(AnyNumber()); - EXPECT_CALL(*b2, DoB(_)) - .Times(AnyNumber()); + 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"); + EXPECT_NONFATAL_FAILURE(delete b1, "Actual: never called"); + EXPECT_NONFATAL_FAILURE(a->Binary(0, 1), "Unexpected mock function call"); + EXPECT_NONFATAL_FAILURE(b2->DoB(1), "Unexpected mock function call"); delete a; delete b2; } class EvenNumberCardinality : public CardinalityInterface { public: - // Returns true iff call_count calls will satisfy this cardinality. - virtual bool IsSatisfiedByCallCount(int call_count) const { + // 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 iff call_count calls will saturate this cardinality. - virtual bool IsSaturatedByCallCount(int /* call_count */) const { + // 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. - virtual void DescribeTo(::std::ostream* os) const { + void DescribeTo(::std::ostream* os) const override { *os << "called even number of times"; } }; -Cardinality EvenNumber() { - return Cardinality(new EvenNumberCardinality); -} +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()); + 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); @@ -1995,8 +1870,7 @@ TEST(ExpectationBaseTest, // The following tests verify the message generated when a mock // function is called. -struct Printable { -}; +struct Printable {}; inline void operator<<(::std::ostream& os, const Printable&) { os << "Printable"; @@ -2009,27 +1883,32 @@ struct Unprintable { class MockC { public: - MockC() {} + MockC() = default; 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); + MockC(const MockC&) = delete; + MockC& operator=(const MockC&) = delete; }; class VerboseFlagPreservingFixture : public testing::Test { protected: VerboseFlagPreservingFixture() - : saved_verbose_flag_(GMOCK_FLAG(verbose)) {} + : saved_verbose_flag_(GMOCK_FLAG_GET(verbose)) {} - ~VerboseFlagPreservingFixture() { GMOCK_FLAG(verbose) = saved_verbose_flag_; } + ~VerboseFlagPreservingFixture() override { + GMOCK_FLAG_SET(verbose, saved_verbose_flag_); + } private: const std::string saved_verbose_flag_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(VerboseFlagPreservingFixture); + VerboseFlagPreservingFixture(const VerboseFlagPreservingFixture&) = delete; + VerboseFlagPreservingFixture& operator=(const VerboseFlagPreservingFixture&) = + delete; }; #if GTEST_HAS_STREAM_REDIRECTION @@ -2039,10 +1918,10 @@ class VerboseFlagPreservingFixture : public testing::Test { // --gmock_verbose=warning is specified. TEST(FunctionCallMessageTest, UninterestingCallOnNaggyMockGeneratesNoStackTraceWhenVerboseWarning) { - GMOCK_FLAG(verbose) = kWarningVerbosity; + GMOCK_FLAG_SET(verbose, kWarningVerbosity); NaggyMock<MockC> c; CaptureStdout(); - c.VoidMethod(false, 5, "Hi", NULL, Printable(), Unprintable()); + 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); @@ -2053,15 +1932,15 @@ TEST(FunctionCallMessageTest, // --gmock_verbose=info is specified. TEST(FunctionCallMessageTest, UninterestingCallOnNaggyMockGeneratesFyiWithStackTraceWhenVerboseInfo) { - GMOCK_FLAG(verbose) = kInfoVerbosity; + GMOCK_FLAG_SET(verbose, kInfoVerbosity); NaggyMock<MockC> c; CaptureStdout(); - c.VoidMethod(false, 5, "Hi", NULL, Printable(), Unprintable()); + 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 +#ifndef NDEBUG // We check the stack trace content in dbg-mode only, as opt-mode // may inline the call we are interested in seeing. @@ -2077,7 +1956,7 @@ TEST(FunctionCallMessageTest, const std::string output2 = GetCapturedStdout(); EXPECT_PRED_FORMAT2(IsSubstring, "NonVoidMethod(", output2); -# endif // NDEBUG +#endif // NDEBUG } // Tests that an uninteresting mock function call on a naggy mock @@ -2093,20 +1972,21 @@ TEST(FunctionCallMessageTest, IsSubstring, "Uninteresting mock function call - returning default value.\n" " Function call: DoB()\n" - " Returns: 0\n", output1.c_str()); + " 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", NULL, Printable(), Unprintable()); + 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>\\)")); + 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. } @@ -2123,14 +2003,14 @@ class GMockVerboseFlagTest : public VerboseFlagPreservingFixture { const std::string& function_name) { if (should_print) { EXPECT_THAT(output.c_str(), HasSubstr(expected_substring)); -# ifndef NDEBUG +#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 +#else // Suppresses 'unused function parameter' warnings. static_cast<void>(function_name); -# endif // NDEBUG +#endif // NDEBUG } else { EXPECT_STREQ("", output.c_str()); } @@ -2140,31 +2020,26 @@ class GMockVerboseFlagTest : public VerboseFlagPreservingFixture { void TestExpectedCall(bool should_print) { MockA a; EXPECT_CALL(a, DoA(5)); - EXPECT_CALL(a, Binary(_, 1)) - .WillOnce(Return(true)); + 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"); + 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"); + 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. @@ -2175,41 +2050,37 @@ class GMockVerboseFlagTest : public VerboseFlagPreservingFixture { "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/" - "CookBook.md#" - "knowing-when-to-expect for details."; + "https://github.com/google/googletest/blob/main/docs/" + "gmock_cook_book.md#" + "knowing-when-to-expect-useoncall 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"); + 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"); + 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; + GMOCK_FLAG_SET(verbose, kInfoVerbosity); TestExpectedCall(true); TestUninterestingCallOnNaggyMock(true); } @@ -2217,7 +2088,7 @@ TEST_F(GMockVerboseFlagTest, Info) { // Tests that --gmock_verbose=warning causes uninteresting calls to be // reported. TEST_F(GMockVerboseFlagTest, Warning) { - GMOCK_FLAG(verbose) = kWarningVerbosity; + GMOCK_FLAG_SET(verbose, kWarningVerbosity); TestExpectedCall(false); TestUninterestingCallOnNaggyMock(true); } @@ -2225,7 +2096,7 @@ TEST_F(GMockVerboseFlagTest, Warning) { // Tests that --gmock_verbose=warning causes neither expected nor // uninteresting calls to be reported. TEST_F(GMockVerboseFlagTest, Error) { - GMOCK_FLAG(verbose) = kErrorVerbosity; + GMOCK_FLAG_SET(verbose, kErrorVerbosity); TestExpectedCall(false); TestUninterestingCallOnNaggyMock(false); } @@ -2233,7 +2104,7 @@ TEST_F(GMockVerboseFlagTest, Error) { // 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". + GMOCK_FLAG_SET(verbose, "invalid"); // Treated as "warning". TestExpectedCall(false); TestUninterestingCallOnNaggyMock(true); } @@ -2252,12 +2123,13 @@ void PrintTo(PrintMeNot /* dummy */, ::std::ostream* /* os */) { class LogTestHelper { public: - LogTestHelper() {} + LogTestHelper() = default; MOCK_METHOD1(Foo, PrintMeNot(PrintMeNot)); private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(LogTestHelper); + LogTestHelper(const LogTestHelper&) = delete; + LogTestHelper& operator=(const LogTestHelper&) = delete; }; class GMockLogTest : public VerboseFlagPreservingFixture { @@ -2266,23 +2138,20 @@ class GMockLogTest : public VerboseFlagPreservingFixture { }; TEST_F(GMockLogTest, DoesNotPrintGoodCallInternallyIfVerbosityIsWarning) { - GMOCK_FLAG(verbose) = kWarningVerbosity; - EXPECT_CALL(helper_, Foo(_)) - .WillOnce(Return(PrintMeNot())); + GMOCK_FLAG_SET(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())); + GMOCK_FLAG_SET(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())); + GMOCK_FLAG_SET(verbose, kErrorVerbosity); + ON_CALL(helper_, Foo(_)).WillByDefault(Return(PrintMeNot())); helper_.Foo(PrintMeNot()); // This should generate a warning. } @@ -2343,8 +2212,7 @@ TEST(VerifyAndClearExpectationsTest, NoMethodHasExpectations) { // verification succeeds. TEST(VerifyAndClearExpectationsTest, SomeMethodsHaveExpectationsAndSucceed) { MockB b; - EXPECT_CALL(b, DoB()) - .WillOnce(Return(1)); + EXPECT_CALL(b, DoB()).WillOnce(Return(1)); b.DoB(); ASSERT_TRUE(Mock::VerifyAndClearExpectations(&b)); @@ -2359,8 +2227,7 @@ TEST(VerifyAndClearExpectationsTest, SomeMethodsHaveExpectationsAndSucceed) { // verification fails. TEST(VerifyAndClearExpectationsTest, SomeMethodsHaveExpectationsAndFail) { MockB b; - EXPECT_CALL(b, DoB()) - .WillOnce(Return(1)); + EXPECT_CALL(b, DoB()).WillOnce(Return(1)); bool result = true; EXPECT_NONFATAL_FAILURE(result = Mock::VerifyAndClearExpectations(&b), "Actual: never called"); @@ -2376,10 +2243,8 @@ TEST(VerifyAndClearExpectationsTest, SomeMethodsHaveExpectationsAndFail) { // 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)); + EXPECT_CALL(b, DoB()).WillOnce(Return(1)); + EXPECT_CALL(b, DoB(_)).WillOnce(Return(2)); b.DoB(); b.DoB(1); ASSERT_TRUE(Mock::VerifyAndClearExpectations(&b)); @@ -2394,10 +2259,8 @@ TEST(VerifyAndClearExpectationsTest, AllMethodsHaveExpectations) { // 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)); + 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), @@ -2418,8 +2281,7 @@ TEST(VerifyAndClearExpectationsTest, CanCallManyTimes) { b.DoB(); Mock::VerifyAndClearExpectations(&b); - EXPECT_CALL(b, DoB(_)) - .WillOnce(Return(1)); + EXPECT_CALL(b, DoB(_)).WillOnce(Return(1)); b.DoB(1); Mock::VerifyAndClearExpectations(&b); Mock::VerifyAndClearExpectations(&b); @@ -2443,8 +2305,7 @@ TEST(VerifyAndClearTest, NoMethodHasDefaultActions) { // but not all of its methods have default actions. TEST(VerifyAndClearTest, SomeMethodsHaveDefaultActions) { MockB b; - ON_CALL(b, DoB()) - .WillByDefault(Return(1)); + ON_CALL(b, DoB()).WillByDefault(Return(1)); Mock::VerifyAndClear(&b); @@ -2456,10 +2317,8 @@ TEST(VerifyAndClearTest, SomeMethodsHaveDefaultActions) { // its methods have default actions. TEST(VerifyAndClearTest, AllMethodsHaveDefaultActions) { MockB b; - ON_CALL(b, DoB()) - .WillByDefault(Return(1)); - ON_CALL(b, DoB(_)) - .WillByDefault(Return(2)); + ON_CALL(b, DoB()).WillByDefault(Return(1)); + ON_CALL(b, DoB(_)).WillByDefault(Return(2)); Mock::VerifyAndClear(&b); @@ -2474,10 +2333,8 @@ TEST(VerifyAndClearTest, AllMethodsHaveDefaultActions) { // 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)); + ON_CALL(b, DoB(0)).WillByDefault(Return(1)); + ON_CALL(b, DoB(_)).WillByDefault(Return(2)); Mock::VerifyAndClear(&b); @@ -2491,13 +2348,11 @@ TEST(VerifyAndClearTest, AMethodHasManyDefaultActions) { // times. TEST(VerifyAndClearTest, CanCallManyTimes) { MockB b; - ON_CALL(b, DoB()) - .WillByDefault(Return(1)); + ON_CALL(b, DoB()).WillByDefault(Return(1)); Mock::VerifyAndClear(&b); Mock::VerifyAndClear(&b); - ON_CALL(b, DoB(_)) - .WillByDefault(Return(1)); + ON_CALL(b, DoB(_)).WillByDefault(Return(1)); Mock::VerifyAndClear(&b); EXPECT_EQ(0, b.DoB()); @@ -2507,10 +2362,8 @@ TEST(VerifyAndClearTest, CanCallManyTimes) { // 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)); + ON_CALL(b, DoB()).WillByDefault(Return(1)); + EXPECT_CALL(b, DoB(1)).WillOnce(Return(2)); b.DoB(); b.DoB(1); @@ -2525,10 +2378,8 @@ TEST(VerifyAndClearTest, Success) { // 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)); + ON_CALL(b, DoB(_)).WillByDefault(Return(1)); + EXPECT_CALL(b, DoB()).WillOnce(Return(2)); b.DoB(1); bool result = true; @@ -2546,12 +2397,9 @@ TEST(VerifyAndClearTest, Failure) { // expectations are set on a const mock object. TEST(VerifyAndClearTest, Const) { MockB b; - ON_CALL(Const(b), DoB()) - .WillByDefault(Return(1)); + ON_CALL(Const(b), DoB()).WillByDefault(Return(1)); - EXPECT_CALL(Const(b), DoB()) - .WillOnce(DoDefault()) - .WillOnce(Return(2)); + EXPECT_CALL(Const(b), DoB()).WillOnce(DoDefault()).WillOnce(Return(2)); b.DoB(); b.DoB(); @@ -2567,18 +2415,14 @@ TEST(VerifyAndClearTest, Const) { // 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)); + 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_CALL(b, DoB()).WillOnce(Return(3)); + ON_CALL(b, DoB(_)).WillByDefault(Return(4)); EXPECT_EQ(3, b.DoB()); EXPECT_EQ(4, b.DoB(1)); @@ -2591,19 +2435,13 @@ TEST(VerifyAndClearTest, DoesNotAffectOtherMockObjects) { MockB b1; MockB b2; - ON_CALL(a, Binary(_, _)) - .WillByDefault(Return(true)); - EXPECT_CALL(a, Binary(_, _)) - .WillOnce(DoDefault()) - .WillOnce(Return(false)); + 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(b1, DoB()).WillByDefault(Return(1)); + EXPECT_CALL(b1, DoB(_)).WillOnce(Return(2)); - ON_CALL(b2, DoB()) - .WillByDefault(Return(3)); + ON_CALL(b2, DoB()).WillByDefault(Return(3)); EXPECT_CALL(b2, DoB(_)); b2.DoB(0); @@ -2620,7 +2458,7 @@ TEST(VerifyAndClearTest, DoesNotAffectOtherMockObjects) { TEST(VerifyAndClearTest, DestroyingChainedMocksDoesNotDeadlockThroughExpectations) { - linked_ptr<MockA> a(new MockA); + std::shared_ptr<MockA> a(new MockA); ReferenceHoldingMock test_mock; // EXPECT_CALL stores a reference to a inside test_mock. @@ -2640,12 +2478,11 @@ TEST(VerifyAndClearTest, TEST(VerifyAndClearTest, DestroyingChainedMocksDoesNotDeadlockThroughDefaultAction) { - linked_ptr<MockA> a(new MockA); + 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)); + 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. @@ -2666,9 +2503,8 @@ TEST(VerifyAndClearTest, TEST(SynchronizationTest, CanCallMockMethodInAction) { MockA a; MockC c; - ON_CALL(a, DoA(_)) - .WillByDefault(IgnoreResult(InvokeWithoutArgs(&c, - &MockC::NonVoidMethod))); + 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)) @@ -2752,20 +2588,14 @@ TEST(ParameterlessExpectationsTest, } } // namespace +} // namespace testing -// 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 +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) = testing::internal::kWarningVerbosity; + GMOCK_FLAG_SET(catch_leaked_mocks, true); + GMOCK_FLAG_SET(verbose, testing::internal::kWarningVerbosity); return RUN_ALL_TESTS(); } diff --git a/contrib/googletest/googlemock/test/gmock_all_test.cc b/contrib/googletest/googlemock/test/gmock_all_test.cc index e1774fbb8ef5..6db0086bb724 100644 --- a/contrib/googletest/googlemock/test/gmock_all_test.cc +++ b/contrib/googletest/googlemock/test/gmock_all_test.cc @@ -37,12 +37,11 @@ // 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-generated-function-mockers_test.cc" -#include "test/gmock-generated-internal-utils_test.cc" -#include "test/gmock-generated-matchers_test.cc" #include "test/gmock-internal-utils_test.cc" -#include "test/gmock-matchers_test.cc" +#include "test/gmock-matchers-arithmetic_test.cc" +#include "test/gmock-matchers-comparisons_test.cc" +#include "test/gmock-matchers-containers_test.cc" +#include "test/gmock-matchers-misc_test.cc" #include "test/gmock-more-actions_test.cc" #include "test/gmock-nice-strict_test.cc" #include "test/gmock-port_test.cc" diff --git a/contrib/googletest/googlemock/test/gmock_ex_test.cc b/contrib/googletest/googlemock/test/gmock_ex_test.cc index 72eb43f74ef4..e174122d9f63 100644 --- a/contrib/googletest/googlemock/test/gmock_ex_test.cc +++ b/contrib/googletest/googlemock/test/gmock_ex_test.cc @@ -27,9 +27,10 @@ // (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 <exception> + #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -75,6 +76,5 @@ TEST(DefaultValueTest, ThrowsRuntimeErrorWhenNoDefaultValue) { } } - } // unnamed namespace #endif diff --git a/contrib/googletest/googlemock/test/gmock_leak_test.py b/contrib/googletest/googlemock/test/gmock_leak_test.py index 7e4b1eea9ae8..8b02bc465d38 100755 --- a/contrib/googletest/googlemock/test/gmock_leak_test.py +++ b/contrib/googletest/googlemock/test/gmock_leak_test.py @@ -31,7 +31,7 @@ """Tests that leaked mock objects can be caught be Google Mock.""" -import gmock_test_utils +from googlemock.test import gmock_test_utils PROGRAM_PATH = gmock_test_utils.GetTestExecutablePath('gmock_leak_test_') TEST_WITH_EXPECT_CALL = [PROGRAM_PATH, '--gtest_filter=*ExpectCall*'] @@ -54,50 +54,59 @@ class GMockLeakTest(gmock_test_utils.TestCase): def testCatchesLeakedMockByDefault(self): self.assertNotEqual( 0, - gmock_test_utils.Subprocess(TEST_WITH_EXPECT_CALL, - env=environ).exit_code) + 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) + 0, gmock_test_utils.Subprocess(TEST_WITH_ON_CALL, env=environ).exit_code + ) def testDoesNotCatchLeakedMockWhenDisabled(self): - self.assertEquals( + self.assertEqual( 0, - gmock_test_utils.Subprocess(TEST_WITH_EXPECT_CALL + - ['--gmock_catch_leaked_mocks=0'], - env=environ).exit_code) - self.assertEquals( + gmock_test_utils.Subprocess( + TEST_WITH_EXPECT_CALL + ['--gmock_catch_leaked_mocks=0'], + env=environ, + ).exit_code, + ) + self.assertEqual( 0, - gmock_test_utils.Subprocess(TEST_WITH_ON_CALL + - ['--gmock_catch_leaked_mocks=0'], - env=environ).exit_code) + 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) + 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) + 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) + 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) + gmock_test_utils.Subprocess( + TEST_MULTIPLE_LEAKS + ['--gmock_catch_leaked_mocks'], env=environ + ).exit_code, + ) if __name__ == '__main__': diff --git a/contrib/googletest/googlemock/test/gmock_leak_test_.cc b/contrib/googletest/googlemock/test/gmock_leak_test_.cc index 2e095abcf496..a6bb339219f5 100644 --- a/contrib/googletest/googlemock/test/gmock_leak_test_.cc +++ b/contrib/googletest/googlemock/test/gmock_leak_test_.cc @@ -27,7 +27,6 @@ // (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 @@ -41,18 +40,19 @@ using ::testing::Return; class FooInterface { public: - virtual ~FooInterface() {} + virtual ~FooInterface() = default; virtual void DoThis() = 0; }; class MockFoo : public FooInterface { public: - MockFoo() {} + MockFoo() = default; MOCK_METHOD0(DoThis, void()); private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo); + MockFoo(const MockFoo&) = delete; + MockFoo& operator=(const MockFoo&) = delete; }; TEST(LeakTest, LeakedMockWithExpectCallCausesFailureWhenLeakCheckingIsEnabled) { diff --git a/contrib/googletest/googlemock/test/gmock_link2_test.cc b/contrib/googletest/googlemock/test/gmock_link2_test.cc index d27ce176887b..cd3d69088761 100644 --- a/contrib/googletest/googlemock/test/gmock_link2_test.cc +++ b/contrib/googletest/googlemock/test/gmock_link2_test.cc @@ -27,7 +27,6 @@ // (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 diff --git a/contrib/googletest/googlemock/test/gmock_link_test.cc b/contrib/googletest/googlemock/test/gmock_link_test.cc index e7c54cc23068..f51e3988df3a 100644 --- a/contrib/googletest/googlemock/test/gmock_link_test.cc +++ b/contrib/googletest/googlemock/test/gmock_link_test.cc @@ -27,7 +27,6 @@ // (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 diff --git a/contrib/googletest/googlemock/test/gmock_link_test.h b/contrib/googletest/googlemock/test/gmock_link_test.h index d26670ecd4f9..db11c2d24d1a 100644 --- a/contrib/googletest/googlemock/test/gmock_link_test.h +++ b/contrib/googletest/googlemock/test/gmock_link_test.h @@ -27,7 +27,6 @@ // (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: @@ -112,13 +111,13 @@ // 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_ +#ifndef GOOGLEMOCK_TEST_GMOCK_LINK_TEST_H_ +#define GOOGLEMOCK_TEST_GMOCK_LINK_TEST_H_ #include "gmock/gmock.h" -#if !GTEST_OS_WINDOWS_MOBILE -# include <errno.h> +#ifndef GTEST_OS_WINDOWS_MOBILE +#include <errno.h> #endif #include <iostream> @@ -182,7 +181,7 @@ using testing::WithArg; using testing::WithArgs; using testing::WithoutArgs; -#if !GTEST_OS_WINDOWS_MOBILE +#ifndef GTEST_OS_WINDOWS_MOBILE using testing::SetErrnoAndReturn; #endif @@ -195,34 +194,35 @@ using testing::MatchesRegex; class Interface { public: - virtual ~Interface() {} + virtual ~Interface() = default; 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 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 { +class Mock : public Interface { public: - Mock() {} + Mock() = default; 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(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); + Mock(const Mock&) = delete; + Mock& operator=(const Mock&) = delete; }; class InvokeHelper { @@ -248,7 +248,7 @@ TEST(LinkTest, TestReturnVoid) { Mock mock; EXPECT_CALL(mock, VoidFromString(_)).WillOnce(Return()); - mock.VoidFromString(NULL); + mock.VoidFromString(nullptr); } // Tests the linkage of the Return action. @@ -257,7 +257,7 @@ TEST(LinkTest, TestReturn) { char ch = 'x'; EXPECT_CALL(mock, StringFromString(_)).WillOnce(Return(&ch)); - mock.StringFromString(NULL); + mock.StringFromString(nullptr); } // Tests the linkage of the ReturnNull action. @@ -265,7 +265,7 @@ TEST(LinkTest, TestReturnNull) { Mock mock; EXPECT_CALL(mock, VoidFromString(_)).WillOnce(Return()); - mock.VoidFromString(NULL); + mock.VoidFromString(nullptr); } // Tests the linkage of the ReturnRef action. @@ -274,7 +274,7 @@ TEST(LinkTest, TestReturnRef) { int n = 42; EXPECT_CALL(mock, IntRefFromString(_)).WillOnce(ReturnRef(n)); - mock.IntRefFromString(NULL); + mock.IntRefFromString(nullptr); } // Tests the linkage of the Assign action. @@ -283,7 +283,7 @@ TEST(LinkTest, TestAssign) { char ch = 'x'; EXPECT_CALL(mock, VoidFromString(_)).WillOnce(Assign(&ch, 'y')); - mock.VoidFromString(NULL); + mock.VoidFromString(nullptr); } // Tests the linkage of the SetArgPointee action. @@ -301,12 +301,12 @@ TEST(LinkTest, TestSetArrayArgument) { char ch = 'x'; char ch2 = 'y'; - EXPECT_CALL(mock, VoidFromString(_)).WillOnce(SetArrayArgument<0>(&ch2, - &ch2 + 1)); + EXPECT_CALL(mock, VoidFromString(_)) + .WillOnce(SetArrayArgument<0>(&ch2, &ch2 + 1)); mock.VoidFromString(&ch); } -#if !GTEST_OS_WINDOWS_MOBILE +#ifndef GTEST_OS_WINDOWS_MOBILE // Tests the linkage of the SetErrnoAndReturn action. TEST(LinkTest, TestSetErrnoAndReturn) { @@ -314,7 +314,7 @@ TEST(LinkTest, TestSetErrnoAndReturn) { int saved_errno = errno; EXPECT_CALL(mock, IntFromString(_)).WillOnce(SetErrnoAndReturn(1, -1)); - mock.IntFromString(NULL); + mock.IntFromString(nullptr); errno = saved_errno; } @@ -328,8 +328,8 @@ TEST(LinkTest, TestInvoke) { EXPECT_CALL(mock, VoidFromString(_)) .WillOnce(Invoke(&InvokeHelper::StaticVoidFromString)) .WillOnce(Invoke(&test_invoke_helper, &InvokeHelper::VoidFromString)); - mock.VoidFromString(NULL); - mock.VoidFromString(NULL); + mock.VoidFromString(nullptr); + mock.VoidFromString(nullptr); } // Tests the linkage of the InvokeWithoutArgs action. @@ -339,10 +339,10 @@ TEST(LinkTest, TestInvokeWithoutArgs) { EXPECT_CALL(mock, VoidFromString(_)) .WillOnce(InvokeWithoutArgs(&InvokeHelper::StaticVoidFromVoid)) - .WillOnce(InvokeWithoutArgs(&test_invoke_helper, - &InvokeHelper::VoidFromVoid)); - mock.VoidFromString(NULL); - mock.VoidFromString(NULL); + .WillOnce( + InvokeWithoutArgs(&test_invoke_helper, &InvokeHelper::VoidFromVoid)); + mock.VoidFromString(nullptr); + mock.VoidFromString(nullptr); } // Tests the linkage of the InvokeArgument action. @@ -360,7 +360,7 @@ TEST(LinkTest, TestWithArg) { EXPECT_CALL(mock, VoidFromString(_)) .WillOnce(WithArg<0>(Invoke(&InvokeHelper::StaticVoidFromString))); - mock.VoidFromString(NULL); + mock.VoidFromString(nullptr); } // Tests the linkage of the WithArgs action. @@ -369,7 +369,7 @@ TEST(LinkTest, TestWithArgs) { EXPECT_CALL(mock, VoidFromString(_)) .WillOnce(WithArgs<0>(Invoke(&InvokeHelper::StaticVoidFromString))); - mock.VoidFromString(NULL); + mock.VoidFromString(nullptr); } // Tests the linkage of the WithoutArgs action. @@ -377,7 +377,7 @@ TEST(LinkTest, TestWithoutArgs) { Mock mock; EXPECT_CALL(mock, VoidFromString(_)).WillOnce(WithoutArgs(Return())); - mock.VoidFromString(NULL); + mock.VoidFromString(nullptr); } // Tests the linkage of the DoAll action. @@ -405,7 +405,7 @@ TEST(LinkTest, TestIgnoreResult) { Mock mock; EXPECT_CALL(mock, VoidFromString(_)).WillOnce(IgnoreResult(Return(42))); - mock.VoidFromString(NULL); + mock.VoidFromString(nullptr); } #if GTEST_HAS_EXCEPTIONS @@ -414,7 +414,7 @@ TEST(LinkTest, TestThrow) { Mock mock; EXPECT_CALL(mock, VoidFromString(_)).WillOnce(Throw(42)); - EXPECT_THROW(mock.VoidFromString(NULL), int); + EXPECT_THROW(mock.VoidFromString(nullptr), int); } #endif // GTEST_HAS_EXCEPTIONS @@ -423,33 +423,30 @@ TEST(LinkTest, TestThrow) { // 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 +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100) // Tests the linkage of actions created using ACTION macro. namespace { ACTION(Return1) { return 1; } -} +} // namespace TEST(LinkTest, TestActionMacro) { Mock mock; EXPECT_CALL(mock, IntFromString(_)).WillOnce(Return1()); - mock.IntFromString(NULL); + mock.IntFromString(nullptr); } // Tests the linkage of actions created using ACTION_P macro. namespace { ACTION_P(ReturnArgument, ret_value) { return ret_value; } -} +} // namespace TEST(LinkTest, TestActionPMacro) { Mock mock; EXPECT_CALL(mock, IntFromString(_)).WillOnce(ReturnArgument(42)); - mock.IntFromString(NULL); + mock.IntFromString(nullptr); } // Tests the linkage of actions created using ACTION_P2 macro. @@ -457,11 +454,9 @@ namespace { ACTION_P2(ReturnEqualsEitherOf, first, second) { return arg0 == first || arg0 == second; } -} +} // namespace -#ifdef _MSC_VER -# pragma warning(pop) -#endif +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100 TEST(LinkTest, TestActionP2Macro) { Mock mock; @@ -492,8 +487,7 @@ TEST(LinkTest, TestMatchersEq) { const char* p = "x"; ON_CALL(mock, VoidFromString(Eq(p))).WillByDefault(Return()); - ON_CALL(mock, VoidFromString(const_cast<char*>("y"))) - .WillByDefault(Return()); + ON_CALL(mock, VoidFromString(const_cast<char*>("y"))).WillByDefault(Return()); } // Tests the linkage of the Lt, Gt, Le, Ge, and Ne matchers. @@ -592,7 +586,7 @@ TEST(LinkTest, TestMatcherElementsAre) { // Tests the linkage of the ElementsAreArray matcher. TEST(LinkTest, TestMatcherElementsAreArray) { Mock mock; - char arr[] = { 'a', 'b' }; + char arr[] = {'a', 'b'}; ON_CALL(mock, VoidFromVector(ElementsAreArray(arr))).WillByDefault(Return()); } @@ -646,7 +640,7 @@ TEST(LinkTest, TestMatcherProperty) { // Tests the linkage of the ResultOf matcher. TEST(LinkTest, TestMatcherResultOf) { Matcher<char*> m = ResultOf(&InvokeHelper::StaticIntFromString, Eq(1)); - EXPECT_TRUE(m.Matches(NULL)); + EXPECT_TRUE(m.Matches(nullptr)); } // Tests the linkage of the ResultOf matcher. @@ -660,7 +654,7 @@ TEST(LinkTest, TestMatcherPointee) { // Tests the linkage of the Truly matcher. TEST(LinkTest, TestMatcherTruly) { Matcher<const char*> m = Truly(&InvokeHelper::StaticBoolFromString); - EXPECT_TRUE(m.Matches(NULL)); + EXPECT_TRUE(m.Matches(nullptr)); } // Tests the linkage of the AllOf matcher. @@ -684,7 +678,7 @@ TEST(LinkTest, TestMatcherNot) { // Tests the linkage of the MatcherCast<T>() function. TEST(LinkTest, TestMatcherCast) { Matcher<const char*> m = MatcherCast<const char*>(_); - EXPECT_TRUE(m.Matches(NULL)); + EXPECT_TRUE(m.Matches(nullptr)); } -#endif // GMOCK_TEST_GMOCK_LINK_TEST_H_ +#endif // GOOGLEMOCK_TEST_GMOCK_LINK_TEST_H_ diff --git a/contrib/googletest/googlemock/test/gmock_output_test.py b/contrib/googletest/googlemock/test/gmock_output_test.py index 0527bd9307f7..7c24d683202c 100755 --- a/contrib/googletest/googlemock/test/gmock_output_test.py +++ b/contrib/googletest/googlemock/test/gmock_output_test.py @@ -39,10 +39,11 @@ 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 +from googlemock.test import gmock_test_utils # The flag for generating the golden file @@ -152,20 +153,28 @@ def GetNormalizedCommandOutputAndLeakyTests(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() + golden = golden_file.read().decode('utf-8') golden_file.close() + # On Windows the repository might have been checked out with \r\n line + # endings, so normalize it here. + golden = ToUnixLineEnding(golden) # The normalized output should match the golden file. - self.assertEquals(golden, output) + self.assertEqual(golden, output) # The raw output should contain 2 leaked mock object errors for # test GMockOutputTest.CatchesLeakedMocks. - self.assertEquals(['GMockOutputTest.CatchesLeakedMocks', - 'GMockOutputTest.CatchesLeakedMocks'], - leaky_tests) + self.assertEqual( + [ + 'GMockOutputTest.CatchesLeakedMocks', + 'GMockOutputTest.CatchesLeakedMocks', + ], + leaky_tests, + ) if __name__ == '__main__': diff --git a/contrib/googletest/googlemock/test/gmock_output_test_.cc b/contrib/googletest/googlemock/test/gmock_output_test_.cc index 3955c7331a12..03d842139fa8 100644 --- a/contrib/googletest/googlemock/test/gmock_output_test_.cc +++ b/contrib/googletest/googlemock/test/gmock_output_test_.cc @@ -27,22 +27,18 @@ // (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 "gmock/gmock.h" #include "gtest/gtest.h" // Silence C4100 (unreferenced formal parameter) -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable:4100) -#endif +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100) using testing::_; using testing::AnyNumber; @@ -56,14 +52,15 @@ using testing::Value; class MockFoo { public: - MockFoo() {} + MockFoo() = default; 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); + MockFoo(const MockFoo&) = delete; + MockFoo& operator=(const MockFoo&) = delete; }; class GMockOutputTest : public testing::Test { @@ -72,27 +69,25 @@ class GMockOutputTest : public testing::Test { }; TEST_F(GMockOutputTest, ExpectedCall) { - testing::GMOCK_FLAG(verbose) = "info"; + GMOCK_FLAG_SET(verbose, "info"); EXPECT_CALL(foo_, Bar2(0, _)); foo_.Bar2(0, 0); // Expected call - testing::GMOCK_FLAG(verbose) = "warning"; + GMOCK_FLAG_SET(verbose, "warning"); } TEST_F(GMockOutputTest, ExpectedCallToVoidFunction) { - testing::GMOCK_FLAG(verbose) = "info"; + GMOCK_FLAG_SET(verbose, "info"); EXPECT_CALL(foo_, Bar3(0, _)); foo_.Bar3(0, 0); // Expected call - testing::GMOCK_FLAG(verbose) = "warning"; + GMOCK_FLAG_SET(verbose, "warning"); } TEST_F(GMockOutputTest, ExplicitActionsRunOut) { - EXPECT_CALL(foo_, Bar2(_, _)) - .Times(2) - .WillOnce(Return(false)); + EXPECT_CALL(foo_, Bar2(_, _)).Times(2).WillOnce(Return(false)); foo_.Bar2(2, 2); foo_.Bar2(1, 1); // Explicit actions in EXPECT_CALL run out. } @@ -134,8 +129,7 @@ TEST_F(GMockOutputTest, UninterestingCallToVoidFunction) { } TEST_F(GMockOutputTest, RetiredExpectation) { - EXPECT_CALL(foo_, Bar2(_, _)) - .RetiresOnSaturation(); + EXPECT_CALL(foo_, Bar2(_, _)).RetiresOnSaturation(); EXPECT_CALL(foo_, Bar2(0, 0)); foo_.Bar2(1, 1); @@ -160,12 +154,9 @@ TEST_F(GMockOutputTest, UnsatisfiedPrerequisite) { 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); + 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); @@ -179,8 +170,7 @@ TEST_F(GMockOutputTest, UnsatisfiedWith) { TEST_F(GMockOutputTest, UnsatisfiedExpectation) { EXPECT_CALL(foo_, Bar(_, _, _)); - EXPECT_CALL(foo_, Bar2(0, _)) - .Times(2); + EXPECT_CALL(foo_, Bar2(0, _)).Times(2); foo_.Bar2(0, 1); } @@ -194,26 +184,22 @@ TEST_F(GMockOutputTest, MismatchArguments) { } TEST_F(GMockOutputTest, MismatchWith) { - EXPECT_CALL(foo_, Bar2(Ge(2), Ge(1))) - .With(Ge()); + 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()); + 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 + 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. @@ -222,10 +208,8 @@ TEST_F(GMockOutputTest, UnexpectedCallWithDefaultAction) { } 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 + 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)); @@ -237,22 +221,17 @@ TEST_F(GMockOutputTest, ExcessiveCallWithDefaultAction) { } 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 + 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 + ON_CALL(foo_, Bar2(_, _)).WillByDefault(Return(true)); // Default action #1 - EXPECT_CALL(foo_, Bar2(_, _)) - .Times(2) - .WillOnce(Return(false)); + EXPECT_CALL(foo_, Bar2(_, _)).Times(2).WillOnce(Return(false)); foo_.Bar2(2, 2); foo_.Bar2(1, 1); // Explicit actions in EXPECT_CALL run out. } @@ -293,17 +272,15 @@ void TestCatchesLeakedMocksInAdHocTests() { // foo is deliberately leaked. } -int main(int argc, char **argv) { +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"; + GMOCK_FLAG_SET(catch_leaked_mocks, true); + GMOCK_FLAG_SET(verbose, "warning"); TestCatchesLeakedMocksInAdHocTests(); return RUN_ALL_TESTS(); } -#ifdef _MSC_VER -# pragma warning(pop) -#endif +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100 diff --git a/contrib/googletest/googlemock/test/gmock_output_test_golden.txt b/contrib/googletest/googlemock/test/gmock_output_test_golden.txt index dbcb211883b2..ca88af0291df 100644 --- a/contrib/googletest/googlemock/test/gmock_output_test_golden.txt +++ b/contrib/googletest/googlemock/test/gmock_output_test_golden.txt @@ -40,6 +40,7 @@ FILE:#: EXPECT_CALL(foo_, Bar2(0, _))... Actual: 1 Expected: to be called once Actual: never called - unsatisfied and active + [ FAILED ] GMockOutputTest.UnexpectedCall [ RUN ] GMockOutputTest.UnexpectedCallToVoidFunction unknown file: Failure @@ -53,6 +54,7 @@ FILE:#: EXPECT_CALL(foo_, Bar3(0, _))... Actual: 1 Expected: to be called once Actual: never called - unsatisfied and active + [ FAILED ] GMockOutputTest.UnexpectedCallToVoidFunction [ RUN ] GMockOutputTest.ExcessiveCall FILE:#: Failure @@ -61,6 +63,7 @@ Mock function called more times than expected - returning default value. Returns: false Expected: to be called once Actual: called twice - over-saturated and active + [ FAILED ] GMockOutputTest.ExcessiveCall [ RUN ] GMockOutputTest.ExcessiveCallToVoidFunction FILE:#: Failure @@ -68,6 +71,7 @@ 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 @@ -75,14 +79,14 @@ 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/CookBook.md#knowing-when-to-expect for details. +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/main/docs/gmock_cook_book.md#knowing-when-to-expect-useoncall 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/CookBook.md#knowing-when-to-expect for details. +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/main/docs/gmock_cook_book.md#knowing-when-to-expect-useoncall for details. [ OK ] GMockOutputTest.UninterestingCallToVoidFunction [ RUN ] GMockOutputTest.RetiredExpectation unknown file: Failure @@ -104,6 +108,7 @@ FILE:#: tried expectation #1: EXPECT_CALL(foo_, Bar2(0, 0))... Actual: 1 Expected: to be called once Actual: never called - unsatisfied and active + [ FAILED ] GMockOutputTest.RetiredExpectation [ RUN ] GMockOutputTest.UnsatisfiedPrerequisite unknown file: Failure @@ -125,6 +130,7 @@ 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 @@ -147,6 +153,7 @@ 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 @@ -154,16 +161,19 @@ 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 @@ -180,6 +190,7 @@ FILE:#: EXPECT_CALL(foo_, Bar(Ref(s), _, Ge(0)))... Actual: -0.1 Expected: to be called once Actual: never called - unsatisfied and active + [ FAILED ] GMockOutputTest.MismatchArguments [ RUN ] GMockOutputTest.MismatchWith unknown file: Failure @@ -194,6 +205,7 @@ FILE:#: EXPECT_CALL(foo_, Bar2(Ge(2), Ge(1)))... Actual: don't match Expected: to be called once Actual: never called - unsatisfied and active + [ FAILED ] GMockOutputTest.MismatchWith [ RUN ] GMockOutputTest.MismatchArgumentsAndWith unknown file: Failure @@ -210,6 +222,7 @@ FILE:#: EXPECT_CALL(foo_, Bar2(Ge(2), Ge(1)))... Actual: don't match Expected: to be called once Actual: never called - unsatisfied and active + [ FAILED ] GMockOutputTest.MismatchArgumentsAndWith [ RUN ] GMockOutputTest.UnexpectedCallWithDefaultAction unknown file: Failure @@ -227,6 +240,7 @@ FILE:#: EXPECT_CALL(foo_, Bar2(2, 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: @@ -242,6 +256,7 @@ FILE:#: EXPECT_CALL(foo_, Bar2(2, 2))... Actual: 0 Expected: to be called once Actual: never called - unsatisfied and active + [ FAILED ] GMockOutputTest.UnexpectedCallWithDefaultAction [ RUN ] GMockOutputTest.ExcessiveCallWithDefaultAction FILE:#: Failure @@ -251,6 +266,7 @@ FILE:#: 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:#: @@ -258,6 +274,7 @@ FILE:#: Returns: false Expected: to be called once Actual: called twice - over-saturated and active + [ FAILED ] GMockOutputTest.ExcessiveCallWithDefaultAction [ RUN ] GMockOutputTest.UninterestingCallWithDefaultAction @@ -266,14 +283,14 @@ 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/CookBook.md#knowing-when-to-expect for details. +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/main/docs/gmock_cook_book.md#knowing-when-to-expect-useoncall 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/CookBook.md#knowing-when-to-expect for details. +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/main/docs/gmock_cook_book.md#knowing-when-to-expect-useoncall for details. [ OK ] GMockOutputTest.UninterestingCallWithDefaultAction [ RUN ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction @@ -291,8 +308,9 @@ Stack trace: [ 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>) +Expected: is pair (first: is >= 48, second: true) + Actual: (42, true) (of type std::pair<int,bool>) + [ FAILED ] GMockOutputTest.PrintsMatcher [ FAILED ] GMockOutputTest.UnexpectedCall [ FAILED ] GMockOutputTest.UnexpectedCallToVoidFunction @@ -314,4 +332,4 @@ Expected: is pair (is >= 48, true) 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 is 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. +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/contrib/googletest/googlemock/test/gmock_stress_test.cc b/contrib/googletest/googlemock/test/gmock_stress_test.cc index 0d99bededa80..9e42cd935847 100644 --- a/contrib/googletest/googlemock/test/gmock_stress_test.cc +++ b/contrib/googletest/googlemock/test/gmock_stress_test.cc @@ -27,7 +27,6 @@ // (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. @@ -49,7 +48,7 @@ const int kRepeat = 50; class MockFoo { public: - MOCK_METHOD1(Bar, int(int n)); // NOLINT + MOCK_METHOD1(Bar, int(int n)); // NOLINT MOCK_METHOD2(Baz, char(const char* s1, const std::string& s2)); // NOLINT }; @@ -60,102 +59,18 @@ void JoinAndDelete(ThreadWithParam<T>* t) { delete t; } -using internal::linked_ptr; - -// Helper classes for testing using linked_ptr concurrently. - -class Base { - public: - explicit Base(int a_x) : x_(a_x) {} - virtual ~Base() {} - int x() const { return x_; } - private: - int x_; -}; - -class Derived1 : public Base { - public: - Derived1(int a_x, int a_y) : Base(a_x), y_(a_y) {} - int y() const { return y_; } - private: - int y_; -}; - -class Derived2 : public Base { - public: - Derived2(int a_x, int a_z) : Base(a_x), z_(a_z) {} - int z() const { return z_; } - private: - int z_; -}; - -linked_ptr<Derived1> pointer1(new Derived1(1, 2)); -linked_ptr<Derived2> pointer2(new Derived2(3, 4)); - struct Dummy {}; -// Tests that we can copy from a linked_ptr and read it concurrently. -void TestConcurrentCopyAndReadLinkedPtr(Dummy /* dummy */) { - // Reads pointer1 and pointer2 while they are being copied from in - // another thread. - EXPECT_EQ(1, pointer1->x()); - EXPECT_EQ(2, pointer1->y()); - EXPECT_EQ(3, pointer2->x()); - EXPECT_EQ(4, pointer2->z()); - - // Copies from pointer1. - linked_ptr<Derived1> p1(pointer1); - EXPECT_EQ(1, p1->x()); - EXPECT_EQ(2, p1->y()); - - // Assigns from pointer2 where the LHS was empty. - linked_ptr<Base> p2; - p2 = pointer1; - EXPECT_EQ(1, p2->x()); - - // Assigns from pointer2 where the LHS was not empty. - p2 = pointer2; - EXPECT_EQ(3, p2->x()); -} - -const linked_ptr<Derived1> p0(new Derived1(1, 2)); - -// Tests that we can concurrently modify two linked_ptrs that point to -// the same object. -void TestConcurrentWriteToEqualLinkedPtr(Dummy /* dummy */) { - // p1 and p2 point to the same, shared thing. One thread resets p1. - // Another thread assigns to p2. This will cause the same - // underlying "ring" to be updated concurrently. - linked_ptr<Derived1> p1(p0); - linked_ptr<Derived1> p2(p0); - - EXPECT_EQ(1, p1->x()); - EXPECT_EQ(2, p1->y()); - - EXPECT_EQ(1, p2->x()); - EXPECT_EQ(2, p2->y()); - - p1.reset(); - p2 = p0; - - EXPECT_EQ(1, p2->x()); - EXPECT_EQ(2, p2->y()); -} - // 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)); + 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')) @@ -198,22 +113,19 @@ void Helper1(Helper1Param param) { void TestConcurrentCallsOnSameObject(Dummy /* dummy */) { MockFoo foo; - ON_CALL(foo, Bar(_)) - .WillByDefault(Return(1)); - EXPECT_CALL(foo, Baz(_, "b")) - .Times(kRepeat) - .WillRepeatedly(Return('a')); + 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 }; + const Helper1Param param = {&foo, &count1}; ThreadWithParam<Helper1Param>* const t = - new ThreadWithParam<Helper1Param>(Helper1, param, NULL); + new ThreadWithParam<Helper1Param>(Helper1, param, nullptr); int count2 = 0; - const Helper1Param param2 = { &foo, &count2 }; + const Helper1Param param2 = {&foo, &count2}; Helper1(param2); JoinAndDelete(t); @@ -241,22 +153,18 @@ void TestPartiallyOrderedExpectationsWithThreads(Dummy /* dummy */) { { InSequence dummy; EXPECT_CALL(foo, Bar(0)); - EXPECT_CALL(foo, Bar(1)) - .InSequence(s1, s2); + EXPECT_CALL(foo, Bar(1)).InSequence(s1, s2); } EXPECT_CALL(foo, Bar(2)) - .Times(2*kRepeat) + .Times(2 * kRepeat) .InSequence(s1) .RetiresOnSaturation(); - EXPECT_CALL(foo, Bar(3)) - .Times(2*kRepeat) - .InSequence(s2); + EXPECT_CALL(foo, Bar(3)).Times(2 * kRepeat).InSequence(s2); { InSequence dummy; - EXPECT_CALL(foo, Bar(2)) - .InSequence(s1, s2); + EXPECT_CALL(foo, Bar(2)).InSequence(s1, s2); EXPECT_CALL(foo, Bar(4)); } @@ -264,7 +172,7 @@ void TestPartiallyOrderedExpectationsWithThreads(Dummy /* dummy */) { foo.Bar(1); ThreadWithParam<MockFoo*>* const t = - new ThreadWithParam<MockFoo*>(Helper2, &foo, NULL); + new ThreadWithParam<MockFoo*>(Helper2, &foo, nullptr); Helper2(&foo); JoinAndDelete(t); @@ -275,21 +183,19 @@ void TestPartiallyOrderedExpectationsWithThreads(Dummy /* dummy */) { // Tests using Google Mock constructs in many threads concurrently. TEST(StressTest, CanUseGMockWithThreads) { void (*test_routines[])(Dummy dummy) = { - &TestConcurrentCopyAndReadLinkedPtr, - &TestConcurrentWriteToEqualLinkedPtr, - &TestConcurrentMockObjects, - &TestConcurrentCallsOnSameObject, - &TestPartiallyOrderedExpectationsWithThreads, + &TestConcurrentMockObjects, + &TestConcurrentCallsOnSameObject, + &TestPartiallyOrderedExpectationsWithThreads, }; - const int kRoutines = sizeof(test_routines)/sizeof(test_routines[0]); + 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(), NULL); + threads[i] = new ThreadWithParam<Dummy>(test_routines[i % kRoutines], + Dummy(), nullptr); GTEST_LOG_(INFO) << "Thread #" << i << " running . . ."; } @@ -301,7 +207,7 @@ TEST(StressTest, CanUseGMockWithThreads) { // 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; + const int kExpectedFailures = (3 * kRepeat + 1) * kCopiesOfEachRoutine; GTEST_CHECK_(kExpectedFailures == result.total_part_count()) << "Expected " << kExpectedFailures << " failures, but got " << result.total_part_count(); @@ -310,7 +216,7 @@ TEST(StressTest, CanUseGMockWithThreads) { } // namespace } // namespace testing -int main(int argc, char **argv) { +int main(int argc, char** argv) { testing::InitGoogleMock(&argc, argv); const int exit_code = RUN_ALL_TESTS(); // Expected to fail. diff --git a/contrib/googletest/googlemock/test/gmock_test.cc b/contrib/googletest/googlemock/test/gmock_test.cc index 341a17da23cb..8cfff3066783 100644 --- a/contrib/googletest/googlemock/test/gmock_test.cc +++ b/contrib/googletest/googlemock/test/gmock_test.cc @@ -27,7 +27,6 @@ // (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. @@ -35,13 +34,12 @@ #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, @@ -49,7 +47,7 @@ using testing::InitGoogleMock; 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); + const ::std::string old_verbose = GMOCK_FLAG_GET(verbose); int argc = M - 1; InitGoogleMock(&argc, const_cast<Char**>(argv)); @@ -59,194 +57,114 @@ void TestInitGoogleMock(const Char* (&argv)[M], const Char* (&new_argv)[N], 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. + EXPECT_EQ(expected_gmock_verbose, GMOCK_FLAG_GET(verbose)); + GMOCK_FLAG_SET(verbose, old_verbose); // Restores the gmock_verbose flag. } TEST(InitGoogleMockTest, ParsesInvalidCommandLine) { - const char* argv[] = { - NULL - }; + const char* argv[] = {nullptr}; - const char* new_argv[] = { - NULL - }; + const char* new_argv[] = {nullptr}; - TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose)); + TestInitGoogleMock(argv, new_argv, GMOCK_FLAG_GET(verbose)); } TEST(InitGoogleMockTest, ParsesEmptyCommandLine) { - const char* argv[] = { - "foo.exe", - NULL - }; + const char* argv[] = {"foo.exe", nullptr}; - const char* new_argv[] = { - "foo.exe", - NULL - }; + const char* new_argv[] = {"foo.exe", nullptr}; - TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose)); + TestInitGoogleMock(argv, new_argv, GMOCK_FLAG_GET(verbose)); } TEST(InitGoogleMockTest, ParsesSingleFlag) { - const char* argv[] = { - "foo.exe", - "--gmock_verbose=info", - NULL - }; + const char* argv[] = {"foo.exe", "--gmock_verbose=info", nullptr}; - const char* new_argv[] = { - "foo.exe", - NULL - }; + 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", - NULL - }; - - const wchar_t* new_argv[] = { - L"foo.exe", - NULL - }; + int old_default_behavior = GMOCK_FLAG_GET(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_EQ(2, GMOCK_FLAG_GET(default_mock_behavior)); EXPECT_NE(2, old_default_behavior); - GMOCK_FLAG(default_mock_behavior) = old_default_behavior; + GMOCK_FLAG_SET(default_mock_behavior, old_default_behavior); } TEST(InitGoogleMockTest, ParsesUnrecognizedFlag) { - const char* argv[] = { - "foo.exe", - "--non_gmock_flag=blah", - NULL - }; - - const char* new_argv[] = { - "foo.exe", - "--non_gmock_flag=blah", - NULL - }; - - TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose)); + 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_GET(verbose)); } TEST(InitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) { - const char* argv[] = { - "foo.exe", - "--non_gmock_flag=blah", - "--gmock_verbose=error", - NULL - }; - - const char* new_argv[] = { - "foo.exe", - "--non_gmock_flag=blah", - NULL - }; + 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[] = { - NULL - }; + const wchar_t* argv[] = {nullptr}; - const wchar_t* new_argv[] = { - NULL - }; + const wchar_t* new_argv[] = {nullptr}; - TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose)); + TestInitGoogleMock(argv, new_argv, GMOCK_FLAG_GET(verbose)); } TEST(WideInitGoogleMockTest, ParsesEmptyCommandLine) { - const wchar_t* argv[] = { - L"foo.exe", - NULL - }; + const wchar_t* argv[] = {L"foo.exe", nullptr}; - const wchar_t* new_argv[] = { - L"foo.exe", - NULL - }; + const wchar_t* new_argv[] = {L"foo.exe", nullptr}; - TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose)); + TestInitGoogleMock(argv, new_argv, GMOCK_FLAG_GET(verbose)); } TEST(WideInitGoogleMockTest, ParsesSingleFlag) { - const wchar_t* argv[] = { - L"foo.exe", - L"--gmock_verbose=info", - NULL - }; + const wchar_t* argv[] = {L"foo.exe", L"--gmock_verbose=info", nullptr}; - const wchar_t* new_argv[] = { - L"foo.exe", - NULL - }; + 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", - NULL - }; - - const wchar_t* new_argv[] = { - L"foo.exe", - NULL - }; + int old_default_behavior = GMOCK_FLAG_GET(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_EQ(2, GMOCK_FLAG_GET(default_mock_behavior)); EXPECT_NE(2, old_default_behavior); - GMOCK_FLAG(default_mock_behavior) = old_default_behavior; + GMOCK_FLAG_SET(default_mock_behavior, old_default_behavior); } TEST(WideInitGoogleMockTest, ParsesUnrecognizedFlag) { - const wchar_t* argv[] = { - L"foo.exe", - L"--non_gmock_flag=blah", - NULL - }; - - const wchar_t* new_argv[] = { - L"foo.exe", - L"--non_gmock_flag=blah", - NULL - }; - - TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose)); + 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_GET(verbose)); } TEST(WideInitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) { - const wchar_t* argv[] = { - L"foo.exe", - L"--non_gmock_flag=blah", - L"--gmock_verbose=error", - NULL - }; - - const wchar_t* new_argv[] = { - L"foo.exe", - L"--non_gmock_flag=blah", - NULL - }; + 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"); } @@ -255,7 +173,7 @@ TEST(WideInitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) { // 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) == ""; + bool dummy = + GMOCK_FLAG_GET(catch_leaked_mocks) && GMOCK_FLAG_GET(verbose).empty(); (void)dummy; // Avoids the "unused local variable" warning. } diff --git a/contrib/googletest/googlemock/test/gmock_test_utils.py b/contrib/googletest/googlemock/test/gmock_test_utils.py index 7dc4e119d3c5..edad1f752f0c 100755 --- a/contrib/googletest/googlemock/test/gmock_test_utils.py +++ b/contrib/googletest/googlemock/test/gmock_test_utils.py @@ -30,21 +30,9 @@ """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 +from googletest.test import gtest_test_utils def GetSourceDir(): @@ -89,9 +77,6 @@ def GetExitStatus(exit_code): 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 @@ -99,8 +84,6 @@ 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.""" |