Commit 6d089311 authored by Tanzinul Islam's avatar Tanzinul Islam
Browse files

Merge branch 'fix_death_test_child_mingw_wer_issue1116' of...

Merge branch 'fix_death_test_child_mingw_wer_issue1116' of https://github.com/tanzislam/googletest into fix_death_test_child_mingw_wer_issue1116
parents 555e6e79 a7a7f51d
...@@ -22,3 +22,19 @@ Win32-Debug/ ...@@ -22,3 +22,19 @@ Win32-Debug/
Win32-Release/ Win32-Release/
x64-Debug/ x64-Debug/
x64-Release/ x64-Release/
# Ignore autoconf / automake files
Makefile.in
aclocal.m4
configure
build-aux/
autom4te.cache/
googletest/m4/libtool.m4
googletest/m4/ltoptions.m4
googletest/m4/ltsugar.m4
googletest/m4/ltversion.m4
googletest/m4/lt~obsolete.m4
# Ignore generated directories.
googlemock/fused-src/
googletest/fused-src/
...@@ -12,40 +12,47 @@ matrix: ...@@ -12,40 +12,47 @@ matrix:
include: include:
- os: linux - os: linux
compiler: gcc compiler: gcc
sudo: true sudo : true
cache:
install: ./ci/install-linux.sh && ./ci/log-config.sh install: ./ci/install-linux.sh && ./ci/log-config.sh
script: ./ci/build-linux-bazel.sh script: ./ci/build-linux-bazel.sh
- os: linux - os: linux
compiler: clang compiler: clang
sudo: true sudo : true
cache:
install: ./ci/install-linux.sh && ./ci/log-config.sh install: ./ci/install-linux.sh && ./ci/log-config.sh
script: ./ci/build-linux-bazel.sh script: ./ci/build-linux-bazel.sh
- os: linux - os: linux
group: deprecated-2017Q4
compiler: gcc compiler: gcc
env: BUILD_TYPE=Debug VERBOSE=1 install: ./ci/install-linux.sh && ./ci/log-config.sh
script: ./ci/build-linux-autotools.sh
- os: linux - os: linux
group: deprecated-2017Q4
compiler: gcc compiler: gcc
env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11 env: BUILD_TYPE=Debug VERBOSE=1 CXX_FLAGS=-std=c++11
- os: linux - os: linux
group: deprecated-2017Q4
compiler: clang compiler: clang
env: BUILD_TYPE=Debug VERBOSE=1 env: BUILD_TYPE=Debug VERBOSE=1
- os: linux - os: linux
group: deprecated-2017Q4
compiler: clang compiler: clang
env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11 env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11
- os: osx - os: osx
compiler: gcc compiler: gcc
env: BUILD_TYPE=Debug VERBOSE=1 env: BUILD_TYPE=Debug VERBOSE=1
if: type != pull_request
- os: osx - os: osx
compiler: gcc compiler: gcc
env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11 env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11
if: type != pull_request
- os: osx - os: osx
compiler: clang compiler: clang
env: BUILD_TYPE=Debug VERBOSE=1 env: BUILD_TYPE=Debug VERBOSE=1
if: type != pull_request
- os: osx - os: osx
compiler: clang compiler: clang
env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11 env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11
if: type != pull_request
# These are the install and build (script) phases for the most common entries in the matrix. They could be included # These are the install and build (script) phases for the most common entries in the matrix. They could be included
# in each entry in the matrix, but that is just repetitive. # in each entry in the matrix, but that is just repetitive.
......
...@@ -37,10 +37,21 @@ package(default_visibility = ["//visibility:public"]) ...@@ -37,10 +37,21 @@ package(default_visibility = ["//visibility:public"])
licenses(["notice"]) licenses(["notice"])
config_setting( config_setting(
name = "win", name = "windows",
values = { "cpu": "x64_windows" },
)
config_setting(
name = "windows_msvc",
values = {"cpu": "x64_windows_msvc"}, values = {"cpu": "x64_windows_msvc"},
) )
config_setting(
name = "has_absl",
values = {"define": "absl=1"},
)
# Google Test including Google Mock # Google Test including Google Mock
cc_library( cc_library(
name = "gtest", name = "gtest",
...@@ -65,7 +76,8 @@ cc_library( ...@@ -65,7 +76,8 @@ cc_library(
]), ]),
copts = select( copts = select(
{ {
":win": [], ":windows": [],
":windows_msvc": [],
"//conditions:default": ["-pthread"], "//conditions:default": ["-pthread"],
}, },
), ),
...@@ -76,11 +88,27 @@ cc_library( ...@@ -76,11 +88,27 @@ cc_library(
"googletest/include", "googletest/include",
], ],
linkopts = select({ linkopts = select({
":win": [], ":windows": [],
":windows_msvc": [],
"//conditions:default": [ "//conditions:default": [
"-pthread", "-pthread",
], ],
}), }),
defines = select ({
":has_absl": [
"GTEST_HAS_ABSL=1",
],
"//conditions:default": [],
}
),
deps = select ({
":has_absl": [
"@com_google_absl//absl/types:optional",
"@com_google_absl//absl/strings"
],
"//conditions:default": [],
}
)
) )
cc_library( cc_library(
......
## Process this file with automake to produce Makefile.in
ACLOCAL_AMFLAGS = -I m4
AUTOMAKE_OPTIONS = foreign
# Build . before src so that our all-local and clean-local hooks kicks in at
# the right time.
SUBDIRS = googletest googlemock
EXTRA_DIST = \
BUILD.bazel \
CMakeLists.txt \
README.md \
WORKSPACE
...@@ -103,7 +103,7 @@ package (as described below): ...@@ -103,7 +103,7 @@ package (as described below):
### Windows Requirements ### ### Windows Requirements ###
* Microsoft Visual C++ 2010 or newer * Microsoft Visual C++ 2015 or newer
### Cygwin Requirements ### ### Cygwin Requirements ###
......
workspace(name = "com_google_googletest") workspace(name = "com_google_googletest")
# Abseil
http_archive(
name = "com_google_absl",
urls = ["https://github.com/abseil/abseil-cpp/archive/master.zip"],
strip_prefix = "abseil-cpp-master",
)
...@@ -11,28 +11,15 @@ environment: ...@@ -11,28 +11,15 @@ environment:
- compiler: msvc-15-seh - compiler: msvc-15-seh
generator: "Visual Studio 15 2017 Win64" generator: "Visual Studio 15 2017 Win64"
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
enabled_on_pr: yes
- compiler: msvc-14-seh - compiler: msvc-14-seh
generator: "Visual Studio 14 2015" generator: "Visual Studio 14 2015"
enabled_on_pr: yes
- compiler: msvc-14-seh - compiler: msvc-14-seh
generator: "Visual Studio 14 2015 Win64" generator: "Visual Studio 14 2015 Win64"
- compiler: msvc-12-seh
generator: "Visual Studio 12 2013"
- compiler: msvc-12-seh
generator: "Visual Studio 12 2013 Win64"
- compiler: msvc-11-seh
generator: "Visual Studio 11 2012"
- compiler: msvc-11-seh
generator: "Visual Studio 11 2012 Win64"
- compiler: msvc-10-seh
generator: "Visual Studio 10 2010"
- compiler: gcc-5.3.0-posix - compiler: gcc-5.3.0-posix
generator: "MinGW Makefiles" generator: "MinGW Makefiles"
cxx_path: 'C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin' cxx_path: 'C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin'
...@@ -43,7 +30,6 @@ environment: ...@@ -43,7 +30,6 @@ environment:
configuration: configuration:
- Debug - Debug
#- Release
build: build:
verbosity: minimal verbosity: minimal
...@@ -52,6 +38,14 @@ install: ...@@ -52,6 +38,14 @@ install:
- ps: | - ps: |
Write-Output "Compiler: $env:compiler" Write-Output "Compiler: $env:compiler"
Write-Output "Generator: $env:generator" Write-Output "Generator: $env:generator"
if (-not (Test-Path env:APPVEYOR_PULL_REQUEST_NUMBER)) {
Write-Output "This is *NOT* a pull request build"
} else {
Write-Output "This is a pull request build"
if (-not (Test-Path env:enabled_on_pr) -or $env:enabled_on_pr -ne "yes") {
Write-Output "PR builds are *NOT* explicitly enabled"
}
}
# git bash conflicts with MinGW makefiles # git bash conflicts with MinGW makefiles
if ($env:generator -eq "MinGW Makefiles") { if ($env:generator -eq "MinGW Makefiles") {
...@@ -63,6 +57,10 @@ install: ...@@ -63,6 +57,10 @@ install:
build_script: build_script:
- ps: | - ps: |
# Only enable some builds for pull requests, the AppVeyor queue is too long.
if ((Test-Path env:APPVEYOR_PULL_REQUEST_NUMBER) -And (-not (Test-Path env:enabled_on_pr) -or $env:enabled_on_pr -ne "yes")) {
return
}
md _build -Force | Out-Null md _build -Force | Out-Null
cd _build cd _build
...@@ -74,13 +72,18 @@ build_script: ...@@ -74,13 +72,18 @@ build_script:
if ($LastExitCode -ne 0) { if ($LastExitCode -ne 0) {
throw "Exec: $ErrorMessage" throw "Exec: $ErrorMessage"
} }
& cmake --build . --config $env:configuration $cmake_parallel = if ($env:generator -eq "MinGW Makefiles") {"-j2"} else {"/m"}
& cmake --build . --config $env:configuration -- $cmake_parallel
if ($LastExitCode -ne 0) { if ($LastExitCode -ne 0) {
throw "Exec: $ErrorMessage" throw "Exec: $ErrorMessage"
} }
test_script: test_script:
- ps: | - ps: |
# Only enable some builds for pull requests, the AppVeyor queue is too long.
if ((Test-Path env:APPVEYOR_PULL_REQUEST_NUMBER) -And (-not (Test-Path env:enabled_on_pr) -or $env:enabled_on_pr -ne "yes")) {
return
}
if ($env:generator -eq "MinGW Makefiles") { if ($env:generator -eq "MinGW Makefiles") {
return # No test available for MinGW return # No test available for MinGW
} }
......
#!/usr/bin/env bash
# Copyright 2017 Google Inc.
# All Rights Reserved.
#
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -e
. ci/get-nprocessors.sh
# Create the configuration script
autoreconf -i
# Run in a subdirectory to keep the sources clean
mkdir build || true
cd build
../configure
make -j ${NPROCESSORS:-2}
...@@ -33,3 +33,4 @@ set -e ...@@ -33,3 +33,4 @@ set -e
bazel build --curses=no //...:all bazel build --curses=no //...:all
bazel test --curses=no //...:all bazel test --curses=no //...:all
bazel test --curses=no //...:all --define absl=1
#!/usr/bin/env bash
# Copyright 2017 Google Inc.
# All Rights Reserved.
#
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# This file is typically sourced by another script.
# if possible, ask for the precise number of processors,
# otherwise take 2 processors as reasonable default; see
# https://docs.travis-ci.com/user/speeding-up-the-build/#Makefile-optimization
if [ -x /usr/bin/getconf ]; then
NPROCESSORS=$(/usr/bin/getconf _NPROCESSORS_ONLN)
else
NPROCESSORS=2
fi
# as of 2017-09-04 Travis CI reports 32 processors, but GCC build
# crashes if parallelized too much (maybe memory consumption problem),
# so limit to 4 processors for the time being.
if [ $NPROCESSORS -gt 4 ] ; then
echo "$0:Note: Limiting processors to use by make from $NPROCESSORS to 4."
NPROCESSORS=4
fi
#!/usr/bin/env sh #!/usr/bin/env sh
set -evx set -evx
. ci/get-nprocessors.sh
# if possible, ask for the precise number of processors, # if possible, ask for the precise number of processors,
# otherwise take 2 processors as reasonable default; see # otherwise take 2 processors as reasonable default; see
# https://docs.travis-ci.com/user/speeding-up-the-build/#Makefile-optimization # https://docs.travis-ci.com/user/speeding-up-the-build/#Makefile-optimization
......
AC_INIT([Google C++ Mocking and Testing Frameworks],
[1.8.0],
[googlemock@googlegroups.com],
[googletest])
# Provide various options to initialize the Autoconf and configure processes.
AC_PREREQ([2.59])
AC_CONFIG_SRCDIR([./README.md])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_FILES([Makefile])
AC_CONFIG_SUBDIRS([googletest googlemock])
AM_INIT_AUTOMAKE
# Output the generated files. No further autoconf macros may be used.
AC_OUTPUT
...@@ -88,16 +88,23 @@ endif() ...@@ -88,16 +88,23 @@ endif()
# Google Mock libraries. We build them using more strict warnings than what # Google Mock libraries. We build them using more strict warnings than what
# are used for other targets, to ensure that Google Mock can be compiled by # are used for other targets, to ensure that Google Mock can be compiled by
# a user aggressive about warnings. # a user aggressive about warnings.
cxx_library(gmock if (MSVC)
"${cxx_strict}" cxx_library(gmock
"${gtest_dir}/src/gtest-all.cc" "${cxx_strict}"
src/gmock-all.cc) "${gtest_dir}/src/gtest-all.cc"
src/gmock-all.cc)
cxx_library(gmock_main
"${cxx_strict}" cxx_library(gmock_main
"${gtest_dir}/src/gtest-all.cc" "${cxx_strict}"
src/gmock-all.cc "${gtest_dir}/src/gtest-all.cc"
src/gmock_main.cc) src/gmock-all.cc
src/gmock_main.cc)
else()
cxx_library(gmock "${cxx_strict}" src/gmock-all.cc)
target_link_libraries(gmock gtest)
cxx_library(gmock_main "${cxx_strict}" src/gmock_main.cc)
target_link_libraries(gmock_main gmock)
endif()
# If the CMake version supports it, attach header directory information # 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 # to the targets for when we are part of a parent build (ie being pulled
...@@ -177,23 +184,33 @@ if (gmock_build_tests) ...@@ -177,23 +184,33 @@ if (gmock_build_tests)
############################################################ ############################################################
# C++ tests built with non-standard compiler flags. # C++ tests built with non-standard compiler flags.
cxx_library(gmock_main_no_exception "${cxx_no_exception}" if (MSVC)
"${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc) cxx_library(gmock_main_no_exception "${cxx_no_exception}"
"${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc)
cxx_library(gmock_main_no_rtti "${cxx_no_rtti}"
"${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc)
if (NOT MSVC OR MSVC_VERSION LESS 1600) # 1600 is Visual Studio 2010. cxx_library(gmock_main_no_rtti "${cxx_no_rtti}"
# 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) "${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}" if (MSVC_VERSION LESS 1600) # 1600 is Visual Studio 2010.
gmock_main_use_own_tuple test/gmock-spec-builders_test.cc) # 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 gmock)
cxx_library(gmock_main_no_rtti "${cxx_no_rtti}" src/gmock_main.cc)
target_link_libraries(gmock_main_no_rtti gmock)
cxx_library(gmock_main_use_own_tuple "${cxx_use_own_tuple}" src/gmock_main.cc)
target_link_libraries(gmock_main_use_own_tuple gmock)
endif() endif()
cxx_test_with_flags(gmock-more-actions_no_exception_test "${cxx_no_exception}" cxx_test_with_flags(gmock-more-actions_no_exception_test "${cxx_no_exception}"
gmock_main_no_exception test/gmock-more-actions_test.cc) gmock_main_no_exception test/gmock-more-actions_test.cc)
......
...@@ -129,7 +129,7 @@ AS_IF([test "x${HAVE_BUILT_GTEST}" = "xyes"], ...@@ -129,7 +129,7 @@ AS_IF([test "x${HAVE_BUILT_GTEST}" = "xyes"],
GTEST_LDFLAGS=`${GTEST_CONFIG} --ldflags` GTEST_LDFLAGS=`${GTEST_CONFIG} --ldflags`
GTEST_LIBS=`${GTEST_CONFIG} --libs` GTEST_LIBS=`${GTEST_CONFIG} --libs`
GTEST_VERSION=`${GTEST_CONFIG} --version`], GTEST_VERSION=`${GTEST_CONFIG} --version`],
[AC_CONFIG_SUBDIRS([../googletest]) [
# GTEST_CONFIG needs to be executable both in a Makefile environment and # 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. # in a shell script environment, so resolve an absolute path for it here.
GTEST_CONFIG="`pwd -P`/../googletest/scripts/gtest-config" GTEST_CONFIG="`pwd -P`/../googletest/scripts/gtest-config"
......
...@@ -178,6 +178,8 @@ divided into several categories: ...@@ -178,6 +178,8 @@ divided into several categories:
|`Ne(value)` |`argument != value`| |`Ne(value)` |`argument != value`|
|`IsNull()` |`argument` is a `NULL` pointer (raw or smart).| |`IsNull()` |`argument` is a `NULL` pointer (raw or smart).|
|`NotNull()` |`argument` is a non-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`.| |`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.| |`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.|
......
...@@ -1231,7 +1231,7 @@ that references the implementation object dies, the implementation ...@@ -1231,7 +1231,7 @@ that references the implementation object dies, the implementation
object will be deleted. object will be deleted.
Therefore, if you have some complex matcher that you want to use again Therefore, if you have some complex matcher that you want to use again
and again, there is no need to build it everytime. Just assign it to a 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 variable and use that variable repeatedly! For example,
``` ```
...@@ -1403,7 +1403,7 @@ edge from node A to node B wherever A must occur before B, we can get ...@@ -1403,7 +1403,7 @@ 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 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 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 which sequences each `EXPECT_CALL()` belongs to in order to be able to
reconstruct the orginal DAG. reconstruct the original DAG.
So, to specify the partial order on the expectations we need to do two 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 things: first to define some `Sequence` objects, and then for each
...@@ -2182,7 +2182,7 @@ the implementation object dies, the implementation object will be ...@@ -2182,7 +2182,7 @@ the implementation object dies, the implementation object will be
deleted. deleted.
If you have some complex action that you want to use again and again, If you have some complex action that you want to use again and again,
you may not have to build it from scratch everytime. If the action 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 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 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 variable and use that variable repeatedly. For example:
......
...@@ -47,10 +47,9 @@ ...@@ -47,10 +47,9 @@
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "gtest/gtest.h"
#include "gmock/internal/gmock-internal-utils.h" #include "gmock/internal/gmock-internal-utils.h"
#include "gmock/internal/gmock-port.h" #include "gmock/internal/gmock-port.h"
#include "gtest/gtest.h"
#if GTEST_HAS_STD_INITIALIZER_LIST_ #if GTEST_HAS_STD_INITIALIZER_LIST_
# include <initializer_list> // NOLINT -- must be after gtest.h # include <initializer_list> // NOLINT -- must be after gtest.h
...@@ -515,7 +514,7 @@ template <typename T, typename M> ...@@ -515,7 +514,7 @@ template <typename T, typename M>
class MatcherCastImpl { class MatcherCastImpl {
public: public:
static Matcher<T> Cast(const M& polymorphic_matcher_or_value) { static Matcher<T> Cast(const M& polymorphic_matcher_or_value) {
// M can be a polymorhic matcher, in which case we want to use // M can be a polymorphic matcher, in which case we want to use
// its conversion operator to create Matcher<T>. Or it can be a value // its conversion operator to create Matcher<T>. Or it can be a value
// that should be passed to the Matcher<T>'s constructor. // that should be passed to the Matcher<T>'s constructor.
// //
...@@ -1551,7 +1550,7 @@ class BothOfMatcherImpl : public MatcherInterface<T> { ...@@ -1551,7 +1550,7 @@ class BothOfMatcherImpl : public MatcherInterface<T> {
// MatcherList provides mechanisms for storing a variable number of matchers in // MatcherList provides mechanisms for storing a variable number of matchers in
// a list structure (ListType) and creating a combining matcher from such a // a list structure (ListType) and creating a combining matcher from such a
// list. // list.
// The template is defined recursively using the following template paramters: // The template is defined recursively using the following template parameters:
// * kSize is the length of the MatcherList. // * kSize is the length of the MatcherList.
// * Head is the type of the first matcher of the list. // * Head is the type of the first matcher of the list.
// * Tail denotes the types of the remaining matchers of the list. // * Tail denotes the types of the remaining matchers of the list.
...@@ -2380,7 +2379,7 @@ class ResultOfMatcher { ...@@ -2380,7 +2379,7 @@ class ResultOfMatcher {
private: private:
// Functors often define operator() as non-const method even though // Functors often define operator() as non-const method even though
// they are actualy stateless. But we need to use them even when // 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 // 'this' is a const pointer. It's the user's responsibility not to
// use stateful callables with ResultOf(), which does't guarantee // use stateful callables with ResultOf(), which does't guarantee
// how many times the callable will be invoked. // how many times the callable will be invoked.
...@@ -3304,14 +3303,23 @@ typedef ::std::vector<ElementMatcherPair> ElementMatcherPairs; ...@@ -3304,14 +3303,23 @@ typedef ::std::vector<ElementMatcherPair> ElementMatcherPairs;
GTEST_API_ ElementMatcherPairs GTEST_API_ ElementMatcherPairs
FindMaxBipartiteMatching(const MatchMatrix& g); FindMaxBipartiteMatching(const MatchMatrix& g);
GTEST_API_ bool FindPairing(const MatchMatrix& matrix, struct UnorderedMatcherRequire {
MatchResultListener* listener); enum Flags {
Superset = 1 << 0,
Subset = 1 << 1,
ExactMatch = Superset | Subset,
};
};
// Untyped base class for implementing UnorderedElementsAre. By // Untyped base class for implementing UnorderedElementsAre. By
// putting logic that's not specific to the element type here, we // putting logic that's not specific to the element type here, we
// reduce binary bloat and increase compilation speed. // reduce binary bloat and increase compilation speed.
class GTEST_API_ UnorderedElementsAreMatcherImplBase { class GTEST_API_ UnorderedElementsAreMatcherImplBase {
protected: protected:
explicit UnorderedElementsAreMatcherImplBase(
UnorderedMatcherRequire::Flags matcher_flags)
: match_flags_(matcher_flags) {}
// A vector of matcher describers, one for each element matcher. // A vector of matcher describers, one for each element matcher.
// Does not own the describers (and thus can be used only when the // Does not own the describers (and thus can be used only when the
// element matchers are alive). // element matchers are alive).
...@@ -3323,9 +3331,12 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase { ...@@ -3323,9 +3331,12 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase {
// Describes the negation of this UnorderedElementsAre matcher. // Describes the negation of this UnorderedElementsAre matcher.
void DescribeNegationToImpl(::std::ostream* os) const; void DescribeNegationToImpl(::std::ostream* os) const;
bool VerifyAllElementsAndMatchersAreMatched( bool VerifyMatchMatrix(const ::std::vector<std::string>& element_printouts,
const ::std::vector<std::string>& element_printouts, const MatchMatrix& matrix,
const MatchMatrix& matrix, MatchResultListener* listener) const; MatchResultListener* listener) const;
bool FindPairing(const MatchMatrix& matrix,
MatchResultListener* listener) const;
MatcherDescriberVec& matcher_describers() { MatcherDescriberVec& matcher_describers() {
return matcher_describers_; return matcher_describers_;
...@@ -3335,13 +3346,17 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase { ...@@ -3335,13 +3346,17 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase {
return Message() << n << " element" << (n == 1 ? "" : "s"); return Message() << n << " element" << (n == 1 ? "" : "s");
} }
UnorderedMatcherRequire::Flags match_flags() const { return match_flags_; }
private: private:
UnorderedMatcherRequire::Flags match_flags_;
MatcherDescriberVec matcher_describers_; MatcherDescriberVec matcher_describers_;
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImplBase); GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImplBase);
}; };
// Implements unordered ElementsAre and unordered ElementsAreArray. // Implements UnorderedElementsAre, UnorderedElementsAreArray, IsSubsetOf, and
// IsSupersetOf.
template <typename Container> template <typename Container>
class UnorderedElementsAreMatcherImpl class UnorderedElementsAreMatcherImpl
: public MatcherInterface<Container>, : public MatcherInterface<Container>,
...@@ -3354,10 +3369,10 @@ class UnorderedElementsAreMatcherImpl ...@@ -3354,10 +3369,10 @@ class UnorderedElementsAreMatcherImpl
typedef typename StlContainer::const_iterator StlContainerConstIterator; typedef typename StlContainer::const_iterator StlContainerConstIterator;
typedef typename StlContainer::value_type Element; typedef typename StlContainer::value_type Element;
// Constructs the matcher from a sequence of element values or
// element matchers.
template <typename InputIter> template <typename InputIter>
UnorderedElementsAreMatcherImpl(InputIter first, InputIter last) { UnorderedElementsAreMatcherImpl(UnorderedMatcherRequire::Flags matcher_flags,
InputIter first, InputIter last)
: UnorderedElementsAreMatcherImplBase(matcher_flags) {
for (; first != last; ++first) { for (; first != last; ++first) {
matchers_.push_back(MatcherCast<const Element&>(*first)); matchers_.push_back(MatcherCast<const Element&>(*first));
matcher_describers().push_back(matchers_.back().GetDescriber()); matcher_describers().push_back(matchers_.back().GetDescriber());
...@@ -3378,34 +3393,32 @@ class UnorderedElementsAreMatcherImpl ...@@ -3378,34 +3393,32 @@ class UnorderedElementsAreMatcherImpl
MatchResultListener* listener) const { MatchResultListener* listener) const {
StlContainerReference stl_container = View::ConstReference(container); StlContainerReference stl_container = View::ConstReference(container);
::std::vector<std::string> element_printouts; ::std::vector<std::string> element_printouts;
MatchMatrix matrix = AnalyzeElements(stl_container.begin(), MatchMatrix matrix =
stl_container.end(), AnalyzeElements(stl_container.begin(), stl_container.end(),
&element_printouts, &element_printouts, listener);
listener);
const size_t actual_count = matrix.LhsSize(); if (matrix.LhsSize() == 0 && matrix.RhsSize() == 0) {
if (actual_count == 0 && matchers_.empty()) {
return true; return true;
} }
if (actual_count != matchers_.size()) {
// The element count doesn't match. If the container is empty, if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
// there's no need to explain anything as Google Mock already if (matrix.LhsSize() != matrix.RhsSize()) {
// prints the empty container. Otherwise we just need to show // The element count doesn't match. If the container is empty,
// how many elements there actually are. // there's no need to explain anything as Google Mock already
if (actual_count != 0 && listener->IsInterested()) { // prints the empty container. Otherwise we just need to show
*listener << "which has " << Elements(actual_count); // how many elements there actually are.
if (matrix.LhsSize() != 0 && listener->IsInterested()) {
*listener << "which has " << Elements(matrix.LhsSize());
}
return false;
} }
return false;
} }
return VerifyAllElementsAndMatchersAreMatched(element_printouts, return VerifyMatchMatrix(element_printouts, matrix, listener) &&
matrix, listener) &&
FindPairing(matrix, listener); FindPairing(matrix, listener);
} }
private: private:
typedef ::std::vector<Matcher<const Element&> > MatcherVec;
template <typename ElementIter> template <typename ElementIter>
MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last, MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last,
::std::vector<std::string>* element_printouts, ::std::vector<std::string>* element_printouts,
...@@ -3432,7 +3445,7 @@ class UnorderedElementsAreMatcherImpl ...@@ -3432,7 +3445,7 @@ class UnorderedElementsAreMatcherImpl
return matrix; return matrix;
} }
MatcherVec matchers_; ::std::vector<Matcher<const Element&> > matchers_;
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImpl); GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImpl);
}; };
...@@ -3465,7 +3478,7 @@ class UnorderedElementsAreMatcher { ...@@ -3465,7 +3478,7 @@ class UnorderedElementsAreMatcher {
TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_, TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,
::std::back_inserter(matchers)); ::std::back_inserter(matchers));
return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>( return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>(
matchers.begin(), matchers.end())); UnorderedMatcherRequire::ExactMatch, matchers.begin(), matchers.end()));
} }
private: private:
...@@ -3498,24 +3511,23 @@ class ElementsAreMatcher { ...@@ -3498,24 +3511,23 @@ class ElementsAreMatcher {
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher); GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher);
}; };
// Implements UnorderedElementsAreArray(). // Implements UnorderedElementsAreArray(), IsSubsetOf(), and IsSupersetOf().
template <typename T> template <typename T>
class UnorderedElementsAreArrayMatcher { class UnorderedElementsAreArrayMatcher {
public: public:
UnorderedElementsAreArrayMatcher() {}
template <typename Iter> template <typename Iter>
UnorderedElementsAreArrayMatcher(Iter first, Iter last) UnorderedElementsAreArrayMatcher(UnorderedMatcherRequire::Flags match_flags,
: matchers_(first, last) {} Iter first, Iter last)
: match_flags_(match_flags), matchers_(first, last) {}
template <typename Container> template <typename Container>
operator Matcher<Container>() const { operator Matcher<Container>() const {
return MakeMatcher( return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>(
new UnorderedElementsAreMatcherImpl<Container>(matchers_.begin(), match_flags_, matchers_.begin(), matchers_.end()));
matchers_.end()));
} }
private: private:
UnorderedMatcherRequire::Flags match_flags_;
::std::vector<T> matchers_; ::std::vector<T> matchers_;
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreArrayMatcher); GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreArrayMatcher);
...@@ -3624,9 +3636,69 @@ GTEST_API_ std::string FormatMatcherDescription(bool negation, ...@@ -3624,9 +3636,69 @@ GTEST_API_ std::string FormatMatcherDescription(bool negation,
const char* matcher_name, const char* matcher_name,
const Strings& param_values); const Strings& param_values);
namespace variant_matcher {
// Overloads to allow VariantMatcher to do proper ADL lookup.
template <typename T>
void holds_alternative() {}
template <typename T>
void get() {}
// Implements a matcher that checks the value of a variant<> type variable.
template <typename T>
class VariantMatcher {
public:
explicit VariantMatcher(::testing::Matcher<const T&> matcher)
: matcher_(internal::move(matcher)) {}
template <typename Variant>
bool MatchAndExplain(const Variant& value,
::testing::MatchResultListener* listener) const {
if (!listener->IsInterested()) {
return holds_alternative<T>(value) && matcher_.Matches(get<T>(value));
}
if (!holds_alternative<T>(value)) {
*listener << "whose value is not of type '" << GetTypeName() << "'";
return false;
}
const T& elem = get<T>(value);
StringMatchResultListener elem_listener;
const bool match = matcher_.MatchAndExplain(elem, &elem_listener);
*listener << "whose value " << PrintToString(elem)
<< (match ? " matches" : " doesn't match");
PrintIfNotEmpty(elem_listener.str(), listener->stream());
return match;
}
void DescribeTo(std::ostream* os) const {
*os << "is a variant<> with value of type '" << GetTypeName()
<< "' and the value ";
matcher_.DescribeTo(os);
}
void DescribeNegationTo(std::ostream* os) const {
*os << "is a variant<> with value of type other than '" << GetTypeName()
<< "' or the value ";
matcher_.DescribeNegationTo(os);
}
private:
static string GetTypeName() {
#if GTEST_HAS_RTTI
return internal::GetTypeName<T>();
#endif
return "the element type";
}
const ::testing::Matcher<const T&> matcher_;
};
} // namespace variant_matcher
} // namespace internal } // namespace internal
// ElementsAreArray(first, last) // ElementsAreArray(iterator_first, iterator_last)
// ElementsAreArray(pointer, count) // ElementsAreArray(pointer, count)
// ElementsAreArray(array) // ElementsAreArray(array)
// ElementsAreArray(container) // ElementsAreArray(container)
...@@ -3675,20 +3747,26 @@ ElementsAreArray(::std::initializer_list<T> xs) { ...@@ -3675,20 +3747,26 @@ ElementsAreArray(::std::initializer_list<T> xs) {
} }
#endif #endif
// UnorderedElementsAreArray(first, last) // UnorderedElementsAreArray(iterator_first, iterator_last)
// UnorderedElementsAreArray(pointer, count) // UnorderedElementsAreArray(pointer, count)
// UnorderedElementsAreArray(array) // UnorderedElementsAreArray(array)
// UnorderedElementsAreArray(container) // UnorderedElementsAreArray(container)
// UnorderedElementsAreArray({ e1, e2, ..., en }) // UnorderedElementsAreArray({ e1, e2, ..., en })
// //
// The UnorderedElementsAreArray() functions are like // UnorderedElementsAreArray() verifies that a bijective mapping onto a
// ElementsAreArray(...), but allow matching the elements in any order. // collection of matchers exists.
//
// The matchers can be specified as an array, a pointer and count, a container,
// an initializer list, or an STL iterator range. In each of these cases, the
// underlying matchers can be either values or matchers.
template <typename Iter> template <typename Iter>
inline internal::UnorderedElementsAreArrayMatcher< inline internal::UnorderedElementsAreArrayMatcher<
typename ::std::iterator_traits<Iter>::value_type> typename ::std::iterator_traits<Iter>::value_type>
UnorderedElementsAreArray(Iter first, Iter last) { UnorderedElementsAreArray(Iter first, Iter last) {
typedef typename ::std::iterator_traits<Iter>::value_type T; typedef typename ::std::iterator_traits<Iter>::value_type T;
return internal::UnorderedElementsAreArrayMatcher<T>(first, last); return internal::UnorderedElementsAreArrayMatcher<T>(
internal::UnorderedMatcherRequire::ExactMatch, first, last);
} }
template <typename T> template <typename T>
...@@ -3730,7 +3808,9 @@ UnorderedElementsAreArray(::std::initializer_list<T> xs) { ...@@ -3730,7 +3808,9 @@ UnorderedElementsAreArray(::std::initializer_list<T> xs) {
const internal::AnythingMatcher _ = {}; const internal::AnythingMatcher _ = {};
// Creates a matcher that matches any value of the given type T. // Creates a matcher that matches any value of the given type T.
template <typename T> template <typename T>
inline Matcher<T> A() { return MakeMatcher(new internal::AnyMatcherImpl<T>()); } inline Matcher<T> A() {
return Matcher<T>(new internal::AnyMatcherImpl<T>());
}
// Creates a matcher that matches any value of the given type T. // Creates a matcher that matches any value of the given type T.
template <typename T> template <typename T>
...@@ -4300,6 +4380,128 @@ inline internal::ContainsMatcher<M> Contains(M matcher) { ...@@ -4300,6 +4380,128 @@ inline internal::ContainsMatcher<M> Contains(M matcher) {
return internal::ContainsMatcher<M>(matcher); return internal::ContainsMatcher<M>(matcher);
} }
// IsSupersetOf(iterator_first, iterator_last)
// IsSupersetOf(pointer, count)
// IsSupersetOf(array)
// IsSupersetOf(container)
// IsSupersetOf({e1, e2, ..., en})
//
// IsSupersetOf() verifies that a surjective partial mapping onto a collection
// of matchers exists. In other words, a container matches
// IsSupersetOf({e1, ..., en}) if and only if there is a permutation
// {y1, ..., yn} of some of the container's elements where y1 matches e1,
// ..., and yn matches en. Obviously, the size of the container must be >= n
// in order to have a match. Examples:
//
// - {1, 2, 3} matches IsSupersetOf({Ge(3), Ne(0)}), as 3 matches Ge(3) and
// 1 matches Ne(0).
// - {1, 2} doesn't match IsSupersetOf({Eq(1), Lt(2)}), even though 1 matches
// both Eq(1) and Lt(2). The reason is that different matchers must be used
// for elements in different slots of the container.
// - {1, 1, 2} matches IsSupersetOf({Eq(1), Lt(2)}), as (the first) 1 matches
// Eq(1) and (the second) 1 matches Lt(2).
// - {1, 2, 3} matches IsSupersetOf(Gt(1), Gt(1)), as 2 matches (the first)
// Gt(1) and 3 matches (the second) Gt(1).
//
// The matchers can be specified as an array, a pointer and count, a container,
// an initializer list, or an STL iterator range. In each of these cases, the
// underlying matchers can be either values or matchers.
template <typename Iter>
inline internal::UnorderedElementsAreArrayMatcher<
typename ::std::iterator_traits<Iter>::value_type>
IsSupersetOf(Iter first, Iter last) {
typedef typename ::std::iterator_traits<Iter>::value_type T;
return internal::UnorderedElementsAreArrayMatcher<T>(
internal::UnorderedMatcherRequire::Superset, first, last);
}
template <typename T>
inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(
const T* pointer, size_t count) {
return IsSupersetOf(pointer, pointer + count);
}
template <typename T, size_t N>
inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(
const T (&array)[N]) {
return IsSupersetOf(array, N);
}
template <typename Container>
inline internal::UnorderedElementsAreArrayMatcher<
typename Container::value_type>
IsSupersetOf(const Container& container) {
return IsSupersetOf(container.begin(), container.end());
}
#if GTEST_HAS_STD_INITIALIZER_LIST_
template <typename T>
inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(
::std::initializer_list<T> xs) {
return IsSupersetOf(xs.begin(), xs.end());
}
#endif
// IsSubsetOf(iterator_first, iterator_last)
// IsSubsetOf(pointer, count)
// IsSubsetOf(array)
// IsSubsetOf(container)
// IsSubsetOf({e1, e2, ..., en})
//
// IsSubsetOf() verifies that an injective mapping onto a collection of matchers
// exists. In other words, a container matches IsSubsetOf({e1, ..., en}) if and
// only if there is a subset of matchers {m1, ..., mk} which would match the
// container using UnorderedElementsAre. Obviously, the size of the container
// must be <= n in order to have a match. Examples:
//
// - {1} matches IsSubsetOf({Gt(0), Lt(0)}), as 1 matches Gt(0).
// - {1, -1} matches IsSubsetOf({Lt(0), Gt(0)}), as 1 matches Gt(0) and -1
// matches Lt(0).
// - {1, 2} doesn't matches IsSubsetOf({Gt(0), Lt(0)}), even though 1 and 2 both
// match Gt(0). The reason is that different matchers must be used for
// elements in different slots of the container.
//
// The matchers can be specified as an array, a pointer and count, a container,
// an initializer list, or an STL iterator range. In each of these cases, the
// underlying matchers can be either values or matchers.
template <typename Iter>
inline internal::UnorderedElementsAreArrayMatcher<
typename ::std::iterator_traits<Iter>::value_type>
IsSubsetOf(Iter first, Iter last) {
typedef typename ::std::iterator_traits<Iter>::value_type T;
return internal::UnorderedElementsAreArrayMatcher<T>(
internal::UnorderedMatcherRequire::Subset, first, last);
}
template <typename T>
inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(
const T* pointer, size_t count) {
return IsSubsetOf(pointer, pointer + count);
}
template <typename T, size_t N>
inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(
const T (&array)[N]) {
return IsSubsetOf(array, N);
}
template <typename Container>
inline internal::UnorderedElementsAreArrayMatcher<
typename Container::value_type>
IsSubsetOf(const Container& container) {
return IsSubsetOf(container.begin(), container.end());
}
#if GTEST_HAS_STD_INITIALIZER_LIST_
template <typename T>
inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(
::std::initializer_list<T> xs) {
return IsSubsetOf(xs.begin(), xs.end());
}
#endif
// Matches an STL-style container or a native array that contains only // Matches an STL-style container or a native array that contains only
// elements matching the given value or matcher. // elements matching the given value or matcher.
// //
...@@ -4398,6 +4600,17 @@ inline internal::AnyOfMatcher<Args...> AnyOf(const Args&... matchers) { ...@@ -4398,6 +4600,17 @@ inline internal::AnyOfMatcher<Args...> AnyOf(const Args&... matchers) {
template <typename InnerMatcher> template <typename InnerMatcher>
inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; } inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; }
// Returns a matcher that matches the value of a variant<> type variable.
// The matcher implementation uses ADL to find the holds_alternative and get
// functions.
// It is compatible with std::variant.
template <typename T>
PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T> > VariantWith(
const Matcher<const T&>& matcher) {
return MakePolymorphicMatcher(
internal::variant_matcher::VariantMatcher<T>(matcher));
}
// These macros allow using matchers to check values in Google Test // These macros allow using matchers to check values in Google Test
// tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher) // tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher)
// succeed iff the value matches the matcher. If the assertion fails, // succeed iff the value matches the matcher. If the assertion fails,
......
...@@ -53,6 +53,22 @@ MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") { ...@@ -53,6 +53,22 @@ MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") {
return false; return false;
} }
// Define a matcher that matches a value that evaluates in boolean
// context to true. Useful for types that define "explicit operator
// bool" operators and so can't be compared for equality with true
// and false.
MATCHER(IsTrue, negation ? "is false" : "is true") {
return static_cast<bool>(arg);
}
// Define a matcher that matches a value that evaluates in boolean
// context to false. Useful for types that define "explicit operator
// bool" operators and so can't be compared for equality with true
// and false.
MATCHER(IsFalse, negation ? "is true" : "is false") {
return !static_cast<bool>(arg);
}
} // namespace testing } // namespace testing
#endif // GMOCK_GMOCK_MORE_MATCHERS_H_ #endif // GMOCK_GMOCK_MORE_MATCHERS_H_
...@@ -65,11 +65,6 @@ ...@@ -65,11 +65,6 @@
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <vector> #include <vector>
#if GTEST_HAS_EXCEPTIONS
# include <stdexcept> // NOLINT
#endif
#include "gmock/gmock-actions.h" #include "gmock/gmock-actions.h"
#include "gmock/gmock-cardinalities.h" #include "gmock/gmock-cardinalities.h"
#include "gmock/gmock-matchers.h" #include "gmock/gmock-matchers.h"
...@@ -77,6 +72,10 @@ ...@@ -77,6 +72,10 @@
#include "gmock/internal/gmock-port.h" #include "gmock/internal/gmock-port.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#if GTEST_HAS_EXCEPTIONS
# include <stdexcept> // NOLINT
#endif
namespace testing { namespace testing {
// An abstract handle of an expectation. // An abstract handle of an expectation.
......
...@@ -59,8 +59,8 @@ ...@@ -59,8 +59,8 @@
#include "gmock/gmock-cardinalities.h" #include "gmock/gmock-cardinalities.h"
#include "gmock/gmock-generated-actions.h" #include "gmock/gmock-generated-actions.h"
#include "gmock/gmock-generated-function-mockers.h" #include "gmock/gmock-generated-function-mockers.h"
#include "gmock/gmock-generated-nice-strict.h"
#include "gmock/gmock-generated-matchers.h" #include "gmock/gmock-generated-matchers.h"
#include "gmock/gmock-generated-nice-strict.h"
#include "gmock/gmock-matchers.h" #include "gmock/gmock-matchers.h"
#include "gmock/gmock-more-actions.h" #include "gmock/gmock-more-actions.h"
#include "gmock/gmock-more-matchers.h" #include "gmock/gmock-more-matchers.h"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment