Compare commits

..

No commits in common. "main" and "release-1.10.0" have entirely different histories.

217 changed files with 28486 additions and 18388 deletions

View File

@ -1,43 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: 'bug'
assignees: ''
---
**Describe the bug**
Include a clear and concise description of what the problem is, including what
you expected to happen, and what actually happened.
**Steps to reproduce the bug**
It's important that we are able to reproduce the problem that you are
experiencing. Please provide all code and relevant steps to reproduce the
problem, including your `BUILD`/`CMakeLists.txt` file and build commands. Links
to a GitHub branch or [godbolt.org](https://godbolt.org/) that demonstrate the
problem are also helpful.
**Does the bug persist in the most recent commit?**
We recommend using the latest commit in the master branch in your projects.
**What operating system and version are you using?**
If you are using a Linux distribution please include the name and version of the
distribution as well.
**What compiler and version are you using?**
Please include the output of `gcc -v` or `clang -v`, or the equivalent for your
compiler.
**What build system are you using?**
Please include the output of `bazel --version` or `cmake --version`, or the
equivalent for your build system.
**Additional context**
Add any other context about the problem here.

View File

@ -1,24 +0,0 @@
---
name: Feature request
about: Propose a new feature
title: ''
labels: 'enhancement'
assignees: ''
---
**Does the feature exist in the most recent commit?**
We recommend using the latest commit from GitHub in your projects.
**Why do we need this feature?**
Ideally, explain why a combination of existing features cannot be used instead.
**Describe the proposal**
Include a detailed description of the feature, with usage examples.
**Is the feature specific to an operating system, compiler, or build system version?**
If it is, please specify which versions.

View File

@ -1 +0,0 @@
blank_issues_enabled: false

73
.travis.yml Normal file
View File

@ -0,0 +1,73 @@
# Build matrix / environment variable are explained on:
# https://docs.travis-ci.com/user/customizing-the-build/
# This file can be validated on:
# http://lint.travis-ci.org/
language: cpp
# Define the matrix explicitly, manually expanding the combinations of (os, compiler, env).
# It is more tedious, but grants us far more flexibility.
matrix:
include:
- os: linux
before_install: chmod -R +x ./ci/*platformio.sh
install: ./ci/install-platformio.sh
script: ./ci/build-platformio.sh
- os: linux
dist: xenial
compiler: gcc
install: ./ci/install-linux.sh && ./ci/log-config.sh
script: ./ci/build-linux-bazel.sh
- os: linux
dist: xenial
compiler: clang
install: ./ci/install-linux.sh && ./ci/log-config.sh
script: ./ci/build-linux-bazel.sh
- os: linux
compiler: gcc
env: BUILD_TYPE=Debug VERBOSE=1 CXX_FLAGS=-std=c++11
- os: linux
compiler: clang
env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11 -Wgnu-zero-variadic-macro-arguments
- os: linux
compiler: clang
env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11 NO_EXCEPTION=ON NO_RTTI=ON COMPILER_IS_GNUCXX=ON
- os: osx
compiler: gcc
env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11 HOMEBREW_LOGS=~/homebrew-logs HOMEBREW_TEMP=~/homebrew-temp
- os: osx
compiler: clang
env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11 HOMEBREW_LOGS=~/homebrew-logs HOMEBREW_TEMP=~/homebrew-temp
# 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.
install:
- ./ci/install-${TRAVIS_OS_NAME}.sh
- . ./ci/env-${TRAVIS_OS_NAME}.sh
- ./ci/log-config.sh
script: ./ci/travis.sh
# This section installs the necessary dependencies.
addons:
apt:
# List of whitelisted in travis packages for ubuntu-precise can be found here:
# https://github.com/travis-ci/apt-package-whitelist/blob/master/ubuntu-precise
# List of whitelisted in travis apt-sources:
# https://github.com/travis-ci/apt-source-whitelist/blob/master/ubuntu.json
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.9
packages:
- g++-4.9
- clang-3.9
update: true
homebrew:
packages:
- ccache
- gcc@4.9
- llvm@4
update: true
notifications:
email: false

View File

@ -30,38 +30,15 @@
#
# Bazel Build for Google C++ Testing Framework(Google Test)
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
exports_files(["LICENSE"])
config_setting(
name = "qnx",
constraint_values = ["@platforms//os:qnx"],
)
config_setting(
name = "windows",
constraint_values = ["@platforms//os:windows"],
)
config_setting(
name = "freebsd",
constraint_values = ["@platforms//os:freebsd"],
)
config_setting(
name = "openbsd",
constraint_values = ["@platforms//os:openbsd"],
)
config_setting(
name = "msvc_compiler",
flag_values = {
"@bazel_tools//tools/cpp:compiler": "msvc-cl",
},
visibility = [":__subpackages__"],
constraint_values = ["@bazel_tools//platforms:windows"],
)
config_setting(
@ -99,7 +76,6 @@ cc_library(
"googlemock/include/gmock/*.h",
]),
copts = select({
":qnx": [],
":windows": [],
"//conditions:default": ["-pthread"],
}),
@ -118,10 +94,7 @@ cc_library(
"googletest/include",
],
linkopts = select({
":qnx": ["-lregex"],
":windows": [],
":freebsd": ["-lm", "-pthread"],
":openbsd": ["-lm", "-pthread"],
"//conditions:default": ["-pthread"],
}),
deps = select({
@ -130,7 +103,6 @@ cc_library(
"@com_google_absl//absl/debugging:stacktrace",
"@com_google_absl//absl/debugging:symbolize",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/types:any",
"@com_google_absl//absl/types:optional",
"@com_google_absl//absl/types:variant",
],

View File

@ -1,17 +1,23 @@
# Note: CMake support is community-based. The maintainers do not use CMake
# internally.
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 2.8.8)
if (POLICY CMP0048)
cmake_policy(SET CMP0048 NEW)
endif (POLICY CMP0048)
project(googletest-distribution)
set(GOOGLETEST_VERSION 1.11.0)
set(GOOGLETEST_VERSION 1.10.0)
if(NOT CYGWIN AND NOT MSYS AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL QNX)
set(CMAKE_CXX_EXTENSIONS OFF)
if (CMAKE_VERSION VERSION_LESS "3.1")
add_definitions(-std=c++11)
else()
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(NOT CYGWIN)
set(CMAKE_CXX_EXTENSIONS OFF)
endif()
endif()
enable_testing()

View File

@ -28,7 +28,7 @@ PR is acceptable as an alternative.
## Contributing A Patch
1. Submit an issue describing your proposed change to the
[issue tracker](https://github.com/google/googletest/issues).
[issue tracker](https://github.com/google/googletest).
2. Please don't mix more than one logical change per submittal, because it
makes the history hard to follow. If you want to make a change that doesn't
have a corresponding issue in the issue tracker, please create one.
@ -36,8 +36,7 @@ PR is acceptable as an alternative.
This ensures that work isn't being duplicated and communicating your plan
early also generally leads to better patches.
4. If your proposed change is accepted, and you haven't already done so, sign a
Contributor License Agreement
([see details above](#contributor-license-agreements)).
Contributor License Agreement (see details above).
5. Fork the desired repo, develop and test your code changes.
6. Ensure that your code adheres to the existing style in the sample to which
you are contributing.
@ -81,7 +80,7 @@ fairly rigid coding style, as defined by the
will be expected to conform to the style outlined
[here](https://google.github.io/styleguide/cppguide.html). Use
[.clang-format](https://github.com/google/googletest/blob/master/.clang-format)
to check your formatting.
to check your formatting
## Requirements for Contributors
@ -90,7 +89,7 @@ and their own tests from a git checkout, which has further requirements:
* [Python](https://www.python.org/) v2.3 or newer (for running some of the
tests and re-generating certain source files from templates)
* [CMake](https://cmake.org/) v2.8.12 or newer
* [CMake](https://cmake.org/) v2.6.4 or newer
## Developing Google Test and Google Mock
@ -129,3 +128,15 @@ To run the tests, do
make test
All tests should pass.
### Regenerating Source Files
Some of Google Test's source files are generated from templates (not in the C++
sense) using a script. For example, the file
include/gtest/internal/gtest-type-util.h.pump is used to generate
gtest-type-util.h in the same directory.
You don't need to worry about regenerating the source files unless you need to
modify them. You would then modify the corresponding `.pump` files and run the
'[pump.py](googletest/scripts/pump.py)' generator script. See the
[Pump Manual](googletest/docs/pump_manual.md).

138
README.md
View File

@ -1,44 +1,48 @@
# GoogleTest
# Google Test
### Announcements
#### OSS Builds Status:
#### Live at Head
[![Build Status](https://api.travis-ci.org/google/googletest.svg?branch=master)](https://travis-ci.org/google/googletest)
[![Build status](https://ci.appveyor.com/api/projects/status/4o38plt0xbo1ubc8/branch/master?svg=true)](https://ci.appveyor.com/project/GoogleTestAppVeyor/googletest/branch/master)
GoogleTest now follows the
[Abseil Live at Head philosophy](https://abseil.io/about/philosophy#upgrade-support).
We recommend using the latest commit in the `master` branch in your projects.
### Future Plans
#### Documentation Updates
#### 1.8.x Release:
Our documentation is now live on GitHub Pages at
https://google.github.io/googletest/. We recommend browsing the documentation on
GitHub Pages rather than directly in the repository.
[the 1.8.x](https://github.com/google/googletest/releases/tag/release-1.8.1) is
the last release that works with pre-C++11 compilers. The 1.8.x will not accept
any requests for any new features and any bugfix requests will only be accepted
if proven "critical"
#### Release 1.11.0
#### Post 1.8.x:
[Release 1.11.0](https://github.com/google/googletest/releases/tag/release-1.11.0)
is now available.
On-going work to improve/cleanup/pay technical debt. When this work is completed
there will be a 1.9.x tagged release
#### Coming Soon
#### Post 1.9.x
* We are planning to take a dependency on
[Abseil](https://github.com/abseil/abseil-cpp).
* More documentation improvements are planned.
Post 1.9.x googletest will follow
[Abseil Live at Head philosophy](https://abseil.io/about/philosophy)
## Welcome to **GoogleTest**, Google's C++ test framework!
## Welcome to **Google Test**, Google's C++ test framework!
This repository is a merger of the formerly separate GoogleTest and GoogleMock
projects. These were so closely related that it makes sense to maintain and
release them together.
### Getting Started
Please subscribe to the mailing list at googletestframework@googlegroups.com for
questions, discussions, and development.
See the [GoogleTest User's Guide](https://google.github.io/googletest/) for
documentation. We recommend starting with the
[GoogleTest Primer](https://google.github.io/googletest/primer.html).
### Getting started:
More information about building GoogleTest can be found at
[googletest/README.md](googletest/README.md).
The information for **Google Test** is available in the
[Google Test Primer](googletest/docs/primer.md) documentation.
**Google Mock** is an extension to Google Test for writing and using C++ mock
classes. See the separate [Google Mock documentation](googlemock/README.md).
More detailed documentation for googletest is in its interior
[googletest/README.md](googletest/README.md) file.
## Features
@ -53,45 +57,22 @@ More information about building GoogleTest can be found at
* Various options for running the tests.
* XML test report generation.
## Supported Platforms
## Platforms
GoogleTest requires a codebase and compiler compliant with the C++11 standard or
newer.
The GoogleTest code is officially supported on the following platforms.
Operating systems or tools not listed below are community-supported. For
community-supported platforms, patches that do not complicate the code may be
considered.
If you notice any problems on your platform, please file an issue on the
[GoogleTest GitHub Issue Tracker](https://github.com/google/googletest/issues).
Pull requests containing fixes are welcome!
### Operating Systems
Google test has been used on a variety of platforms:
* Linux
* macOS
* Mac OS X
* Windows
* Cygwin
* MinGW
* Windows Mobile
* Symbian
* PlatformIO
### Compilers
## Who Is Using Google Test?
* gcc 5.0+
* clang 5.0+
* MSVC 2015+
**macOS users:** Xcode 9.3+ provides clang 5.0+.
### Build Systems
* [Bazel](https://bazel.build/)
* [CMake](https://cmake.org/)
**Note:** Bazel is the build system used by the team internally and in tests.
CMake is supported on a best-effort basis and by the community.
## Who Is Using GoogleTest?
In addition to many internal projects at Google, GoogleTest is also used by the
In addition to many internal projects at Google, Google Test is also used by the
following notable projects:
* The [Chromium projects](http://www.chromium.org/) (behind the Chrome browser
@ -100,6 +81,8 @@ following notable projects:
* [Protocol Buffers](https://github.com/google/protobuf), Google's data
interchange format.
* The [OpenCV](http://opencv.org/) computer vision library.
* [tiny-dnn](https://github.com/tiny-dnn/tiny-dnn): header only,
dependency-free deep learning framework in C++11.
## Related Open Source Projects
@ -107,13 +90,13 @@ following notable projects:
automated test-runner and Graphical User Interface with powerful features for
Windows and Linux platforms.
[GoogleTest UI](https://github.com/ospector/gtest-gbar) is a test runner that
[Google Test UI](https://github.com/ospector/gtest-gbar) is test runner that
runs your test binary, allows you to track its progress via a progress bar, and
displays a list of test failures. Clicking on one shows failure text. GoogleTest
UI is written in C#.
displays a list of test failures. Clicking on one shows failure text. Google
Test UI is written in C#.
[GTest TAP Listener](https://github.com/kinow/gtest-tap-listener) is an event
listener for GoogleTest that implements the
listener for Google Test that implements the
[TAP protocol](https://en.wikipedia.org/wiki/Test_Anything_Protocol) for test
result output. If your test runner understands TAP, you may find it useful.
@ -121,20 +104,31 @@ result output. If your test runner understands TAP, you may find it useful.
runs tests from your binary in parallel to provide significant speed-up.
[GoogleTest Adapter](https://marketplace.visualstudio.com/items?itemName=DavidSchuldenfrei.gtest-adapter)
is a VS Code extension allowing to view GoogleTest in a tree view, and run/debug
your tests.
is a VS Code extension allowing to view Google Tests in a tree view, and
run/debug your tests.
[C++ TestMate](https://github.com/matepek/vscode-catch2-test-adapter) is a VS
Code extension allowing to view GoogleTest in a tree view, and run/debug your
tests.
## Requirements
[Cornichon](https://pypi.org/project/cornichon/) is a small Gherkin DSL parser
that generates stub code for GoogleTest.
Google Test is designed to have fairly minimal requirements to build and use
with your projects, but there are some. If you notice any problems on your
platform, please notify
[googletestframework@googlegroups.com](https://groups.google.com/forum/#!forum/googletestframework).
Patches for fixing them are welcome!
## Contributing Changes
### Build Requirements
Please read
[`CONTRIBUTING.md`](https://github.com/google/googletest/blob/master/CONTRIBUTING.md)
for details on how to contribute to this project.
These are the base requirements to build and use Google Test from a source
package:
* [Bazel](https://bazel.build/) or [CMake](https://cmake.org/). NOTE: Bazel is
the build system that googletest is using internally and tests against.
CMake is community-supported.
* a C++11-standard-compliant compiler
## Contributing change
Please read the [`CONTRIBUTING.md`](CONTRIBUTING.md) for details on how to
contribute to this project.
Happy testing!

View File

@ -2,16 +2,22 @@ workspace(name = "com_google_googletest")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# Abseil
http_archive(
name = "com_google_absl",
sha256 = "aeba534f7307e36fe084b452299e49b97420667a8d28102cf9a0daeed340b859",
strip_prefix = "abseil-cpp-7971fb358ae376e016d2d4fc9327aad95659b25e",
urls = ["https://github.com/abseil/abseil-cpp/archive/7971fb358ae376e016d2d4fc9327aad95659b25e.zip"], # 2021-05-20T02:59:16Z
name = "com_google_absl",
urls = ["https://github.com/abseil/abseil-cpp/archive/master.zip"],
strip_prefix = "abseil-cpp-master",
)
http_archive(
name = "rules_cc",
strip_prefix = "rules_cc-master",
urls = ["https://github.com/bazelbuild/rules_cc/archive/master.zip"],
)
http_archive(
name = "rules_python",
sha256 = "98b3c592faea9636ac8444bfd9de7f3fb4c60590932d6e6ac5946e3f8dbd5ff6",
strip_prefix = "rules_python-ed6cc8f2c3692a6a7f013ff8bc185ba77eb9b4d2",
urls = ["https://github.com/bazelbuild/rules_python/archive/ed6cc8f2c3692a6a7f013ff8bc185ba77eb9b4d2.zip"], # 2021-05-17T00:24:16Z
strip_prefix = "rules_python-master",
urls = ["https://github.com/bazelbuild/rules_python/archive/master.zip"],
)

154
appveyor.yml Normal file
View File

@ -0,0 +1,154 @@
version: '{build}'
os: Visual Studio 2015
environment:
matrix:
- compiler: msvc-15-seh
generator: "Visual Studio 15 2017"
build_system: cmake
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
- compiler: msvc-15-seh
generator: "Visual Studio 15 2017 Win64"
build_system: cmake
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
enabled_on_pr: yes
- compiler: msvc-15-seh
build_system: bazel
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
enabled_on_pr: yes
- compiler: msvc-14-seh
build_system: cmake
generator: "Visual Studio 14 2015"
enabled_on_pr: yes
- compiler: msvc-14-seh
build_system: cmake
generator: "Visual Studio 14 2015 Win64"
- compiler: gcc-6.3.0-posix
build_system: cmake
generator: "MinGW Makefiles"
cxx_path: 'C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\bin'
enabled_on_pr: yes
configuration:
- Debug
build:
verbosity: minimal
install:
- ps: |
Write-Output "Compiler: $env:compiler"
Write-Output "Generator: $env:generator"
Write-Output "Env:Configuation: $env:configuration"
Write-Output "Env: $env"
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"
}
}
# install Bazel
if ($env:build_system -eq "bazel") {
appveyor DownloadFile https://github.com/bazelbuild/bazel/releases/download/0.28.1/bazel-0.28.1-windows-x86_64.exe -FileName bazel.exe
}
if ($env:build_system -eq "cmake") {
# git bash conflicts with MinGW makefiles
if ($env:generator -eq "MinGW Makefiles") {
$env:path = $env:path.replace("C:\Program Files\Git\usr\bin;", "")
if ($env:cxx_path -ne "") {
$env:path += ";$env:cxx_path"
}
}
}
before_build:
- ps: |
$env:root=$env:APPVEYOR_BUILD_FOLDER
Write-Output "env:root: $env:root"
build_script:
- 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
} else {
# special case - build with Bazel
if ($env:build_system -eq "bazel") {
& $env:root\bazel.exe build -c opt //:gtest_samples
if ($LastExitCode -eq 0) { # bazel writes to StdErr and PowerShell interprets it as an error
$host.SetShouldExit(0)
} else { # a real error
throw "Exec: $ErrorMessage"
}
return
}
}
# by default build with CMake
md _build -Force | Out-Null
cd _build
$conf = if ($env:generator -eq "MinGW Makefiles") {"-DCMAKE_BUILD_TYPE=$env:configuration"} else {"-DCMAKE_CONFIGURATION_TYPES=Debug;Release"}
# Disable test for MinGW (gtest tests fail, gmock tests can not build)
$gtest_build_tests = if ($env:generator -eq "MinGW Makefiles") {"-Dgtest_build_tests=OFF"} else {"-Dgtest_build_tests=ON"}
$gmock_build_tests = if ($env:generator -eq "MinGW Makefiles") {"-Dgmock_build_tests=OFF"} else {"-Dgmock_build_tests=ON"}
& cmake -G "$env:generator" $conf -Dgtest_build_samples=ON $gtest_build_tests $gmock_build_tests ..
if ($LastExitCode -ne 0) {
throw "Exec: $ErrorMessage"
}
$cmake_parallel = if ($env:generator -eq "MinGW Makefiles") {"-j2"} else {"/m"}
& cmake --build . --config $env:configuration -- $cmake_parallel
if ($LastExitCode -ne 0) {
throw "Exec: $ErrorMessage"
}
skip_commits:
files:
- '**/*.md'
test_script:
- 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:build_system -eq "bazel") {
# special case - testing with Bazel
& $env:root\bazel.exe test //:gtest_samples
if ($LastExitCode -eq 0) { # bazel writes to StdErr and PowerShell interprets it as an error
$host.SetShouldExit(0)
} else { # a real error
throw "Exec: $ErrorMessage"
}
}
if ($env:build_system -eq "cmake") {
# built with CMake - test with CTest
if ($env:generator -eq "MinGW Makefiles") {
return # No test available for MinGW
}
& ctest -C $env:configuration --timeout 600 --output-on-failure
if ($LastExitCode -ne 0) {
throw "Exec: $ErrorMessage"
}
}
artifacts:
- path: '_build/CMakeFiles/*.log'
name: logs
- path: '_build/Testing/**/*.xml'
name: test_results
- path: 'bazel-testlogs/**/test.log'
name: test_logs
- path: 'bazel-testlogs/**/test.xml'
name: test_results

37
ci/build-linux-bazel.sh Executable file
View File

@ -0,0 +1,37 @@
#!/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
bazel version
bazel build --curses=no //...:all
bazel test --curses=no //...:all
bazel test --curses=no //...:all --define absl=1

2
ci/build-platformio.sh Normal file
View File

@ -0,0 +1,2 @@
# run PlatformIO builds
platformio run

41
ci/env-linux.sh Executable file
View File

@ -0,0 +1,41 @@
#!/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 should be sourced, and not executed as a standalone script.
#
# TODO() - we can check if this is being sourced using $BASH_VERSION and $BASH_SOURCE[0] != ${0}.
if [ "${TRAVIS_OS_NAME}" = "linux" ]; then
if [ "$CXX" = "g++" ]; then export CXX="g++-4.9" CC="gcc-4.9"; fi
if [ "$CXX" = "clang++" ]; then export CXX="clang++-3.9" CC="clang-3.9"; fi
fi

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env bash
# Copyright 2017 Google Inc.
# All Rights Reserved.
#
# Copyright 2019 Google LLC. All Rights Reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
@ -27,33 +28,20 @@
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Tests Google Test's gtest skip in environment setup behavior.
This script invokes gtest_skip_in_environment_setup_test_ and verifies its
output.
"""
#
# This file should be sourced, and not executed as a standalone script.
#
import re
# TODO() - we can check if this is being sourced using $BASH_VERSION and $BASH_SOURCE[0] != ${0}.
#
import gtest_test_utils
# Path to the gtest_skip_in_environment_setup_test binary
EXE_PATH = gtest_test_utils.GetTestExecutablePath('gtest_skip_test')
OUTPUT = gtest_test_utils.Subprocess([EXE_PATH]).output
# Test.
class SkipEntireEnvironmentTest(gtest_test_utils.TestCase):
def testSkipEntireEnvironmentTest(self):
self.assertIn('Skipped\nskipping single test\n', OUTPUT)
skip_fixture = 'Skipped\nskipping all tests for this fixture\n'
self.assertIsNotNone(
re.search(skip_fixture + '.*' + skip_fixture, OUTPUT, flags=re.DOTALL),
repr(OUTPUT))
self.assertNotIn('FAILED', OUTPUT)
if __name__ == '__main__':
gtest_test_utils.Main()
if [ "${TRAVIS_OS_NAME}" = "osx" ]; then
if [ "$CXX" = "clang++" ]; then
# $PATH needs to be adjusted because the llvm tap doesn't install the
# package to /usr/local/bin, etc, like the gcc tap does.
# See: https://github.com/Homebrew/legacy-homebrew/issues/29733
clang_version=3.9
export PATH="/usr/local/opt/llvm@${clang_version}/bin:$PATH";
fi
fi

59
ci/macos-presubmit.sh → ci/get-nprocessors.sh Normal file → Executable file
View File

@ -1,7 +1,7 @@
#!/bin/bash
#!/usr/bin/env bash
# Copyright 2017 Google Inc.
# All Rights Reserved.
#
# Copyright 2020, 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
@ -29,45 +29,20 @@
# (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 -euox pipefail
if [[ -z ${GTEST_ROOT:-} ]]; then
GTEST_ROOT="$(realpath $(dirname ${0})/..)"
fi
# Test the CMake build
for cmake_off_on in OFF ON; do
BUILD_DIR=$(mktemp -d build_dir.XXXXXXXX)
cd ${BUILD_DIR}
time cmake ${GTEST_ROOT} \
-DCMAKE_CXX_STANDARD=11 \
-Dgtest_build_samples=ON \
-Dgtest_build_tests=ON \
-Dgmock_build_tests=ON \
-Dcxx_no_exception=${cmake_off_on} \
-Dcxx_no_rtti=${cmake_off_on}
time make
time ctest -j$(nproc) --output-on-failure
done
# Test the Bazel build
# If we are running on Kokoro, check for a versioned Bazel binary.
KOKORO_GFILE_BAZEL_BIN="bazel-3.7.0-darwin-x86_64"
if [[ ${KOKORO_GFILE_DIR:-} ]] && [[ -f ${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN} ]]; then
BAZEL_BIN="${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN}"
chmod +x ${BAZEL_BIN}
# 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
BAZEL_BIN="bazel"
NPROCESSORS=2
fi
cd ${GTEST_ROOT}
for absl in 0 1; do
${BAZEL_BIN} test ... \
--copt="-Wall" \
--copt="-Werror" \
--define="absl=${absl}" \
--keep_going \
--show_timestamps \
--test_output=errors
done
# 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

49
ci/install-linux.sh Executable file
View File

@ -0,0 +1,49 @@
#!/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 -eu
if [ "${TRAVIS_OS_NAME}" != linux ]; then
echo "Not a Linux build; skipping installation"
exit 0
fi
if [ "${TRAVIS_SUDO}" = "true" ]; then
echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" | \
sudo tee /etc/apt/sources.list.d/bazel.list
curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -
sudo apt-get update && sudo apt-get install -y bazel gcc-4.9 g++-4.9 clang-3.9
elif [ "${CXX}" = "clang++" ]; then
# Use ccache, assuming $HOME/bin is in the path, which is true in the Travis build environment.
ln -sf /usr/bin/ccache $HOME/bin/${CXX};
ln -sf /usr/bin/ccache $HOME/bin/${CC};
fi

40
ci/install-osx.sh Executable file
View File

@ -0,0 +1,40 @@
#!/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 -eu
if [ "${TRAVIS_OS_NAME}" != "osx" ]; then
echo "Not a macOS build; skipping installation"
exit 0
fi
brew update
brew install ccache gcc@4.9

5
ci/install-platformio.sh Normal file
View File

@ -0,0 +1,5 @@
# install PlatformIO
sudo pip install -U platformio
# update PlatformIO
platformio update

View File

@ -1,126 +0,0 @@
#!/bin/bash
#
# Copyright 2020, 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 -euox pipefail
readonly LINUX_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20210617"
readonly LINUX_GCC_FLOOR_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-floor:20210617"
if [[ -z ${GTEST_ROOT:-} ]]; then
GTEST_ROOT="$(realpath $(dirname ${0})/..)"
fi
if [[ -z ${STD:-} ]]; then
STD="c++11 c++14 c++17 c++20"
fi
# Test the CMake build
for cc in /usr/local/bin/gcc /opt/llvm/clang/bin/clang; do
for cmake_off_on in OFF ON; do
time docker run \
--volume="${GTEST_ROOT}:/src:ro" \
--tmpfs="/build:exec" \
--workdir="/build" \
--rm \
--env="CC=${cc}" \
--env="CXX_FLAGS=\"-Werror -Wdeprecated\"" \
${LINUX_LATEST_CONTAINER} \
/bin/bash -c "
cmake /src \
-DCMAKE_CXX_STANDARD=11 \
-Dgtest_build_samples=ON \
-Dgtest_build_tests=ON \
-Dgmock_build_tests=ON \
-Dcxx_no_exception=${cmake_off_on} \
-Dcxx_no_rtti=${cmake_off_on} && \
make -j$(nproc) && \
ctest -j$(nproc) --output-on-failure"
done
done
# Do one test with an older version of GCC
time docker run \
--volume="${GTEST_ROOT}:/src:ro" \
--workdir="/src" \
--rm \
--env="CC=/usr/local/bin/gcc" \
${LINUX_GCC_FLOOR_CONTAINER} \
/usr/local/bin/bazel test ... \
--copt="-Wall" \
--copt="-Werror" \
--copt="-Wno-error=pragmas" \
--keep_going \
--show_timestamps \
--test_output=errors
# Test GCC
for std in ${STD}; do
for absl in 0 1; do
time docker run \
--volume="${GTEST_ROOT}:/src:ro" \
--workdir="/src" \
--rm \
--env="CC=/usr/local/bin/gcc" \
--env="BAZEL_CXXOPTS=-std=${std}" \
${LINUX_LATEST_CONTAINER} \
/usr/local/bin/bazel test ... \
--copt="-Wall" \
--copt="-Werror" \
--define="absl=${absl}" \
--distdir="/bazel-distdir" \
--keep_going \
--show_timestamps \
--test_output=errors
done
done
# Test Clang
for std in ${STD}; do
for absl in 0 1; do
time docker run \
--volume="${GTEST_ROOT}:/src:ro" \
--workdir="/src" \
--rm \
--env="CC=/opt/llvm/clang/bin/clang" \
--env="BAZEL_CXXOPTS=-std=${std}" \
${LINUX_LATEST_CONTAINER} \
/usr/local/bin/bazel test ... \
--copt="--gcc-toolchain=/usr/local" \
--copt="-Wall" \
--copt="-Werror" \
--define="absl=${absl}" \
--distdir="/bazel-distdir" \
--keep_going \
--linkopt="--gcc-toolchain=/usr/local" \
--show_timestamps \
--test_output=errors
done
done

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env bash
# Copyright 2017 Google Inc.
# All Rights Reserved.
#
# Copyright 2019, 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
@ -29,26 +29,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.
"""Verifies that SetUpTestSuite and TearDownTestSuite errors are noticed."""
set -e
import gtest_test_utils
# ccache on OS X needs installation first
# reset ccache statistics
ccache --zero-stats
COMMAND = gtest_test_utils.GetTestExecutablePath(
'googletest-setuptestsuite-test_')
echo PATH=${PATH}
echo "Compiler configuration:"
echo CXX=${CXX}
echo CC=${CC}
echo CXXFLAGS=${CXXFLAGS}
class GTestSetUpTestSuiteTest(gtest_test_utils.TestCase):
echo "C++ compiler version:"
${CXX} --version || echo "${CXX} does not seem to support the --version flag"
${CXX} -v || echo "${CXX} does not seem to support the -v flag"
def testSetupErrorAndTearDownError(self):
p = gtest_test_utils.Subprocess(COMMAND)
self.assertNotEqual(p.exit_code, 0, msg=p.output)
self.assertIn(
'[ FAILED ] SetupFailTest: SetUpTestSuite or TearDownTestSuite\n'
'[ FAILED ] TearDownFailTest: SetUpTestSuite or TearDownTestSuite\n'
'\n'
' 2 FAILED TEST SUITES\n',
p.output)
if __name__ == '__main__':
gtest_test_utils.Main()
echo "C compiler version:"
${CC} --version || echo "${CXX} does not seem to support the --version flag"
${CC} -v || echo "${CXX} does not seem to support the -v flag"

44
ci/travis.sh Executable file
View File

@ -0,0 +1,44 @@
#!/usr/bin/env sh
set -evx
. ci/get-nprocessors.sh
# 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
# Tell make to use the processors. No preceding '-' required.
MAKEFLAGS="j${NPROCESSORS}"
export MAKEFLAGS
env | sort
# Set default values to OFF for these variables if not specified.
: "${NO_EXCEPTION:=OFF}"
: "${NO_RTTI:=OFF}"
: "${COMPILER_IS_GNUCXX:=OFF}"
mkdir build || true
cd build
cmake -Dgtest_build_samples=ON \
-Dgtest_build_tests=ON \
-Dgmock_build_tests=ON \
-Dcxx_no_exception=$NO_EXCEPTION \
-Dcxx_no_rtti=$NO_RTTI \
-DCMAKE_COMPILER_IS_GNUCXX=$COMPILER_IS_GNUCXX \
-DCMAKE_CXX_FLAGS=$CXX_FLAGS \
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
..
make
CTEST_OUTPUT_ON_FAILURE=1 make test

View File

@ -1 +0,0 @@
title: GoogleTest

View File

@ -1,43 +0,0 @@
nav:
- section: "Get Started"
items:
- title: "Supported Platforms"
url: "/platforms.html"
- title: "Quickstart: Bazel"
url: "/quickstart-bazel.html"
- title: "Quickstart: CMake"
url: "/quickstart-cmake.html"
- section: "Guides"
items:
- title: "GoogleTest Primer"
url: "/primer.html"
- title: "Advanced Topics"
url: "/advanced.html"
- title: "Mocking for Dummies"
url: "/gmock_for_dummies.html"
- title: "Mocking Cookbook"
url: "/gmock_cook_book.html"
- title: "Mocking Cheat Sheet"
url: "/gmock_cheat_sheet.html"
- section: "References"
items:
- title: "Testing Reference"
url: "/reference/testing.html"
- title: "Mocking Reference"
url: "/reference/mocking.html"
- title: "Assertions"
url: "/reference/assertions.html"
- title: "Matchers"
url: "/reference/matchers.html"
- title: "Actions"
url: "/reference/actions.html"
- title: "Testing FAQ"
url: "/faq.html"
- title: "Mocking FAQ"
url: "/gmock_faq.html"
- title: "Code Samples"
url: "/samples.html"
- title: "Using pkg-config"
url: "/pkgconfig.html"
- title: "Community Documentation"
url: "/community_created_documentation.html"

View File

@ -1,58 +0,0 @@
<!DOCTYPE html>
<html lang="{{ site.lang | default: "en-US" }}">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
{% seo %}
<link rel="stylesheet" href="{{ "/assets/css/style.css?v=" | append: site.github.build_revision | relative_url }}">
<script>
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
ga('create', 'UA-197576187-1', { 'storage': 'none' });
ga('set', 'referrer', document.referrer.split('?')[0]);
ga('set', 'location', window.location.href.split('?')[0]);
ga('set', 'anonymizeIp', true);
ga('send', 'pageview');
</script>
<script async src='https://www.google-analytics.com/analytics.js'></script>
</head>
<body>
<div class="sidebar">
<div class="header">
<h1><a href="{{ "/" | relative_url }}">{{ site.title | default: "Documentation" }}</a></h1>
</div>
<input type="checkbox" id="nav-toggle" class="nav-toggle">
<label for="nav-toggle" class="expander">
<span class="arrow"></span>
</label>
<nav>
{% for item in site.data.navigation.nav %}
<h2>{{ item.section }}</h2>
<ul>
{% for subitem in item.items %}
<a href="{{subitem.url | relative_url }}">
<li class="{% if subitem.url == page.url %}active{% endif %}">
{{ subitem.title }}
</li>
</a>
{% endfor %}
</ul>
{% endfor %}
</nav>
</div>
<div class="main markdown-body">
<div class="main-inner">
{{ content }}
</div>
<div class="footer">
GoogleTest &middot;
<a href="https://github.com/google/googletest">GitHub Repository</a> &middot;
<a href="https://github.com/google/googletest/blob/master/LICENSE">License</a> &middot;
<a href="https://policies.google.com/privacy">Privacy Policy</a>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/anchor-js/4.1.0/anchor.min.js" integrity="sha256-lZaRhKri35AyJSypXXs4o6OPFTbTmUoltBbDCbdzegg=" crossorigin="anonymous"></script>
<script>anchors.add('.main h2, .main h3, .main h4, .main h5, .main h6');</script>
</body>
</html>

View File

@ -1,200 +0,0 @@
// Styles for GoogleTest docs website on GitHub Pages.
// Color variables are defined in
// https://github.com/pages-themes/primer/tree/master/_sass/primer-support/lib/variables
$sidebar-width: 260px;
body {
display: flex;
margin: 0;
}
.sidebar {
background: $black;
color: $text-white;
flex-shrink: 0;
height: 100vh;
overflow: auto;
position: sticky;
top: 0;
width: $sidebar-width;
}
.sidebar h1 {
font-size: 1.5em;
}
.sidebar h2 {
color: $gray-light;
font-size: 0.8em;
font-weight: normal;
margin-bottom: 0.8em;
padding-left: 2.5em;
text-transform: uppercase;
}
.sidebar .header {
background: $black;
padding: 2em;
position: sticky;
top: 0;
width: 100%;
}
.sidebar .header a {
color: $text-white;
text-decoration: none;
}
.sidebar .nav-toggle {
display: none;
}
.sidebar .expander {
cursor: pointer;
display: none;
height: 3em;
position: absolute;
right: 1em;
top: 1.5em;
width: 3em;
}
.sidebar .expander .arrow {
border: solid $white;
border-width: 0 3px 3px 0;
display: block;
height: 0.7em;
margin: 1em auto;
transform: rotate(45deg);
transition: transform 0.5s;
width: 0.7em;
}
.sidebar nav {
width: 100%;
}
.sidebar nav ul {
list-style-type: none;
margin-bottom: 1em;
padding: 0;
&:last-child {
margin-bottom: 2em;
}
a {
text-decoration: none;
}
li {
color: $text-white;
padding-left: 2em;
text-decoration: none;
}
li.active {
background: $border-gray-darker;
font-weight: bold;
}
li:hover {
background: $border-gray-darker;
}
}
.main {
background-color: $bg-gray;
width: calc(100% - #{$sidebar-width});
}
.main .main-inner {
background-color: $white;
padding: 2em;
}
.main .footer {
margin: 0;
padding: 2em;
}
.main table th {
text-align: left;
}
.main .callout {
border-left: 0.25em solid $white;
padding: 1em;
a {
text-decoration: underline;
}
&.important {
background-color: $bg-yellow-light;
border-color: $bg-yellow;
color: $black;
}
&.note {
background-color: $bg-blue-light;
border-color: $text-blue;
color: $text-blue;
}
&.tip {
background-color: $green-000;
border-color: $green-700;
color: $green-700;
}
&.warning {
background-color: $red-000;
border-color: $text-red;
color: $text-red;
}
}
.main .good pre {
background-color: $bg-green-light;
}
.main .bad pre {
background-color: $red-000;
}
@media all and (max-width: 768px) {
body {
flex-direction: column;
}
.sidebar {
height: auto;
position: relative;
width: 100%;
}
.sidebar .expander {
display: block;
}
.sidebar nav {
height: 0;
overflow: hidden;
}
.sidebar .nav-toggle:checked {
& ~ nav {
height: auto;
}
& + .expander .arrow {
transform: rotate(-135deg);
}
}
.main {
width: 100%;
}
}

View File

@ -1,5 +0,0 @@
---
---
@import "jekyll-theme-primer";
@import "main";

View File

@ -1,7 +0,0 @@
# Community-Created Documentation
The following is a list, in no particular order, of links to documentation
created by the Googletest community.
* [Googlemock Insights](https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/blob/master/googletest/insights.md),
by [ElectricRCAircraftGuy](https://github.com/ElectricRCAircraftGuy)

View File

@ -1,241 +0,0 @@
# gMock Cheat Sheet
## Defining a Mock Class
### Mocking a Normal Class {#MockClass}
Given
```cpp
class Foo {
...
virtual ~Foo();
virtual int GetSize() const = 0;
virtual string Describe(const char* name) = 0;
virtual string Describe(int type) = 0;
virtual bool Process(Bar elem, int count) = 0;
};
```
(note that `~Foo()` **must** be virtual) we can define its mock as
```cpp
#include "gmock/gmock.h"
class MockFoo : public Foo {
...
MOCK_METHOD(int, GetSize, (), (const, override));
MOCK_METHOD(string, Describe, (const char* name), (override));
MOCK_METHOD(string, Describe, (int type), (override));
MOCK_METHOD(bool, Process, (Bar elem, int count), (override));
};
```
To create a "nice" mock, which ignores all uninteresting calls, a "naggy" mock,
which warns on all uninteresting calls, or a "strict" mock, which treats them as
failures:
```cpp
using ::testing::NiceMock;
using ::testing::NaggyMock;
using ::testing::StrictMock;
NiceMock<MockFoo> nice_foo; // The type is a subclass of MockFoo.
NaggyMock<MockFoo> naggy_foo; // The type is a subclass of MockFoo.
StrictMock<MockFoo> strict_foo; // The type is a subclass of MockFoo.
```
{: .callout .note}
**Note:** A mock object is currently naggy by default. We may make it nice by
default in the future.
### Mocking a Class Template {#MockTemplate}
Class templates can be mocked just like any class.
To mock
```cpp
template <typename Elem>
class StackInterface {
...
virtual ~StackInterface();
virtual int GetSize() const = 0;
virtual void Push(const Elem& x) = 0;
};
```
(note that all member functions that are mocked, including `~StackInterface()`
**must** be virtual).
```cpp
template <typename Elem>
class MockStack : public StackInterface<Elem> {
...
MOCK_METHOD(int, GetSize, (), (const, override));
MOCK_METHOD(void, Push, (const Elem& x), (override));
};
```
### Specifying Calling Conventions for Mock Functions
If your mock function doesn't use the default calling convention, you can
specify it by adding `Calltype(convention)` to `MOCK_METHOD`'s 4th parameter.
For example,
```cpp
MOCK_METHOD(bool, Foo, (int n), (Calltype(STDMETHODCALLTYPE)));
MOCK_METHOD(int, Bar, (double x, double y),
(const, Calltype(STDMETHODCALLTYPE)));
```
where `STDMETHODCALLTYPE` is defined by `<objbase.h>` on Windows.
## Using Mocks in Tests {#UsingMocks}
The typical work flow is:
1. Import the gMock names you need to use. All gMock symbols are in the
`testing` namespace unless they are macros or otherwise noted.
2. Create the mock objects.
3. Optionally, set the default actions of the mock objects.
4. Set your expectations on the mock objects (How will they be called? What
will they do?).
5. Exercise code that uses the mock objects; if necessary, check the result
using googletest assertions.
6. When a mock object is destructed, gMock automatically verifies that all
expectations on it have been satisfied.
Here's an example:
```cpp
using ::testing::Return; // #1
TEST(BarTest, DoesThis) {
MockFoo foo; // #2
ON_CALL(foo, GetSize()) // #3
.WillByDefault(Return(1));
// ... other default actions ...
EXPECT_CALL(foo, Describe(5)) // #4
.Times(3)
.WillRepeatedly(Return("Category 5"));
// ... other expectations ...
EXPECT_EQ(MyProductionFunction(&foo), "good"); // #5
} // #6
```
## Setting Default Actions {#OnCall}
gMock has a **built-in default action** for any function that returns `void`,
`bool`, a numeric value, or a pointer. In C++11, it will additionally returns
the default-constructed value, if one exists for the given type.
To customize the default action for functions with return type `T`, use
[`DefaultValue<T>`](reference/mocking.md#DefaultValue). For example:
```cpp
// Sets the default action for return type std::unique_ptr<Buzz> to
// creating a new Buzz every time.
DefaultValue<std::unique_ptr<Buzz>>::SetFactory(
[] { return MakeUnique<Buzz>(AccessLevel::kInternal); });
// When this fires, the default action of MakeBuzz() will run, which
// will return a new Buzz object.
EXPECT_CALL(mock_buzzer_, MakeBuzz("hello")).Times(AnyNumber());
auto buzz1 = mock_buzzer_.MakeBuzz("hello");
auto buzz2 = mock_buzzer_.MakeBuzz("hello");
EXPECT_NE(buzz1, nullptr);
EXPECT_NE(buzz2, nullptr);
EXPECT_NE(buzz1, buzz2);
// Resets the default action for return type std::unique_ptr<Buzz>,
// to avoid interfere with other tests.
DefaultValue<std::unique_ptr<Buzz>>::Clear();
```
To customize the default action for a particular method of a specific mock
object, use [`ON_CALL`](reference/mocking.md#ON_CALL). `ON_CALL` has a similar
syntax to `EXPECT_CALL`, but it is used for setting default behaviors when you
do not require that the mock method is called. See
[Knowing When to Expect](gmock_cook_book.md#UseOnCall) for a more detailed
discussion.
## Setting Expectations {#ExpectCall}
See [`EXPECT_CALL`](reference/mocking.md#EXPECT_CALL) in the Mocking Reference.
## Matchers {#MatcherList}
See the [Matchers Reference](reference/matchers.md).
## Actions {#ActionList}
See the [Actions Reference](reference/actions.md).
## Cardinalities {#CardinalityList}
See the [`Times` clause](reference/mocking.md#EXPECT_CALL.Times) of
`EXPECT_CALL` in the Mocking Reference.
## Expectation Order
By default, expectations can be matched in *any* order. If some or all
expectations must be matched in a given order, you can use the
[`After` clause](reference/mocking.md#EXPECT_CALL.After) or
[`InSequence` clause](reference/mocking.md#EXPECT_CALL.InSequence) of
`EXPECT_CALL`, or use an [`InSequence` object](reference/mocking.md#InSequence).
## Verifying and Resetting a Mock
gMock will verify the expectations on a mock object when it is destructed, or
you can do it earlier:
```cpp
using ::testing::Mock;
...
// Verifies and removes the expectations on mock_obj;
// returns true if and only if successful.
Mock::VerifyAndClearExpectations(&mock_obj);
...
// Verifies and removes the expectations on mock_obj;
// also removes the default actions set by ON_CALL();
// returns true if and only if successful.
Mock::VerifyAndClear(&mock_obj);
```
Do not set new expectations after verifying and clearing a mock after its use.
Setting expectations after code that exercises the mock has undefined behavior.
See [Using Mocks in Tests](gmock_for_dummies.md#using-mocks-in-tests) for more
information.
You can also tell gMock that a mock object can be leaked and doesn't need to be
verified:
```cpp
Mock::AllowLeak(&mock_obj);
```
## Mock Classes
gMock defines a convenient mock class template
```cpp
class MockFunction<R(A1, ..., An)> {
public:
MOCK_METHOD(R, Call, (A1, ..., An));
};
```
See this [recipe](gmock_cook_book.md#UsingCheckPoints) for one application of
it.
## Flags
| Flag | Description |
| :----------------------------- | :---------------------------------------- |
| `--gmock_catch_leaked_mocks=0` | Don't report leaked mock objects as failures. |
| `--gmock_verbose=LEVEL` | Sets the default verbosity level (`info`, `warning`, or `error`) of Google Mock messages. |

View File

@ -1,22 +0,0 @@
# GoogleTest User's Guide
## Welcome to GoogleTest!
GoogleTest is Google's C++ testing and mocking framework. This user's guide has
the following contents:
* [GoogleTest Primer](primer.md) - Teaches you how to write simple tests using
GoogleTest. Read this first if you are new to GoogleTest.
* [GoogleTest Advanced](advanced.md) - Read this when you've finished the
Primer and want to utilize GoogleTest to its full potential.
* [GoogleTest Samples](samples.md) - Describes some GoogleTest samples.
* [GoogleTest FAQ](faq.md) - Have a question? Want some tips? Check here
first.
* [Mocking for Dummies](gmock_for_dummies.md) - Teaches you how to create mock
objects and use them in tests.
* [Mocking Cookbook](gmock_cook_book.md) - Includes tips and approaches to
common mocking use cases.
* [Mocking Cheat Sheet](gmock_cheat_sheet.md) - A handy reference for
matchers, actions, invariants, and more.
* [Mocking FAQ](gmock_faq.md) - Contains answers to some mocking-specific
questions.

View File

@ -1,35 +0,0 @@
# Supported Platforms
GoogleTest requires a codebase and compiler compliant with the C++11 standard or
newer.
The GoogleTest code is officially supported on the following platforms.
Operating systems or tools not listed below are community-supported. For
community-supported platforms, patches that do not complicate the code may be
considered.
If you notice any problems on your platform, please file an issue on the
[GoogleTest GitHub Issue Tracker](https://github.com/google/googletest/issues).
Pull requests containing fixes are welcome!
### Operating systems
* Linux
* macOS
* Windows
### Compilers
* gcc 5.0+
* clang 5.0+
* MSVC 2015+
**macOS users:** Xcode 9.3+ provides clang 5.0+.
### Build systems
* [Bazel](https://bazel.build/)
* [CMake](https://cmake.org/)
Bazel is the build system used by the team internally and in tests. CMake is
supported on a best-effort basis and by the community.

View File

@ -1,147 +0,0 @@
# Quickstart: Building with Bazel
This tutorial aims to get you up and running with GoogleTest using the Bazel
build system. If you're using GoogleTest for the first time or need a refresher,
we recommend this tutorial as a starting point.
## Prerequisites
To complete this tutorial, you'll need:
* A compatible operating system (e.g. Linux, macOS, Windows).
* A compatible C++ compiler that supports at least C++11.
* [Bazel](https://bazel.build/), the preferred build system used by the
GoogleTest team.
See [Supported Platforms](platforms.md) for more information about platforms
compatible with GoogleTest.
If you don't already have Bazel installed, see the
[Bazel installation guide](https://docs.bazel.build/versions/main/install.html).
{: .callout .note}
Note: The terminal commands in this tutorial show a Unix shell prompt, but the
commands work on the Windows command line as well.
## Set up a Bazel workspace
A
[Bazel workspace](https://docs.bazel.build/versions/main/build-ref.html#workspace)
is a directory on your filesystem that you use to manage source files for the
software you want to build. Each workspace directory has a text file named
`WORKSPACE` which may be empty, or may contain references to external
dependencies required to build the outputs.
First, create a directory for your workspace:
```
$ mkdir my_workspace && cd my_workspace
```
Next, youll create the `WORKSPACE` file to specify dependencies. A common and
recommended way to depend on GoogleTest is to use a
[Bazel external dependency](https://docs.bazel.build/versions/main/external.html)
via the
[`http_archive` rule](https://docs.bazel.build/versions/main/repo/http.html#http_archive).
To do this, in the root directory of your workspace (`my_workspace/`), create a
file named `WORKSPACE` with the following contents:
```
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "com_google_googletest",
urls = ["https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip"],
strip_prefix = "googletest-609281088cfefc76f9d0ce82e1ff6c30cc3591e5",
)
```
The above configuration declares a dependency on GoogleTest which is downloaded
as a ZIP archive from GitHub. In the above example,
`609281088cfefc76f9d0ce82e1ff6c30cc3591e5` is the Git commit hash of the
GoogleTest version to use; we recommend updating the hash often to point to the
latest version.
Now you're ready to build C++ code that uses GoogleTest.
## Create and run a binary
With your Bazel workspace set up, you can now use GoogleTest code within your
own project.
As an example, create a file named `hello_test.cc` in your `my_workspace`
directory with the following contents:
```cpp
#include <gtest/gtest.h>
// Demonstrate some basic assertions.
TEST(HelloTest, BasicAssertions) {
// Expect two strings not to be equal.
EXPECT_STRNE("hello", "world");
// Expect equality.
EXPECT_EQ(7 * 6, 42);
}
```
GoogleTest provides [assertions](primer.md#assertions) that you use to test the
behavior of your code. The above sample includes the main GoogleTest header file
and demonstrates some basic assertions.
To build the code, create a file named `BUILD` in the same directory with the
following contents:
```
cc_test(
name = "hello_test",
size = "small",
srcs = ["hello_test.cc"],
deps = ["@com_google_googletest//:gtest_main"],
)
```
This `cc_test` rule declares the C++ test binary you want to build, and links to
GoogleTest (`//:gtest_main`) using the prefix you specified in the `WORKSPACE`
file (`@com_google_googletest`). For more information about Bazel `BUILD` files,
see the
[Bazel C++ Tutorial](https://docs.bazel.build/versions/main/tutorial/cpp.html).
Now you can build and run your test:
<pre>
<strong>my_workspace$ bazel test --test_output=all //:hello_test</strong>
INFO: Analyzed target //:hello_test (26 packages loaded, 362 targets configured).
INFO: Found 1 test target...
INFO: From Testing //:hello_test:
==================== Test output for //:hello_test:
Running main() from gmock_main.cc
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from HelloTest
[ RUN ] HelloTest.BasicAssertions
[ OK ] HelloTest.BasicAssertions (0 ms)
[----------] 1 test from HelloTest (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[ PASSED ] 1 test.
================================================================================
Target //:hello_test up-to-date:
bazel-bin/hello_test
INFO: Elapsed time: 4.190s, Critical Path: 3.05s
INFO: 27 processes: 8 internal, 19 linux-sandbox.
INFO: Build completed successfully, 27 total actions
//:hello_test PASSED in 0.1s
INFO: Build completed successfully, 27 total actions
</pre>
Congratulations! You've successfully built and run a test binary using
GoogleTest.
## Next steps
* [Check out the Primer](primer.md) to start learning how to write simple
tests.
* [See the code samples](samples.md) for more examples showing how to use a
variety of GoogleTest features.

View File

@ -1,156 +0,0 @@
# Quickstart: Building with CMake
This tutorial aims to get you up and running with GoogleTest using CMake. If
you're using GoogleTest for the first time or need a refresher, we recommend
this tutorial as a starting point. If your project uses Bazel, see the
[Quickstart for Bazel](quickstart-bazel.md) instead.
## Prerequisites
To complete this tutorial, you'll need:
* A compatible operating system (e.g. Linux, macOS, Windows).
* A compatible C++ compiler that supports at least C++11.
* [CMake](https://cmake.org/) and a compatible build tool for building the
project.
* Compatible build tools include
[Make](https://www.gnu.org/software/make/),
[Ninja](https://ninja-build.org/), and others - see
[CMake Generators](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html)
for more information.
See [Supported Platforms](platforms.md) for more information about platforms
compatible with GoogleTest.
If you don't already have CMake installed, see the
[CMake installation guide](https://cmake.org/install).
{: .callout .note}
Note: The terminal commands in this tutorial show a Unix shell prompt, but the
commands work on the Windows command line as well.
## Set up a project
CMake uses a file named `CMakeLists.txt` to configure the build system for a
project. You'll use this file to set up your project and declare a dependency on
GoogleTest.
First, create a directory for your project:
```
$ mkdir my_project && cd my_project
```
Next, you'll create the `CMakeLists.txt` file and declare a dependency on
GoogleTest. There are many ways to express dependencies in the CMake ecosystem;
in this quickstart, you'll use the
[`FetchContent` CMake module](https://cmake.org/cmake/help/latest/module/FetchContent.html).
To do this, in your project directory (`my_project`), create a file named
`CMakeLists.txt` with the following contents:
```cmake
cmake_minimum_required(VERSION 3.14)
project(my_project)
# GoogleTest requires at least C++11
set(CMAKE_CXX_STANDARD 11)
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
```
The above configuration declares a dependency on GoogleTest which is downloaded
from GitHub. In the above example, `609281088cfefc76f9d0ce82e1ff6c30cc3591e5` is
the Git commit hash of the GoogleTest version to use; we recommend updating the
hash often to point to the latest version.
For more information about how to create `CMakeLists.txt` files, see the
[CMake Tutorial](https://cmake.org/cmake/help/latest/guide/tutorial/index.html).
## Create and run a binary
With GoogleTest declared as a dependency, you can use GoogleTest code within
your own project.
As an example, create a file named `hello_test.cc` in your `my_project`
directory with the following contents:
```cpp
#include <gtest/gtest.h>
// Demonstrate some basic assertions.
TEST(HelloTest, BasicAssertions) {
// Expect two strings not to be equal.
EXPECT_STRNE("hello", "world");
// Expect equality.
EXPECT_EQ(7 * 6, 42);
}
```
GoogleTest provides [assertions](primer.md#assertions) that you use to test the
behavior of your code. The above sample includes the main GoogleTest header file
and demonstrates some basic assertions.
To build the code, add the following to the end of your `CMakeLists.txt` file:
```cmake
enable_testing()
add_executable(
hello_test
hello_test.cc
)
target_link_libraries(
hello_test
gtest_main
)
include(GoogleTest)
gtest_discover_tests(hello_test)
```
The above configuration enables testing in CMake, declares the C++ test binary
you want to build (`hello_test`), and links it to GoogleTest (`gtest_main`). The
last two lines enable CMake's test runner to discover the tests included in the
binary, using the
[`GoogleTest` CMake module](https://cmake.org/cmake/help/git-stage/module/GoogleTest.html).
Now you can build and run your test:
<pre>
<strong>my_project$ cmake -S . -B build</strong>
-- The C compiler identification is GNU 10.2.1
-- The CXX compiler identification is GNU 10.2.1
...
-- Build files have been written to: .../my_project/build
<strong>my_project$ cmake --build build</strong>
Scanning dependencies of target gtest
...
[100%] Built target gmock_main
<strong>my_project$ cd build && ctest</strong>
Test project .../my_project/build
Start 1: HelloTest.BasicAssertions
1/1 Test #1: HelloTest.BasicAssertions ........ Passed 0.00 sec
100% tests passed, 0 tests failed out of 1
Total Test time (real) = 0.01 sec
</pre>
Congratulations! You've successfully built and run a test binary using
GoogleTest.
## Next steps
* [Check out the Primer](primer.md) to start learning how to write simple
tests.
* [See the code samples](samples.md) for more examples showing how to use a
variety of GoogleTest features.

View File

@ -1,115 +0,0 @@
# Actions Reference
[**Actions**](../gmock_for_dummies.md#actions-what-should-it-do) specify what a
mock function should do when invoked. This page lists the built-in actions
provided by GoogleTest. All actions are defined in the `::testing` namespace.
## Returning a Value
| Action | Description |
| :-------------------------------- | :-------------------------------------------- |
| `Return()` | Return from a `void` mock function. |
| `Return(value)` | Return `value`. If the type of `value` is different to the mock function's return type, `value` is converted to the latter type <i>at the time the expectation is set</i>, not when the action is executed. |
| `ReturnArg<N>()` | Return the `N`-th (0-based) argument. |
| `ReturnNew<T>(a1, ..., ak)` | Return `new T(a1, ..., ak)`; a different object is created each time. |
| `ReturnNull()` | Return a null pointer. |
| `ReturnPointee(ptr)` | Return the value pointed to by `ptr`. |
| `ReturnRef(variable)` | Return a reference to `variable`. |
| `ReturnRefOfCopy(value)` | Return a reference to a copy of `value`; the copy lives as long as the action. |
| `ReturnRoundRobin({a1, ..., ak})` | Each call will return the next `ai` in the list, starting at the beginning when the end of the list is reached. |
## Side Effects
| Action | Description |
| :--------------------------------- | :-------------------------------------- |
| `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, Functor, or Lambda as an Action
In the following, by "callable" we mean a free function, `std::function`,
functor, or lambda.
| Action | Description |
| :---------------------------------- | :------------------------------------- |
| `f` | Invoke `f` with the arguments passed to the mock function, where `f` is a callable. |
| `Invoke(f)` | Invoke `f` with the arguments passed to the mock function, where `f` can be a global/static function or a functor. |
| `Invoke(object_pointer, &class::method)` | Invoke the method on the object with the arguments passed to the mock function. |
| `InvokeWithoutArgs(f)` | Invoke `f`, which can be a global/static function or a functor. `f` must take no arguments. |
| `InvokeWithoutArgs(object_pointer, &class::method)` | Invoke the method on the object, which takes no arguments. |
| `InvokeArgument<N>(arg1, arg2, ..., argk)` | Invoke the mock function's `N`-th (0-based) argument, which must be a function or a functor, with the `k` arguments. |
The return value of the invoked function is used as the return value of the
action.
When defining a callable to be used with `Invoke*()`, you can declare any unused
parameters as `Unused`:
```cpp
using ::testing::Invoke;
double Distance(Unused, double x, double y) { return sqrt(x*x + y*y); }
...
EXPECT_CALL(mock, Foo("Hi", _, _)).WillOnce(Invoke(Distance));
```
`Invoke(callback)` and `InvokeWithoutArgs(callback)` take ownership of
`callback`, which must be permanent. The type of `callback` must be a base
callback type instead of a derived one, e.g.
```cpp
BlockingClosure* done = new BlockingClosure;
... Invoke(done) ...; // This won't compile!
Closure* done2 = new BlockingClosure;
... Invoke(done2) ...; // This works.
```
In `InvokeArgument<N>(...)`, if an argument needs to be passed by reference,
wrap it inside `std::ref()`. For example,
```cpp
using ::testing::InvokeArgument;
...
InvokeArgument<2>(5, string("Hi"), std::ref(foo))
```
calls the mock function's #2 argument, passing to it `5` and `string("Hi")` by
value, and `foo` by reference.
## Default Action
| Action | Description |
| :------------ | :----------------------------------------------------- |
| `DoDefault()` | Do the default action (specified by `ON_CALL()` or the built-in one). |
{: .callout .note}
**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
| Action | Description |
| :----------------------------- | :------------------------------------------ |
| `DoAll(a1, a2, ..., an)` | Do all actions `a1` to `an` and return the result of `an` in each invocation. The first `n - 1` sub-actions must return void and will receive a readonly view of the arguments. |
| `IgnoreResult(a)` | Perform action `a` and ignore its result. `a` must not return void. |
| `WithArg<N>(a)` | Pass the `N`-th (0-based) argument of the mock function to action `a` and perform it. |
| `WithArgs<N1, N2, ..., Nk>(a)` | Pass the selected (0-based) arguments of the mock function to action `a` and perform it. |
| `WithoutArgs(a)` | Perform action `a` without any arguments. |
## Defining Actions
| Macro | Description |
| :--------------------------------- | :-------------------------------------- |
| `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.

View File

@ -1,633 +0,0 @@
# Assertions Reference
This page lists the assertion macros provided by GoogleTest for verifying code
behavior. To use them, include the header `gtest/gtest.h`.
The majority of the macros listed below come as a pair with an `EXPECT_` variant
and an `ASSERT_` variant. Upon failure, `EXPECT_` macros generate nonfatal
failures and allow the current function to continue running, while `ASSERT_`
macros generate fatal failures and abort the current function.
All assertion macros support streaming a custom failure message into them with
the `<<` operator, for example:
```cpp
EXPECT_TRUE(my_condition) << "My condition is not true";
```
Anything that can be streamed to an `ostream` can be streamed to an assertion
macro—in particular, C strings and string objects. If a wide string (`wchar_t*`,
`TCHAR*` in `UNICODE` mode on Windows, or `std::wstring`) is streamed to an
assertion, it will be translated to UTF-8 when printed.
## Explicit Success and Failure {#success-failure}
The assertions in this section generate a success or failure directly instead of
testing a value or expression. These are useful when control flow, rather than a
Boolean expression, determines the test's success or failure, as shown by the
following example:
```c++
switch(expression) {
case 1:
... some checks ...
case 2:
... some other checks ...
default:
FAIL() << "We shouldn't get here.";
}
```
### SUCCEED {#SUCCEED}
`SUCCEED()`
Generates a success. This *does not* make the overall test succeed. A test is
considered successful only if none of its assertions fail during its execution.
The `SUCCEED` assertion is purely documentary and currently doesn't generate any
user-visible output. However, we may add `SUCCEED` messages to GoogleTest output
in the future.
### FAIL {#FAIL}
`FAIL()`
Generates a fatal failure, which returns from the current function.
Can only be used in functions that return `void`. See
[Assertion Placement](../advanced.md#assertion-placement) for more information.
### ADD_FAILURE {#ADD_FAILURE}
`ADD_FAILURE()`
Generates a nonfatal failure, which allows the current function to continue
running.
### ADD_FAILURE_AT {#ADD_FAILURE_AT}
`ADD_FAILURE_AT(`*`file_path`*`,`*`line_number`*`)`
Generates a nonfatal failure at the file and line number specified.
## Generalized Assertion {#generalized}
The following assertion allows [matchers](matchers.md) to be used to verify
values.
### EXPECT_THAT {#EXPECT_THAT}
`EXPECT_THAT(`*`value`*`,`*`matcher`*`)` \
`ASSERT_THAT(`*`value`*`,`*`matcher`*`)`
Verifies that *`value`* matches the [matcher](matchers.md) *`matcher`*.
For example, the following code verifies that the string `value1` starts with
`"Hello"`, `value2` matches a regular expression, and `value3` is between 5 and
10:
```cpp
#include "gmock/gmock.h"
using ::testing::AllOf;
using ::testing::Gt;
using ::testing::Lt;
using ::testing::MatchesRegex;
using ::testing::StartsWith;
...
EXPECT_THAT(value1, StartsWith("Hello"));
EXPECT_THAT(value2, MatchesRegex("Line \\d+"));
ASSERT_THAT(value3, AllOf(Gt(5), Lt(10)));
```
Matchers enable assertions of this form to read like English and generate
informative failure messages. For example, if the above assertion on `value1`
fails, the resulting message will be similar to the following:
```
Value of: value1
Actual: "Hi, world!"
Expected: starts with "Hello"
```
GoogleTest provides a built-in library of matchers—see the
[Matchers Reference](matchers.md). It is also possible to write your own
matchers—see [Writing New Matchers Quickly](../gmock_cook_book.md#NewMatchers).
The use of matchers makes `EXPECT_THAT` a powerful, extensible assertion.
*The idea for this assertion was borrowed from Joe Walnes' Hamcrest project,
which adds `assertThat()` to JUnit.*
## Boolean Conditions {#boolean}
The following assertions test Boolean conditions.
### EXPECT_TRUE {#EXPECT_TRUE}
`EXPECT_TRUE(`*`condition`*`)` \
`ASSERT_TRUE(`*`condition`*`)`
Verifies that *`condition`* is true.
### EXPECT_FALSE {#EXPECT_FALSE}
`EXPECT_FALSE(`*`condition`*`)` \
`ASSERT_FALSE(`*`condition`*`)`
Verifies that *`condition`* is false.
## Binary Comparison {#binary-comparison}
The following assertions compare two values. The value arguments must be
comparable by the assertion's comparison operator, otherwise a compiler error
will result.
If an argument supports the `<<` operator, it will be called to print the
argument when the assertion fails. Otherwise, GoogleTest will attempt to print
them in the best way it can—see
[Teaching GoogleTest How to Print Your Values](../advanced.md#teaching-googletest-how-to-print-your-values).
Arguments are always evaluated exactly once, so it's OK for the arguments to
have side effects. However, the argument evaluation order is undefined and
programs should not depend on any particular argument evaluation order.
These assertions work with both narrow and wide string objects (`string` and
`wstring`).
See also the [Floating-Point Comparison](#floating-point) assertions to compare
floating-point numbers and avoid problems caused by rounding.
### EXPECT_EQ {#EXPECT_EQ}
`EXPECT_EQ(`*`val1`*`,`*`val2`*`)` \
`ASSERT_EQ(`*`val1`*`,`*`val2`*`)`
Verifies that *`val1`*`==`*`val2`*.
Does pointer equality on pointers. If used on two C strings, it tests if they
are in the same memory location, not if they have the same value. Use
[`EXPECT_STREQ`](#EXPECT_STREQ) to compare C strings (e.g. `const char*`) by
value.
When comparing a pointer to `NULL`, use `EXPECT_EQ(`*`ptr`*`, nullptr)` instead
of `EXPECT_EQ(`*`ptr`*`, NULL)`.
### EXPECT_NE {#EXPECT_NE}
`EXPECT_NE(`*`val1`*`,`*`val2`*`)` \
`ASSERT_NE(`*`val1`*`,`*`val2`*`)`
Verifies that *`val1`*`!=`*`val2`*.
Does pointer equality on pointers. If used on two C strings, it tests if they
are in different memory locations, not if they have different values. Use
[`EXPECT_STRNE`](#EXPECT_STRNE) to compare C strings (e.g. `const char*`) by
value.
When comparing a pointer to `NULL`, use `EXPECT_NE(`*`ptr`*`, nullptr)` instead
of `EXPECT_NE(`*`ptr`*`, NULL)`.
### EXPECT_LT {#EXPECT_LT}
`EXPECT_LT(`*`val1`*`,`*`val2`*`)` \
`ASSERT_LT(`*`val1`*`,`*`val2`*`)`
Verifies that *`val1`*`<`*`val2`*.
### EXPECT_LE {#EXPECT_LE}
`EXPECT_LE(`*`val1`*`,`*`val2`*`)` \
`ASSERT_LE(`*`val1`*`,`*`val2`*`)`
Verifies that *`val1`*`<=`*`val2`*.
### EXPECT_GT {#EXPECT_GT}
`EXPECT_GT(`*`val1`*`,`*`val2`*`)` \
`ASSERT_GT(`*`val1`*`,`*`val2`*`)`
Verifies that *`val1`*`>`*`val2`*.
### EXPECT_GE {#EXPECT_GE}
`EXPECT_GE(`*`val1`*`,`*`val2`*`)` \
`ASSERT_GE(`*`val1`*`,`*`val2`*`)`
Verifies that *`val1`*`>=`*`val2`*.
## String Comparison {#c-strings}
The following assertions compare two **C strings**. To compare two `string`
objects, use [`EXPECT_EQ`](#EXPECT_EQ) or [`EXPECT_NE`](#EXPECT_NE) instead.
These assertions also accept wide C strings (`wchar_t*`). If a comparison of two
wide strings fails, their values will be printed as UTF-8 narrow strings.
To compare a C string with `NULL`, use `EXPECT_EQ(`*`c_string`*`, nullptr)` or
`EXPECT_NE(`*`c_string`*`, nullptr)`.
### EXPECT_STREQ {#EXPECT_STREQ}
`EXPECT_STREQ(`*`str1`*`,`*`str2`*`)` \
`ASSERT_STREQ(`*`str1`*`,`*`str2`*`)`
Verifies that the two C strings *`str1`* and *`str2`* have the same contents.
### EXPECT_STRNE {#EXPECT_STRNE}
`EXPECT_STRNE(`*`str1`*`,`*`str2`*`)` \
`ASSERT_STRNE(`*`str1`*`,`*`str2`*`)`
Verifies that the two C strings *`str1`* and *`str2`* have different contents.
### EXPECT_STRCASEEQ {#EXPECT_STRCASEEQ}
`EXPECT_STRCASEEQ(`*`str1`*`,`*`str2`*`)` \
`ASSERT_STRCASEEQ(`*`str1`*`,`*`str2`*`)`
Verifies that the two C strings *`str1`* and *`str2`* have the same contents,
ignoring case.
### EXPECT_STRCASENE {#EXPECT_STRCASENE}
`EXPECT_STRCASENE(`*`str1`*`,`*`str2`*`)` \
`ASSERT_STRCASENE(`*`str1`*`,`*`str2`*`)`
Verifies that the two C strings *`str1`* and *`str2`* have different contents,
ignoring case.
## Floating-Point Comparison {#floating-point}
The following assertions compare two floating-point values.
Due to rounding errors, it is very unlikely that two floating-point values will
match exactly, so `EXPECT_EQ` is not suitable. In general, for floating-point
comparison to make sense, the user needs to carefully choose the error bound.
GoogleTest also provides assertions that use a default error bound based on
Units in the Last Place (ULPs). To learn more about ULPs, see the article
[Comparing Floating Point Numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
### EXPECT_FLOAT_EQ {#EXPECT_FLOAT_EQ}
`EXPECT_FLOAT_EQ(`*`val1`*`,`*`val2`*`)` \
`ASSERT_FLOAT_EQ(`*`val1`*`,`*`val2`*`)`
Verifies that the two `float` values *`val1`* and *`val2`* are approximately
equal, to within 4 ULPs from each other.
### EXPECT_DOUBLE_EQ {#EXPECT_DOUBLE_EQ}
`EXPECT_DOUBLE_EQ(`*`val1`*`,`*`val2`*`)` \
`ASSERT_DOUBLE_EQ(`*`val1`*`,`*`val2`*`)`
Verifies that the two `double` values *`val1`* and *`val2`* are approximately
equal, to within 4 ULPs from each other.
### EXPECT_NEAR {#EXPECT_NEAR}
`EXPECT_NEAR(`*`val1`*`,`*`val2`*`,`*`abs_error`*`)` \
`ASSERT_NEAR(`*`val1`*`,`*`val2`*`,`*`abs_error`*`)`
Verifies that the difference between *`val1`* and *`val2`* does not exceed the
absolute error bound *`abs_error`*.
## Exception Assertions {#exceptions}
The following assertions verify that a piece of code throws, or does not throw,
an exception. Usage requires exceptions to be enabled in the build environment.
Note that the piece of code under test can be a compound statement, for example:
```cpp
EXPECT_NO_THROW({
int n = 5;
DoSomething(&n);
});
```
### EXPECT_THROW {#EXPECT_THROW}
`EXPECT_THROW(`*`statement`*`,`*`exception_type`*`)` \
`ASSERT_THROW(`*`statement`*`,`*`exception_type`*`)`
Verifies that *`statement`* throws an exception of type *`exception_type`*.
### EXPECT_ANY_THROW {#EXPECT_ANY_THROW}
`EXPECT_ANY_THROW(`*`statement`*`)` \
`ASSERT_ANY_THROW(`*`statement`*`)`
Verifies that *`statement`* throws an exception of any type.
### EXPECT_NO_THROW {#EXPECT_NO_THROW}
`EXPECT_NO_THROW(`*`statement`*`)` \
`ASSERT_NO_THROW(`*`statement`*`)`
Verifies that *`statement`* does not throw any exception.
## Predicate Assertions {#predicates}
The following assertions enable more complex predicates to be verified while
printing a more clear failure message than if `EXPECT_TRUE` were used alone.
### EXPECT_PRED* {#EXPECT_PRED}
`EXPECT_PRED1(`*`pred`*`,`*`val1`*`)` \
`EXPECT_PRED2(`*`pred`*`,`*`val1`*`,`*`val2`*`)` \
`EXPECT_PRED3(`*`pred`*`,`*`val1`*`,`*`val2`*`,`*`val3`*`)` \
`EXPECT_PRED4(`*`pred`*`,`*`val1`*`,`*`val2`*`,`*`val3`*`,`*`val4`*`)` \
`EXPECT_PRED5(`*`pred`*`,`*`val1`*`,`*`val2`*`,`*`val3`*`,`*`val4`*`,`*`val5`*`)`
`ASSERT_PRED1(`*`pred`*`,`*`val1`*`)` \
`ASSERT_PRED2(`*`pred`*`,`*`val1`*`,`*`val2`*`)` \
`ASSERT_PRED3(`*`pred`*`,`*`val1`*`,`*`val2`*`,`*`val3`*`)` \
`ASSERT_PRED4(`*`pred`*`,`*`val1`*`,`*`val2`*`,`*`val3`*`,`*`val4`*`)` \
`ASSERT_PRED5(`*`pred`*`,`*`val1`*`,`*`val2`*`,`*`val3`*`,`*`val4`*`,`*`val5`*`)`
Verifies that the predicate *`pred`* returns `true` when passed the given values
as arguments.
The parameter *`pred`* is a function or functor that accepts as many arguments
as the corresponding macro accepts values. If *`pred`* returns `true` for the
given arguments, the assertion succeeds, otherwise the assertion fails.
When the assertion fails, it prints the value of each argument. Arguments are
always evaluated exactly once.
As an example, see the following code:
```cpp
// Returns true if m and n have no common divisors except 1.
bool MutuallyPrime(int m, int n) { ... }
...
const int a = 3;
const int b = 4;
const int c = 10;
...
EXPECT_PRED2(MutuallyPrime, a, b); // Succeeds
EXPECT_PRED2(MutuallyPrime, b, c); // Fails
```
In the above example, the first assertion succeeds, and the second fails with
the following message:
```
MutuallyPrime(b, c) is false, where
b is 4
c is 10
```
Note that if the given predicate is an overloaded function or a function
template, the assertion macro might not be able to determine which version to
use, and it might be necessary to explicitly specify the type of the function.
For example, for a Boolean function `IsPositive()` overloaded to take either a
single `int` or `double` argument, it would be necessary to write one of the
following:
```cpp
EXPECT_PRED1(static_cast<bool (*)(int)>(IsPositive), 5);
EXPECT_PRED1(static_cast<bool (*)(double)>(IsPositive), 3.14);
```
Writing simply `EXPECT_PRED1(IsPositive, 5);` would result in a compiler error.
Similarly, to use a template function, specify the template arguments:
```cpp
template <typename T>
bool IsNegative(T x) {
return x < 0;
}
...
EXPECT_PRED1(IsNegative<int>, -5); // Must specify type for IsNegative
```
If a template has multiple parameters, wrap the predicate in parentheses so the
macro arguments are parsed correctly:
```cpp
ASSERT_PRED2((MyPredicate<int, int>), 5, 0);
```
### EXPECT_PRED_FORMAT* {#EXPECT_PRED_FORMAT}
`EXPECT_PRED_FORMAT1(`*`pred_formatter`*`,`*`val1`*`)` \
`EXPECT_PRED_FORMAT2(`*`pred_formatter`*`,`*`val1`*`,`*`val2`*`)` \
`EXPECT_PRED_FORMAT3(`*`pred_formatter`*`,`*`val1`*`,`*`val2`*`,`*`val3`*`)` \
`EXPECT_PRED_FORMAT4(`*`pred_formatter`*`,`*`val1`*`,`*`val2`*`,`*`val3`*`,`*`val4`*`)`
\
`EXPECT_PRED_FORMAT5(`*`pred_formatter`*`,`*`val1`*`,`*`val2`*`,`*`val3`*`,`*`val4`*`,`*`val5`*`)`
`ASSERT_PRED_FORMAT1(`*`pred_formatter`*`,`*`val1`*`)` \
`ASSERT_PRED_FORMAT2(`*`pred_formatter`*`,`*`val1`*`,`*`val2`*`)` \
`ASSERT_PRED_FORMAT3(`*`pred_formatter`*`,`*`val1`*`,`*`val2`*`,`*`val3`*`)` \
`ASSERT_PRED_FORMAT4(`*`pred_formatter`*`,`*`val1`*`,`*`val2`*`,`*`val3`*`,`*`val4`*`)`
\
`ASSERT_PRED_FORMAT5(`*`pred_formatter`*`,`*`val1`*`,`*`val2`*`,`*`val3`*`,`*`val4`*`,`*`val5`*`)`
Verifies that the predicate *`pred_formatter`* succeeds when passed the given
values as arguments.
The parameter *`pred_formatter`* is a *predicate-formatter*, which is a function
or functor with the signature:
```cpp
testing::AssertionResult PredicateFormatter(const char* expr1,
const char* expr2,
...
const char* exprn,
T1 val1,
T2 val2,
...
Tn valn);
```
where *`val1`*, *`val2`*, ..., *`valn`* are the values of the predicate
arguments, and *`expr1`*, *`expr2`*, ..., *`exprn`* are the corresponding
expressions as they appear in the source code. The types `T1`, `T2`, ..., `Tn`
can be either value types or reference types; if an argument has type `T`, it
can be declared as either `T` or `const T&`, whichever is appropriate. For more
about the return type `testing::AssertionResult`, see
[Using a Function That Returns an AssertionResult](../advanced.md#using-a-function-that-returns-an-assertionresult).
As an example, see the following code:
```cpp
// Returns the smallest prime common divisor of m and n,
// or 1 when m and n are mutually prime.
int SmallestPrimeCommonDivisor(int m, int n) { ... }
// Returns true if m and n have no common divisors except 1.
bool MutuallyPrime(int m, int n) { ... }
// A predicate-formatter for asserting that two integers are mutually prime.
testing::AssertionResult AssertMutuallyPrime(const char* m_expr,
const char* n_expr,
int m,
int n) {
if (MutuallyPrime(m, n)) return testing::AssertionSuccess();
return testing::AssertionFailure() << m_expr << " and " << n_expr
<< " (" << m << " and " << n << ") are not mutually prime, "
<< "as they have a common divisor " << SmallestPrimeCommonDivisor(m, n);
}
...
const int a = 3;
const int b = 4;
const int c = 10;
...
EXPECT_PRED_FORMAT2(AssertMutuallyPrime, a, b); // Succeeds
EXPECT_PRED_FORMAT2(AssertMutuallyPrime, b, c); // Fails
```
In the above example, the final assertion fails and the predicate-formatter
produces the following failure message:
```
b and c (4 and 10) are not mutually prime, as they have a common divisor 2
```
## Windows HRESULT Assertions {#HRESULT}
The following assertions test for `HRESULT` success or failure. For example:
```cpp
CComPtr<IShellDispatch2> shell;
ASSERT_HRESULT_SUCCEEDED(shell.CoCreateInstance(L"Shell.Application"));
CComVariant empty;
ASSERT_HRESULT_SUCCEEDED(shell->ShellExecute(CComBSTR(url), empty, empty, empty, empty));
```
The generated output contains the human-readable error message associated with
the returned `HRESULT` code.
### EXPECT_HRESULT_SUCCEEDED {#EXPECT_HRESULT_SUCCEEDED}
`EXPECT_HRESULT_SUCCEEDED(`*`expression`*`)` \
`ASSERT_HRESULT_SUCCEEDED(`*`expression`*`)`
Verifies that *`expression`* is a success `HRESULT`.
### EXPECT_HRESULT_FAILED {#EXPECT_HRESULT_FAILED}
`EXPECT_HRESULT_FAILED(`*`expression`*`)` \
`EXPECT_HRESULT_FAILED(`*`expression`*`)`
Verifies that *`expression`* is a failure `HRESULT`.
## Death Assertions {#death}
The following assertions verify that a piece of code causes the process to
terminate. For context, see [Death Tests](../advanced.md#death-tests).
These assertions spawn a new process and execute the code under test in that
process. How that happens depends on the platform and the variable
`::testing::GTEST_FLAG(death_test_style)`, which is initialized from the
command-line flag `--gtest_death_test_style`.
* On POSIX systems, `fork()` (or `clone()` on Linux) is used to spawn the
child, after which:
* If the variable's value is `"fast"`, the death test statement is
immediately executed.
* If the variable's value is `"threadsafe"`, the child process re-executes
the unit test binary just as it was originally invoked, but with some
extra flags to cause just the single death test under consideration to
be run.
* On Windows, the child is spawned using the `CreateProcess()` API, and
re-executes the binary to cause just the single death test under
consideration to be run - much like the `"threadsafe"` mode on POSIX.
Other values for the variable are illegal and will cause the death test to fail.
Currently, the flag's default value is
**`"fast"`**.
If the death test statement runs to completion without dying, the child process
will nonetheless terminate, and the assertion fails.
Note that the piece of code under test can be a compound statement, for example:
```cpp
EXPECT_DEATH({
int n = 5;
DoSomething(&n);
}, "Error on line .* of DoSomething()");
```
### EXPECT_DEATH {#EXPECT_DEATH}
`EXPECT_DEATH(`*`statement`*`,`*`matcher`*`)` \
`ASSERT_DEATH(`*`statement`*`,`*`matcher`*`)`
Verifies that *`statement`* causes the process to terminate with a nonzero exit
status and produces `stderr` output that matches *`matcher`*.
The parameter *`matcher`* is either a [matcher](matchers.md) for a `const
std::string&`, or a regular expression (see
[Regular Expression Syntax](../advanced.md#regular-expression-syntax))—a bare
string *`s`* (with no matcher) is treated as
[`ContainsRegex(s)`](matchers.md#string-matchers), **not**
[`Eq(s)`](matchers.md#generic-comparison).
For example, the following code verifies that calling `DoSomething(42)` causes
the process to die with an error message that contains the text `My error`:
```cpp
EXPECT_DEATH(DoSomething(42), "My error");
```
### EXPECT_DEATH_IF_SUPPORTED {#EXPECT_DEATH_IF_SUPPORTED}
`EXPECT_DEATH_IF_SUPPORTED(`*`statement`*`,`*`matcher`*`)` \
`ASSERT_DEATH_IF_SUPPORTED(`*`statement`*`,`*`matcher`*`)`
If death tests are supported, behaves the same as
[`EXPECT_DEATH`](#EXPECT_DEATH). Otherwise, verifies nothing.
### EXPECT_DEBUG_DEATH {#EXPECT_DEBUG_DEATH}
`EXPECT_DEBUG_DEATH(`*`statement`*`,`*`matcher`*`)` \
`ASSERT_DEBUG_DEATH(`*`statement`*`,`*`matcher`*`)`
In debug mode, behaves the same as [`EXPECT_DEATH`](#EXPECT_DEATH). When not in
debug mode (i.e. `NDEBUG` is defined), just executes *`statement`*.
### EXPECT_EXIT {#EXPECT_EXIT}
`EXPECT_EXIT(`*`statement`*`,`*`predicate`*`,`*`matcher`*`)` \
`ASSERT_EXIT(`*`statement`*`,`*`predicate`*`,`*`matcher`*`)`
Verifies that *`statement`* causes the process to terminate with an exit status
that satisfies *`predicate`*, and produces `stderr` output that matches
*`matcher`*.
The parameter *`predicate`* is a function or functor that accepts an `int` exit
status and returns a `bool`. GoogleTest provides two predicates to handle common
cases:
```cpp
// Returns true if the program exited normally with the given exit status code.
::testing::ExitedWithCode(exit_code);
// Returns true if the program was killed by the given signal.
// Not available on Windows.
::testing::KilledBySignal(signal_number);
```
The parameter *`matcher`* is either a [matcher](matchers.md) for a `const
std::string&`, or a regular expression (see
[Regular Expression Syntax](../advanced.md#regular-expression-syntax))—a bare
string *`s`* (with no matcher) is treated as
[`ContainsRegex(s)`](matchers.md#string-matchers), **not**
[`Eq(s)`](matchers.md#generic-comparison).
For example, the following code verifies that calling `NormalExit()` causes the
process to print a message containing the text `Success` to `stderr` and exit
with exit status code 0:
```cpp
EXPECT_EXIT(NormalExit(), testing::ExitedWithCode(0), "Success");
```

View File

@ -1,285 +0,0 @@
# Matchers Reference
A **matcher** matches a *single* argument. You can use it inside `ON_CALL()` or
`EXPECT_CALL()`, or use it to validate a value directly using two macros:
| Macro | Description |
| :----------------------------------- | :------------------------------------ |
| `EXPECT_THAT(actual_value, matcher)` | Asserts that `actual_value` matches `matcher`. |
| `ASSERT_THAT(actual_value, matcher)` | The same as `EXPECT_THAT(actual_value, matcher)`, except that it generates a **fatal** failure. |
{: .callout .note}
**Note:** Although equality matching via `EXPECT_THAT(actual_value,
expected_value)` is supported, prefer to make the comparison explicit via
`EXPECT_THAT(actual_value, Eq(expected_value))` or `EXPECT_EQ(actual_value,
expected_value)`.
Built-in matchers (where `argument` is the function argument, e.g.
`actual_value` in the example above, or when used in the context of
`EXPECT_CALL(mock_object, method(matchers))`, the arguments of `method`) are
divided into several categories. All matchers are defined in the `::testing`
namespace unless otherwise noted.
## Wildcard
Matcher | Description
:-------------------------- | :-----------------------------------------------
`_` | `argument` can be any value of the correct type.
`A<type>()` or `An<type>()` | `argument` can be any value of type `type`.
## Generic Comparison
| Matcher | Description |
| :--------------------- | :-------------------------------------------------- |
| `Eq(value)` or `value` | `argument == value` |
| `Ge(value)` | `argument >= value` |
| `Gt(value)` | `argument > value` |
| `Le(value)` | `argument <= value` |
| `Lt(value)` | `argument < value` |
| `Ne(value)` | `argument != value` |
| `IsFalse()` | `argument` evaluates to `false` in a Boolean context. |
| `IsTrue()` | `argument` evaluates to `true` in a Boolean context. |
| `IsNull()` | `argument` is a `NULL` pointer (raw or smart). |
| `NotNull()` | `argument` is a non-null pointer (raw or smart). |
| `Optional(m)` | `argument` is `optional<>` that contains a value matching `m`. (For testing whether an `optional<>` is set, check for equality with `nullopt`. You may need to use `Eq(nullopt)` if the inner type doesn't have `==`.)|
| `VariantWith<T>(m)` | `argument` is `variant<>` that holds the alternative of type T with a value matching `m`. |
| `Ref(variable)` | `argument` is a reference to `variable`. |
| `TypedEq<type>(value)` | `argument` has type `type` and is equal to `value`. You may need to use this instead of `Eq(value)` when the mock function is overloaded. |
Except `Ref()`, these matchers make a *copy* of `value` in case it's modified or
destructed later. If the compiler complains that `value` doesn't have a public
copy constructor, try wrap it in `std::ref()`, e.g.
`Eq(std::ref(non_copyable_value))`. If you do that, make sure
`non_copyable_value` is not changed afterwards, or the meaning of your matcher
will be changed.
`IsTrue` and `IsFalse` are useful when you need to use a matcher, or for types
that can be explicitly converted to Boolean, but are not implicitly converted to
Boolean. In other cases, you can use the basic
[`EXPECT_TRUE` and `EXPECT_FALSE`](assertions.md#boolean) assertions.
## Floating-Point Matchers {#FpMatchers}
| Matcher | Description |
| :------------------------------- | :--------------------------------- |
| `DoubleEq(a_double)` | `argument` is a `double` value approximately equal to `a_double`, treating two NaNs as unequal. |
| `FloatEq(a_float)` | `argument` is a `float` value approximately equal to `a_float`, treating two NaNs as unequal. |
| `NanSensitiveDoubleEq(a_double)` | `argument` is a `double` value approximately equal to `a_double`, treating two NaNs as equal. |
| `NanSensitiveFloatEq(a_float)` | `argument` is a `float` value approximately equal to `a_float`, treating two NaNs as equal. |
| `IsNan()` | `argument` is any floating-point type with a NaN value. |
The above matchers use ULP-based comparison (the same as used in googletest).
They automatically pick a reasonable error bound based on the absolute value of
the expected value. `DoubleEq()` and `FloatEq()` conform to the IEEE standard,
which requires comparing two NaNs for equality to return false. The
`NanSensitive*` version instead treats two NaNs as equal, which is often what a
user wants.
| Matcher | Description |
| :------------------------------------------------ | :----------------------- |
| `DoubleNear(a_double, max_abs_error)` | `argument` is a `double` value close to `a_double` (absolute error <= `max_abs_error`), treating two NaNs as unequal. |
| `FloatNear(a_float, max_abs_error)` | `argument` is a `float` value close to `a_float` (absolute error <= `max_abs_error`), treating two NaNs as unequal. |
| `NanSensitiveDoubleNear(a_double, max_abs_error)` | `argument` is a `double` value close to `a_double` (absolute error <= `max_abs_error`), treating two NaNs as equal. |
| `NanSensitiveFloatNear(a_float, max_abs_error)` | `argument` is a `float` value close to `a_float` (absolute error <= `max_abs_error`), treating two NaNs as equal. |
## String Matchers
The `argument` can be either a C string or a C++ string object:
| Matcher | Description |
| :---------------------- | :------------------------------------------------- |
| `ContainsRegex(string)` | `argument` matches the given regular expression. |
| `EndsWith(suffix)` | `argument` ends with string `suffix`. |
| `HasSubstr(string)` | `argument` contains `string` as a sub-string. |
| `IsEmpty()` | `argument` is an empty 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`. |
| `WhenBase64Unescaped(m)` | `argument` is a base-64 escaped string whose unescaped string matches `m`. |
`ContainsRegex()` and `MatchesRegex()` take ownership of the `RE` object. They
use the regular expression syntax defined
[here](../advanced.md#regular-expression-syntax). All of these matchers, except
`ContainsRegex()` and `MatchesRegex()` work for wide strings as well.
## Container Matchers
Most STL-style containers support `==`, so you can use `Eq(expected_container)`
or simply `expected_container` to match a container exactly. If you want to
write the elements in-line, match them more flexibly, or get more informative
messages, you can use:
| Matcher | Description |
| :---------------------------------------- | :------------------------------- |
| `BeginEndDistanceIs(m)` | `argument` is a container whose `begin()` and `end()` iterators are separated by a number of increments matching `m`. E.g. `BeginEndDistanceIs(2)` or `BeginEndDistanceIs(Lt(2))`. For containers that define a `size()` method, `SizeIs(m)` may be more efficient. |
| `ContainerEq(container)` | The same as `Eq(container)` except that the failure message also includes which elements are in one container but not the other. |
| `Contains(e)` | `argument` contains an element that matches `e`, which can be either a value or a matcher. |
| `Contains(e).Times(n)` | `argument` contains elements that match `e`, which can be either a value or a matcher, and the number of matches is `n`, which can be either a value or a matcher. Unlike the plain `Contains` and `Each` this allows to check for arbitrary occurrences including testing for absence with `Contains(e).Times(0)`. |
| `Each(e)` | `argument` is a container where *every* element matches `e`, which can be either a value or a matcher. |
| `ElementsAre(e0, e1, ..., en)` | `argument` has `n + 1` elements, where the *i*-th element matches `ei`, which can be a value or a matcher. |
| `ElementsAreArray({e0, e1, ..., en})`, `ElementsAreArray(a_container)`, `ElementsAreArray(begin, end)`, `ElementsAreArray(array)`, or `ElementsAreArray(array, count)` | The same as `ElementsAre()` except that the expected element values/matchers come from an initializer list, STL-style container, iterator range, or C-style array. |
| `IsEmpty()` | `argument` is an empty container (`container.empty()`). |
| `IsSubsetOf({e0, e1, ..., en})`, `IsSubsetOf(a_container)`, `IsSubsetOf(begin, end)`, `IsSubsetOf(array)`, or `IsSubsetOf(array, count)` | `argument` matches `UnorderedElementsAre(x0, x1, ..., xk)` for some subset `{x0, x1, ..., xk}` of the expected matchers. |
| `IsSupersetOf({e0, e1, ..., en})`, `IsSupersetOf(a_container)`, `IsSupersetOf(begin, end)`, `IsSupersetOf(array)`, or `IsSupersetOf(array, count)` | Some subset of `argument` matches `UnorderedElementsAre(`expected matchers`)`. |
| `Pointwise(m, container)`, `Pointwise(m, {e0, e1, ..., en})` | `argument` contains the same number of elements as in `container`, and for all i, (the i-th element in `argument`, the i-th element in `container`) match `m`, which is a matcher on 2-tuples. E.g. `Pointwise(Le(), upper_bounds)` verifies that each element in `argument` doesn't exceed the corresponding element in `upper_bounds`. See more detail below. |
| `SizeIs(m)` | `argument` is a container whose size matches `m`. E.g. `SizeIs(2)` or `SizeIs(Lt(2))`. |
| `UnorderedElementsAre(e0, e1, ..., en)` | `argument` has `n + 1` elements, and under *some* permutation of the elements, each element matches an `ei` (for a different `i`), which can be a value or a matcher. |
| `UnorderedElementsAreArray({e0, e1, ..., en})`, `UnorderedElementsAreArray(a_container)`, `UnorderedElementsAreArray(begin, end)`, `UnorderedElementsAreArray(array)`, or `UnorderedElementsAreArray(array, count)` | The same as `UnorderedElementsAre()` except that the expected element values/matchers come from an initializer list, STL-style container, iterator range, or C-style array. |
| `UnorderedPointwise(m, container)`, `UnorderedPointwise(m, {e0, e1, ..., en})` | Like `Pointwise(m, container)`, but ignores the order of elements. |
| `WhenSorted(m)` | When `argument` is sorted using the `<` operator, it matches container matcher `m`. E.g. `WhenSorted(ElementsAre(1, 2, 3))` verifies that `argument` contains elements 1, 2, and 3, ignoring order. |
| `WhenSortedBy(comparator, m)` | The same as `WhenSorted(m)`, except that the given comparator instead of `<` is used to sort `argument`. E.g. `WhenSortedBy(std::greater(), ElementsAre(3, 2, 1))`. |
**Notes:**
* These matchers can also match:
1. a native array passed by reference (e.g. in `Foo(const int (&a)[5])`),
and
2. an array passed as a pointer and a count (e.g. in `Bar(const T* buffer,
int len)` -- see [Multi-argument Matchers](#MultiArgMatchers)).
* The array being matched may be multi-dimensional (i.e. its elements can be
arrays).
* `m` in `Pointwise(m, ...)` and `UnorderedPointwise(m, ...)` should be a
matcher for `::std::tuple<T, U>` where `T` and `U` are the element type of
the actual container and the expected container, respectively. For example,
to compare two `Foo` containers where `Foo` doesn't support `operator==`,
one might write:
```cpp
MATCHER(FooEq, "") {
return std::get<0>(arg).Equals(std::get<1>(arg));
}
...
EXPECT_THAT(actual_foos, Pointwise(FooEq(), expected_foos));
```
## Member Matchers
| Matcher | Description |
| :------------------------------ | :----------------------------------------- |
| `Field(&class::field, m)` | `argument.field` (or `argument->field` when `argument` is a plain pointer) matches matcher `m`, where `argument` is an object of type _class_. |
| `Field(field_name, &class::field, m)` | The same as the two-parameter version, but provides a better error message. |
| `Key(e)` | `argument.first` matches `e`, which can be either a value or a matcher. E.g. `Contains(Key(Le(5)))` can verify that a `map` contains a key `<= 5`. |
| `Pair(m1, m2)` | `argument` is an `std::pair` whose `first` field matches `m1` and `second` field matches `m2`. |
| `FieldsAre(m...)` | `argument` is a compatible object where each field matches piecewise with the matchers `m...`. A compatible object is any that supports the `std::tuple_size<Obj>`+`get<I>(obj)` protocol. In C++17 and up this also supports types compatible with structured bindings, like aggregates. |
| `Property(&class::property, m)` | `argument.property()` (or `argument->property()` when `argument` is a plain pointer) matches matcher `m`, where `argument` is an object of type _class_. The method `property()` must take no argument and be declared as `const`. |
| `Property(property_name, &class::property, m)` | The same as the two-parameter version, but provides a better error message.
**Notes:**
* You can use `FieldsAre()` to match any type that supports structured
bindings, such as `std::tuple`, `std::pair`, `std::array`, and aggregate
types. For example:
```cpp
std::tuple<int, std::string> my_tuple{7, "hello world"};
EXPECT_THAT(my_tuple, FieldsAre(Ge(0), HasSubstr("hello")));
struct MyStruct {
int value = 42;
std::string greeting = "aloha";
};
MyStruct s;
EXPECT_THAT(s, FieldsAre(42, "aloha"));
```
* Don't use `Property()` against member functions that you do not own, because
taking addresses of functions is fragile and generally not part of the
contract of the function.
## Matching the Result of a Function, Functor, or Callback
| Matcher | Description |
| :--------------- | :------------------------------------------------ |
| `ResultOf(f, m)` | `f(argument)` matches matcher `m`, where `f` is a function or functor. |
## Pointer Matchers
| Matcher | Description |
| :------------------------ | :---------------------------------------------- |
| `Address(m)` | the result of `std::addressof(argument)` matches `m`. |
| `Pointee(m)` | `argument` (either a smart pointer or a raw pointer) points to a value that matches matcher `m`. |
| `Pointer(m)` | `argument` (either a smart pointer or a raw pointer) contains a pointer that matches `m`. `m` will match against the raw pointer regardless of the type of `argument`. |
| `WhenDynamicCastTo<T>(m)` | when `argument` is passed through `dynamic_cast<T>()`, it matches matcher `m`. |
## Multi-argument Matchers {#MultiArgMatchers}
Technically, all matchers match a *single* value. A "multi-argument" matcher is
just one that matches a *tuple*. The following matchers can be used to match a
tuple `(x, y)`:
Matcher | Description
:------ | :----------
`Eq()` | `x == y`
`Ge()` | `x >= y`
`Gt()` | `x > y`
`Le()` | `x <= y`
`Lt()` | `x < y`
`Ne()` | `x != y`
You can use the following selectors to pick a subset of the arguments (or
reorder them) to participate in the matching:
| Matcher | Description |
| :------------------------- | :---------------------------------------------- |
| `AllArgs(m)` | Equivalent to `m`. Useful as syntactic sugar in `.With(AllArgs(m))`. |
| `Args<N1, N2, ..., Nk>(m)` | The tuple of the `k` selected (using 0-based indices) arguments matches `m`, e.g. `Args<1, 2>(Eq())`. |
## Composite Matchers
You can make a matcher from one or more other matchers:
| Matcher | Description |
| :------------------------------- | :-------------------------------------- |
| `AllOf(m1, m2, ..., mn)` | `argument` matches all of the matchers `m1` to `mn`. |
| `AllOfArray({m0, m1, ..., mn})`, `AllOfArray(a_container)`, `AllOfArray(begin, end)`, `AllOfArray(array)`, or `AllOfArray(array, count)` | The same as `AllOf()` except that the matchers come from an initializer list, STL-style container, iterator range, or C-style array. |
| `AnyOf(m1, m2, ..., mn)` | `argument` matches at least one of the matchers `m1` to `mn`. |
| `AnyOfArray({m0, m1, ..., mn})`, `AnyOfArray(a_container)`, `AnyOfArray(begin, end)`, `AnyOfArray(array)`, or `AnyOfArray(array, count)` | The same as `AnyOf()` except that the matchers come from an initializer list, STL-style container, iterator range, or C-style array. |
| `Not(m)` | `argument` doesn't match matcher `m`. |
| `Conditional(cond, m1, m2)` | Matches matcher `m1` if `cond` evaluates to true, else matches `m2`.|
## Adapters for Matchers
| Matcher | Description |
| :---------------------- | :------------------------------------ |
| `MatcherCast<T>(m)` | casts matcher `m` to type `Matcher<T>`. |
| `SafeMatcherCast<T>(m)` | [safely casts](../gmock_cook_book.md#SafeMatcherCast) 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. |
`AddressSatisfies(callback)` and `Truly(callback)` take ownership of `callback`,
which must be a permanent callback.
## Using Matchers as Predicates {#MatchersAsPredicatesCheat}
| Matcher | Description |
| :---------------------------- | :------------------------------------------ |
| `Matches(m)(value)` | evaluates to `true` if `value` matches `m`. You can use `Matches(m)` alone as a unary functor. |
| `ExplainMatchResult(m, value, result_listener)` | evaluates to `true` if `value` matches `m`, explaining the result to `result_listener`. |
| `Value(value, m)` | evaluates to `true` if `value` matches `m`. |
## Defining Matchers
| Macro | Description |
| :----------------------------------- | :------------------------------------ |
| `MATCHER(IsEven, "") { return (arg % 2) == 0; }` | Defines a matcher `IsEven()` to match an even number. |
| `MATCHER_P(IsDivisibleBy, n, "") { *result_listener << "where the remainder is " << (arg % n); return (arg % n) == 0; }` | Defines a matcher `IsDivisibleBy(n)` to match a number divisible by `n`. |
| `MATCHER_P2(IsBetween, a, b, absl::StrCat(negation ? "isn't" : "is", " between ", PrintToString(a), " and ", PrintToString(b))) { return a <= arg && arg <= b; }` | Defines a matcher `IsBetween(a, b)` to match a value in the range [`a`, `b`]. |
**Notes:**
1. The `MATCHER*` macros cannot be used inside a function or class.
2. The matcher body must be *purely functional* (i.e. it cannot have any side
effect, and the result must not depend on anything other than the value
being matched and the matcher parameters).
3. You can use `PrintToString(x)` to convert a value `x` of any type to a
string.
4. You can use `ExplainMatchResult()` in a custom matcher to wrap another
matcher, for example:
```cpp
MATCHER_P(NestedPropertyMatches, matcher, "") {
return ExplainMatchResult(matcher, arg.nested().property(), result_listener);
}
```

View File

@ -1,587 +0,0 @@
# Mocking Reference
This page lists the facilities provided by GoogleTest for creating and working
with mock objects. To use them, include the header
`gmock/gmock.h`.
## Macros {#macros}
GoogleTest defines the following macros for working with mocks.
### MOCK_METHOD {#MOCK_METHOD}
`MOCK_METHOD(`*`return_type`*`,`*`method_name`*`, (`*`args...`*`));` \
`MOCK_METHOD(`*`return_type`*`,`*`method_name`*`, (`*`args...`*`),
(`*`specs...`*`));`
Defines a mock method *`method_name`* with arguments `(`*`args...`*`)` and
return type *`return_type`* within a mock class.
The parameters of `MOCK_METHOD` mirror the method declaration. The optional
fourth parameter *`specs...`* is a comma-separated list of qualifiers. The
following qualifiers are accepted:
| Qualifier | Meaning |
| -------------------------- | -------------------------------------------- |
| `const` | Makes the mocked method a `const` method. Required if overriding a `const` method. |
| `override` | Marks the method with `override`. Recommended if overriding a `virtual` method. |
| `noexcept` | Marks the method with `noexcept`. Required if overriding a `noexcept` method. |
| `Calltype(`*`calltype`*`)` | Sets the call type for the method, for example `Calltype(STDMETHODCALLTYPE)`. Useful on Windows. |
| `ref(`*`qualifier`*`)` | Marks the method with the given reference qualifier, for example `ref(&)` or `ref(&&)`. Required if overriding a method that has a reference qualifier. |
Note that commas in arguments prevent `MOCK_METHOD` from parsing the arguments
correctly if they are not appropriately surrounded by parentheses. See the
following example:
```cpp
class MyMock {
public:
// The following 2 lines will not compile due to commas in the arguments:
MOCK_METHOD(std::pair<bool, int>, GetPair, ()); // Error!
MOCK_METHOD(bool, CheckMap, (std::map<int, double>, bool)); // Error!
// One solution - wrap arguments that contain commas in parentheses:
MOCK_METHOD((std::pair<bool, int>), GetPair, ());
MOCK_METHOD(bool, CheckMap, ((std::map<int, double>), bool));
// Another solution - use type aliases:
using BoolAndInt = std::pair<bool, int>;
MOCK_METHOD(BoolAndInt, GetPair, ());
using MapIntDouble = std::map<int, double>;
MOCK_METHOD(bool, CheckMap, (MapIntDouble, bool));
};
```
`MOCK_METHOD` must be used in the `public:` section of a mock class definition,
regardless of whether the method being mocked is `public`, `protected`, or
`private` in the base class.
### EXPECT_CALL {#EXPECT_CALL}
`EXPECT_CALL(`*`mock_object`*`,`*`method_name`*`(`*`matchers...`*`))`
Creates an [expectation](../gmock_for_dummies.md#setting-expectations) that the
method *`method_name`* of the object *`mock_object`* is called with arguments
that match the given matchers *`matchers...`*. `EXPECT_CALL` must precede any
code that exercises the mock object.
The parameter *`matchers...`* is a comma-separated list of
[matchers](../gmock_for_dummies.md#matchers-what-arguments-do-we-expect) that
correspond to each argument of the method *`method_name`*. The expectation will
apply only to calls of *`method_name`* whose arguments match all of the
matchers. If `(`*`matchers...`*`)` is omitted, the expectation behaves as if
each argument's matcher were a [wildcard matcher (`_`)](matchers.md#wildcard).
See the [Matchers Reference](matchers.md) for a list of all built-in matchers.
The following chainable clauses can be used to modify the expectation, and they
must be used in the following order:
```cpp
EXPECT_CALL(mock_object, method_name(matchers...))
.With(multi_argument_matcher) // Can be used at most once
.Times(cardinality) // Can be used at most once
.InSequence(sequences...) // Can be used any number of times
.After(expectations...) // Can be used any number of times
.WillOnce(action) // Can be used any number of times
.WillRepeatedly(action) // Can be used at most once
.RetiresOnSaturation(); // Can be used at most once
```
See details for each modifier clause below.
#### With {#EXPECT_CALL.With}
`.With(`*`multi_argument_matcher`*`)`
Restricts the expectation to apply only to mock function calls whose arguments
as a whole match the multi-argument matcher *`multi_argument_matcher`*.
GoogleTest passes all of the arguments as one tuple into the matcher. The
parameter *`multi_argument_matcher`* must thus be a matcher of type
`Matcher<std::tuple<A1, ..., An>>`, where `A1, ..., An` are the types of the
function arguments.
For example, the following code sets the expectation that
`my_mock.SetPosition()` is called with any two arguments, the first argument
being less than the second:
```cpp
using ::testing::_;
using ::testing::Lt;
...
EXPECT_CALL(my_mock, SetPosition(_, _))
.With(Lt());
```
GoogleTest provides some built-in matchers for 2-tuples, including the `Lt()`
matcher above. See [Multi-argument Matchers](matchers.md#MultiArgMatchers).
The `With` clause can be used at most once on an expectation and must be the
first clause.
#### Times {#EXPECT_CALL.Times}
`.Times(`*`cardinality`*`)`
Specifies how many times the mock function call is expected.
The parameter *`cardinality`* represents the number of expected calls and can be
one of the following, all defined in the `::testing` namespace:
| Cardinality | Meaning |
| ------------------- | --------------------------------------------------- |
| `AnyNumber()` | The function can be called any number of times. |
| `AtLeast(n)` | The function call is expected at least *n* times. |
| `AtMost(n)` | The function call is expected at most *n* times. |
| `Between(m, n)` | The function call is expected between *m* and *n* times, inclusive. |
| `Exactly(n)` or `n` | The function call is expected exactly *n* times. If *n* is 0, the call should never happen. |
If the `Times` clause is omitted, GoogleTest infers the cardinality as follows:
* If neither [`WillOnce`](#EXPECT_CALL.WillOnce) nor
[`WillRepeatedly`](#EXPECT_CALL.WillRepeatedly) are specified, the inferred
cardinality is `Times(1)`.
* If there are *n* `WillOnce` clauses and no `WillRepeatedly` clause, where
*n* >= 1, the inferred cardinality is `Times(n)`.
* If there are *n* `WillOnce` clauses and one `WillRepeatedly` clause, where
*n* >= 0, the inferred cardinality is `Times(AtLeast(n))`.
The `Times` clause can be used at most once on an expectation.
#### InSequence {#EXPECT_CALL.InSequence}
`.InSequence(`*`sequences...`*`)`
Specifies that the mock function call is expected in a certain sequence.
The parameter *`sequences...`* is any number of [`Sequence`](#Sequence) objects.
Expected calls assigned to the same sequence are expected to occur in the order
the expectations are declared.
For example, the following code sets the expectation that the `Reset()` method
of `my_mock` is called before both `GetSize()` and `Describe()`, and `GetSize()`
and `Describe()` can occur in any order relative to each other:
```cpp
using ::testing::Sequence;
Sequence s1, s2;
...
EXPECT_CALL(my_mock, Reset())
.InSequence(s1, s2);
EXPECT_CALL(my_mock, GetSize())
.InSequence(s1);
EXPECT_CALL(my_mock, Describe())
.InSequence(s2);
```
The `InSequence` clause can be used any number of times on an expectation.
See also the [`InSequence` class](#InSequence).
#### After {#EXPECT_CALL.After}
`.After(`*`expectations...`*`)`
Specifies that the mock function call is expected to occur after one or more
other calls.
The parameter *`expectations...`* can be up to five
[`Expectation`](#Expectation) or [`ExpectationSet`](#ExpectationSet) objects.
The mock function call is expected to occur after all of the given expectations.
For example, the following code sets the expectation that the `Describe()`
method of `my_mock` is called only after both `InitX()` and `InitY()` have been
called.
```cpp
using ::testing::Expectation;
...
Expectation init_x = EXPECT_CALL(my_mock, InitX());
Expectation init_y = EXPECT_CALL(my_mock, InitY());
EXPECT_CALL(my_mock, Describe())
.After(init_x, init_y);
```
The `ExpectationSet` object is helpful when the number of prerequisites for an
expectation is large or variable, for example:
```cpp
using ::testing::ExpectationSet;
...
ExpectationSet all_inits;
// Collect all expectations of InitElement() calls
for (int i = 0; i < element_count; i++) {
all_inits += EXPECT_CALL(my_mock, InitElement(i));
}
EXPECT_CALL(my_mock, Describe())
.After(all_inits); // Expect Describe() call after all InitElement() calls
```
The `After` clause can be used any number of times on an expectation.
#### WillOnce {#EXPECT_CALL.WillOnce}
`.WillOnce(`*`action`*`)`
Specifies the mock function's actual behavior when invoked, for a single
matching function call.
The parameter *`action`* represents the
[action](../gmock_for_dummies.md#actions-what-should-it-do) that the function
call will perform. See the [Actions Reference](actions.md) for a list of
built-in actions.
The use of `WillOnce` implicitly sets a cardinality on the expectation when
`Times` is not specified. See [`Times`](#EXPECT_CALL.Times).
Each matching function call will perform the next action in the order declared.
For example, the following code specifies that `my_mock.GetNumber()` is expected
to be called exactly 3 times and will return `1`, `2`, and `3` respectively on
the first, second, and third calls:
```cpp
using ::testing::Return;
...
EXPECT_CALL(my_mock, GetNumber())
.WillOnce(Return(1))
.WillOnce(Return(2))
.WillOnce(Return(3));
```
The `WillOnce` clause can be used any number of times on an expectation.
#### WillRepeatedly {#EXPECT_CALL.WillRepeatedly}
`.WillRepeatedly(`*`action`*`)`
Specifies the mock function's actual behavior when invoked, for all subsequent
matching function calls. Takes effect after the actions specified in the
[`WillOnce`](#EXPECT_CALL.WillOnce) clauses, if any, have been performed.
The parameter *`action`* represents the
[action](../gmock_for_dummies.md#actions-what-should-it-do) that the function
call will perform. See the [Actions Reference](actions.md) for a list of
built-in actions.
The use of `WillRepeatedly` implicitly sets a cardinality on the expectation
when `Times` is not specified. See [`Times`](#EXPECT_CALL.Times).
If any `WillOnce` clauses have been specified, matching function calls will
perform those actions before the action specified by `WillRepeatedly`. See the
following example:
```cpp
using ::testing::Return;
...
EXPECT_CALL(my_mock, GetName())
.WillRepeatedly(Return("John Doe")); // Return "John Doe" on all calls
EXPECT_CALL(my_mock, GetNumber())
.WillOnce(Return(42)) // Return 42 on the first call
.WillRepeatedly(Return(7)); // Return 7 on all subsequent calls
```
The `WillRepeatedly` clause can be used at most once on an expectation.
#### RetiresOnSaturation {#EXPECT_CALL.RetiresOnSaturation}
`.RetiresOnSaturation()`
Indicates that the expectation will no longer be active after the expected
number of matching function calls has been reached.
The `RetiresOnSaturation` clause is only meaningful for expectations with an
upper-bounded cardinality. The expectation will *retire* (no longer match any
function calls) after it has been *saturated* (the upper bound has been
reached). See the following example:
```cpp
using ::testing::_;
using ::testing::AnyNumber;
...
EXPECT_CALL(my_mock, SetNumber(_)) // Expectation 1
.Times(AnyNumber());
EXPECT_CALL(my_mock, SetNumber(7)) // Expectation 2
.Times(2)
.RetiresOnSaturation();
```
In the above example, the first two calls to `my_mock.SetNumber(7)` match
expectation 2, which then becomes inactive and no longer matches any calls. A
third call to `my_mock.SetNumber(7)` would then match expectation 1. Without
`RetiresOnSaturation()` on expectation 2, a third call to `my_mock.SetNumber(7)`
would match expectation 2 again, producing a failure since the limit of 2 calls
was exceeded.
The `RetiresOnSaturation` clause can be used at most once on an expectation and
must be the last clause.
### ON_CALL {#ON_CALL}
`ON_CALL(`*`mock_object`*`,`*`method_name`*`(`*`matchers...`*`))`
Defines what happens when the method *`method_name`* of the object
*`mock_object`* is called with arguments that match the given matchers
*`matchers...`*. Requires a modifier clause to specify the method's behavior.
*Does not* set any expectations that the method will be called.
The parameter *`matchers...`* is a comma-separated list of
[matchers](../gmock_for_dummies.md#matchers-what-arguments-do-we-expect) that
correspond to each argument of the method *`method_name`*. The `ON_CALL`
specification will apply only to calls of *`method_name`* whose arguments match
all of the matchers. If `(`*`matchers...`*`)` is omitted, the behavior is as if
each argument's matcher were a [wildcard matcher (`_`)](matchers.md#wildcard).
See the [Matchers Reference](matchers.md) for a list of all built-in matchers.
The following chainable clauses can be used to set the method's behavior, and
they must be used in the following order:
```cpp
ON_CALL(mock_object, method_name(matchers...))
.With(multi_argument_matcher) // Can be used at most once
.WillByDefault(action); // Required
```
See details for each modifier clause below.
#### With {#ON_CALL.With}
`.With(`*`multi_argument_matcher`*`)`
Restricts the specification to only mock function calls whose arguments as a
whole match the multi-argument matcher *`multi_argument_matcher`*.
GoogleTest passes all of the arguments as one tuple into the matcher. The
parameter *`multi_argument_matcher`* must thus be a matcher of type
`Matcher<std::tuple<A1, ..., An>>`, where `A1, ..., An` are the types of the
function arguments.
For example, the following code sets the default behavior when
`my_mock.SetPosition()` is called with any two arguments, the first argument
being less than the second:
```cpp
using ::testing::_;
using ::testing::Lt;
using ::testing::Return;
...
ON_CALL(my_mock, SetPosition(_, _))
.With(Lt())
.WillByDefault(Return(true));
```
GoogleTest provides some built-in matchers for 2-tuples, including the `Lt()`
matcher above. See [Multi-argument Matchers](matchers.md#MultiArgMatchers).
The `With` clause can be used at most once with each `ON_CALL` statement.
#### WillByDefault {#ON_CALL.WillByDefault}
`.WillByDefault(`*`action`*`)`
Specifies the default behavior of a matching mock function call.
The parameter *`action`* represents the
[action](../gmock_for_dummies.md#actions-what-should-it-do) that the function
call will perform. See the [Actions Reference](actions.md) for a list of
built-in actions.
For example, the following code specifies that by default, a call to
`my_mock.Greet()` will return `"hello"`:
```cpp
using ::testing::Return;
...
ON_CALL(my_mock, Greet())
.WillByDefault(Return("hello"));
```
The action specified by `WillByDefault` is superseded by the actions specified
on a matching `EXPECT_CALL` statement, if any. See the
[`WillOnce`](#EXPECT_CALL.WillOnce) and
[`WillRepeatedly`](#EXPECT_CALL.WillRepeatedly) clauses of `EXPECT_CALL`.
The `WillByDefault` clause must be used exactly once with each `ON_CALL`
statement.
## Classes {#classes}
GoogleTest defines the following classes for working with mocks.
### DefaultValue {#DefaultValue}
`::testing::DefaultValue<T>`
Allows a user to specify the default value for a type `T` that is both copyable
and publicly destructible (i.e. anything that can be used as a function return
type). For mock functions with a return type of `T`, this default value is
returned from function calls that do not specify an action.
Provides the static methods `Set()`, `SetFactory()`, and `Clear()` to manage the
default value:
```cpp
// Sets the default value to be returned. T must be copy constructible.
DefaultValue<T>::Set(value);
// Sets a factory. Will be invoked on demand. T must be move constructible.
T MakeT();
DefaultValue<T>::SetFactory(&MakeT);
// Unsets the default value.
DefaultValue<T>::Clear();
```
### NiceMock {#NiceMock}
`::testing::NiceMock<T>`
Represents a mock object that suppresses warnings on
[uninteresting calls](../gmock_cook_book.md#uninteresting-vs-unexpected). The
template parameter `T` is any mock class, except for another `NiceMock`,
`NaggyMock`, or `StrictMock`.
Usage of `NiceMock<T>` is analogous to usage of `T`. `NiceMock<T>` is a subclass
of `T`, so it can be used wherever an object of type `T` is accepted. In
addition, `NiceMock<T>` can be constructed with any arguments that a constructor
of `T` accepts.
For example, the following code suppresses warnings on the mock `my_mock` of
type `MockClass` if a method other than `DoSomething()` is called:
```cpp
using ::testing::NiceMock;
...
NiceMock<MockClass> my_mock("some", "args");
EXPECT_CALL(my_mock, DoSomething());
... code that uses my_mock ...
```
`NiceMock<T>` only works for mock methods defined using the `MOCK_METHOD` macro
directly in the definition of class `T`. If a mock method is defined in a base
class of `T`, a warning might still be generated.
`NiceMock<T>` might not work correctly if the destructor of `T` is not virtual.
### NaggyMock {#NaggyMock}
`::testing::NaggyMock<T>`
Represents a mock object that generates warnings on
[uninteresting calls](../gmock_cook_book.md#uninteresting-vs-unexpected). The
template parameter `T` is any mock class, except for another `NiceMock`,
`NaggyMock`, or `StrictMock`.
Usage of `NaggyMock<T>` is analogous to usage of `T`. `NaggyMock<T>` is a
subclass of `T`, so it can be used wherever an object of type `T` is accepted.
In addition, `NaggyMock<T>` can be constructed with any arguments that a
constructor of `T` accepts.
For example, the following code generates warnings on the mock `my_mock` of type
`MockClass` if a method other than `DoSomething()` is called:
```cpp
using ::testing::NaggyMock;
...
NaggyMock<MockClass> my_mock("some", "args");
EXPECT_CALL(my_mock, DoSomething());
... code that uses my_mock ...
```
Mock objects of type `T` by default behave the same way as `NaggyMock<T>`.
### StrictMock {#StrictMock}
`::testing::StrictMock<T>`
Represents a mock object that generates test failures on
[uninteresting calls](../gmock_cook_book.md#uninteresting-vs-unexpected). The
template parameter `T` is any mock class, except for another `NiceMock`,
`NaggyMock`, or `StrictMock`.
Usage of `StrictMock<T>` is analogous to usage of `T`. `StrictMock<T>` is a
subclass of `T`, so it can be used wherever an object of type `T` is accepted.
In addition, `StrictMock<T>` can be constructed with any arguments that a
constructor of `T` accepts.
For example, the following code generates a test failure on the mock `my_mock`
of type `MockClass` if a method other than `DoSomething()` is called:
```cpp
using ::testing::StrictMock;
...
StrictMock<MockClass> my_mock("some", "args");
EXPECT_CALL(my_mock, DoSomething());
... code that uses my_mock ...
```
`StrictMock<T>` only works for mock methods defined using the `MOCK_METHOD`
macro directly in the definition of class `T`. If a mock method is defined in a
base class of `T`, a failure might not be generated.
`StrictMock<T>` might not work correctly if the destructor of `T` is not
virtual.
### Sequence {#Sequence}
`::testing::Sequence`
Represents a chronological sequence of expectations. See the
[`InSequence`](#EXPECT_CALL.InSequence) clause of `EXPECT_CALL` for usage.
### InSequence {#InSequence}
`::testing::InSequence`
An object of this type causes all expectations encountered in its scope to be
put in an anonymous sequence.
This allows more convenient expression of multiple expectations in a single
sequence:
```cpp
using ::testing::InSequence;
{
InSequence seq;
// The following are expected to occur in the order declared.
EXPECT_CALL(...);
EXPECT_CALL(...);
...
EXPECT_CALL(...);
}
```
The name of the `InSequence` object does not matter.
### Expectation {#Expectation}
`::testing::Expectation`
Represents a mock function call expectation as created by
[`EXPECT_CALL`](#EXPECT_CALL):
```cpp
using ::testing::Expectation;
Expectation my_expectation = EXPECT_CALL(...);
```
Useful for specifying sequences of expectations; see the
[`After`](#EXPECT_CALL.After) clause of `EXPECT_CALL`.
### ExpectationSet {#ExpectationSet}
`::testing::ExpectationSet`
Represents a set of mock function call expectations.
Use the `+=` operator to add [`Expectation`](#Expectation) objects to the set:
```cpp
using ::testing::ExpectationSet;
ExpectationSet my_expectations;
my_expectations += EXPECT_CALL(...);
```
Useful for specifying sequences of expectations; see the
[`After`](#EXPECT_CALL.After) clause of `EXPECT_CALL`.

File diff suppressed because it is too large Load Diff

View File

@ -36,9 +36,13 @@ endif()
# as ${gmock_SOURCE_DIR} and to the root binary directory as
# ${gmock_BINARY_DIR}.
# Language "C" is required for find_package(Threads).
cmake_minimum_required(VERSION 3.5)
cmake_policy(SET CMP0048 NEW)
project(gmock VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)
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)
if (COMMAND set_up_hermetic_build)
set_up_hermetic_build()
@ -96,10 +100,8 @@ 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)
set_target_properties(gmock_main PROPERTIES VERSION ${GOOGLETEST_VERSION})
endif()
# If the CMake version supports it, attach header directory information
# to the targets for when we are part of a parent build (ie being pulled
@ -134,6 +136,20 @@ if (gmock_build_tests)
# 'make test' or ctest.
enable_testing()
if (WIN32)
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/RunTest.ps1"
CONTENT
"$project_bin = \"${CMAKE_BINARY_DIR}/bin/$<CONFIG>\"
$env:Path = \"$project_bin;$env:Path\"
& $args")
elseif (MINGW OR CYGWIN)
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/RunTest.ps1"
CONTENT
"$project_bin = (cygpath --windows ${CMAKE_BINARY_DIR}/bin)
$env:Path = \"$project_bin;$env:Path\"
& $args")
endif()
if (MINGW OR CYGWIN)
if (CMAKE_VERSION VERSION_LESS "2.8.12")
add_compile_options("-Wa,-mbig-obj")
@ -149,6 +165,9 @@ if (gmock_build_tests)
cxx_test(gmock-cardinalities_test gmock_main)
cxx_test(gmock_ex_test gmock_main)
cxx_test(gmock-function-mocker_test gmock_main)
cxx_test(gmock-generated-actions_test gmock_main)
cxx_test(gmock-generated-function-mockers_test gmock_main)
cxx_test(gmock-generated-matchers_test gmock_main)
cxx_test(gmock-internal-utils_test gmock_main)
cxx_test(gmock-matchers_test gmock_main)
cxx_test(gmock-more-actions_test gmock_main)

40
googlemock/CONTRIBUTORS Normal file
View File

@ -0,0 +1,40 @@
# This file contains a list of people who've made non-trivial
# contribution to the Google C++ Mocking Framework project. People
# who commit code to the project are encouraged to add their names
# here. Please keep the list sorted by first names.
Benoit Sigoure <tsuna@google.com>
Bogdan Piloca <boo@google.com>
Chandler Carruth <chandlerc@google.com>
Dave MacLachlan <dmaclach@gmail.com>
David Anderson <danderson@google.com>
Dean Sturtevant
Gene Volovich <gv@cite.com>
Hal Burch <gmock@hburch.com>
Jeffrey Yasskin <jyasskin@google.com>
Jim Keller <jimkeller@google.com>
Joe Walnes <joe@truemesh.com>
Jon Wray <jwray@google.com>
Keir Mierle <mierle@gmail.com>
Keith Ray <keith.ray@gmail.com>
Kostya Serebryany <kcc@google.com>
Lev Makhlis
Manuel Klimek <klimek@google.com>
Mario Tanev <radix@google.com>
Mark Paskin
Markus Heule <markus.heule@gmail.com>
Matthew Simmons <simmonmt@acm.org>
Mike Bland <mbland@google.com>
Neal Norwitz <nnorwitz@gmail.com>
Nermin Ozkiranartli <nermin@google.com>
Owen Carlsen <ocarlsen@google.com>
Paneendra Ba <paneendra@google.com>
Paul Menage <menage@google.com>
Piotr Kaminski <piotrk@google.com>
Russ Rufer <russ@pentad.com>
Sverre Sundsdal <sundsdal@gmail.com>
Takeshi Yoshino <tyoshino@google.com>
Vadim Berman <vadimb@google.com>
Vlad Losev <vladl@google.com>
Wolfgang Klier <wklier@google.com>
Zhanyong Wan <wan@google.com>

28
googlemock/LICENSE Normal file
View File

@ -0,0 +1,28 @@
Copyright 2008, Google Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -7,34 +7,38 @@ derive better designs of your system and write better tests.
It is inspired by:
* [jMock](http://www.jmock.org/)
* [EasyMock](http://www.easymock.org/)
* [Hamcrest](http://code.google.com/p/hamcrest/)
* [jMock](http://www.jmock.org/),
* [EasyMock](http://www.easymock.org/), and
* [Hamcrest](http://code.google.com/p/hamcrest/),
It is designed with C++'s specifics in mind.
and 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.
- 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, and
- 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)
* [gMock for Dummies](docs/for_dummies.md)
* [Legacy gMock FAQ](docs/gmock_faq.md)
* [gMock Cookbook](docs/cook_book.md)
* [gMock Cheat Sheet](docs/cheat_sheet.md)
GoogleMock is a part of
[GoogleTest C++ testing framework](http://github.com/google/googletest/) and a
Please note that code under scripts/generator/ is from the [cppclean
project](http://code.google.com/p/cppclean/) and under the Apache
License, which is different from Google Mock's license.
Google Mock is a part of
[Google Test C++ testing framework](http://github.com/google/googletest/) and a
subject to the same requirements.

View File

@ -1,10 +1,11 @@
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
prefix=${pcfiledir}/../..
libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
Name: gmock
Description: GoogleMock (without main() function)
Version: @PROJECT_VERSION@
URL: https://github.com/google/googletest
Requires: gtest = @PROJECT_VERSION@
Requires: gtest
Libs: -L${libdir} -lgmock @CMAKE_THREAD_LIBS_INIT@
Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@
Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ @CMAKE_THREAD_LIBS_INIT@

View File

@ -1,10 +1,11 @@
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
prefix=${pcfiledir}/../..
libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
Name: gmock_main
Description: GoogleMock (with main() function)
Version: @PROJECT_VERSION@
URL: https://github.com/google/googletest
Requires: gmock = @PROJECT_VERSION@
Requires: gmock
Libs: -L${libdir} -lgmock_main @CMAKE_THREAD_LIBS_INIT@
Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@
Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ @CMAKE_THREAD_LIBS_INIT@

View File

@ -1,4 +0,0 @@
# Content Moved
We are working on updates to the GoogleTest documentation, which has moved to
the top-level [docs](../../docs) directory.

View File

@ -0,0 +1,781 @@
## gMock Cheat Sheet
<!-- GOOGLETEST_CM0019 DO NOT DELETE -->
<!-- GOOGLETEST_CM0033 DO NOT DELETE -->
### Defining a Mock Class
#### Mocking a Normal Class {#MockClass}
Given
```cpp
class Foo {
...
virtual ~Foo();
virtual int GetSize() const = 0;
virtual string Describe(const char* name) = 0;
virtual string Describe(int type) = 0;
virtual bool Process(Bar elem, int count) = 0;
};
```
(note that `~Foo()` **must** be virtual) we can define its mock as
```cpp
#include "gmock/gmock.h"
class MockFoo : public Foo {
...
MOCK_METHOD(int, GetSize, (), (const, override));
MOCK_METHOD(string, Describe, (const char* name), (override));
MOCK_METHOD(string, Describe, (int type), (override));
MOCK_METHOD(bool, Process, (Bar elem, int count), (override));
};
```
To create a "nice" mock, which ignores all uninteresting calls, a "naggy" mock,
which warns on all uninteresting calls, or a "strict" mock, which treats them as
failures:
```cpp
using ::testing::NiceMock;
using ::testing::NaggyMock;
using ::testing::StrictMock;
NiceMock<MockFoo> nice_foo; // The type is a subclass of MockFoo.
NaggyMock<MockFoo> naggy_foo; // The type is a subclass of MockFoo.
StrictMock<MockFoo> strict_foo; // The type is a subclass of MockFoo.
```
**Note:** A mock object is currently naggy by default. We may make it nice by
default in the future.
#### Mocking a Class Template {#MockTemplate}
Class templates can be mocked just like any class.
To mock
```cpp
template <typename Elem>
class StackInterface {
...
virtual ~StackInterface();
virtual int GetSize() const = 0;
virtual void Push(const Elem& x) = 0;
};
```
(note that all member functions that are mocked, including `~StackInterface()`
**must** be virtual).
```cpp
template <typename Elem>
class MockStack : public StackInterface<Elem> {
...
MOCK_METHOD(int, GetSize, (), (const, override));
MOCK_METHOD(void, Push, (const Elem& x), (override));
};
```
#### Specifying Calling Conventions for Mock Functions
If your mock function doesn't use the default calling convention, you can
specify it by adding `Calltype(convention)` to `MOCK_METHOD`'s 4th parameter.
For example,
```cpp
MOCK_METHOD(bool, Foo, (int n), (Calltype(STDMETHODCALLTYPE)));
MOCK_METHOD(int, Bar, (double x, double y),
(const, Calltype(STDMETHODCALLTYPE)));
```
where `STDMETHODCALLTYPE` is defined by `<objbase.h>` on Windows.
### Using Mocks in Tests {#UsingMocks}
The typical work flow is:
1. Import the gMock names you need to use. All gMock symbols are in the
`testing` namespace unless they are macros or otherwise noted.
2. Create the mock objects.
3. Optionally, set the default actions of the mock objects.
4. Set your expectations on the mock objects (How will they be called? What
will they do?).
5. Exercise code that uses the mock objects; if necessary, check the result
using googletest assertions.
6. When a mock object is destructed, gMock automatically verifies that all
expectations on it have been satisfied.
Here's an example:
```cpp
using ::testing::Return; // #1
TEST(BarTest, DoesThis) {
MockFoo foo; // #2
ON_CALL(foo, GetSize()) // #3
.WillByDefault(Return(1));
// ... other default actions ...
EXPECT_CALL(foo, Describe(5)) // #4
.Times(3)
.WillRepeatedly(Return("Category 5"));
// ... other expectations ...
EXPECT_EQ("good", MyProductionFunction(&foo)); // #5
} // #6
```
### Setting Default Actions {#OnCall}
gMock has a **built-in default action** for any function that returns `void`,
`bool`, a numeric value, or a pointer. In C++11, it will additionally returns
the default-constructed value, if one exists for the given type.
To customize the default action for functions with return type *`T`*:
```cpp
using ::testing::DefaultValue;
// Sets the default value to be returned. T must be CopyConstructible.
DefaultValue<T>::Set(value);
// Sets a factory. Will be invoked on demand. T must be MoveConstructible.
// T MakeT();
DefaultValue<T>::SetFactory(&MakeT);
// ... use the mocks ...
// Resets the default value.
DefaultValue<T>::Clear();
```
Example usage:
```cpp
// Sets the default action for return type std::unique_ptr<Buzz> to
// creating a new Buzz every time.
DefaultValue<std::unique_ptr<Buzz>>::SetFactory(
[] { return MakeUnique<Buzz>(AccessLevel::kInternal); });
// When this fires, the default action of MakeBuzz() will run, which
// will return a new Buzz object.
EXPECT_CALL(mock_buzzer_, MakeBuzz("hello")).Times(AnyNumber());
auto buzz1 = mock_buzzer_.MakeBuzz("hello");
auto buzz2 = mock_buzzer_.MakeBuzz("hello");
EXPECT_NE(nullptr, buzz1);
EXPECT_NE(nullptr, buzz2);
EXPECT_NE(buzz1, buzz2);
// Resets the default action for return type std::unique_ptr<Buzz>,
// to avoid interfere with other tests.
DefaultValue<std::unique_ptr<Buzz>>::Clear();
```
To customize the default action for a particular method of a specific mock
object, use `ON_CALL()`. `ON_CALL()` has a similar syntax to `EXPECT_CALL()`,
but it is used for setting default behaviors (when you do not require that the
mock method is called). See [here](cook_book.md#UseOnCall) for a more detailed
discussion.
```cpp
ON_CALL(mock-object, method(matchers))
.With(multi-argument-matcher) ?
.WillByDefault(action);
```
### Setting Expectations {#ExpectCall}
`EXPECT_CALL()` sets **expectations** on a mock method (How will it be called?
What will it do?):
```cpp
EXPECT_CALL(mock-object, method (matchers)?)
.With(multi-argument-matcher) ?
.Times(cardinality) ?
.InSequence(sequences) *
.After(expectations) *
.WillOnce(action) *
.WillRepeatedly(action) ?
.RetiresOnSaturation(); ?
```
For each item above, `?` means it can be used at most once, while `*` means it
can be used any number of times.
In order to pass, `EXPECT_CALL` must be used before the calls are actually made.
The `(matchers)` is a comma-separated list of matchers that correspond to each
of the arguments of `method`, and sets the expectation only for calls of
`method` that matches all of the matchers.
If `(matchers)` is omitted, the expectation is the same as if the matchers were
set to anything matchers (for example, `(_, _, _, _)` for a four-arg method).
If `Times()` is omitted, the cardinality is assumed to be:
* `Times(1)` when there is neither `WillOnce()` nor `WillRepeatedly()`;
* `Times(n)` when there are `n` `WillOnce()`s but no `WillRepeatedly()`, where
`n` >= 1; or
* `Times(AtLeast(n))` when there are `n` `WillOnce()`s and a
`WillRepeatedly()`, where `n` >= 0.
A method with no `EXPECT_CALL()` is free to be invoked *any number of times*,
and the default action will be taken each time.
### Matchers {#MatcherList}
<!-- GOOGLETEST_CM0020 DO NOT DELETE -->
A **matcher** matches a *single* argument. You can use it inside `ON_CALL()` or
`EXPECT_CALL()`, or use it to validate a value directly using two macros:
<!-- mdformat off(github rendering does not support multiline tables) -->
| Macro | Description |
| :----------------------------------- | :------------------------------------ |
| `EXPECT_THAT(actual_value, matcher)` | Asserts that `actual_value` matches `matcher`. |
| `ASSERT_THAT(actual_value, matcher)` | The same as `EXPECT_THAT(actual_value, matcher)`, except that it generates a **fatal** failure. |
<!-- mdformat on -->
Built-in matchers (where `argument` is the function argument, e.g.
`actual_value` in the example above, or when used in the context of
`EXPECT_CALL(mock_object, method(matchers))`, the arguments of `method`) are
divided into several categories:
#### Wildcard
Matcher | Description
:-------------------------- | :-----------------------------------------------
`_` | `argument` can be any value of the correct type.
`A<type>()` or `An<type>()` | `argument` can be any value of type `type`.
#### Generic Comparison
<!-- mdformat off(no multiline tables) -->
| Matcher | Description |
| :--------------------- | :-------------------------------------------------- |
| `Eq(value)` or `value` | `argument == value` |
| `Ge(value)` | `argument >= value` |
| `Gt(value)` | `argument > value` |
| `Le(value)` | `argument <= value` |
| `Lt(value)` | `argument < value` |
| `Ne(value)` | `argument != value` |
| `IsFalse()` | `argument` evaluates to `false` in a Boolean context. |
| `IsTrue()` | `argument` evaluates to `true` in a Boolean context. |
| `IsNull()` | `argument` is a `NULL` pointer (raw or smart). |
| `NotNull()` | `argument` is a non-null pointer (raw or smart). |
| `Optional(m)` | `argument` is `optional<>` that contains a value matching `m`. |
| `VariantWith<T>(m)` | `argument` is `variant<>` that holds the alternative of type T with a value matching `m`. |
| `Ref(variable)` | `argument` is a reference to `variable`. |
| `TypedEq<type>(value)` | `argument` has type `type` and is equal to `value`. You may need to use this instead of `Eq(value)` when the mock function is overloaded. |
<!-- mdformat on -->
Except `Ref()`, these matchers make a *copy* of `value` in case it's modified or
destructed later. If the compiler complains that `value` doesn't have a public
copy constructor, try wrap it in `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 {#FpMatchers}
<!-- mdformat off(no multiline tables) -->
| Matcher | Description |
| :------------------------------- | :--------------------------------- |
| `DoubleEq(a_double)` | `argument` is a `double` value approximately equal to `a_double`, treating two NaNs as unequal. |
| `FloatEq(a_float)` | `argument` is a `float` value approximately equal to `a_float`, treating two NaNs as unequal. |
| `NanSensitiveDoubleEq(a_double)` | `argument` is a `double` value approximately equal to `a_double`, treating two NaNs as equal. |
| `NanSensitiveFloatEq(a_float)` | `argument` is a `float` value approximately equal to `a_float`, treating two NaNs as equal. |
<!-- mdformat on -->
The above matchers use ULP-based comparison (the same as used in googletest).
They automatically pick a reasonable error bound based on the absolute value of
the expected value. `DoubleEq()` and `FloatEq()` conform to the IEEE standard,
which requires comparing two NaNs for equality to return false. The
`NanSensitive*` version instead treats two NaNs as equal, which is often what a
user wants.
<!-- mdformat off(no multiline tables) -->
| Matcher | Description |
| :------------------------------------------------ | :----------------------- |
| `DoubleNear(a_double, max_abs_error)` | `argument` is a `double` value close to `a_double` (absolute error <= `max_abs_error`), treating two NaNs as unequal. |
| `FloatNear(a_float, max_abs_error)` | `argument` is a `float` value close to `a_float` (absolute error <= `max_abs_error`), treating two NaNs as unequal. |
| `NanSensitiveDoubleNear(a_double, max_abs_error)` | `argument` is a `double` value close to `a_double` (absolute error <= `max_abs_error`), treating two NaNs as equal. |
| `NanSensitiveFloatNear(a_float, max_abs_error)` | `argument` is a `float` value close to `a_float` (absolute error <= `max_abs_error`), treating two NaNs as equal. |
<!-- mdformat on -->
#### String Matchers
The `argument` can be either a C string or a C++ string object:
<!-- mdformat off(no multiline tables) -->
| Matcher | Description |
| :---------------------- | :------------------------------------------------- |
| `ContainsRegex(string)` | `argument` matches the given regular expression. |
| `EndsWith(suffix)` | `argument` ends with string `suffix`. |
| `HasSubstr(string)` | `argument` contains `string` as a sub-string. |
| `MatchesRegex(string)` | `argument` matches the given regular expression with the match starting at the first character and ending at the last character. |
| `StartsWith(prefix)` | `argument` starts with string `prefix`. |
| `StrCaseEq(string)` | `argument` is equal to `string`, ignoring case. |
| `StrCaseNe(string)` | `argument` is not equal to `string`, ignoring case. |
| `StrEq(string)` | `argument` is equal to `string`. |
| `StrNe(string)` | `argument` is not equal to `string`. |
<!-- mdformat on -->
`ContainsRegex()` and `MatchesRegex()` take ownership of the `RE` object. They
use the regular expression syntax defined
[here](../../googletest/docs/advanced.md#regular-expression-syntax).
`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:
<!-- mdformat off(no multiline tables) -->
| Matcher | Description |
| :---------------------------------------- | :------------------------------- |
| `BeginEndDistanceIs(m)` | `argument` is a container whose `begin()` and `end()` iterators are separated by a number of increments matching `m`. E.g. `BeginEndDistanceIs(2)` or `BeginEndDistanceIs(Lt(2))`. For containers that define a `size()` method, `SizeIs(m)` may be more efficient. |
| `ContainerEq(container)` | The same as `Eq(container)` except that the failure message also includes which elements are in one container but not the other. |
| `Contains(e)` | `argument` contains an element that matches `e`, which can be either a value or a matcher. |
| `Each(e)` | `argument` is a container where *every* element matches `e`, which can be either a value or a matcher. |
| `ElementsAre(e0, e1, ..., en)` | `argument` has `n + 1` elements, where the *i*-th element matches `ei`, which can be a value or a matcher. |
| `ElementsAreArray({e0, e1, ..., en})`, `ElementsAreArray(a_container)`, `ElementsAreArray(begin, end)`, `ElementsAreArray(array)`, or `ElementsAreArray(array, count)` | The same as `ElementsAre()` except that the expected element values/matchers come from an initializer list, STL-style container, iterator range, or C-style array. |
| `IsEmpty()` | `argument` is an empty container (`container.empty()`). |
| `IsSubsetOf({e0, e1, ..., en})`, `IsSubsetOf(a_container)`, `IsSubsetOf(begin, end)`, `IsSubsetOf(array)`, or `IsSubsetOf(array, count)` | `argument` matches `UnorderedElementsAre(x0, x1, ..., xk)` for some subset `{x0, x1, ..., xk}` of the expected matchers. |
| `IsSupersetOf({e0, e1, ..., en})`, `IsSupersetOf(a_container)`, `IsSupersetOf(begin, end)`, `IsSupersetOf(array)`, or `IsSupersetOf(array, count)` | Some subset of `argument` matches `UnorderedElementsAre(`expected matchers`)`. |
| `Pointwise(m, container)`, `Pointwise(m, {e0, e1, ..., en})` | `argument` contains the same number of elements as in `container`, and for all i, (the i-th element in `argument`, the i-th element in `container`) match `m`, which is a matcher on 2-tuples. E.g. `Pointwise(Le(), upper_bounds)` verifies that each element in `argument` doesn't exceed the corresponding element in `upper_bounds`. See more detail below. |
| `SizeIs(m)` | `argument` is a container whose size matches `m`. E.g. `SizeIs(2)` or `SizeIs(Lt(2))`. |
| `UnorderedElementsAre(e0, e1, ..., en)` | `argument` has `n + 1` elements, and under *some* permutation of the elements, each element matches an `ei` (for a different `i`), which can be a value or a matcher. |
| `UnorderedElementsAreArray({e0, e1, ..., en})`, `UnorderedElementsAreArray(a_container)`, `UnorderedElementsAreArray(begin, end)`, `UnorderedElementsAreArray(array)`, or `UnorderedElementsAreArray(array, count)` | The same as `UnorderedElementsAre()` except that the expected element values/matchers come from an initializer list, STL-style container, iterator range, or C-style array. |
| `UnorderedPointwise(m, container)`, `UnorderedPointwise(m, {e0, e1, ..., en})` | Like `Pointwise(m, container)`, but ignores the order of elements. |
| `WhenSorted(m)` | When `argument` is sorted using the `<` operator, it matches container matcher `m`. E.g. `WhenSorted(ElementsAre(1, 2, 3))` verifies that `argument` contains elements 1, 2, and 3, ignoring order. |
| `WhenSortedBy(comparator, m)` | The same as `WhenSorted(m)`, except that the given comparator instead of `<` is used to sort `argument`. E.g. `WhenSortedBy(std::greater(), ElementsAre(3, 2, 1))`. |
<!-- mdformat on -->
**Notes:**
* These matchers can also match:
1. a native array passed by reference (e.g. in `Foo(const int (&a)[5])`),
and
2. an array passed as a pointer and a count (e.g. in `Bar(const T* buffer,
int len)` -- see [Multi-argument Matchers](#MultiArgMatchers)).
* The array being matched may be multi-dimensional (i.e. its elements can be
arrays).
* `m` in `Pointwise(m, ...)` should be a matcher for `::std::tuple<T, U>`
where `T` and `U` are the element type of the actual container and the
expected container, respectively. For example, to compare two `Foo`
containers where `Foo` doesn't support `operator==`, one might write:
```cpp
using ::std::get;
MATCHER(FooEq, "") {
return std::get<0>(arg).Equals(std::get<1>(arg));
}
...
EXPECT_THAT(actual_foos, Pointwise(FooEq(), expected_foos));
```
#### Member Matchers
<!-- mdformat off(no multiline tables) -->
| Matcher | Description |
| :------------------------------ | :----------------------------------------- |
| `Field(&class::field, m)` | `argument.field` (or `argument->field` when `argument` is a plain pointer) matches matcher `m`, where `argument` is an object of type _class_. |
| `Key(e)` | `argument.first` matches `e`, which can be either a value or a matcher. E.g. `Contains(Key(Le(5)))` can verify that a `map` contains a key `<= 5`. |
| `Pair(m1, m2)` | `argument` is an `std::pair` whose `first` field matches `m1` and `second` field matches `m2`. |
| `Property(&class::property, m)` | `argument.property()` (or `argument->property()` when `argument` is a plain pointer) matches matcher `m`, where `argument` is an object of type _class_. |
<!-- mdformat on -->
#### Matching the Result of a Function, Functor, or Callback
<!-- mdformat off(no multiline tables) -->
| Matcher | Description |
| :--------------- | :------------------------------------------------ |
| `ResultOf(f, m)` | `f(argument)` matches matcher `m`, where `f` is a function or functor. |
<!-- mdformat on -->
#### Pointer Matchers
<!-- mdformat off(no multiline tables) -->
| Matcher | Description |
| :------------------------ | :---------------------------------------------- |
| `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`. |
<!-- mdformat on -->
<!-- GOOGLETEST_CM0026 DO NOT DELETE -->
<!-- GOOGLETEST_CM0027 DO NOT DELETE -->
#### Multi-argument Matchers {#MultiArgMatchers}
Technically, all matchers match a *single* value. A "multi-argument" matcher is
just one that matches a *tuple*. The following matchers can be used to match a
tuple `(x, y)`:
Matcher | Description
:------ | :----------
`Eq()` | `x == y`
`Ge()` | `x >= y`
`Gt()` | `x > y`
`Le()` | `x <= y`
`Lt()` | `x < y`
`Ne()` | `x != y`
You can use the following selectors to pick a subset of the arguments (or
reorder them) to participate in the matching:
<!-- mdformat off(no multiline tables) -->
| Matcher | Description |
| :------------------------- | :---------------------------------------------- |
| `AllArgs(m)` | Equivalent to `m`. Useful as syntactic sugar in `.With(AllArgs(m))`. |
| `Args<N1, N2, ..., Nk>(m)` | The tuple of the `k` selected (using 0-based indices) arguments matches `m`, e.g. `Args<1, 2>(Eq())`. |
<!-- mdformat on -->
#### Composite Matchers
You can make a matcher from one or more other matchers:
<!-- mdformat off(no multiline tables) -->
| Matcher | Description |
| :------------------------------- | :-------------------------------------- |
| `AllOf(m1, m2, ..., mn)` | `argument` matches all of the matchers `m1` to `mn`. |
| `AllOfArray({m0, m1, ..., mn})`, `AllOfArray(a_container)`, `AllOfArray(begin, end)`, `AllOfArray(array)`, or `AllOfArray(array, count)` | The same as `AllOf()` except that the matchers come from an initializer list, STL-style container, iterator range, or C-style array. |
| `AnyOf(m1, m2, ..., mn)` | `argument` matches at least one of the matchers `m1` to `mn`. |
| `AnyOfArray({m0, m1, ..., mn})`, `AnyOfArray(a_container)`, `AnyOfArray(begin, end)`, `AnyOfArray(array)`, or `AnyOfArray(array, count)` | The same as `AnyOf()` except that the matchers come from an initializer list, STL-style container, iterator range, or C-style array. |
| `Not(m)` | `argument` doesn't match matcher `m`. |
<!-- mdformat on -->
<!-- GOOGLETEST_CM0028 DO NOT DELETE -->
#### Adapters for Matchers
<!-- mdformat off(no multiline tables) -->
| Matcher | Description |
| :---------------------- | :------------------------------------ |
| `MatcherCast<T>(m)` | casts matcher `m` to type `Matcher<T>`. |
| `SafeMatcherCast<T>(m)` | [safely casts](cook_book.md#casting-matchers) matcher `m` to type `Matcher<T>`. |
| `Truly(predicate)` | `predicate(argument)` returns something considered by C++ to be true, where `predicate` is a function or functor. |
<!-- mdformat on -->
`AddressSatisfies(callback)` and `Truly(callback)` take ownership of `callback`,
which must be a permanent callback.
#### Using Matchers as Predicates {#MatchersAsPredicatesCheat}
<!-- mdformat off(no multiline tables) -->
| Matcher | Description |
| :---------------------------- | :------------------------------------------ |
| `Matches(m)(value)` | evaluates to `true` if `value` matches `m`. You can use `Matches(m)` alone as a unary functor. |
| `ExplainMatchResult(m, value, result_listener)` | evaluates to `true` if `value` matches `m`, explaining the result to `result_listener`. |
| `Value(value, m)` | evaluates to `true` if `value` matches `m`. |
<!-- mdformat on -->
#### Defining Matchers
<!-- mdformat off(no multiline tables) -->
| Matcher | Description |
| :----------------------------------- | :------------------------------------ |
| `MATCHER(IsEven, "") { return (arg % 2) == 0; }` | Defines a matcher `IsEven()` to match an even number. |
| `MATCHER_P(IsDivisibleBy, n, "") { *result_listener << "where the remainder is " << (arg % n); return (arg % n) == 0; }` | Defines a 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`]. |
<!-- mdformat on -->
**Notes:**
1. The `MATCHER*` macros cannot be used inside a function or class.
2. The matcher body must be *purely functional* (i.e. it cannot have any side
effect, and the result must not depend on anything other than the value
being matched and the matcher parameters).
3. You can use `PrintToString(x)` to convert a value `x` of any type to a
string.
### Actions {#ActionList}
**Actions** specify what a mock function should do when invoked.
#### Returning a Value
<!-- mdformat off(no multiline tables) -->
| | |
| :-------------------------- | :-------------------------------------------- |
| `Return()` | Return from a `void` mock function. |
| `Return(value)` | Return `value`. If the type of `value` is different to the mock function's return type, `value` is converted to the latter type <i>at the time the expectation is set</i>, not when the action is executed. |
| `ReturnArg<N>()` | Return the `N`-th (0-based) argument. |
| `ReturnNew<T>(a1, ..., ak)` | Return `new T(a1, ..., ak)`; a different object is created each time. |
| `ReturnNull()` | Return a null pointer. |
| `ReturnPointee(ptr)` | Return the value pointed to by `ptr`. |
| `ReturnRef(variable)` | Return a reference to `variable`. |
| `ReturnRefOfCopy(value)` | Return a reference to a copy of `value`; the copy lives as long as the action. |
<!-- mdformat on -->
#### Side Effects
<!-- mdformat off(no multiline tables) -->
| | |
| :--------------------------------- | :-------------------------------------- |
| `Assign(&variable, value)` | Assign `value` to variable. |
| `DeleteArg<N>()` | Delete the `N`-th (0-based) argument, which must be a pointer. |
| `SaveArg<N>(pointer)` | Save the `N`-th (0-based) argument to `*pointer`. |
| `SaveArgPointee<N>(pointer)` | Save the value pointed to by the `N`-th (0-based) argument to `*pointer`. |
| `SetArgReferee<N>(value)` | Assign value to the variable referenced by the `N`-th (0-based) argument. |
| `SetArgPointee<N>(value)` | Assign `value` to the variable pointed by the `N`-th (0-based) argument. |
| `SetArgumentPointee<N>(value)` | Same as `SetArgPointee<N>(value)`. Deprecated. Will be removed in v1.7.0. |
| `SetArrayArgument<N>(first, last)` | Copies the elements in source range [`first`, `last`) to the array pointed to by the `N`-th (0-based) argument, which can be either a pointer or an iterator. The action does not take ownership of the elements in the source range. |
| `SetErrnoAndReturn(error, value)` | Set `errno` to `error` and return `value`. |
| `Throw(exception)` | Throws the given exception, which can be any copyable value. Available since v1.1.0. |
<!-- mdformat on -->
#### Using a Function, Functor, or Lambda as an Action
In the following, by "callable" we mean a free function, `std::function`,
functor, or lambda.
<!-- mdformat off(no multiline tables) -->
| | |
| :---------------------------------- | :------------------------------------- |
| `f` | Invoke f with the arguments passed to the mock function, where f is a callable. |
| `Invoke(f)` | Invoke `f` with the arguments passed to the mock function, where `f` can be a global/static function or a functor. |
| `Invoke(object_pointer, &class::method)` | Invoke the method on the object with the arguments passed to the mock function. |
| `InvokeWithoutArgs(f)` | Invoke `f`, which can be a global/static function or a functor. `f` must take no arguments. |
| `InvokeWithoutArgs(object_pointer, &class::method)` | Invoke the method on the object, which takes no arguments. |
| `InvokeArgument<N>(arg1, arg2, ..., argk)` | Invoke the mock function's `N`-th (0-based) argument, which must be a function or a functor, with the `k` arguments. |
<!-- mdformat on -->
The return value of the invoked function is used as the return value of the
action.
When defining a callable to be used with `Invoke*()`, you can declare any unused
parameters as `Unused`:
```cpp
using ::testing::Invoke;
double Distance(Unused, double x, double y) { return sqrt(x*x + y*y); }
...
EXPECT_CALL(mock, Foo("Hi", _, _)).WillOnce(Invoke(Distance));
```
`Invoke(callback)` and `InvokeWithoutArgs(callback)` take ownership of
`callback`, which must be permanent. The type of `callback` must be a base
callback type instead of a derived one, e.g.
```cpp
BlockingClosure* done = new BlockingClosure;
... Invoke(done) ...; // This won't compile!
Closure* done2 = new BlockingClosure;
... Invoke(done2) ...; // This works.
```
In `InvokeArgument<N>(...)`, if an argument needs to be passed by reference,
wrap it inside `ByRef()`. For example,
```cpp
using ::testing::ByRef;
using ::testing::InvokeArgument;
...
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
<!-- mdformat off(no multiline tables) -->
| Matcher | Description |
| :------------ | :----------------------------------------------------- |
| `DoDefault()` | Do the default action (specified by `ON_CALL()` or the built-in one). |
<!-- mdformat on -->
**Note:** due to technical reasons, `DoDefault()` cannot be used inside a
composite action - trying to do so will result in a run-time error.
<!-- GOOGLETEST_CM0032 DO NOT DELETE -->
#### Composite Actions
<!-- mdformat off(no multiline tables) -->
| | |
| :----------------------------- | :------------------------------------------ |
| `DoAll(a1, a2, ..., an)` | Do all actions `a1` to `an` and return the result of `an` in each invocation. The first `n - 1` sub-actions must return void. |
| `IgnoreResult(a)` | Perform action `a` and ignore its result. `a` must not return void. |
| `WithArg<N>(a)` | Pass the `N`-th (0-based) argument of the mock function to action `a` and perform it. |
| `WithArgs<N1, N2, ..., Nk>(a)` | Pass the selected (0-based) arguments of the mock function to action `a` and perform it. |
| `WithoutArgs(a)` | Perform action `a` without any arguments. |
<!-- mdformat on -->
#### Defining Actions
<table border="1" cellspacing="0" cellpadding="1">
<tr>
<td>`struct SumAction {` <br>
&emsp;`template <typename T>` <br>
&emsp;`T operator()(T x, Ty) { return x + y; }` <br>
`};`
</td>
<td> Defines a generic functor that can be used as an action summing its
arguments. </td> </tr>
<tr>
</tr>
</table>
<!-- mdformat off(no multiline tables) -->
| | |
| :--------------------------------- | :-------------------------------------- |
| `ACTION(Sum) { return arg0 + arg1; }` | Defines an action `Sum()` to return the sum of the mock function's argument #0 and #1. |
| `ACTION_P(Plus, n) { return arg0 + n; }` | Defines an action `Plus(n)` to return the sum of the mock function's argument #0 and `n`. |
| `ACTION_Pk(Foo, p1, ..., pk) { statements; }` | Defines a parameterized action `Foo(p1, ..., pk)` to execute the given `statements`. |
<!-- mdformat on -->
The `ACTION*` macros cannot be used inside a function or class.
### Cardinalities {#CardinalityList}
These are used in `Times()` to specify how many times a mock function will be
called:
<!-- mdformat off(no multiline tables) -->
| | |
| :---------------- | :----------------------------------------------------- |
| `AnyNumber()` | The function can be called any number of times. |
| `AtLeast(n)` | The call is expected at least `n` times. |
| `AtMost(n)` | The call is expected at most `n` times. |
| `Between(m, n)` | The call is expected between `m` and `n` (inclusive) times. |
| `Exactly(n) or n` | The call is expected exactly `n` times. In particular, the call should never happen when `n` is 0. |
<!-- mdformat on -->
### Expectation Order
By default, the expectations can be matched in *any* order. If some or all
expectations must be matched in a given order, there are two ways to specify it.
They can be used either independently or together.
#### The After Clause {#AfterClause}
```cpp
using ::testing::Expectation;
...
Expectation init_x = EXPECT_CALL(foo, InitX());
Expectation init_y = EXPECT_CALL(foo, InitY());
EXPECT_CALL(foo, Bar())
.After(init_x, init_y);
```
says that `Bar()` can be called only after both `InitX()` and `InitY()` have
been called.
If you don't know how many pre-requisites an expectation has when you write it,
you can use an `ExpectationSet` to collect them:
```cpp
using ::testing::ExpectationSet;
...
ExpectationSet all_inits;
for (int i = 0; i < element_count; i++) {
all_inits += EXPECT_CALL(foo, InitElement(i));
}
EXPECT_CALL(foo, Bar())
.After(all_inits);
```
says that `Bar()` can be called only after all elements have been initialized
(but we don't care about which elements get initialized before the others).
Modifying an `ExpectationSet` after using it in an `.After()` doesn't affect the
meaning of the `.After()`.
#### Sequences {#UsingSequences}
When you have a long chain of sequential expectations, it's easier to specify
the order using **sequences**, which don't require you to given each expectation
in the chain a different name. *All expected calls* in the same sequence must
occur in the order they are specified.
```cpp
using ::testing::Return;
using ::testing::Sequence;
Sequence s1, s2;
...
EXPECT_CALL(foo, Reset())
.InSequence(s1, s2)
.WillOnce(Return(true));
EXPECT_CALL(foo, GetSize())
.InSequence(s1)
.WillOnce(Return(1));
EXPECT_CALL(foo, Describe(A<const char*>()))
.InSequence(s2)
.WillOnce(Return("dummy"));
```
says that `Reset()` must be called before *both* `GetSize()` *and* `Describe()`,
and the latter two can occur in any order.
To put many expectations in a sequence conveniently:
```cpp
using ::testing::InSequence;
{
InSequence seq;
EXPECT_CALL(...)...;
EXPECT_CALL(...)...;
...
EXPECT_CALL(...)...;
}
```
says that all expected calls in the scope of `seq` must occur in strict order.
The name `seq` is irrelevant.
### Verifying and Resetting a Mock
gMock will verify the expectations on a mock object when it is destructed, or
you can do it earlier:
```cpp
using ::testing::Mock;
...
// Verifies and removes the expectations on mock_obj;
// returns true if and only if successful.
Mock::VerifyAndClearExpectations(&mock_obj);
...
// Verifies and removes the expectations on mock_obj;
// also removes the default actions set by ON_CALL();
// returns true if and only if successful.
Mock::VerifyAndClear(&mock_obj);
```
You can also tell gMock that a mock object can be leaked and doesn't need to be
verified:
```cpp
Mock::AllowLeak(&mock_obj);
```
### Mock Classes
gMock defines a convenient mock class template
```cpp
class MockFunction<R(A1, ..., An)> {
public:
MOCK_METHOD(R, Call, (A1, ..., An));
};
```
See this [recipe](cook_book.md#using-check-points) for one application of it.
### Flags
<!-- mdformat off(no multiline tables) -->
| Flag | Description |
| :----------------------------- | :---------------------------------------- |
| `--gmock_catch_leaked_mocks=0` | Don't report leaked mock objects as failures. |
| `--gmock_verbose=LEVEL` | Sets the default verbosity level (`info`, `warning`, or `error`) of Google Mock messages. |
<!-- mdformat on -->

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,8 @@
# gMock for Dummies
## gMock for Dummies {#GMockForDummies}
## What Is gMock?
<!-- GOOGLETEST_CM0013 DO NOT DELETE -->
### What Is gMock?
When you write a prototype or test, often it's not feasible or wise to rely on
real objects entirely. A **mock object** implements the same interface as a real
@ -8,9 +10,9 @@ 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).
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:
**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
@ -37,7 +39,7 @@ When using gMock,
3. then you exercise code that uses the mock objects. gMock will catch any
violation to the expectations as soon as it arises.
## Why gMock?
### Why gMock?
While mock objects help you remove unnecessary dependencies in tests and make
them fast and reliable, using mocks manually in C++ is *hard*:
@ -51,9 +53,9 @@ them fast and reliable, using mocks manually in C++ is *hard*:
one.
In contrast, Java and Python programmers have some fine mock frameworks (jMock,
EasyMock, etc), which automate the creation of mocks. As a result, mocking is a
proven effective technique and widely adopted practice in those communities.
Having the right tool absolutely makes the difference.
EasyMock, [Mox](http://wtf/mox), etc), which automate the creation of mocks. As
a result, mocking is a proven effective technique and widely adopted practice in
those communities. Having the right tool absolutely makes the difference.
gMock was built to help C++ programmers. It was inspired by jMock and EasyMock,
but designed with C++'s specifics in mind. It is your friend if any of the
@ -83,11 +85,11 @@ We encourage you to use gMock as
* a *testing* tool to cut your tests' outbound dependencies and probe the
interaction between your module and its collaborators.
## Getting Started
### Getting Started
gMock is bundled with googletest.
## A Case for Mock Turtles
### A Case for Mock Turtles
Let's look at an example. Suppose you are developing a graphics program that
relies on a [LOGO](http://en.wikipedia.org/wiki/Logo_programming_language)-like
@ -104,7 +106,7 @@ the API in an interface (say, `Turtle`) and code to that interface:
```cpp
class Turtle {
...
virtual ~Turtle() {}
virtual ~Turtle() {};
virtual void PenUp() = 0;
virtual void PenDown() = 0;
virtual void Forward(int distance) = 0;
@ -133,20 +135,20 @@ 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
### Writing the Mock Class
If you are lucky, the mocks you need to use have already been implemented by
some nice people. If, however, you find yourself in the position to write a mock
class, relax - gMock turns this task into a fun game! (Well, almost.)
### How to Define It
#### How to Define It
Using the `Turtle` interface as example, here are the simple steps you need to
follow:
* Derive a class `MockTurtle` from `Turtle`.
* Take a *virtual* function of `Turtle` (while it's possible to
[mock non-virtual methods using templates](gmock_cook_book.md#MockingNonVirtualMethods),
[mock non-virtual methods using templates](cook_book.md#MockingNonVirtualMethods),
it's much more involved).
* In the `public:` section of the child class, write `MOCK_METHOD();`
* Now comes the fun part: you take the function signature, cut-and-paste it
@ -182,7 +184,7 @@ class MockTurtle : public Turtle {
You don't need to define these mock methods somewhere else - the `MOCK_METHOD`
macro will generate the definitions for you. It's that simple!
### Where to Put It
#### 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
@ -204,12 +206,14 @@ 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
<!-- GOOGLETEST_CM0029 DO NOT DELETE -->
### Using Mocks in Tests
Once you have a mock class, using it is easy. The typical work flow is:
1. Import the gMock names from the `testing` namespace such that you can use
them unqualified (You only have to do it once per file). Remember that
them unqualified (You only have to do it once per file. Remember that
namespaces are a good idea.
2. Create some mock objects.
3. Specify your expectations on them (How many times will a method be called?
@ -253,8 +257,8 @@ Stack trace:
...
```
**Tip 1:** If you run the test from an Emacs buffer, you can hit `<Enter>` on
the line number to jump right to the failed expectation.
**Tip 1:** If you run the test from an Emacs buffer, you can hit <Enter> on the
line number to jump right to the failed expectation.
**Tip 2:** If your mock objects are never deleted, the final verification won't
happen. Therefore it's a good idea to turn on the heap checker in your tests
@ -262,9 +266,8 @@ when you allocate mocks on the heap. You get that automatically if you use the
`gtest_main` library already.
**Important note:** gMock requires expectations to be set **before** the mock
functions are called, otherwise the behavior is **undefined**. Do not alternate
between calls to `EXPECT_CALL()` and calls to the mock functions, and do not set
any expectations on a mock after passing the mock to an API.
functions are called, otherwise the behavior is **undefined**. In particular,
you mustn't interleave `EXPECT_CALL()s` and calls to the mock functions.
This means `EXPECT_CALL()` should be read as expecting that a call will occur
*in the future*, not that a call has occurred. Why does gMock work like that?
@ -276,7 +279,7 @@ Admittedly, this test is contrived and doesn't do much. You can easily achieve
the same effect without using gMock. However, as we shall reveal soon, gMock
allows you to do *so much more* with the mocks.
## Setting Expectations
### 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
@ -285,7 +288,7 @@ to do it just right such that your test can catch exactly the kind of bugs you
intend it to catch. gMock provides the necessary means for you to do it "just
right."
### General Syntax
#### General Syntax
In gMock we use the `EXPECT_CALL()` macro to set an expectation on a mock
method. The general syntax is:
@ -311,8 +314,8 @@ EXPECT_CALL(mock_object, non-overloaded-method)
This syntax allows the test writer to specify "called with any arguments"
without explicitly specifying the number or types of arguments. To avoid
unintended ambiguity, this syntax may only be used for methods that are not
overloaded.
unintended ambiguity, this syntax may only be used for methods which are not
overloaded
Either form of the macro can be followed by some optional *clauses* that provide
more information about the expectation. We'll discuss how each clause works in
@ -335,13 +338,12 @@ 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).
{: .callout .note}
**Note:** Why do we use a macro to do this? Well it serves two purposes: first
it makes expectations easily identifiable (either by `grep` or by a human
it makes expectations easily identifiable (either by `gsearch` or by a human
reader), and second it allows gMock to include the source file location of a
failed expectation in messages, making debugging easier.
### Matchers: What Arguments Do We Expect?
#### Matchers: What Arguments Do We Expect?
When a mock function takes arguments, we may specify what arguments we are
expecting, for example:
@ -372,8 +374,8 @@ convenient way of saying "any value".
In the above examples, `100` and `50` are also matchers; implicitly, they are
the same as `Eq(100)` and `Eq(50)`, which specify that the argument must be
equal (using `operator==`) to the matcher argument. There are many
[built-in matchers](reference/matchers.md) for common types (as well as
[custom matchers](gmock_cook_book.md#NewMatchers)); for example:
[built-in matchers](#MatcherList) for common types (as well as
[custom matchers](cook_book.md#NewMatchers)); for example:
```cpp
using ::testing::Ge;
@ -395,9 +397,9 @@ EXPECT_CALL(turtle, GoTo);
This works for all non-overloaded methods; if a method is overloaded, you need
to help gMock resolve which overload is expected by specifying the number of
arguments and possibly also the
[types of the arguments](gmock_cook_book.md#SelectOverload).
[types of the arguments](cook_book.md#SelectOverload).
### Cardinalities: How Many Times Will It Be Called?
#### 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
@ -412,7 +414,7 @@ called.
We've seen `AtLeast(n)` as an example of fuzzy cardinalities earlier. For the
list of built-in cardinalities you can use, see
[here](gmock_cheat_sheet.md#CardinalityList).
[here](cheat_sheet.md#CardinalityList).
The `Times()` clause can be omitted. **If you omit `Times()`, gMock will infer
the cardinality for you.** The rules are easy to remember:
@ -427,7 +429,7 @@ the cardinality for you.** The rules are easy to remember:
**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?
#### 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
@ -480,8 +482,8 @@ 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](gmock_cook_book.md#using-actions).
reference using `ReturnRef(*variable*)`, or invoke a pre-defined function, among
[others](cook_book.md#using-actions).
**Important note:** The `EXPECT_CALL()` statement evaluates the action clause
only once, even though the action may be performed many times. Therefore you
@ -501,7 +503,7 @@ always return 100 as `n++` is only evaluated once. Similarly, `Return(new Foo)`
will create a new `Foo` object when the `EXPECT_CALL()` is executed, and will
return the same pointer every time. If you want the side effect to happen every
time, you need to define a custom action, which we'll teach in the
[cook book](gmock_cook_book.md).
[cook book](http://<!-- GOOGLETEST_CM0012 DO NOT DELETE -->).
Time for another quiz! What do you think the following means?
@ -520,7 +522,7 @@ will be taken afterwards. So the right answer is that `turtle.GetY()` will
return 100 the first time, but **return 0 from the second time on**, as
returning 0 is the default action for `int` functions.
### Using Multiple Expectations {#MultiExpectations}
#### Using Multiple Expectations {#MultiExpectations}
So far we've only shown examples where you have a single expectation. More
realistically, you'll specify expectations on multiple mock methods which may be
@ -545,7 +547,6 @@ 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.
{: .callout .note}
**Note:** Why does gMock search for a match in the *reverse* order of the
expectations? The reason is that this allows a user to set up the default
expectations in a mock object's constructor or the test fixture's set-up phase
@ -554,16 +555,15 @@ 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.
{: .callout .tip}
**Tip:** It is very common to start with a catch-all expectation for a method
and `Times(AnyNumber())` (omitting arguments, or with `_` for all arguments, if
overloaded). This makes any calls to the method expected. This is not necessary
for methods that are not mentioned at all (these are "uninteresting"), but is
useful for methods that have some expectations, but for which other calls are
ok. See
[Understanding Uninteresting vs Unexpected Calls](gmock_cook_book.md#uninteresting-vs-unexpected).
[Understanding Uninteresting vs Unexpected Calls](cook_book.md#uninteresting-vs-unexpected).
### Ordered vs Unordered Calls {#OrderedCalls}
#### Ordered vs Unordered Calls {#OrderedCalls}
By default, an expectation can match a call even though an earlier expectation
hasn't been satisfied. In other words, the calls don't have to occur in the
@ -598,9 +598,9 @@ order as written. If a call is made out-of-order, it will be an error.
(What if you care about the relative order of some of the calls, but not all of
them? Can you specify an arbitrary partial order? The answer is ... yes! The
details can be found [here](gmock_cook_book.md#OrderedCalls).)
details can be found [here](cook_book.md#OrderedCalls).)
### All Expectations Are Sticky (Unless Said Otherwise) {#StickyExpectations}
#### All Expectations Are Sticky (Unless Said Otherwise) {#StickyExpectations}
Now let's do a quick quiz to see how well you can use this mock stuff already.
How would you test that the turtle is asked to go to the origin *exactly twice*
@ -688,7 +688,7 @@ 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
#### 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
@ -697,4 +697,4 @@ For example, in some tests we may not care about how many times `GetX()` and
In gMock, if you are not interested in a method, just don't say anything about
it. If a call to this method occurs, you'll see a warning in the test output,
but it won't be a failure. This is called "naggy" behavior; to change, see
[The Nice, the Strict, and the Naggy](gmock_cook_book.md#NiceStrictNaggy).
[The Nice, the Strict, and the Naggy](cook_book.md#NiceStrictNaggy).

View File

@ -1,9 +1,11 @@
# Legacy gMock FAQ
## Legacy gMock FAQ {#GMockFaq}
<!-- GOOGLETEST_CM0021 DO NOT DELETE -->
### When I call a method on my mock object, the method for the real object is invoked instead. What's the problem?
In order for a method to be mocked, it must be *virtual*, unless you use the
[high-perf dependency injection technique](gmock_cook_book.md#MockingNonVirtualMethods).
[high-perf dependency injection technique](#MockingNonVirtualMethods).
### Can I mock a variadic function?
@ -79,6 +81,8 @@ void Bar(int* p); // Neither p nor *p is const.
void Bar(const int* p); // p is not const, but *p is.
```
<!-- GOOGLETEST_CM0030 DO NOT DELETE -->
### I can't figure out why gMock thinks my expectations are not satisfied. What should I do?
You might want to run your test with `--gmock_verbose=info`. This flag lets
@ -87,7 +91,7 @@ trace, you'll gain insights on why the expectations you set are not met.
If you see the message "The mock function has no default action set, and its
return type has no default value set.", then try
[adding a default action](gmock_cheat_sheet.md#OnCall). Due to a known issue,
[adding a default action](for_dummies.md#DefaultValue). Due to a known issue,
unexpected calls on mocks without default actions don't print out a detailed
comparison between the actual arguments and the expected arguments.
@ -122,6 +126,8 @@ using ::testing::_;
.Times(0);
```
<!-- GOOGLETEST_CM0031 DO NOT DELETE -->
### I have a failed test where gMock tells me TWICE that a particular expectation is not satisfied. Isn't this redundant?
When gMock detects a failure, it prints relevant information (the mock function
@ -380,8 +386,8 @@ doesn't say what the return value should be. You need `DoAll()` to chain a
`SetArgPointee()` with a `Return()` that provides a value appropriate to the API
being mocked.
See this [recipe](gmock_cook_book.md#mocking-side-effects) for more details and
an example.
See this [recipe](cook_book.md#mocking-side-effects) for more details and an
example.
### I have a huge mock class, and Microsoft Visual C++ runs out of memory when compiling it. What can I do?

View File

@ -30,103 +30,12 @@
// Google Mock - a framework for writing C++ mock classes.
//
// The ACTION* family of macros can be used in a namespace scope to
// define custom actions easily. The syntax:
//
// ACTION(name) { statements; }
//
// will define an action with the given name that executes the
// statements. The value returned by the statements will be used as
// the return value of the action. Inside the statements, you can
// refer to the K-th (0-based) argument of the mock function by
// 'argK', and refer to its type by 'argK_type'. For example:
//
// ACTION(IncrementArg1) {
// arg1_type temp = arg1;
// return ++(*temp);
// }
//
// allows you to write
//
// ...WillOnce(IncrementArg1());
//
// You can also refer to the entire argument tuple and its type by
// 'args' and 'args_type', and refer to the mock function type and its
// return type by 'function_type' and 'return_type'.
//
// Note that you don't need to specify the types of the mock function
// arguments. However rest assured that your code is still type-safe:
// you'll get a compiler error if *arg1 doesn't support the ++
// operator, or if the type of ++(*arg1) isn't compatible with the
// mock function's return type, for example.
//
// Sometimes you'll want to parameterize the action. For that you can use
// another macro:
//
// ACTION_P(name, param_name) { statements; }
//
// For example:
//
// ACTION_P(Add, n) { return arg0 + n; }
//
// will allow you to write:
//
// ...WillOnce(Add(5));
//
// Note that you don't need to provide the type of the parameter
// either. If you need to reference the type of a parameter named
// 'foo', you can write 'foo_type'. For example, in the body of
// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type
// of 'n'.
//
// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P10 to support
// multi-parameter actions.
//
// For the purpose of typing, you can view
//
// ACTION_Pk(Foo, p1, ..., pk) { ... }
//
// as shorthand for
//
// template <typename p1_type, ..., typename pk_type>
// FooActionPk<p1_type, ..., pk_type> Foo(p1_type p1, ..., pk_type pk) { ... }
//
// In particular, you can provide the template type arguments
// explicitly when invoking Foo(), as in Foo<long, bool>(5, false);
// although usually you can rely on the compiler to infer the types
// for you automatically. You can assign the result of expression
// Foo(p1, ..., pk) to a variable of type FooActionPk<p1_type, ...,
// pk_type>. This can be useful when composing actions.
//
// You can also overload actions with different numbers of parameters:
//
// ACTION_P(Plus, a) { ... }
// ACTION_P2(Plus, a, b) { ... }
//
// While it's tempting to always use the ACTION* macros when defining
// a new action, you should also consider implementing ActionInterface
// or using MakePolymorphicAction() instead, especially if you need to
// use the action a lot. While these approaches require more work,
// they give you more control on the types of the mock function
// arguments and the action parameters, which in general leads to
// better compiler error messages that pay off in the long run. They
// also allow overloading actions based on parameter types (as opposed
// to just based on the number of parameters).
//
// CAVEAT:
//
// ACTION*() can only be used in a namespace scope as templates cannot be
// declared inside of a local class.
// Users can, however, define any local functors (e.g. a lambda) that
// can be used as actions.
//
// MORE INFORMATION:
//
// To learn more about using these macros, please search for 'ACTION' on
// https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md
// This file implements some commonly used actions.
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
#ifndef _WIN32_WCE
# include <errno.h>
@ -136,13 +45,11 @@
#include <functional>
#include <memory>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
#include "gmock/internal/gmock-internal-utils.h"
#include "gmock/internal/gmock-port.h"
#include "gmock/internal/gmock-pp.h"
#ifdef _MSC_VER
# pragma warning(push)
@ -255,17 +162,13 @@ GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned int, 0U);
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed int, 0);
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long, 0UL); // NOLINT
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long, 0L); // NOLINT
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long long, 0); // NOLINT
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long long, 0); // NOLINT
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(UInt64, 0);
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(Int64, 0);
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(float, 0);
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(double, 0);
#undef GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_
// Simple two-arg form of std::disjunction.
template <typename P, typename Q>
using disjunction = typename ::std::conditional<P::value, P, Q>::type;
} // namespace internal
// When an unexpected function call is encountered, Google Mock will
@ -447,9 +350,6 @@ class Action {
}
};
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;
@ -461,14 +361,10 @@ class Action {
// Construct an Action from a specified callable.
// This cannot take std::function directly, because then Action would not be
// directly constructible from lambda (it would require two conversions).
template <
typename G,
typename = typename std::enable_if<internal::disjunction<
IsCompatibleFunctor<G>, std::is_constructible<std::function<Result()>,
G>>::value>::type>
Action(G&& fun) { // NOLINT
Init(::std::forward<G>(fun), IsCompatibleFunctor<G>());
}
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
// Constructs an Action from its implementation.
explicit Action(ActionInterface<F>* impl)
@ -500,26 +396,6 @@ class Action {
template <typename G>
friend class Action;
template <typename G>
void Init(G&& g, ::std::true_type) {
fun_ = ::std::forward<G>(g);
}
template <typename G>
void Init(G&& g, ::std::false_type) {
fun_ = IgnoreArgs<typename ::std::decay<G>::type>{::std::forward<G>(g)};
}
template <typename FunctionImpl>
struct IgnoreArgs {
template <typename... Args>
Result operator()(const Args&...) const {
return function_impl();
}
FunctionImpl function_impl;
};
// fun_ is an empty function if and only if this is the DoDefault() action.
::std::function<F> fun_;
};
@ -570,9 +446,13 @@ class PolymorphicAction {
private:
Impl impl_;
GTEST_DISALLOW_ASSIGN_(MonomorphicImpl);
};
Impl impl_;
GTEST_DISALLOW_ASSIGN_(PolymorphicAction);
};
// Creates an Action from its implementation and returns it. The
@ -713,9 +593,13 @@ class ReturnAction {
private:
bool performed_;
const std::shared_ptr<R> wrapper_;
GTEST_DISALLOW_ASSIGN_(Impl);
};
const std::shared_ptr<R> value_;
GTEST_DISALLOW_ASSIGN_(ReturnAction);
};
// Implements the ReturnNull() action.
@ -776,9 +660,13 @@ class ReturnRefAction {
private:
T& ref_;
GTEST_DISALLOW_ASSIGN_(Impl);
};
T& ref_;
GTEST_DISALLOW_ASSIGN_(ReturnRefAction);
};
// Implements the polymorphic ReturnRefOfCopy(x) action, which can be
@ -819,39 +707,13 @@ class ReturnRefOfCopyAction {
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);
}
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>();
GTEST_DISALLOW_ASSIGN_(ReturnRefOfCopyAction);
};
// Implements the polymorphic DoDefault() action.
@ -878,6 +740,8 @@ class AssignAction {
private:
T1* const ptr_;
const T2 value_;
GTEST_DISALLOW_ASSIGN_(AssignAction);
};
#if !GTEST_OS_WINDOWS_MOBILE
@ -899,6 +763,8 @@ class SetErrnoAndReturnAction {
private:
const int errno_;
const T result_;
GTEST_DISALLOW_ASSIGN_(SetErrnoAndReturnAction);
};
#endif // !GTEST_OS_WINDOWS_MOBILE
@ -950,8 +816,7 @@ struct InvokeMethodWithoutArgsAction {
Class* const obj_ptr;
const MethodPtr method_ptr;
using ReturnType =
decltype((std::declval<Class*>()->*std::declval<MethodPtr>())());
using ReturnType = typename std::result_of<MethodPtr(Class*)>::type;
template <typename... Args>
ReturnType operator()(const Args&...) const {
@ -1004,9 +869,13 @@ class IgnoreResultAction {
OriginalFunction;
const Action<OriginalFunction> action_;
GTEST_DISALLOW_ASSIGN_(Impl);
};
const A action_;
GTEST_DISALLOW_ASSIGN_(IgnoreResultAction);
};
template <typename InnerAction, size_t... I>
@ -1017,8 +886,7 @@ struct WithArgsAction {
// We use the conversion operator to detect the signature of the inner Action.
template <typename R, typename... Args>
operator Action<R(Args...)>() const { // NOLINT
using TupleType = std::tuple<Args...>;
Action<R(typename std::tuple_element<I, TupleType>::type...)>
Action<R(typename std::tuple_element<I, std::tuple<Args...>>::type...)>
converted(action);
return [converted](Args... args) -> R {
@ -1031,13 +899,9 @@ struct WithArgsAction {
template <typename... Actions>
struct DoAllAction {
private:
template <typename T>
using NonFinalType =
typename std::conditional<std::is_scalar<T>::value, T, const T&>::type;
template <typename ActionT, size_t... I>
std::vector<ActionT> Convert(IndexSequence<I...>) const {
return {ActionT(std::get<I>(actions))...};
template <typename... Args, size_t... I>
std::vector<Action<void(Args...)>> Convert(IndexSequence<I...>) const {
return {std::get<I>(actions)...};
}
public:
@ -1046,121 +910,21 @@ struct DoAllAction {
template <typename R, typename... Args>
operator Action<R(Args...)>() const { // NOLINT
struct Op {
std::vector<Action<void(NonFinalType<Args>...)>> converted;
std::vector<Action<void(Args...)>> converted;
Action<R(Args...)> last;
R operator()(Args... args) const {
auto tuple_args = std::forward_as_tuple(std::forward<Args>(args)...);
for (auto& a : converted) {
a.Perform(tuple_args);
}
return last.Perform(std::move(tuple_args));
return last.Perform(tuple_args);
}
};
return Op{Convert<Action<void(NonFinalType<Args>...)>>(
MakeIndexSequence<sizeof...(Actions) - 1>()),
return Op{Convert<Args...>(MakeIndexSequence<sizeof...(Actions) - 1>()),
std::get<sizeof...(Actions) - 1>(actions)};
}
};
template <typename T, typename... Params>
struct ReturnNewAction {
T* operator()() const {
return internal::Apply(
[](const Params&... unpacked_params) {
return new T(unpacked_params...);
},
params);
}
std::tuple<Params...> params;
};
template <size_t k>
struct ReturnArgAction {
template <typename... Args>
auto operator()(const Args&... args) const ->
typename std::tuple_element<k, std::tuple<Args...>>::type {
return std::get<k>(std::tie(args...));
}
};
template <size_t k, typename Ptr>
struct SaveArgAction {
Ptr pointer;
template <typename... Args>
void operator()(const Args&... args) const {
*pointer = std::get<k>(std::tie(args...));
}
};
template <size_t k, typename Ptr>
struct SaveArgPointeeAction {
Ptr pointer;
template <typename... Args>
void operator()(const Args&... args) const {
*pointer = *std::get<k>(std::tie(args...));
}
};
template <size_t k, typename T>
struct SetArgRefereeAction {
T value;
template <typename... Args>
void operator()(Args&&... args) const {
using argk_type =
typename ::std::tuple_element<k, std::tuple<Args...>>::type;
static_assert(std::is_lvalue_reference<argk_type>::value,
"Argument must be a reference type.");
std::get<k>(std::tie(args...)) = value;
}
};
template <size_t k, typename I1, typename I2>
struct SetArrayArgumentAction {
I1 first;
I2 last;
template <typename... Args>
void operator()(const Args&... args) const {
auto value = std::get<k>(std::tie(args...));
for (auto it = first; it != last; ++it, (void)++value) {
*value = *it;
}
}
};
template <size_t k>
struct DeleteArgAction {
template <typename... Args>
void operator()(const Args&... args) const {
delete std::get<k>(std::tie(args...));
}
};
template <typename Ptr>
struct ReturnPointeeAction {
Ptr pointer;
template <typename... Args>
auto operator()(const Args&...) const -> decltype(*pointer) {
return *pointer;
}
};
#if GTEST_HAS_EXCEPTIONS
template <typename T>
struct ThrowAction {
T exception;
// We use a conversion operator to adapt to any return type.
template <typename R, typename... Args>
operator Action<R(Args...)>() const { // NOLINT
T copy = exception;
return [copy](Args...) -> R { throw copy; };
}
};
#endif // GTEST_HAS_EXCEPTIONS
} // namespace internal
// An Unused object can be implicitly constructed from ANY value.
@ -1196,8 +960,7 @@ struct ThrowAction {
typedef internal::IgnoredValue Unused;
// Creates an action that does actions a1, a2, ..., sequentially in
// each invocation. All but the last action will have a readonly view of the
// arguments.
// each invocation.
template <typename... Action>
internal::DoAllAction<typename std::decay<Action>::type...> DoAll(
Action&&... action) {
@ -1259,10 +1022,6 @@ 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.
@ -1280,23 +1039,6 @@ internal::ByMoveWrapper<R> ByMove(R x) {
return internal::ByMoveWrapper<R>(std::move(x));
}
// Creates an action that returns an element of `vals`. Calling this action will
// repeatedly return the next value from `vals` until it reaches the end and
// will restart from the beginning.
template <typename T>
internal::ReturnRoundRobinAction<T> ReturnRoundRobin(std::vector<T> vals) {
return internal::ReturnRoundRobinAction<T>(std::move(vals));
}
// Creates an action that returns an element of `vals`. Calling this action will
// repeatedly return the next value from `vals` until it reaches the end and
// will restart from the beginning.
template <typename T>
internal::ReturnRoundRobinAction<T> ReturnRoundRobin(
std::initializer_list<T> vals) {
return internal::ReturnRoundRobinAction<T>(std::vector<T>(vals));
}
// Creates an action that does the default action for the give mock function.
inline internal::DoDefaultAction DoDefault() {
return internal::DoDefaultAction();
@ -1305,14 +1047,14 @@ 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>
internal::SetArgumentPointeeAction<N, T> SetArgPointee(T value) {
return {std::move(value)};
internal::SetArgumentPointeeAction<N, T> SetArgPointee(T x) {
return {std::move(x)};
}
// The following version is DEPRECATED.
template <size_t N, typename T>
internal::SetArgumentPointeeAction<N, T> SetArgumentPointee(T value) {
return {std::move(value)};
internal::SetArgumentPointeeAction<N, T> SetArgumentPointee(T x) {
return {std::move(x)};
}
// Creates an action that sets a pointer referent to a given value.
@ -1390,296 +1132,11 @@ inline ::std::reference_wrapper<T> ByRef(T& l_value) { // NOLINT
return ::std::reference_wrapper<T>(l_value);
}
// The ReturnNew<T>(a1, a2, ..., a_k) action returns a pointer to a new
// instance of type T, constructed on the heap with constructor arguments
// a1, a2, ..., and a_k. The caller assumes ownership of the returned value.
template <typename T, typename... Params>
internal::ReturnNewAction<T, typename std::decay<Params>::type...> ReturnNew(
Params&&... params) {
return {std::forward_as_tuple(std::forward<Params>(params)...)};
}
// Action ReturnArg<k>() returns the k-th argument of the mock function.
template <size_t k>
internal::ReturnArgAction<k> ReturnArg() {
return {};
}
// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
// mock function to *pointer.
template <size_t k, typename Ptr>
internal::SaveArgAction<k, Ptr> SaveArg(Ptr pointer) {
return {pointer};
}
// Action SaveArgPointee<k>(pointer) saves the value pointed to
// by the k-th (0-based) argument of the mock function to *pointer.
template <size_t k, typename Ptr>
internal::SaveArgPointeeAction<k, Ptr> SaveArgPointee(Ptr pointer) {
return {pointer};
}
// Action SetArgReferee<k>(value) assigns 'value' to the variable
// referenced by the k-th (0-based) argument of the mock function.
template <size_t k, typename T>
internal::SetArgRefereeAction<k, typename std::decay<T>::type> SetArgReferee(
T&& value) {
return {std::forward<T>(value)};
}
// Action SetArrayArgument<k>(first, last) copies the elements in
// source range [first, last) to the array pointed to by the k-th
// (0-based) argument, which can be either a pointer or an
// iterator. The action does not take ownership of the elements in the
// source range.
template <size_t k, typename I1, typename I2>
internal::SetArrayArgumentAction<k, I1, I2> SetArrayArgument(I1 first,
I2 last) {
return {first, last};
}
// Action DeleteArg<k>() deletes the k-th (0-based) argument of the mock
// function.
template <size_t k>
internal::DeleteArgAction<k> DeleteArg() {
return {};
}
// This action returns the value pointed to by 'pointer'.
template <typename Ptr>
internal::ReturnPointeeAction<Ptr> ReturnPointee(Ptr pointer) {
return {pointer};
}
// Action Throw(exception) can be used in a mock function of any type
// to throw the given exception. Any copyable value can be thrown.
#if GTEST_HAS_EXCEPTIONS
template <typename T>
internal::ThrowAction<typename std::decay<T>::type> Throw(T&& exception) {
return {std::forward<T>(exception)};
}
#endif // GTEST_HAS_EXCEPTIONS
namespace internal {
// A macro from the ACTION* family (defined later in gmock-generated-actions.h)
// defines an action that can be used in a mock function. Typically,
// these actions only care about a subset of the arguments of the mock
// function. For example, if such an action only uses the second
// argument, it can be used in any mock function that takes >= 2
// arguments where the type of the second argument is compatible.
//
// Therefore, the action implementation must be prepared to take more
// arguments than it needs. The ExcessiveArg type is used to
// represent those excessive arguments. In order to keep the compiler
// error messages tractable, we define it in the testing namespace
// instead of testing::internal. However, this is an INTERNAL TYPE
// and subject to change without notice, so a user MUST NOT USE THIS
// TYPE DIRECTLY.
struct ExcessiveArg {};
// Builds an implementation of an Action<> for some particular signature, using
// a class defined by an ACTION* macro.
template <typename F, typename Impl> struct ActionImpl;
template <typename Impl>
struct ImplBase {
struct Holder {
// Allows each copy of the Action<> to get to the Impl.
explicit operator const Impl&() const { return *ptr; }
std::shared_ptr<Impl> ptr;
};
using type = typename std::conditional<std::is_constructible<Impl>::value,
Impl, Holder>::type;
};
template <typename R, typename... Args, typename Impl>
struct ActionImpl<R(Args...), Impl> : ImplBase<Impl>::type {
using Base = typename ImplBase<Impl>::type;
using function_type = R(Args...);
using args_type = std::tuple<Args...>;
ActionImpl() = default; // Only defined if appropriate for Base.
explicit ActionImpl(std::shared_ptr<Impl> impl) : Base{std::move(impl)} { }
R operator()(Args&&... arg) const {
static constexpr size_t kMaxArgs =
sizeof...(Args) <= 10 ? sizeof...(Args) : 10;
return Apply(MakeIndexSequence<kMaxArgs>{},
MakeIndexSequence<10 - kMaxArgs>{},
args_type{std::forward<Args>(arg)...});
}
template <std::size_t... arg_id, std::size_t... excess_id>
R Apply(IndexSequence<arg_id...>, IndexSequence<excess_id...>,
const args_type& args) const {
// Impl need not be specific to the signature of action being implemented;
// only the implementing function body needs to have all of the specific
// types instantiated. Up to 10 of the args that are provided by the
// args_type get passed, followed by a dummy of unspecified type for the
// remainder up to 10 explicit args.
static 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)) { \
return full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>( \
GMOCK_ACTION_GVALUE_PARAMS_(params)); \
} \
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
template <typename function_type, typename return_type, typename args_type, \
GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
return_type full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>::gmock_Impl:: \
gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
} // namespace internal
// Similar to GMOCK_INTERNAL_ACTION, but no bound parameters are stored.
#define ACTION(name) \
class name##Action { \
public: \
explicit name##Action() noexcept {} \
name##Action(const name##Action&) noexcept {} \
template <typename F> \
operator ::testing::Action<F>() const { \
return ::testing::internal::MakeAction<F, gmock_Impl>(); \
} \
private: \
class gmock_Impl { \
public: \
template <typename function_type, typename return_type, \
typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \
}; \
}; \
inline name##Action name() GTEST_MUST_USE_RESULT_; \
inline name##Action name() { return name##Action(); } \
template <typename function_type, typename return_type, typename args_type, \
GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
return_type name##Action::gmock_Impl::gmock_PerformImpl( \
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
#define ACTION_P(name, ...) \
GMOCK_INTERNAL_ACTION(name, name##ActionP, (__VA_ARGS__))
#define ACTION_P2(name, ...) \
GMOCK_INTERNAL_ACTION(name, name##ActionP2, (__VA_ARGS__))
#define ACTION_P3(name, ...) \
GMOCK_INTERNAL_ACTION(name, name##ActionP3, (__VA_ARGS__))
#define ACTION_P4(name, ...) \
GMOCK_INTERNAL_ACTION(name, name##ActionP4, (__VA_ARGS__))
#define ACTION_P5(name, ...) \
GMOCK_INTERNAL_ACTION(name, name##ActionP5, (__VA_ARGS__))
#define ACTION_P6(name, ...) \
GMOCK_INTERNAL_ACTION(name, name##ActionP6, (__VA_ARGS__))
#define ACTION_P7(name, ...) \
GMOCK_INTERNAL_ACTION(name, name##ActionP7, (__VA_ARGS__))
#define ACTION_P8(name, ...) \
GMOCK_INTERNAL_ACTION(name, name##ActionP8, (__VA_ARGS__))
#define ACTION_P9(name, ...) \
GMOCK_INTERNAL_ACTION(name, name##ActionP9, (__VA_ARGS__))
#define ACTION_P10(name, ...) \
GMOCK_INTERNAL_ACTION(name, name##ActionP10, (__VA_ARGS__))
} // namespace testing
#ifdef _MSC_VER
# pragma warning(pop)
#endif
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_

View File

@ -34,8 +34,10 @@
// cardinalities can be defined by the user implementing the
// CardinalityInterface interface if necessary.
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
#include <limits.h>
#include <memory>
@ -152,4 +154,4 @@ inline Cardinality MakeCardinality(const CardinalityInterface* c) {
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_

View File

@ -31,80 +31,14 @@
//
// This file implements MOCK_METHOD.
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
// GOOGLETEST_CM0002 DO NOT DELETE
#include <type_traits> // IWYU pragma: keep
#include <utility> // IWYU pragma: keep
#ifndef THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
#define THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
#include "gmock/gmock-spec-builders.h"
#include "gmock/internal/gmock-internal-utils.h"
#include "gmock/gmock-generated-function-mockers.h" // NOLINT
#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_PP_VARIADIC_CALL(GMOCK_INTERNAL_MOCK_METHOD_ARG_, __VA_ARGS__)
@ -117,18 +51,16 @@ using internal::FunctionMocker;
#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), \
#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_HAS_NOEXCEPT(_Spec), GMOCK_INTERNAL_GET_CALLTYPE(_Spec), \
(GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)))
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_5(...) \
@ -162,20 +94,21 @@ using internal::FunctionMocker;
::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.")
_N) " arguments. Parenthesize all types with unproctected 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) \
_Override, _Final, _Noexcept, \
_CallType, _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_PP_IF(_Constness, const, ) GMOCK_PP_IF(_Noexcept, noexcept, ) \
GMOCK_PP_IF(_Override, override, ) \
GMOCK_PP_IF(_Final, final, ) { \
GMOCK_MOCKER_(_N, _Constness, _MethodName) \
.SetOwnerAndName(this, #_MethodName); \
return GMOCK_MOCKER_(_N, _Constness, _MethodName) \
@ -183,7 +116,7 @@ using internal::FunctionMocker;
} \
::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_PP_IF(_Constness, const, ) { \
GMOCK_MOCKER_(_N, _Constness, _MethodName).RegisterOwner(this); \
return GMOCK_MOCKER_(_N, _Constness, _MethodName) \
.With(GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_ARGUMENT, , _N)); \
@ -191,10 +124,11 @@ using internal::FunctionMocker;
::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_PP_REMOVE_PARENS(_Signature)>*) \
const GMOCK_PP_IF(_Noexcept, noexcept, ) { \
return GMOCK_PP_CAT(::testing::internal::AdjustConstness_, \
GMOCK_PP_IF(_Constness, const, ))(this) \
->gmock_##_MethodName(GMOCK_PP_REPEAT( \
GMOCK_INTERNAL_A_MATCHER_ARGUMENT, _Signature, _N)); \
} \
mutable ::testing::FunctionMocker<GMOCK_PP_REMOVE_PARENS(_Signature)> \
@ -202,7 +136,7 @@ using internal::FunctionMocker;
#define GMOCK_INTERNAL_EXPAND(...) __VA_ARGS__
// Valid modifiers.
// Five Valid modifiers.
#define GMOCK_INTERNAL_HAS_CONST(_Tuple) \
GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_CONST, ~, _Tuple))
@ -213,48 +147,22 @@ using internal::FunctionMocker;
#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_HAS_NOEXCEPT(_Tuple) \
GMOCK_PP_HAS_COMMA( \
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_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(_Tuple) \
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_CALLTYPE_IMPL, ~, _Tuple)
#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( \
#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_INTERNAL_IS_CALLTYPE(_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) \
@ -272,43 +180,37 @@ using internal::FunctionMocker;
#define GMOCK_INTERNAL_DETECT_FINAL_I_final ,
// TODO(iserna): Maybe noexcept should accept an argument here as well.
#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_GET_CALLTYPE_IMPL(_i, _, _elem) \
GMOCK_PP_IF(GMOCK_INTERNAL_IS_CALLTYPE(_elem), \
GMOCK_INTERNAL_GET_VALUE_CALLTYPE, GMOCK_PP_EMPTY) \
(_elem)
#define GMOCK_INTERNAL_DETECT_REF_I_ref ,
// TODO(iserna): GMOCK_INTERNAL_IS_CALLTYPE and
// GMOCK_INTERNAL_GET_VALUE_CALLTYPE needed more expansions to work on windows
// maybe they can be simplified somehow.
#define GMOCK_INTERNAL_IS_CALLTYPE(_arg) \
GMOCK_INTERNAL_IS_CALLTYPE_I( \
GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg))
#define GMOCK_INTERNAL_IS_CALLTYPE_I(_arg) GMOCK_PP_IS_ENCLOSED_PARENS(_arg)
#define GMOCK_INTERNAL_UNPACK_ref(x) x
#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE(_arg) \
GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I( \
GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg))
#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I(_arg) \
GMOCK_PP_CAT(GMOCK_PP_IDENTITY, _arg)
#define GMOCK_INTERNAL_DETECT_CALLTYPE(_i, _, _elem) \
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_CALLTYPE_I_, _elem)
#define GMOCK_INTERNAL_IS_CALLTYPE_HELPER_Calltype
#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_SIGNATURE(_Ret, _Args) \
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) \
@ -316,196 +218,36 @@ using internal::FunctionMocker;
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)) \
#define GMOCK_INTERNAL_PARAMETER(_i, _Signature, _) \
GMOCK_PP_COMMA_IF(_i) \
GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_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_FORWARD_ARG(_i, _Signature, _) \
GMOCK_PP_COMMA_IF(_i) \
::std::forward<GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_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)) \
#define GMOCK_INTERNAL_MATCHER_PARAMETER(_i, _Signature, _) \
GMOCK_PP_COMMA_IF(_i) \
GMOCK_INTERNAL_MATCHER_O(typename, GMOCK_PP_INC(_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_A_MATCHER_ARGUMENT(_i, _Signature, _) \
GMOCK_PP_COMMA_IF(_i) \
::testing::A<GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_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_ARG_O(_tn, _i, ...) GMOCK_ARG_(_tn, _i, __VA_ARGS__)
#define GMOCK_INTERNAL_MATCHER_O(_i, ...) \
const ::testing::Matcher<typename ::testing::internal::Function< \
__VA_ARGS__>::template Arg<_i>::type>&
#define GMOCK_INTERNAL_MATCHER_O(_tn, _i, ...) \
GMOCK_MATCHER_(_tn, _i, __VA_ARGS__)
#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_INTERNAL_GMOCK_FUNCTION_MOCKER_H_
#endif // THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,627 @@
$$ -*- mode: c++; -*-
$$ This is a Pump source file. Please use Pump to convert it to
$$ gmock-generated-actions.h.
$$
$var n = 10 $$ The maximum arity we support.
$$}} This meta comment fixes auto-indentation in editors.
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements some commonly used variadic actions.
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
#include <memory>
#include <utility>
#include "gmock/gmock-actions.h"
#include "gmock/internal/gmock-port.h"
namespace testing {
namespace internal {
// 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, [[std::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 ::std::tuple<$As>& args) {
return impl->template gmock_PerformImpl<$As>(args, $arg_list);
}
]]
};
} // namespace internal
} // 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 as templates cannot be
// declared inside of a local class.
// Users can, however, define any local functors (e.g. a lambda) that
// can be used as actions.
//
// MORE INFORMATION:
//
// To learn more about using these macros, please search for 'ACTION' on
// https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md
$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 [[, \
const 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(::std::get<k>(args));
// }
// ...
// int n;
// EXPECT_CALL(mock, Foo(_, _))
// .WillOnce(DuplicateArg<1, unsigned char>(&n));
//
// To create an instance of an action template, write:
//
// ActionName<t1, ..., t_m>(v1, ..., v_n)
//
// where the ts are the template arguments and the vs are the value
// arguments. The value argument types are inferred by the compiler.
// If you want to explicitly specify the value argument types, you can
// provide additional template arguments:
//
// ActionName<t1, ..., t_m, u1, ..., u_k>(v1, ..., v_n)
//
// where u_i is the desired type of v_i.
//
// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the
// number of value parameters, but not on the number of template
// parameters. Without the restriction, the meaning of the following
// is unclear:
//
// OverloadedAction<int, bool>(x);
//
// Are we using a single-template-parameter action where 'bool' refers
// to the type of x, or are we using a two-template-parameter action
// where the compiler is asked to infer the type of x?
//
// Implementation notes:
//
// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and
// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for
// implementing ACTION_TEMPLATE. The main trick we use is to create
// new macro invocations when expanding a macro. For example, we have
//
// #define ACTION_TEMPLATE(name, template_params, value_params)
// ... GMOCK_INTERNAL_DECL_##template_params ...
//
// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...)
// to expand to
//
// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ...
//
// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the
// preprocessor will continue to expand it to
//
// ... typename T ...
//
// This technique conforms to the C++ standard and is portable. It
// allows us to implement action templates using O(N) code, where N is
// the maximum number of template/value parameters supported. Without
// using it, we'd have to devote O(N^2) amount of code to implement all
// combinations of m and n.
// Declares the template parameters.
$range j 1..n
$for j [[
$range m 0..j-1
#define GMOCK_INTERNAL_DECL_HAS_$j[[]]
_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[kind$m name$m]]
]]
// Lists the template parameters.
$for j [[
$range m 0..j-1
#define GMOCK_INTERNAL_LIST_HAS_$j[[]]
_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[name$m]]
]]
// Declares the types of value parameters.
$for i [[
$range j 0..i-1
#define GMOCK_INTERNAL_DECL_TYPE_AND_$i[[]]
_VALUE_PARAMS($for j, [[p$j]]) $for j [[, typename p$j##_type]]
]]
// Initializes the value parameters.
$for i [[
$range j 0..i-1
#define GMOCK_INTERNAL_INIT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])\
($for j, [[p$j##_type gmock_p$j]])$if i>0 [[ : ]]$for j, [[p$j(::std::move(gmock_p$j))]]
]]
// 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 [[, const 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(::std::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, [[const 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(),
::std::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_

View File

@ -0,0 +1,752 @@
// 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 <functional>
#include <utility>
#include "gmock/gmock-spec-builders.h"
#include "gmock/internal/gmock-internal-utils.h"
namespace testing {
namespace internal {
// 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__>::template Arg<N-1>::type
// 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, ...) \
static_assert(0 == \
::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
"MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
) constness { \
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, ...) \
static_assert(1 == \
::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
"MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1) constness { \
GMOCK_MOCKER_(1, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(1, constness, \
Method).Invoke(::std::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, ...) \
static_assert(2 == \
::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
"MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
__VA_ARGS__) gmock_a2) constness { \
GMOCK_MOCKER_(2, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(2, constness, \
Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
__VA_ARGS__)>(gmock_a1), \
::std::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, ...) \
static_assert(3 == \
::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
"MOCK_METHOD<N> must match argument count.");\
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 { \
GMOCK_MOCKER_(3, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(3, constness, \
Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
__VA_ARGS__)>(gmock_a1), \
::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
::std::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, ...) \
static_assert(4 == \
::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
"MOCK_METHOD<N> must match argument count.");\
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 { \
GMOCK_MOCKER_(4, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(4, constness, \
Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
__VA_ARGS__)>(gmock_a1), \
::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
::std::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, ...) \
static_assert(5 == \
::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
"MOCK_METHOD<N> must match argument count.");\
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 { \
GMOCK_MOCKER_(5, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(5, constness, \
Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
__VA_ARGS__)>(gmock_a1), \
::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \
::std::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, ...) \
static_assert(6 == \
::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
"MOCK_METHOD<N> must match argument count.");\
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 { \
GMOCK_MOCKER_(6, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(6, constness, \
Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
__VA_ARGS__)>(gmock_a1), \
::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \
::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5), \
::std::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, ...) \
static_assert(7 == \
::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
"MOCK_METHOD<N> must match argument count.");\
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 { \
GMOCK_MOCKER_(7, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(7, constness, \
Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
__VA_ARGS__)>(gmock_a1), \
::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \
::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5), \
::std::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(gmock_a6), \
::std::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, ...) \
static_assert(8 == \
::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
"MOCK_METHOD<N> must match argument count.");\
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 { \
GMOCK_MOCKER_(8, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(8, constness, \
Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
__VA_ARGS__)>(gmock_a1), \
::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \
::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5), \
::std::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(gmock_a6), \
::std::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(gmock_a7), \
::std::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, ...) \
static_assert(9 == \
::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
"MOCK_METHOD<N> must match argument count.");\
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 { \
GMOCK_MOCKER_(9, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(9, constness, \
Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
__VA_ARGS__)>(gmock_a1), \
::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \
::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5), \
::std::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(gmock_a6), \
::std::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(gmock_a7), \
::std::forward<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(gmock_a8), \
::std::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, ...) \
static_assert(10 == \
::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
"MOCK_METHOD<N> must match argument count.");\
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 { \
GMOCK_MOCKER_(10, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(10, constness, \
Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
__VA_ARGS__)>(gmock_a1), \
::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \
::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5), \
::std::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(gmock_a6), \
::std::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(gmock_a7), \
::std::forward<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(gmock_a8), \
::std::forward<GMOCK_ARG_(tn, 9, __VA_ARGS__)>(gmock_a9), \
::std::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__)
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_

View File

@ -0,0 +1,227 @@
$$ -*- 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 <functional>
#include <utility>
#include "gmock/gmock-spec-builders.h"
#include "gmock/internal/gmock-internal-utils.h"
namespace testing {
namespace internal {
$range i 0..n
// 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__>::template Arg<N-1>::type
// 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, \
[[::std::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, ...) \
static_assert($i == ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, "MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
$arg_as) constness { \
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__)
]]
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,346 @@
$$ -*- 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 <utility>
#include <vector>
#include "gmock/gmock-matchers.h"
// The MATCHER* family of macros can be used in a namespace scope to
// define custom matchers easily.
//
// Basic Usage
// ===========
//
// The syntax
//
// MATCHER(name, description_string) { statements; }
//
// defines a matcher with the given name that executes the statements,
// which must return a bool to indicate if the match succeeds. Inside
// the statements, you can refer to the value being matched by 'arg',
// and refer to its type by 'arg_type'.
//
// The description string documents what the matcher does, and is used
// to generate the failure message when the match fails. Since a
// MATCHER() is usually defined in a header file shared by multiple
// C++ source files, we require the description to be a C-string
// literal to avoid possible side effects. It can be empty, in which
// case we'll use the sequence of words in the matcher name as the
// description.
//
// For example:
//
// MATCHER(IsEven, "") { return (arg % 2) == 0; }
//
// allows you to write
//
// // Expects mock_foo.Bar(n) to be called where n is even.
// EXPECT_CALL(mock_foo, Bar(IsEven()));
//
// or,
//
// // Verifies that the value of some_expression is even.
// EXPECT_THAT(some_expression, IsEven());
//
// If the above assertion fails, it will print something like:
//
// Value of: some_expression
// Expected: is even
// Actual: 7
//
// where the description "is even" is automatically calculated from the
// matcher name IsEven.
//
// Argument Type
// =============
//
// Note that the type of the value being matched (arg_type) is
// determined by the context in which you use the matcher and is
// supplied to you by the compiler, so you don't need to worry about
// declaring it (nor can you). This allows the matcher to be
// polymorphic. For example, IsEven() can be used to match any type
// where the value of "(arg % 2) == 0" can be implicitly converted to
// a bool. In the "Bar(IsEven())" example above, if method Bar()
// takes an int, 'arg_type' will be int; if it takes an unsigned long,
// 'arg_type' will be unsigned long; and so on.
//
// Parameterizing Matchers
// =======================
//
// Sometimes you'll want to parameterize the matcher. For that you
// can use another macro:
//
// MATCHER_P(name, param_name, description_string) { statements; }
//
// For example:
//
// MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; }
//
// will allow you to write:
//
// EXPECT_THAT(Blah("a"), HasAbsoluteValue(n));
//
// which may lead to this message (assuming n is 10):
//
// Value of: Blah("a")
// Expected: has absolute value 10
// Actual: -9
//
// Note that both the matcher description and its parameter are
// printed, making the message human-friendly.
//
// In the matcher definition body, you can write 'foo_type' to
// reference the type of a parameter named 'foo'. For example, in the
// body of MATCHER_P(HasAbsoluteValue, value) above, you can write
// 'value_type' to refer to the type of 'value'.
//
// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P$n to
// support multi-parameter matchers.
//
// Describing Parameterized Matchers
// =================================
//
// The last argument to MATCHER*() is a string-typed expression. The
// expression can reference all of the matcher's parameters and a
// special bool-typed variable named 'negation'. When 'negation' is
// false, the expression should evaluate to the matcher's description;
// otherwise it should evaluate to the description of the negation of
// the matcher. For example,
//
// using testing::PrintToString;
//
// MATCHER_P2(InClosedRange, low, hi,
// std::string(negation ? "is not" : "is") + " in range [" +
// PrintToString(low) + ", " + PrintToString(hi) + "]") {
// return low <= arg && arg <= hi;
// }
// ...
// EXPECT_THAT(3, InClosedRange(4, 6));
// EXPECT_THAT(3, Not(InClosedRange(2, 4)));
//
// would generate two failures that contain the text:
//
// Expected: is in range [4, 6]
// ...
// Expected: is not in range [2, 4]
//
// If you specify "" as the description, the failure message will
// contain the sequence of words in the matcher name followed by the
// parameter values printed as a tuple. For example,
//
// MATCHER_P2(InClosedRange, low, hi, "") { ... }
// ...
// EXPECT_THAT(3, InClosedRange(4, 6));
// EXPECT_THAT(3, Not(InClosedRange(2, 4)));
//
// would generate two failures that contain the text:
//
// Expected: in closed range (4, 6)
// ...
// Expected: not (in closed range (2, 4))
//
// Types of Matcher Parameters
// ===========================
//
// For the purpose of typing, you can view
//
// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... }
//
// as shorthand for
//
// template <typename p1_type, ..., typename pk_type>
// FooMatcherPk<p1_type, ..., pk_type>
// Foo(p1_type p1, ..., pk_type pk) { ... }
//
// When you write Foo(v1, ..., vk), the compiler infers the types of
// the parameters v1, ..., and vk for you. If you are not happy with
// the result of the type inference, you can specify the types by
// explicitly instantiating the template, as in Foo<long, bool>(5,
// false). As said earlier, you don't get to (or need to) specify
// 'arg_type' as that's determined by the context in which the matcher
// is used. You can assign the result of expression Foo(p1, ..., pk)
// to a variable of type FooMatcherPk<p1_type, ..., pk_type>. This
// can be useful when composing matchers.
//
// While you can instantiate a matcher template with reference types,
// passing the parameters by pointer usually makes your code more
// readable. If, however, you still want to pass a parameter by
// reference, be aware that in the failure message generated by the
// matcher you will see the value of the referenced object but not its
// address.
//
// Explaining Match Results
// ========================
//
// Sometimes the matcher description alone isn't enough to explain why
// the match has failed or succeeded. For example, when expecting a
// long string, it can be very helpful to also print the diff between
// the expected string and the actual one. To achieve that, you can
// optionally stream additional information to a special variable
// named result_listener, whose type is a pointer to class
// MatchResultListener:
//
// MATCHER_P(EqualsLongString, str, "") {
// if (arg == str) return true;
//
// *result_listener << "the difference: "
/// << DiffStrings(str, arg);
// return false;
// }
//
// Overloading Matchers
// ====================
//
// You can overload matchers with different numbers of parameters:
//
// MATCHER_P(Blah, a, description_string1) { ... }
// MATCHER_P2(Blah, a, b, description_string2) { ... }
//
// Caveats
// =======
//
// When defining a new matcher, you should also consider implementing
// MatcherInterface or using MakePolymorphicMatcher(). These
// approaches require more work than the MATCHER* macros, but also
// give you more control on the types of the value being matched and
// the matcher parameters, which may leads to better compiler error
// messages when the matcher is used wrong. They also allow
// overloading matchers based on parameter types (as opposed to just
// based on the number of parameters).
//
// MATCHER*() can only be used in a namespace scope as templates cannot be
// declared inside of a local class.
//
// More Information
// ================
//
// To learn more about using these macros, please search for 'MATCHER'
// on
// https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md
$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(::std::move(gmock_p$j))]]]]]]
$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::std::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(\
::std::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_

File diff suppressed because it is too large Load Diff

View File

@ -30,462 +30,38 @@
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements some commonly used variadic actions.
// This file implements some actions that depend on gmock-generated-actions.h.
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
// GOOGLETEST_CM0002 DO NOT DELETE
#include <memory>
#include <utility>
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
#include "gmock/gmock-actions.h"
#include "gmock/internal/gmock-port.h"
#include <algorithm>
#include <type_traits>
// Include any custom callback actions added by the local installation.
#include "gmock/internal/custom/gmock-generated-actions.h"
// Sometimes you want to give an action explicit template parameters
// that cannot be inferred from its value parameters. ACTION() and
// ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that
// and can be viewed as an extension to ACTION() and ACTION_P*().
//
// The syntax:
//
// ACTION_TEMPLATE(ActionName,
// HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m),
// AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; }
//
// defines an action template that takes m explicit template
// parameters and n value parameters. name_i is the name of the i-th
// template parameter, and kind_i specifies whether it's a typename,
// an integral constant, or a template. p_i is the name of the i-th
// value parameter.
//
// Example:
//
// // DuplicateArg<k, T>(output) converts the k-th argument of the mock
// // function to type T and copies it to *output.
// ACTION_TEMPLATE(DuplicateArg,
// HAS_2_TEMPLATE_PARAMS(int, k, typename, T),
// AND_1_VALUE_PARAMS(output)) {
// *output = T(::std::get<k>(args));
// }
// ...
// int n;
// EXPECT_CALL(mock, Foo(_, _))
// .WillOnce(DuplicateArg<1, unsigned char>(&n));
//
// To create an instance of an action template, write:
//
// ActionName<t1, ..., t_m>(v1, ..., v_n)
//
// where the ts are the template arguments and the vs are the value
// arguments. The value argument types are inferred by the compiler.
// If you want to explicitly specify the value argument types, you can
// provide additional template arguments:
//
// ActionName<t1, ..., t_m, u1, ..., u_k>(v1, ..., v_n)
//
// where u_i is the desired type of v_i.
//
// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the
// number of value parameters, but not on the number of template
// parameters. Without the restriction, the meaning of the following
// is unclear:
//
// OverloadedAction<int, bool>(x);
//
// Are we using a single-template-parameter action where 'bool' refers
// to the type of x, or are we using a two-template-parameter action
// where the compiler is asked to infer the type of x?
//
// Implementation notes:
//
// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and
// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for
// implementing ACTION_TEMPLATE. The main trick we use is to create
// new macro invocations when expanding a macro. For example, we have
//
// #define ACTION_TEMPLATE(name, template_params, value_params)
// ... GMOCK_INTERNAL_DECL_##template_params ...
//
// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...)
// to expand to
//
// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ...
//
// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the
// preprocessor will continue to expand it to
//
// ... typename T ...
//
// This technique conforms to the C++ standard and is portable. It
// allows us to implement action templates using O(N) code, where N is
// the maximum number of template/value parameters supported. Without
// using it, we'd have to devote O(N^2) amount of code to implement all
// combinations of m and n.
// Declares the template parameters.
#define GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(kind0, name0) kind0 name0
#define GMOCK_INTERNAL_DECL_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, \
name1) kind0 name0, kind1 name1
#define GMOCK_INTERNAL_DECL_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2) kind0 name0, kind1 name1, kind2 name2
#define GMOCK_INTERNAL_DECL_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2, kind3, name3) kind0 name0, kind1 name1, kind2 name2, \
kind3 name3
#define GMOCK_INTERNAL_DECL_HAS_5_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2, kind3, name3, kind4, name4) kind0 name0, kind1 name1, \
kind2 name2, kind3 name3, kind4 name4
#define GMOCK_INTERNAL_DECL_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2, kind3, name3, kind4, name4, kind5, name5) kind0 name0, \
kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5
#define GMOCK_INTERNAL_DECL_HAS_7_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \
name6) kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4, \
kind5 name5, kind6 name6
#define GMOCK_INTERNAL_DECL_HAS_8_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \
kind7, name7) kind0 name0, kind1 name1, kind2 name2, kind3 name3, \
kind4 name4, kind5 name5, kind6 name6, kind7 name7
#define GMOCK_INTERNAL_DECL_HAS_9_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \
kind7, name7, kind8, name8) kind0 name0, kind1 name1, kind2 name2, \
kind3 name3, kind4 name4, kind5 name5, kind6 name6, kind7 name7, \
kind8 name8
#define GMOCK_INTERNAL_DECL_HAS_10_TEMPLATE_PARAMS(kind0, name0, kind1, \
name1, kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \
name6, kind7, name7, kind8, name8, kind9, name9) kind0 name0, \
kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5, \
kind6 name6, kind7 name7, kind8 name8, kind9 name9
// Lists the template parameters.
#define GMOCK_INTERNAL_LIST_HAS_1_TEMPLATE_PARAMS(kind0, name0) name0
#define GMOCK_INTERNAL_LIST_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, \
name1) name0, name1
#define GMOCK_INTERNAL_LIST_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2) name0, name1, name2
#define GMOCK_INTERNAL_LIST_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2, kind3, name3) name0, name1, name2, name3
#define GMOCK_INTERNAL_LIST_HAS_5_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2, kind3, name3, kind4, name4) name0, name1, name2, name3, \
name4
#define GMOCK_INTERNAL_LIST_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2, kind3, name3, kind4, name4, kind5, name5) name0, name1, \
name2, name3, name4, name5
#define GMOCK_INTERNAL_LIST_HAS_7_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \
name6) name0, name1, name2, name3, name4, name5, name6
#define GMOCK_INTERNAL_LIST_HAS_8_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \
kind7, name7) name0, name1, name2, name3, name4, name5, name6, name7
#define GMOCK_INTERNAL_LIST_HAS_9_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \
kind7, name7, kind8, name8) name0, name1, name2, name3, name4, name5, \
name6, name7, name8
#define GMOCK_INTERNAL_LIST_HAS_10_TEMPLATE_PARAMS(kind0, name0, kind1, \
name1, kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \
name6, kind7, name7, kind8, name8, kind9, name9) name0, name1, name2, \
name3, name4, name5, name6, name7, name8, name9
// Declares the types of value parameters.
#define GMOCK_INTERNAL_DECL_TYPE_AND_0_VALUE_PARAMS()
#define GMOCK_INTERNAL_DECL_TYPE_AND_1_VALUE_PARAMS(p0) , typename p0##_type
#define GMOCK_INTERNAL_DECL_TYPE_AND_2_VALUE_PARAMS(p0, p1) , \
typename p0##_type, typename p1##_type
#define GMOCK_INTERNAL_DECL_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) , \
typename p0##_type, typename p1##_type, typename p2##_type
#define GMOCK_INTERNAL_DECL_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) , \
typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type
#define GMOCK_INTERNAL_DECL_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) , \
typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type
#define GMOCK_INTERNAL_DECL_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) , \
typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type
#define GMOCK_INTERNAL_DECL_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
p6) , typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type, \
typename p6##_type
#define GMOCK_INTERNAL_DECL_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
p6, p7) , typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type, \
typename p6##_type, typename p7##_type
#define GMOCK_INTERNAL_DECL_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
p6, p7, p8) , typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type, \
typename p6##_type, typename p7##_type, typename p8##_type
#define GMOCK_INTERNAL_DECL_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
p6, p7, p8, p9) , typename p0##_type, typename p1##_type, \
typename p2##_type, typename p3##_type, typename p4##_type, \
typename p5##_type, typename p6##_type, typename p7##_type, \
typename p8##_type, typename p9##_type
// Initializes the value parameters.
#define GMOCK_INTERNAL_INIT_AND_0_VALUE_PARAMS()\
()
#define GMOCK_INTERNAL_INIT_AND_1_VALUE_PARAMS(p0)\
(p0##_type gmock_p0) : p0(::std::move(gmock_p0))
#define GMOCK_INTERNAL_INIT_AND_2_VALUE_PARAMS(p0, p1)\
(p0##_type gmock_p0, p1##_type gmock_p1) : p0(::std::move(gmock_p0)), \
p1(::std::move(gmock_p1))
#define GMOCK_INTERNAL_INIT_AND_3_VALUE_PARAMS(p0, p1, p2)\
(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2) : p0(::std::move(gmock_p0)), \
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2))
#define GMOCK_INTERNAL_INIT_AND_4_VALUE_PARAMS(p0, p1, p2, p3)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3) : p0(::std::move(gmock_p0)), \
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
p3(::std::move(gmock_p3))
#define GMOCK_INTERNAL_INIT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4) : p0(::std::move(gmock_p0)), \
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4))
#define GMOCK_INTERNAL_INIT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, \
p5##_type gmock_p5) : p0(::std::move(gmock_p0)), \
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
p5(::std::move(gmock_p5))
#define GMOCK_INTERNAL_INIT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
p6##_type gmock_p6) : p0(::std::move(gmock_p0)), \
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6))
#define GMOCK_INTERNAL_INIT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
p6##_type gmock_p6, p7##_type gmock_p7) : p0(::std::move(gmock_p0)), \
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \
p7(::std::move(gmock_p7))
#define GMOCK_INTERNAL_INIT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
p7, p8)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
p6##_type gmock_p6, p7##_type gmock_p7, \
p8##_type gmock_p8) : p0(::std::move(gmock_p0)), \
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \
p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8))
#define GMOCK_INTERNAL_INIT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
p7, p8, p9)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \
p9##_type gmock_p9) : p0(::std::move(gmock_p0)), \
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \
p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8)), \
p9(::std::move(gmock_p9))
// Defines the copy constructor
#define GMOCK_INTERNAL_DEFN_COPY_AND_0_VALUE_PARAMS() \
{} // 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
#include "gmock/gmock-generated-actions.h"
namespace testing {
namespace internal {
// 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;
}
} // namespace internal
// Various overloads for Invoke().
// The ACTION*() macros trigger warning C4100 (unreferenced formal
// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
@ -497,75 +73,90 @@ namespace testing {
# pragma warning(disable:4100)
#endif
namespace internal {
// internal::InvokeArgument - a helper for InvokeArgument action.
// The basic overloads are provided here for generic functors.
// Overloads for other custom-callables are provided in the
// internal/custom/gmock-generated-actions.h header.
template <typename F, typename... Args>
auto InvokeArgument(F f, Args... args) -> decltype(f(args...)) {
return f(args...);
// 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 ::std::get<k>(args);
}
template <std::size_t index, typename... Params>
struct InvokeArgumentAction {
template <typename... Args>
auto operator()(Args&&... args) const -> decltype(internal::InvokeArgument(
std::get<index>(std::forward_as_tuple(std::forward<Args>(args)...)),
std::declval<const Params&>()...)) {
internal::FlatTuple<Args&&...> args_tuple(FlatTupleConstructTag{},
std::forward<Args>(args)...);
return params.Apply([&](const Params&... unpacked_params) {
auto&& callable = args_tuple.template Get<index>();
return internal::InvokeArgument(
std::forward<decltype(callable)>(callable), unpacked_params...);
});
}
internal::FlatTuple<Params...> params;
};
} // namespace internal
// The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th
// (0-based) argument, which must be a k-ary callable, of the mock
// function, with arguments a1, a2, ..., a_k.
//
// Notes:
//
// 1. The arguments are passed by value by default. If you need to
// pass an argument by reference, wrap it inside std::ref(). For
// example,
//
// InvokeArgument<1>(5, string("Hello"), std::ref(foo))
//
// passes 5 and string("Hello") by value, and passes foo by
// reference.
//
// 2. If the callable takes an argument by reference but std::ref() is
// not used, it will receive the reference to a copy of the value,
// instead of the original value. For example, when the 0-th
// argument of the mock function takes a const string&, the action
//
// InvokeArgument<0>(string("Hello"))
//
// makes a copy of the temporary string("Hello") object and passes a
// reference of the copy, instead of the original temporary object,
// to the callable. This makes it easy for a user to define an
// InvokeArgument action from temporary values and have it performed
// later.
template <std::size_t index, typename... Params>
internal::InvokeArgumentAction<index, typename std::decay<Params>::type...>
InvokeArgument(Params&&... params) {
return {internal::FlatTuple<typename std::decay<Params>::type...>(
internal::FlatTupleConstructTag{}, std::forward<Params>(params)...)};
// 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 = ::std::get<k>(args);
}
// 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 = *::std::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 ::std::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_(std::is_reference<argk_type>::value,
SetArgReferee_must_be_used_with_a_reference_argument);
::std::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, ::std::get<k>(args));
#else
::std::copy(first, last, ::std::get<k>(args));
#endif
}
// 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 ::std::get<k>(args);
}
// This action returns the value pointed to by 'pointer'.
ACTION_P(ReturnPointee, 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
// 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
#endif // GTEST_HAS_EXCEPTIONS
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // namespace testing
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_

View File

@ -30,15 +30,17 @@
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements some matchers that depend on gmock-matchers.h.
// This file implements some matchers that depend on gmock-generated-matchers.h.
//
// Note that tests are implemented in gmock-matchers_test.cc rather than
// gmock-more-matchers-test.cc.
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_
// GOOGLETEST_CM0002 DO NOT DELETE
#include "gmock/gmock-matchers.h"
#ifndef GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_
#define GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_
#include "gmock/gmock-generated-matchers.h"
namespace testing {
@ -87,4 +89,4 @@ MATCHER(IsFalse, negation ? "is true" : "is false") {
} // namespace testing
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_
#endif // GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_

View File

@ -58,91 +58,22 @@
// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
// supported.
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
// GOOGLETEST_CM0002 DO NOT DELETE
#include <type_traits>
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
#include "gmock/gmock-spec-builders.h"
#include "gmock/internal/gmock-port.h"
namespace testing {
template <class MockClass>
class NiceMock;
template <class MockClass>
class NaggyMock;
template <class MockClass>
class StrictMock;
namespace internal {
template <typename T>
std::true_type StrictnessModifierProbe(const NiceMock<T>&);
template <typename T>
std::true_type StrictnessModifierProbe(const NaggyMock<T>&);
template <typename T>
std::true_type StrictnessModifierProbe(const StrictMock<T>&);
std::false_type StrictnessModifierProbe(...);
template <typename T>
constexpr bool HasStrictnessModifier() {
return decltype(StrictnessModifierProbe(std::declval<const T&>()))::value;
}
// Base classes that register and deregister with testing::Mock to alter the
// default behavior around uninteresting calls. Inheriting from one of these
// classes first and then MockClass ensures the MockClass constructor is run
// after registration, and that the MockClass destructor runs before
// deregistration. This guarantees that MockClass's constructor and destructor
// run with the same level of strictness as its instance methods.
#if GTEST_OS_WINDOWS && !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(this); }
~NiceMockImpl() { ::testing::Mock::UnregisterCallReaction(this); }
};
template <typename Base>
class NaggyMockImpl {
public:
NaggyMockImpl() { ::testing::Mock::WarnUninterestingCalls(this); }
~NaggyMockImpl() { ::testing::Mock::UnregisterCallReaction(this); }
};
template <typename Base>
class StrictMockImpl {
public:
StrictMockImpl() { ::testing::Mock::FailUninterestingCalls(this); }
~StrictMockImpl() { ::testing::Mock::UnregisterCallReaction(this); }
};
} // namespace internal
template <class MockClass>
class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
: private internal::NiceMockImpl<MockClass>,
public MockClass {
class NiceMock : 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");
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
// Ideally, we would inherit base class's constructors through a using
@ -154,16 +85,21 @@ class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
// 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");
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename TArg1, typename TArg2, typename... An>
NiceMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
: MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
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)...) {
static_assert(sizeof(*this) == sizeof(MockClass),
"The impl subclass shouldn't introduce any padding");
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
~NiceMock() { // NOLINT
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this));
}
private:
@ -171,19 +107,11 @@ class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
};
template <class MockClass>
class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
: private internal::NaggyMockImpl<MockClass>,
public MockClass {
static_assert(!internal::HasStrictnessModifier<MockClass>(),
"Can't apply NaggyMock to a class hierarchy that already has a "
"strictness modifier. See "
"https://google.github.io/googletest/"
"gmock_cook_book.html#NiceStrictNaggy");
class NaggyMock : public MockClass {
public:
NaggyMock() : MockClass() {
static_assert(sizeof(*this) == sizeof(MockClass),
"The impl subclass shouldn't introduce any padding");
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
// Ideally, we would inherit base class's constructors through a using
@ -195,16 +123,21 @@ class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
// 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");
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename TArg1, typename TArg2, typename... An>
NaggyMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
: MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
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)...) {
static_assert(sizeof(*this) == sizeof(MockClass),
"The impl subclass shouldn't introduce any padding");
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
~NaggyMock() { // NOLINT
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this));
}
private:
@ -212,19 +145,11 @@ class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
};
template <class MockClass>
class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock
: private internal::StrictMockImpl<MockClass>,
public MockClass {
class StrictMock : 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");
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
// Ideally, we would inherit base class's constructors through a using
@ -236,24 +161,55 @@ class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock
// 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");
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename TArg1, typename TArg2, typename... An>
StrictMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
: MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
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)...) {
static_assert(sizeof(*this) == sizeof(MockClass),
"The impl subclass shouldn't introduce any padding");
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
~StrictMock() { // NOLINT
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this));
}
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock);
};
#undef GTEST_INTERNAL_EMPTY_BASE_CLASS
// 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 // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_

View File

@ -56,8 +56,10 @@
// where all clauses are optional, and .InSequence()/.After()/
// .WillOnce() can appear any number of times.
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
#include <functional>
#include <map>
@ -106,14 +108,6 @@ template <typename F> class TypedExpectation;
// Helper class for testing the Expectation class template.
class ExpectationTester;
// Helper classes for implementing NiceMock, StrictMock, and NaggyMock.
template <typename MockClass>
class NiceMockImpl;
template <typename MockClass>
class StrictMockImpl;
template <typename MockClass>
class NaggyMockImpl;
// Protects the mock object registry (in class Mock), all function
// mockers, and all expectations.
//
@ -419,12 +413,14 @@ class GTEST_API_ Mock {
template <typename F>
friend class internal::FunctionMocker;
template <typename MockClass>
friend class internal::NiceMockImpl;
template <typename MockClass>
friend class internal::NaggyMockImpl;
template <typename MockClass>
friend class internal::StrictMockImpl;
template <typename M>
friend class NiceMock;
template <typename M>
friend class NaggyMock;
template <typename M>
friend class StrictMock;
// Tells Google Mock to allow uninteresting calls on the given mock
// object.
@ -503,10 +499,7 @@ 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
@ -886,9 +879,11 @@ class GTEST_API_ ExpectationBase {
Clause last_clause_;
mutable bool action_count_checked_; // Under mutex_.
mutable Mutex mutex_; // Protects action_count_checked_.
GTEST_DISALLOW_ASSIGN_(ExpectationBase);
}; // class ExpectationBase
// Implements an expectation for the given function type.
// Impements an expectation for the given function type.
template <typename F>
class TypedExpectation : public ExpectationBase {
public:
@ -1300,6 +1295,8 @@ class MockSpec {
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.
@ -1353,6 +1350,12 @@ 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
@ -1508,7 +1511,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
// 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 description if there
// exceptions are enabled) with a helpful call descrption if there
// is no valid return value. This method doesn't depend on the
// mutable state of this object, and thus can be called concurrently
// without locking.
@ -1783,87 +1786,18 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
}
}; // class FunctionMocker
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4355
// Reports an uninteresting call (whose description is in msg) in the
// manner specified by 'reaction'.
void ReportUninterestingCall(CallReaction reaction, const std::string& msg);
} // namespace internal
namespace internal {
template <typename F>
class MockFunction;
template <typename R, typename... Args>
class MockFunction<R(Args...)> {
public:
MockFunction(const MockFunction&) = delete;
MockFunction& operator=(const MockFunction&) = delete;
std::function<R(Args...)> AsStdFunction() {
return [this](Args... args) -> R {
return this->Call(std::forward<Args>(args)...);
};
}
// Implementation detail: the expansion of the MOCK_METHOD macro.
R Call(Args... args) {
mock_.SetOwnerAndName(this, "Call");
return mock_.Invoke(std::forward<Args>(args)...);
}
MockSpec<R(Args...)> gmock_Call(Matcher<Args>... m) {
mock_.RegisterOwner(this);
return mock_.With(std::move(m)...);
}
MockSpec<R(Args...)> gmock_Call(const WithoutMatchers&, R (*)(Args...)) {
return this->gmock_Call(::testing::A<Args>()...);
}
protected:
MockFunction() = default;
~MockFunction() = default;
private:
FunctionMocker<R(Args...)> mock_;
};
/*
The SignatureOf<F> struct is a meta-function returning function signature
corresponding to the provided F argument.
It makes use of MockFunction easier by allowing it to accept more F arguments
than just function signatures.
Specializations provided here cover 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:
// 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);
@ -1897,34 +1831,49 @@ using SignatureOfT = typename SignatureOf<F>::type;
// 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:
// 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());
// }
//
// 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>>;
class MockFunction;
template <typename R, typename... Args>
class MockFunction<R(Args...)> {
public:
using Base::Base;
MockFunction() {}
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)...);
}
internal::MockSpec<R(Args...)> gmock_Call(Matcher<Args>... m) {
mock_.RegisterOwner(this);
return mock_.With(std::move(m)...);
}
internal::MockSpec<R(Args...)> gmock_Call(const internal::WithoutMatchers&,
R (*)(Args...)) {
return this->gmock_Call(::testing::A<Args>()...);
}
private:
internal::FunctionMocker<R(Args...)> mock_;
};
// The style guide prohibits "using" statements in a namespace scope
@ -2033,4 +1982,4 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#define EXPECT_CALL(obj, call) \
GMOCK_ON_CALL_IMPL_(obj, InternalExpectedAt, call)
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_

View File

@ -32,8 +32,10 @@
//
// This is the main header file a user should include.
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_H_
// This file implements the following syntax:
//
@ -57,19 +59,22 @@
#include "gmock/gmock-actions.h"
#include "gmock/gmock-cardinalities.h"
#include "gmock/gmock-function-mocker.h"
#include "gmock/gmock-generated-actions.h"
#include "gmock/gmock-generated-function-mockers.h"
#include "gmock/gmock-generated-matchers.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 {
// 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,
@ -93,4 +98,4 @@ GTEST_API_ void InitGoogleMock();
} // namespace testing
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_H_

View File

@ -14,5 +14,3 @@ 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)`

View File

@ -1,4 +1,10 @@
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
// This file was GENERATED by command:
// pump.py gmock-generated-actions.h.pump
// DO NOT EDIT BY HAND!!!
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
// 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_

View File

@ -0,0 +1,12 @@
$$ -*- mode: c++; -*-
$$ This is a Pump source file. Please use Pump to convert
$$ it to callback-actions.h.
$$
$var max_callback_arity = 5
$$}} This meta comment fixes auto-indentation in editors.
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_

View File

@ -28,7 +28,9 @@
// 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 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_
#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_

View File

@ -31,7 +31,9 @@
//
// ** Custom implementation starts here **
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
// GOOGLETEST_CM0002 DO NOT DELETE
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_

View File

@ -34,8 +34,10 @@
// Mock. They are subject to change without notice, so please DO NOT
// USE THEM IN USER CODE.
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
#include <stdio.h>
#include <ostream> // NOLINT
@ -69,6 +71,20 @@ 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.
@ -120,13 +136,15 @@ GMOCK_DECLARE_KIND_(int, kInteger);
GMOCK_DECLARE_KIND_(unsigned int, kInteger);
GMOCK_DECLARE_KIND_(long, kInteger); // NOLINT
GMOCK_DECLARE_KIND_(unsigned long, kInteger); // NOLINT
GMOCK_DECLARE_KIND_(long long, kInteger); // NOLINT
GMOCK_DECLARE_KIND_(unsigned long long, kInteger); // NOLINT
#if GMOCK_WCHAR_T_IS_NATIVE_
GMOCK_DECLARE_KIND_(wchar_t, kInteger);
#endif
// 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);
@ -139,6 +157,9 @@ GMOCK_DECLARE_KIND_(long double, kFloatingPoint);
static_cast< ::testing::internal::TypeKind>( \
::testing::internal::KindOf<type>::value)
// Evaluates to true if and only if integer type T is signed.
#define GMOCK_IS_SIGNED_(T) (static_cast<T>(-1) < 0)
// LosslessArithmeticConvertibleImpl<kFromKind, From, kToKind, To>::value
// is true if and only if arithmetic type From can be losslessly converted to
// arithmetic type To.
@ -149,30 +170,65 @@ 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>
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
>;
struct LosslessArithmeticConvertibleImpl : public std::false_type {};
// Converting bool to bool is lossless.
template <>
struct LosslessArithmeticConvertibleImpl<kBool, bool, kBool, bool>
: public std::true_type {};
// Converting bool to any integer type is lossless.
template <typename To>
struct LosslessArithmeticConvertibleImpl<kBool, bool, kInteger, To>
: public std::true_type {};
// Converting bool to any floating-point type is lossless.
template <typename To>
struct LosslessArithmeticConvertibleImpl<kBool, bool, kFloatingPoint, To>
: public std::true_type {};
// Converting an integer to bool is lossy.
template <typename From>
struct LosslessArithmeticConvertibleImpl<kInteger, From, kBool, bool>
: public std::false_type {};
// Converting an integer to another non-bool integer is lossless
// if and only if 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 std::false_type {};
// Converting a floating-point to bool is lossy.
template <typename From>
struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kBool, bool>
: public std::false_type {};
// Converting a floating-point to an integer is lossy.
template <typename From, typename To>
struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kInteger, To>
: public std::false_type {};
// Converting a floating-point to another floating-point is lossless
// if and only if 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 if and only if
// arithmetic type From can be losslessly converted to arithmetic type To.
@ -182,9 +238,9 @@ using LosslessArithmeticConvertibleImpl = std::integral_constant<
// reference) built-in arithmetic types; the value is
// implementation-defined when the above pre-condition is violated.
template <typename From, typename To>
using LosslessArithmeticConvertible =
LosslessArithmeticConvertibleImpl<GMOCK_KIND_OF_(From), From,
GMOCK_KIND_OF_(To), To>;
struct LosslessArithmeticConvertible
: public LosslessArithmeticConvertibleImpl<
GMOCK_KIND_OF_(From), From, GMOCK_KIND_OF_(To), To> {}; // NOLINT
// This interface knows how to report a Google Mock failure (either
// non-fatal or fatal).
@ -278,8 +334,10 @@ class WithoutMatchers {
// Internal use only: access the singleton instance of WithoutMatchers.
GTEST_API_ WithoutMatchers GetWithoutMatchers();
// Type traits.
// Disable MSVC warnings for infinite recursion, since in this case the
// recursion is unreachable.
// the recursion is unreachable.
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable:4717)
@ -362,8 +420,7 @@ template <typename ElementPointer, typename Size>
class StlContainerView< ::std::tuple<ElementPointer, Size> > {
public:
typedef typename std::remove_const<
typename std::pointer_traits<ElementPointer>::element_type>::type
RawElement;
typename internal::PointeeOf<ElementPointer>::type>::type RawElement;
typedef internal::NativeArray<RawElement> type;
typedef const type const_reference;
@ -407,13 +464,11 @@ auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>) -> decltype(
// Apply the function to a tuple of arguments.
template <typename F, typename Tuple>
auto Apply(F&& f, Tuple&& args) -> decltype(
ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
MakeIndexSequence<std::tuple_size<
typename std::remove_reference<Tuple>::type>::value>())) {
auto Apply(F&& f, Tuple&& args)
-> decltype(ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
MakeIndexSequence<std::tuple_size<Tuple>::value>())) {
return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
MakeIndexSequence<std::tuple_size<
typename std::remove_reference<Tuple>::type>::value>());
MakeIndexSequence<std::tuple_size<Tuple>::value>());
}
// Template struct Function<F>, where F must be a function type, contains
@ -437,7 +492,8 @@ struct Function<R(Args...)> {
using Result = R;
static constexpr size_t ArgumentCount = sizeof...(Args);
template <size_t I>
using Arg = ElemFromList<I, Args...>;
using Arg = ElemFromList<I, typename MakeIndexSequence<sizeof...(Args)>::type,
Args...>;
using ArgumentTuple = std::tuple<Args...>;
using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;
using MakeResultVoid = void(Args...);
@ -447,8 +503,6 @@ struct Function<R(Args...)> {
template <typename R, typename... Args>
constexpr size_t Function<R(Args...)>::ArgumentCount;
bool Base64Unescape(const std::string& encoded, std::string* decoded);
#ifdef _MSC_VER
# pragma warning(pop)
#endif
@ -456,4 +510,4 @@ bool Base64Unescape(const std::string& encoded, std::string* decoded);
} // namespace internal
} // namespace testing
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_

View File

@ -35,12 +35,13 @@
// end with _ are part of Google Mock's public API and can be used by
// code outside Google Mock.
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
#include <assert.h>
#include <stdlib.h>
#include <cstdint>
#include <iostream>
// Most of the utilities needed for porting Google Mock are also
@ -67,37 +68,20 @@
#if !defined(GMOCK_DECLARE_bool_)
// 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_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)
// Macros for defining flags.
#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")
# 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)
#endif // !defined(GMOCK_DECLARE_bool_)
#if !defined(GMOCK_FLAG_GET)
#define GMOCK_FLAG_GET(name) ::testing::GMOCK_FLAG(name)
#define GMOCK_FLAG_SET(name, value) (void)(::testing::GMOCK_FLAG(name) = value)
#endif // !defined(GMOCK_FLAG_GET)
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_

View File

@ -1,5 +1,18 @@
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_
#ifndef THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_PP_H_
#define THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_PP_H_
#undef GMOCK_PP_INTERNAL_USE_MSVC
#if defined(__clang__)
#define GMOCK_PP_INTERNAL_USE_MSVC 0
#elif defined(_MSC_VER)
// TODO(iserna): Also verify tradional versus comformant preprocessor.
static_assert(
_MSC_VER >= 1900,
"MSVC version not supported. There is support for MSVC 14.0 and above.");
#define GMOCK_PP_INTERNAL_USE_MSVC 1
#else
#define GMOCK_PP_INTERNAL_USE_MSVC 0
#endif
// Expands and concatenates the arguments. Constructed macros reevaluate.
#define GMOCK_PP_CAT(_1, _2) GMOCK_PP_INTERNAL_CAT(_1, _2)
@ -16,6 +29,10 @@
// Returns the only argument.
#define GMOCK_PP_IDENTITY(_1) _1
// MSVC preprocessor collapses __VA_ARGS__ in a single argument, we use a
// CAT-like directive to force correct evaluation. Each macro has its own.
#if GMOCK_PP_INTERNAL_USE_MSVC
// Evaluates to the number of arguments after expansion.
//
// #define PAIR x, y
@ -26,27 +43,45 @@
// 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))
#define GMOCK_PP_NARG(...) \
GMOCK_PP_INTERNAL_NARG_CAT( \
GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, \
8, 7, 6, 5, 4, 3, 2, 1), )
// 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))
#define GMOCK_PP_HAS_COMMA(...) \
GMOCK_PP_INTERNAL_HAS_COMMA_CAT( \
GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 0), )
// Returns the first argument.
#define GMOCK_PP_HEAD(...) GMOCK_PP_INTERNAL_HEAD((__VA_ARGS__, unusedArg))
#define GMOCK_PP_HEAD(...) \
GMOCK_PP_INTERNAL_HEAD_CAT(GMOCK_PP_INTERNAL_HEAD(__VA_ARGS__), )
// 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__))
#define GMOCK_PP_TAIL(...) \
GMOCK_PP_INTERNAL_TAIL_CAT(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__))
GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT( \
GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__), )
#else // GMOCK_PP_INTERNAL_USE_MSVC
#define GMOCK_PP_NARG(...) \
GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, \
7, 6, 5, 4, 3, 2, 1)
#define GMOCK_PP_HAS_COMMA(...) \
GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 0)
#define GMOCK_PP_HEAD(...) GMOCK_PP_INTERNAL_HEAD(__VA_ARGS__)
#define GMOCK_PP_TAIL(...) GMOCK_PP_INTERNAL_TAIL(__VA_ARGS__)
#define GMOCK_PP_VARIADIC_CALL(_Macro, ...) \
GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__)
#endif // GMOCK_PP_INTERNAL_USE_MSVC
// If the arguments after expansion have no tokens, evaluates to `1`. Otherwise
// evaluates to `0`.
@ -86,14 +121,6 @@
#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.
//
@ -112,9 +139,10 @@
// 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__))
#define GMOCK_PP_IS_BEGIN_PARENS(...) \
GMOCK_PP_INTERNAL_ALTERNATE_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(...) \
@ -151,6 +179,10 @@
#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_INTERNAL_16TH(_1, _2, _3, _4, _5, _6, _7, _8, _9, \
_10, _11, _12, _13, _14, _15, _16, \
...) \
_16
#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_, \
@ -158,24 +190,30 @@
#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
#define GMOCK_PP_INTERNAL_HEAD(_1, ...) _1
#define GMOCK_PP_INTERNAL_TAIL(_1, ...) __VA_ARGS__
// 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)
#if GMOCK_PP_INTERNAL_USE_MSVC
#define GMOCK_PP_INTERNAL_NARG_CAT(_1, _2) GMOCK_PP_INTERNAL_NARG_CAT_I(_1, _2)
#define GMOCK_PP_INTERNAL_HEAD_CAT(_1, _2) GMOCK_PP_INTERNAL_HEAD_CAT_I(_1, _2)
#define GMOCK_PP_INTERNAL_HAS_COMMA_CAT(_1, _2) \
GMOCK_PP_INTERNAL_HAS_COMMA_CAT_I(_1, _2)
#define GMOCK_PP_INTERNAL_TAIL_CAT(_1, _2) GMOCK_PP_INTERNAL_TAIL_CAT_I(_1, _2)
#define GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT(_1, _2) \
GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT_I(_1, _2)
#define GMOCK_PP_INTERNAL_NARG_CAT_I(_1, _2) _1##_2
#define GMOCK_PP_INTERNAL_HEAD_CAT_I(_1, _2) _1##_2
#define GMOCK_PP_INTERNAL_HAS_COMMA_CAT_I(_1, _2) _1##_2
#define GMOCK_PP_INTERNAL_TAIL_CAT_I(_1, _2) _1##_2
#define GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT_I(_1, _2) _1##_2
#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD(...) \
GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT(GMOCK_PP_HEAD(__VA_ARGS__), )
#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT(_1, _2) \
GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT_I(_1, _2)
#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT_I(_1, _2) _1##_2
#else // GMOCK_PP_INTERNAL_USE_MSVC
#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD(...) GMOCK_PP_HEAD(__VA_ARGS__)
#endif // GMOCK_PP_INTERNAL_USE_MSVC
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C(...) 1 _
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_1 1,
@ -276,4 +314,4 @@
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_
#endif // THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_

View File

@ -0,0 +1,240 @@
#!/usr/bin/env python
#
# Copyright 2009, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""fuse_gmock_files.py v0.1.0
Fuses Google Mock and Google Test source code into two .h files and a .cc file.
SYNOPSIS
fuse_gmock_files.py [GMOCK_ROOT_DIR] OUTPUT_DIR
Scans GMOCK_ROOT_DIR for Google Mock and Google Test source
code, assuming Google Test is in the GMOCK_ROOT_DIR/../googletest
directory, and generates three files:
OUTPUT_DIR/gtest/gtest.h, OUTPUT_DIR/gmock/gmock.h, and
OUTPUT_DIR/gmock-gtest-all.cc. Then you can build your tests
by adding OUTPUT_DIR to the include search path and linking
with OUTPUT_DIR/gmock-gtest-all.cc. These three files contain
everything you need to use Google Mock. Hence you can
"install" Google Mock by copying them to wherever you want.
GMOCK_ROOT_DIR can be omitted and defaults to the parent
directory of the directory holding this script.
EXAMPLES
./fuse_gmock_files.py fused_gmock
./fuse_gmock_files.py path/to/unpacked/gmock fused_gmock
This tool is experimental. In particular, it assumes that there is no
conditional inclusion of Google Mock or Google Test headers. Please
report any problems to googlemock@googlegroups.com. You can read
https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md for more
information.
"""
__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()

View File

@ -0,0 +1,203 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [2007] Neal Norwitz
Portions Copyright [2007] Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,34 @@
The Google Mock class generator is an application that is part of cppclean.
For more information about cppclean, visit http://code.google.com/p/cppclean/
The mock generator requires Python 2.3.5 or later. If you don't have Python
installed on your system, you will also need to install it. You can download
Python from: http://www.python.org/download/releases/
To use the Google Mock class generator, you need to call it
on the command line passing the header file and class for which you want
to generate a Google Mock class.
Make sure to install the scripts somewhere in your path. Then you can
run the program.
gmock_gen.py header-file.h [ClassName]...
If no ClassNames are specified, all classes in the file are emitted.
To change the indentation from the default of 2, set INDENT in
the environment. For example to use an indent of 4 spaces:
INDENT=4 gmock_gen.py header-file.h ClassName
This version was made from SVN revision 281 in the cppclean repository.
Known Limitations
-----------------
Not all code will be generated properly. For example, when mocking templated
classes, the template information is lost. You will need to add the template
information manually.
Not all permutations of using multiple pointers/references will be rendered
properly. These will also have to be fixed manually.

View File

@ -0,0 +1,115 @@
Goal:
-----
CppClean attempts to find problems in C++ source that slow development
in large code bases, for example various forms of unused code.
Unused code can be unused functions, methods, data members, types, etc
to unnecessary #include directives. Unnecessary #includes can cause
considerable extra compiles increasing the edit-compile-run cycle.
The project home page is: http://code.google.com/p/cppclean/
Features:
---------
* Find and print C++ language constructs: classes, methods, functions, etc.
* Find classes with virtual methods, no virtual destructor, and no bases
* Find global/static data that are potential problems when using threads
* Unnecessary forward class declarations
* Unnecessary function declarations
* Undeclared function definitions
* (planned) Find unnecessary header files #included
- No direct reference to anything in the header
- Header is unnecessary if classes were forward declared instead
* (planned) Source files that reference headers not directly #included,
ie, files that rely on a transitive #include from another header
* (planned) Unused members (private, protected, & public) methods and data
* (planned) Store AST in a SQL database so relationships can be queried
AST is Abstract Syntax Tree, a representation of parsed source code.
http://en.wikipedia.org/wiki/Abstract_syntax_tree
System Requirements:
--------------------
* Python 2.4 or later (2.3 probably works too)
* Works on Windows (untested), Mac OS X, and Unix
How to Run:
-----------
For all examples, it is assumed that cppclean resides in a directory called
/cppclean.
To print warnings for classes with virtual methods, no virtual destructor and
no base classes:
/cppclean/run.sh nonvirtual_dtors.py file1.h file2.h file3.cc ...
To print all the functions defined in header file(s):
/cppclean/run.sh functions.py file1.h file2.h ...
All the commands take multiple files on the command line. Other programs
include: find_warnings, headers, methods, and types. Some other programs
are available, but used primarily for debugging.
run.sh is a simple wrapper that sets PYTHONPATH to /cppclean and then
runs the program in /cppclean/cpp/PROGRAM.py. There is currently
no equivalent for Windows. Contributions for a run.bat file
would be greatly appreciated.
How to Configure:
-----------------
You can add a siteheaders.py file in /cppclean/cpp to configure where
to look for other headers (typically -I options passed to a compiler).
Currently two values are supported: _TRANSITIVE and GetIncludeDirs.
_TRANSITIVE should be set to a boolean value (True or False) indicating
whether to transitively process all header files. The default is False.
GetIncludeDirs is a function that takes a single argument and returns
a sequence of directories to include. This can be a generator or
return a static list.
def GetIncludeDirs(filename):
return ['/some/path/with/other/headers']
# Here is a more complicated example.
def GetIncludeDirs(filename):
yield '/path1'
yield os.path.join('/path2', os.path.dirname(filename))
yield '/path3'
How to Test:
------------
For all examples, it is assumed that cppclean resides in a directory called
/cppclean. The tests require
cd /cppclean
make test
# To generate expected results after a change:
make expected
Current Status:
---------------
The parser works pretty well for header files, parsing about 99% of Google's
header files. Anything which inspects structure of C++ source files should
work reasonably well. Function bodies are not transformed to an AST,
but left as tokens. Much work is still needed on finding unused header files
and storing an AST in a database.
Non-goals:
----------
* Parsing all valid C++ source
* Handling invalid C++ source gracefully
* Compiling to machine code (or anything beyond an AST)
Contact:
--------
If you used cppclean, I would love to hear about your experiences
cppclean@googlegroups.com. Even if you don't use cppclean, I'd like to
hear from you. :-) (You can contact me directly at: nnorwitz@gmail.com)

View File

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,227 @@
#!/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)

View File

@ -0,0 +1,466 @@
#!/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()

View File

@ -0,0 +1,59 @@
#!/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

View File

@ -0,0 +1,287 @@
#!/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)

View File

@ -0,0 +1,41 @@
#!/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

View File

@ -0,0 +1,31 @@
#!/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()

View File

@ -0,0 +1,303 @@
#!/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

View File

@ -0,0 +1,640 @@
#!/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()

1387
googlemock/scripts/upload.py Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,78 @@
#!/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()

View File

@ -37,14 +37,8 @@
#include "gmock/internal/gmock-internal-utils.h"
#include <ctype.h>
#include <array>
#include <cctype>
#include <cstdint>
#include <cstring>
#include <ostream> // NOLINT
#include <string>
#include "gmock/gmock.h"
#include "gmock/internal/gmock-port.h"
#include "gtest/gtest.h"
@ -132,10 +126,10 @@ static GTEST_DEFINE_STATIC_MUTEX_(g_log_mutex);
// Returns true if and only if a log with the given severity is visible
// according to the --gmock_verbose flag.
GTEST_API_ bool LogIsVisible(LogSeverity severity) {
if (GMOCK_FLAG_GET(verbose) == kInfoVerbosity) {
if (GMOCK_FLAG(verbose) == kInfoVerbosity) {
// Always show the log if --gmock_verbose=info.
return true;
} else if (GMOCK_FLAG_GET(verbose) == kErrorVerbosity) {
} else if (GMOCK_FLAG(verbose) == kErrorVerbosity) {
// Always hide it if --gmock_verbose=error.
return false;
} else {
@ -202,53 +196,5 @@ GTEST_API_ void IllegalDoDefault(const char* file, int line) {
"the variable in various places.");
}
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, carry + 1);
}
template <size_t... I>
constexpr std::array<char, 256> UnBase64Impl(IndexSequence<I...>,
const char* const base64) {
return {{UnBase64Impl(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 |= 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

View File

@ -34,6 +34,7 @@
// utilities for defining matchers.
#include "gmock/gmock-matchers.h"
#include "gmock/gmock-generated-matchers.h"
#include <string.h>
#include <iostream>
@ -218,6 +219,8 @@ 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;

View File

@ -36,17 +36,14 @@
#include "gmock/gmock-spec-builders.h"
#include <stdlib.h>
#include <iostream> // NOLINT
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "gtest/internal/gtest-port.h"
#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC
# include <unistd.h> // NOLINT
@ -73,8 +70,7 @@ GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity,
const char* file, int line,
const std::string& message) {
::std::ostringstream s;
s << internal::FormatFileLocation(file, line) << " " << message
<< ::std::endl;
s << file << ":" << line << ": " << message << ::std::endl;
Log(severity, s.str(), 0);
}
@ -264,10 +260,10 @@ void ExpectationBase::UntypedTimes(const Cardinality& a_cardinality) {
".Times() cannot appear "
"more than once in an EXPECT_CALL().");
} else {
ExpectSpecProperty(
last_clause_ < kTimes,
".Times() may only appear *before* .InSequence(), .WillOnce(), "
".WillRepeatedly(), or .RetiresonSaturation(), not after.");
ExpectSpecProperty(last_clause_ < kTimes,
".Times() cannot appear after "
".InSequence(), .WillOnce(), .WillRepeatedly(), "
"or .RetiresOnSaturation().");
}
last_clause_ = kTimes;
@ -283,7 +279,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_GET(verbose) == kInfoVerbosity ? 3 : -1;
GMOCK_FLAG(verbose) == kInfoVerbosity ? 3 : -1;
switch (reaction) {
case kAllow:
Log(kInfo, msg, stack_frames_to_skip);
@ -295,8 +291,8 @@ 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/docs/"
"gmock_cook_book.md#"
"https://github.com/google/googletest/blob/master/googlemock/"
"docs/cook_book.md#"
"knowing-when-to-expect for details.\n",
stack_frames_to_skip);
break;
@ -433,10 +429,10 @@ UntypedActionResultHolderBase* UntypedFunctionMockerBase::UntypedInvokeWith(
// The UntypedFindMatchingExpectation() function acquires and
// releases g_gmock_mutex.
const ExpectationBase* const untyped_expectation =
this->UntypedFindMatchingExpectation(untyped_args, &untyped_action,
&is_excessive, &ss, &why);
this->UntypedFindMatchingExpectation(
untyped_args, &untyped_action, &is_excessive,
&ss, &why);
const bool found = untyped_expectation != nullptr;
// True if and only if we need to print the call's arguments
@ -461,42 +457,26 @@ UntypedActionResultHolderBase* UntypedFunctionMockerBase::UntypedInvokeWith(
untyped_expectation->DescribeLocationTo(&loc);
}
UntypedActionResultHolderBase* result = nullptr;
auto perform_action = [&] {
return untyped_action == nullptr
? this->UntypedPerformDefaultAction(untyped_args, ss.str())
: this->UntypedPerformAction(untyped_action, untyped_args);
};
auto handle_failures = [&] {
ss << "\n" << why.str();
if (!found) {
// No expectation matches this call - reports a failure.
Expect(false, nullptr, -1, ss.str());
} else if (is_excessive) {
// We had an upper-bound violation and the failure message is in ss.
Expect(false, untyped_expectation->file(), untyped_expectation->line(),
ss.str());
} else {
// We had an expected call and the matching expectation is
// described in ss.
Log(kInfo, loc.str() + ss.str(), 2);
}
};
#if GTEST_HAS_EXCEPTIONS
try {
result = perform_action();
} catch (...) {
handle_failures();
throw;
}
#else
result = perform_action();
#endif
UntypedActionResultHolderBase* const result =
untyped_action == nullptr
? this->UntypedPerformDefaultAction(untyped_args, ss.str())
: this->UntypedPerformAction(untyped_action, untyped_args);
if (result != nullptr) result->PrintAsActionResult(&ss);
handle_failures();
ss << "\n" << why.str();
if (!found) {
// No expectation matches this call - reports a failure.
Expect(false, nullptr, -1, ss.str());
} else if (is_excessive) {
// We had an upper-bound violation and the failure message is in ss.
Expect(false, untyped_expectation->file(),
untyped_expectation->line(), ss.str());
} else {
// We had an expected call and the matching expectation is
// described in ss.
Log(kInfo, loc.str() + ss.str(), 2);
}
return result;
}
@ -613,7 +593,8 @@ class MockObjectRegistry {
// object alive. Therefore we report any living object as test
// failure, unless the user explicitly asked us to ignore it.
~MockObjectRegistry() {
if (!GMOCK_FLAG_GET(catch_leaked_mocks)) return;
if (!GMOCK_FLAG(catch_leaked_mocks))
return;
int leaked_count = 0;
for (StateMap::const_iterator it = states_.begin(); it != states_.end();
@ -639,7 +620,7 @@ class MockObjectRegistry {
if (leaked_count > 0) {
std::cout << "\nERROR: " << leaked_count << " leaked mock "
<< (leaked_count == 1 ? "object" : "objects")
<< " found at program exit. Expectations on a mock object are "
<< " 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, "
@ -715,10 +696,9 @@ internal::CallReaction Mock::GetReactionOnUninterestingCalls(
const void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
return (g_uninteresting_call_reaction.count(mock_obj) == 0)
? internal::intToCallReaction(
GMOCK_FLAG_GET(default_mock_behavior))
: g_uninteresting_call_reaction[mock_obj];
return (g_uninteresting_call_reaction.count(mock_obj) == 0) ?
internal::intToCallReaction(GMOCK_FLAG(default_mock_behavior)) :
g_uninteresting_call_reaction[mock_obj];
}
// Tells Google Mock to ignore mock_obj when checking for leaked mock

View File

@ -31,11 +31,13 @@
#include "gmock/gmock.h"
#include "gmock/internal/gmock-port.h"
namespace testing {
GMOCK_DEFINE_bool_(catch_leaked_mocks, true,
"true if and only if Google Mock should report leaked "
"mock objects as failures.");
GMOCK_DEFINE_string_(verbose, testing::internal::kWarningVerbosity,
GMOCK_DEFINE_string_(verbose, internal::kWarningVerbosity,
"Controls how verbose Google Mock's output is."
" Valid values:\n"
" info - prints all messages.\n"
@ -49,7 +51,6 @@ 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
@ -58,18 +59,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_name,
const char* flag,
bool def_optional) {
// str and flag must not be NULL.
if (str == nullptr || flag_name == nullptr) return nullptr;
if (str == nullptr || flag == nullptr) return nullptr;
// The flag must start with "--gmock_".
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;
const std::string flag_str = std::string("--gmock_") + flag;
const size_t flag_len = flag_str.length();
if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr;
// Skips the flag name.
const char* flag_end = str + flag_name_len;
const char* flag_end = str + flag_len;
// When def_optional is true, it's OK to not have a "=value" part.
if (def_optional && (flag_end[0] == '\0')) {
@ -90,10 +91,10 @@ 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 ParseGoogleMockFlag(const char* str, const char* flag_name,
bool* value) {
static bool ParseGoogleMockBoolFlag(const char* str, const char* flag,
bool* value) {
// Gets the value of the flag as a string.
const char* const value_str = ParseGoogleMockFlagValue(str, flag_name, true);
const char* const value_str = ParseGoogleMockFlagValue(str, flag, true);
// Aborts if the parsing failed.
if (value_str == nullptr) return false;
@ -109,10 +110,10 @@ static bool ParseGoogleMockFlag(const char* str, const char* flag_name,
// 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 ParseGoogleMockFlag(const char* str, const char* flag_name,
String* value) {
static bool ParseGoogleMockStringFlag(const char* str, const char* flag,
String* value) {
// Gets the value of the flag as a string.
const char* const value_str = ParseGoogleMockFlagValue(str, flag_name, false);
const char* const value_str = ParseGoogleMockFlagValue(str, flag, false);
// Aborts if the parsing failed.
if (value_str == nullptr) return false;
@ -122,17 +123,17 @@ static bool ParseGoogleMockFlag(const char* str, const char* flag_name,
return true;
}
static bool ParseGoogleMockFlag(const char* str, const char* flag_name,
int32_t* value) {
static bool ParseGoogleMockIntFlag(const char* str, const char* flag,
int* value) {
// Gets the value of the flag as a string.
const char* const value_str = ParseGoogleMockFlagValue(str, flag_name, true);
const char* const value_str = ParseGoogleMockFlagValue(str, flag, true);
// Aborts if the parsing failed.
if (value_str == nullptr) return false;
// Sets *value to the value of the flag.
return ParseInt32(Message() << "The value of flag --" << flag_name, value_str,
value);
return ParseInt32(Message() << "The value of flag --" << flag,
value_str, value);
}
// The internal implementation of InitGoogleMock().
@ -151,22 +152,11 @@ void InitGoogleMockImpl(int* argc, CharType** argv) {
const char* const arg = arg_string.c_str();
// Do we see a Google Mock flag?
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) {
if (ParseGoogleMockBoolFlag(arg, "catch_leaked_mocks",
&GMOCK_FLAG(catch_leaked_mocks)) ||
ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose)) ||
ParseGoogleMockIntFlag(arg, "default_mock_behavior",
&GMOCK_FLAG(default_mock_behavior))) {
// Yes. Shift the remainder of the argv list left by one. Note
// that argv has (*argc + 1) elements, the last one always being
// NULL. The following loop moves the trailing NULL element as

View File

@ -32,10 +32,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#if GTEST_OS_ESP8266 || GTEST_OS_ESP32
#if GTEST_OS_ESP8266
extern "C" {
#endif
#ifdef ARDUINO
void setup() {
// Since Google Mock depends on Google Test, InitGoogleMock() is
// also responsible for initializing Google Test. Therefore there's
@ -43,10 +40,6 @@ void setup() {
testing::InitGoogleMock();
}
void loop() { RUN_ALL_TESTS(); }
#if GTEST_OS_ESP8266
}
#endif
#else
// MS C++ compiler/linker has a bug on Windows (not on Windows CE), which

View File

@ -28,8 +28,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.
#
# Author: misterg@google.com (Gennadiy Civil)
#
# Bazel Build for Google C++ Testing Framework(Google Test)-googlemock
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test")
load("@rules_python//python:defs.bzl", "py_library", "py_test")
licenses(["notice"])
@ -40,7 +43,6 @@ cc_test(
size = "small",
srcs = glob(include = ["gmock-*.cc"]),
linkopts = select({
"//:qnx": [],
"//:windows": [],
"//conditions:default": ["-pthread"],
}),
@ -52,9 +54,6 @@ py_library(
name = "gmock_test_utils",
testonly = 1,
srcs = ["gmock_test_utils.py"],
deps = [
"//googletest/test:gtest_test_utils",
],
)
cc_binary(
@ -72,10 +71,6 @@ py_test(
":gmock_leak_test_",
":gmock_test_utils",
],
tags = [
"no_test_msvc2015",
"no_test_msvc2017",
],
)
cc_test(
@ -103,10 +98,7 @@ py_test(
":gmock_output_test_",
":gmock_output_test_golden.txt",
],
tags = [
"no_test_msvc2015",
"no_test_msvc2017",
],
python_version = "PY2",
deps = [":gmock_test_utils"],
)

View File

@ -32,13 +32,11 @@
//
// This file tests the built-in actions.
// Silence C4100 (unreferenced formal parameter) for MSVC
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable:4100)
#if _MSC_VER == 1900
// and silence C4800 (C4800: 'int *const ': forcing value
// Silence C4800 (C4800: 'int *const ': forcing value
// to bool 'true' or 'false') for MSVC 15
#ifdef _MSC_VER
#if _MSC_VER == 1900
# pragma warning(push)
# pragma warning(disable:4800)
#endif
#endif
@ -48,7 +46,6 @@
#include <iterator>
#include <memory>
#include <string>
#include <type_traits>
#include "gmock/gmock.h"
#include "gmock/internal/gmock-port.h"
#include "gtest/gtest.h"
@ -56,34 +53,36 @@
namespace {
using ::testing::_;
using ::testing::Action;
using ::testing::ActionInterface;
using ::testing::Assign;
using ::testing::ByMove;
using ::testing::ByRef;
using ::testing::DefaultValue;
using ::testing::DoAll;
using ::testing::DoDefault;
using ::testing::IgnoreResult;
using ::testing::Invoke;
using ::testing::InvokeWithoutArgs;
using ::testing::MakePolymorphicAction;
using ::testing::PolymorphicAction;
using ::testing::Return;
using ::testing::ReturnNew;
using ::testing::ReturnNull;
using ::testing::ReturnRef;
using ::testing::ReturnRefOfCopy;
using ::testing::ReturnRoundRobin;
using ::testing::SetArgPointee;
using ::testing::SetArgumentPointee;
using ::testing::Unused;
using ::testing::WithArgs;
using ::testing::internal::BuiltInDefaultValue;
// This list should be kept sorted.
using testing::_;
using testing::Action;
using testing::ActionInterface;
using testing::Assign;
using testing::ByMove;
using testing::ByRef;
using testing::DefaultValue;
using testing::DoAll;
using testing::DoDefault;
using testing::IgnoreResult;
using testing::Invoke;
using testing::InvokeWithoutArgs;
using testing::MakePolymorphicAction;
using testing::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::WithArgs;
using testing::internal::BuiltInDefaultValue;
using testing::internal::Int64;
using testing::internal::UInt64;
#if !GTEST_OS_WINDOWS_MOBILE
using ::testing::SetErrnoAndReturn;
using testing::SetErrnoAndReturn;
#endif
// Tests that BuiltInDefaultValue<T*>::Get() returns NULL.
@ -122,9 +121,8 @@ TEST(BuiltInDefaultValueTest, IsZeroForNumericTypes) {
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(0U, BuiltInDefaultValue<UInt64>::Get());
EXPECT_EQ(0, BuiltInDefaultValue<Int64>::Get());
EXPECT_EQ(0, BuiltInDefaultValue<float>::Get());
EXPECT_EQ(0, BuiltInDefaultValue<double>::Get());
}
@ -147,9 +145,8 @@ TEST(BuiltInDefaultValueTest, ExistsForNumericTypes) {
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<UInt64>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<Int64>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<float>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<double>::Exists());
}
@ -384,7 +381,7 @@ TEST(ActionInterfaceTest, MakeAction) {
EXPECT_EQ(5, action.Perform(std::make_tuple(true, 5)));
}
// Tests that Action<F> can be constructed from a pointer to
// Tests that Action<F> can be contructed from a pointer to
// ActionInterface<F>.
TEST(ActionTest, CanBeConstructedFromActionInterface) {
Action<MyGlobalFunction> action(new MyActionImpl);
@ -576,6 +573,8 @@ class FromType {
private:
bool* const converted_;
GTEST_DISALLOW_ASSIGN_(FromType);
};
class ToType {
@ -647,41 +646,6 @@ TEST(ReturnRefTest, IsCovariant) {
EXPECT_EQ(&derived, &a.Perform(std::make_tuple()));
}
template <typename T, typename = decltype(ReturnRef(std::declval<T&&>()))>
bool CanCallReturnRef(T&&) { return true; }
bool CanCallReturnRef(Unused) { return false; }
// Tests that ReturnRef(v) is working with non-temporaries (T&)
TEST(ReturnRefTest, WorksForNonTemporary) {
int scalar_value = 123;
EXPECT_TRUE(CanCallReturnRef(scalar_value));
std::string non_scalar_value("ABC");
EXPECT_TRUE(CanCallReturnRef(non_scalar_value));
const int const_scalar_value{321};
EXPECT_TRUE(CanCallReturnRef(const_scalar_value));
const std::string const_non_scalar_value("CBA");
EXPECT_TRUE(CanCallReturnRef(const_non_scalar_value));
}
// Tests that ReturnRef(v) is not working with temporaries (T&&)
TEST(ReturnRefTest, DoesNotWorkForTemporary) {
auto scalar_value = []() -> int { return 123; };
EXPECT_FALSE(CanCallReturnRef(scalar_value()));
auto non_scalar_value = []() -> std::string { return "ABC"; };
EXPECT_FALSE(CanCallReturnRef(non_scalar_value()));
// cannot use here callable returning "const scalar type",
// because such const for scalar return type is ignored
EXPECT_FALSE(CanCallReturnRef(static_cast<const int>(321)));
auto const_non_scalar_value = []() -> const std::string { return "CBA"; };
EXPECT_FALSE(CanCallReturnRef(const_non_scalar_value()));
}
// Tests that ReturnRefOfCopy(v) works for reference types.
TEST(ReturnRefOfCopyTest, WorksForReference) {
int n = 42;
@ -706,31 +670,6 @@ TEST(ReturnRefOfCopyTest, IsCovariant) {
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 {
@ -795,7 +734,7 @@ TEST(DoDefaultDeathTest, DiesIfUsedInCompositeAction) {
}
// Tests that DoDefault() returns the default value set by
// DefaultValue<T>::Set() when it's not overridden by an ON_CALL().
// DefaultValue<T>::Set() when it's not overriden by an ON_CALL().
TEST(DoDefaultTest, ReturnsUserSpecifiedPerTypeDefaultValueWhenThereIsOne) {
DefaultValue<int>::Set(1);
MockClass mock;
@ -1291,52 +1230,6 @@ TEST(ByRefTest, PrintsCorrectly) {
EXPECT_EQ(expected.str(), actual.str());
}
struct UnaryConstructorClass {
explicit UnaryConstructorClass(int v) : value(v) {}
int value;
};
// Tests using ReturnNew() with a unary constructor.
TEST(ReturnNewTest, Unary) {
Action<UnaryConstructorClass*()> a = ReturnNew<UnaryConstructorClass>(4000);
UnaryConstructorClass* c = a.Perform(std::make_tuple());
EXPECT_EQ(4000, c->value);
delete c;
}
TEST(ReturnNewTest, UnaryWorksWhenMockMethodHasArgs) {
Action<UnaryConstructorClass*(bool, int)> a =
ReturnNew<UnaryConstructorClass>(4000);
UnaryConstructorClass* c = a.Perform(std::make_tuple(false, 5));
EXPECT_EQ(4000, c->value);
delete c;
}
TEST(ReturnNewTest, UnaryWorksWhenMockMethodReturnsPointerToConst) {
Action<const UnaryConstructorClass*()> a =
ReturnNew<UnaryConstructorClass>(4000);
const UnaryConstructorClass* c = a.Perform(std::make_tuple());
EXPECT_EQ(4000, c->value);
delete c;
}
class TenArgConstructorClass {
public:
TenArgConstructorClass(int a1, int a2, int a3, int a4, int a5, int a6, int a7,
int a8, int a9, int a10)
: value_(a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10) {}
int value_;
};
// Tests using ReturnNew() with a 10-argument constructor.
TEST(ReturnNewTest, ConstructorThatTakes10Arguments) {
Action<TenArgConstructorClass*()> a = ReturnNew<TenArgConstructorClass>(
1000000000, 200000000, 30000000, 4000000, 500000, 60000, 7000, 800, 90,
0);
TenArgConstructorClass* c = a.Perform(std::make_tuple());
EXPECT_EQ(1234567890, c->value_);
delete c;
}
std::unique_ptr<int> UniquePtrSource() {
return std::unique_ptr<int>(new int(19));
@ -1515,19 +1408,8 @@ TEST(FunctorActionTest, TypeConversion) {
EXPECT_EQ(1, s2.Perform(std::make_tuple("hello")));
// Also between the lambda and the action itself.
const Action<bool(std::string)> x1 = [](Unused) { return 42; };
const Action<bool(std::string)> x2 = [] { return 42; };
EXPECT_TRUE(x1.Perform(std::make_tuple("hello")));
EXPECT_TRUE(x2.Perform(std::make_tuple("hello")));
// Ensure decay occurs where required.
std::function<int()> f = [] { return 7; };
Action<int(int)> d = f;
f = nullptr;
EXPECT_EQ(7, d.Perform(std::make_tuple(1)));
// Ensure creation of an empty action succeeds.
Action<void(int)>(nullptr);
const Action<bool(std::string)> x = [](Unused) { return 42; };
EXPECT_TRUE(x.Perform(std::make_tuple("hello")));
}
TEST(FunctorActionTest, UnusedArguments) {
@ -1552,26 +1434,6 @@ TEST(MoveOnlyArgumentsTest, ReturningActions) {
EXPECT_EQ(x, 3);
}
ACTION(ReturnArity) {
return std::tuple_size<args_type>::value;
}
TEST(ActionMacro, LargeArity) {
EXPECT_EQ(
1, testing::Action<int(int)>(ReturnArity()).Perform(std::make_tuple(0)));
EXPECT_EQ(
10,
testing::Action<int(int, int, int, int, int, int, int, int, int, int)>(
ReturnArity())
.Perform(std::make_tuple(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)));
EXPECT_EQ(
20,
testing::Action<int(int, int, int, int, int, int, int, int, int, int, int,
int, int, int, int, int, int, int, int, int)>(
ReturnArity())
.Perform(std::make_tuple(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19)));
}
} // Unnamed namespace

View File

@ -0,0 +1,16 @@
#include "gmock/gmock.h"
#include <memory>
#include <string>
#if defined(TEST_MOCK_METHOD_INVALID_CONST_SPEC)
struct Base {
MOCK_METHOD(int, F, (), (onst));
};
#else
// Sanity check - this should compile.
#endif

View File

@ -0,0 +1,43 @@
"""Negative compilation tests for Google Mock macro MOCK_METHOD."""
import os
import sys
IS_LINUX = os.name == "posix" and os.uname()[0] == "Linux"
if not IS_LINUX:
sys.stderr.write(
"WARNING: Negative compilation tests are not supported on this platform")
sys.exit(0)
# Suppresses the 'Import not at the top of the file' lint complaint.
# pylint: disable-msg=C6204
from google3.testing.pybase import fake_target_util
from google3.testing.pybase import googletest
# pylint: enable-msg=C6204
class GMockMethodNCTest(googletest.TestCase):
"""Negative compilation tests for MOCK_METHOD."""
# The class body is intentionally empty. The actual test*() methods
# will be defined at run time by a call to
# DefineNegativeCompilationTests() later.
pass
# Defines a list of test specs, where each element is a tuple
# (test name, list of regexes for matching the compiler errors).
TEST_SPECS = [
("MOCK_METHOD_INVALID_CONST_SPEC",
[r"onst cannot be recognized as a valid specification modifier"]),
]
# Define a test method in GMockNCTest for each element in TEST_SPECS.
fake_target_util.DefineNegativeCompilationTests(
GMockMethodNCTest,
"google3/third_party/googletest/googlemock/test/gmock-function-mocker_nc",
"gmock-function-mocker_nc.o", TEST_SPECS)
if __name__ == "__main__":
googletest.main()

View File

@ -31,7 +31,7 @@
// Google Mock - a framework for writing C++ mock classes.
//
// This file tests the function mocker classes.
#include "gmock/gmock-function-mocker.h"
#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
@ -40,11 +40,8 @@
# include <objbase.h>
#endif // GTEST_OS_WINDOWS
#include <functional>
#include <map>
#include <string>
#include <type_traits>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@ -104,20 +101,6 @@ class FooInterface {
virtual int TypeWithComma(const std::map<int, std::string>& a_map) = 0;
virtual int TypeWithTemplatedCopyCtor(const TemplatedCopyable<int>&) = 0;
virtual int (*ReturnsFunctionPointer1(int))(bool) = 0;
using fn_ptr = int (*)(bool);
virtual fn_ptr ReturnsFunctionPointer2(int) = 0;
virtual int RefQualifiedConstRef() const& = 0;
virtual int RefQualifiedConstRefRef() const&& = 0;
virtual int RefQualifiedRef() & = 0;
virtual int RefQualifiedRefRef() && = 0;
virtual int RefQualifiedOverloaded() const& = 0;
virtual int RefQualifiedOverloaded() const&& = 0;
virtual int RefQualifiedOverloaded() & = 0;
virtual int RefQualifiedOverloaded() && = 0;
#if GTEST_OS_WINDOWS
STDMETHOD_(int, CTNullary)() = 0;
STDMETHOD_(bool, CTUnary)(int x) = 0;
@ -176,9 +159,6 @@ class MockFoo : public FooInterface {
MOCK_METHOD(int, TypeWithTemplatedCopyCtor,
(const TemplatedCopyable<int>&)); // NOLINT
MOCK_METHOD(int (*)(bool), ReturnsFunctionPointer1, (int), ());
MOCK_METHOD(fn_ptr, ReturnsFunctionPointer2, (int), ());
#if GTEST_OS_WINDOWS
MOCK_METHOD(int, CTNullary, (), (Calltype(STDMETHODCALLTYPE)));
MOCK_METHOD(bool, CTUnary, (int), (Calltype(STDMETHODCALLTYPE)));
@ -191,301 +171,189 @@ class MockFoo : public FooInterface {
(Calltype(STDMETHODCALLTYPE)));
#endif // GTEST_OS_WINDOWS
// Test reference qualified functions.
MOCK_METHOD(int, RefQualifiedConstRef, (), (const, ref(&), override));
MOCK_METHOD(int, RefQualifiedConstRefRef, (), (const, ref(&&), override));
MOCK_METHOD(int, RefQualifiedRef, (), (ref(&), override));
MOCK_METHOD(int, RefQualifiedRefRef, (), (ref(&&), override));
MOCK_METHOD(int, RefQualifiedOverloaded, (), (const, ref(&), override));
MOCK_METHOD(int, RefQualifiedOverloaded, (), (const, ref(&&), override));
MOCK_METHOD(int, RefQualifiedOverloaded, (), (ref(&), override));
MOCK_METHOD(int, RefQualifiedOverloaded, (), (ref(&&), override));
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo);
};
class LegacyMockFoo : public FooInterface {
public:
LegacyMockFoo() {}
// Makes sure that a mock function parameter can be named.
MOCK_METHOD1(VoidReturning, void(int n)); // NOLINT
MOCK_METHOD0(Nullary, int()); // NOLINT
// Makes sure that a mock function parameter can be unnamed.
MOCK_METHOD1(Unary, bool(int)); // NOLINT
MOCK_METHOD2(Binary, long(short, int)); // NOLINT
MOCK_METHOD10(Decimal, int(bool, char, short, int, long, float, // NOLINT
double, unsigned, char*, const std::string& str));
MOCK_METHOD1(TakesNonConstReference, bool(int&)); // NOLINT
MOCK_METHOD1(TakesConstReference, std::string(const int&));
MOCK_METHOD1(TakesConst, bool(const int)); // NOLINT
// Tests that the function return type can contain unprotected comma.
MOCK_METHOD0(ReturnTypeWithComma, std::map<int, std::string>());
MOCK_CONST_METHOD1(ReturnTypeWithComma,
std::map<int, std::string>(int)); // NOLINT
MOCK_METHOD0(OverloadedOnArgumentNumber, int()); // NOLINT
MOCK_METHOD1(OverloadedOnArgumentNumber, int(int)); // NOLINT
MOCK_METHOD1(OverloadedOnArgumentType, int(int)); // NOLINT
MOCK_METHOD1(OverloadedOnArgumentType, char(char)); // NOLINT
MOCK_METHOD0(OverloadedOnConstness, int()); // NOLINT
MOCK_CONST_METHOD0(OverloadedOnConstness, char()); // NOLINT
MOCK_METHOD1(TypeWithHole, int(int (*)())); // NOLINT
MOCK_METHOD1(TypeWithComma,
int(const std::map<int, std::string>&)); // NOLINT
MOCK_METHOD1(TypeWithTemplatedCopyCtor,
int(const TemplatedCopyable<int>&)); // NOLINT
MOCK_METHOD1(ReturnsFunctionPointer1, int (*(int))(bool));
MOCK_METHOD1(ReturnsFunctionPointer2, fn_ptr(int));
#if GTEST_OS_WINDOWS
MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTNullary, int());
MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTUnary, bool(int)); // NOLINT
MOCK_METHOD10_WITH_CALLTYPE(STDMETHODCALLTYPE, CTDecimal,
int(bool b, char c, short d, int e, // NOLINT
long f, float g, double h, // NOLINT
unsigned i, char* j, const std::string& k));
MOCK_CONST_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTConst,
char(int)); // NOLINT
// Tests that the function return type can contain unprotected comma.
MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTReturnTypeWithComma,
std::map<int, std::string>());
#endif // GTEST_OS_WINDOWS
// We can't mock these with the old macros, but we need to define them to make
// it concrete.
int RefQualifiedConstRef() const& override { return 0; }
int RefQualifiedConstRefRef() const&& override { return 0; }
int RefQualifiedRef() & override { return 0; }
int RefQualifiedRefRef() && override { return 0; }
int RefQualifiedOverloaded() const& override { return 0; }
int RefQualifiedOverloaded() const&& override { return 0; }
int RefQualifiedOverloaded() & override { return 0; }
int RefQualifiedOverloaded() && override { return 0; }
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockFoo);
};
#ifdef _MSC_VER
# pragma warning(pop)
#endif
template <class T>
class FunctionMockerTest : public testing::Test {
class MockMethodFunctionMockerTest : public testing::Test {
protected:
FunctionMockerTest() : foo_(&mock_foo_) {}
MockMethodFunctionMockerTest() : foo_(&mock_foo_) {}
FooInterface* const foo_;
T mock_foo_;
MockFoo 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);
TEST_F(MockMethodFunctionMockerTest, MocksVoidFunction) {
EXPECT_CALL(mock_foo_, VoidReturning(Lt(100)));
foo_->VoidReturning(0);
}
// Tests mocking a nullary function.
TYPED_TEST(FunctionMockerTest, MocksNullaryFunction) {
EXPECT_CALL(this->mock_foo_, Nullary())
TEST_F(MockMethodFunctionMockerTest, MocksNullaryFunction) {
EXPECT_CALL(mock_foo_, Nullary())
.WillOnce(DoDefault())
.WillOnce(Return(1));
EXPECT_EQ(0, this->foo_->Nullary());
EXPECT_EQ(1, this->foo_->Nullary());
EXPECT_EQ(0, foo_->Nullary());
EXPECT_EQ(1, foo_->Nullary());
}
// Tests mocking a unary function.
TYPED_TEST(FunctionMockerTest, MocksUnaryFunction) {
EXPECT_CALL(this->mock_foo_, Unary(Eq(2))).Times(2).WillOnce(Return(true));
TEST_F(MockMethodFunctionMockerTest, MocksUnaryFunction) {
EXPECT_CALL(mock_foo_, Unary(Eq(2)))
.Times(2)
.WillOnce(Return(true));
EXPECT_TRUE(this->foo_->Unary(2));
EXPECT_FALSE(this->foo_->Unary(2));
EXPECT_TRUE(foo_->Unary(2));
EXPECT_FALSE(foo_->Unary(2));
}
// Tests mocking a binary function.
TYPED_TEST(FunctionMockerTest, MocksBinaryFunction) {
EXPECT_CALL(this->mock_foo_, Binary(2, _)).WillOnce(Return(3));
TEST_F(MockMethodFunctionMockerTest, MocksBinaryFunction) {
EXPECT_CALL(mock_foo_, Binary(2, _))
.WillOnce(Return(3));
EXPECT_EQ(3, this->foo_->Binary(2, 1));
EXPECT_EQ(3, 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"))
TEST_F(MockMethodFunctionMockerTest, MocksDecimalFunction) {
EXPECT_CALL(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"));
EXPECT_EQ(5, 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) {
TEST_F(MockMethodFunctionMockerTest,
MocksFunctionWithNonConstReferenceArgument) {
int a = 0;
EXPECT_CALL(this->mock_foo_, TakesNonConstReference(Ref(a)))
EXPECT_CALL(mock_foo_, TakesNonConstReference(Ref(a)))
.WillOnce(Return(true));
EXPECT_TRUE(this->foo_->TakesNonConstReference(a));
EXPECT_TRUE(foo_->TakesNonConstReference(a));
}
// Tests mocking a function that takes a const reference.
TYPED_TEST(FunctionMockerTest, MocksFunctionWithConstReferenceArgument) {
TEST_F(MockMethodFunctionMockerTest, MocksFunctionWithConstReferenceArgument) {
int a = 0;
EXPECT_CALL(this->mock_foo_, TakesConstReference(Ref(a)))
EXPECT_CALL(mock_foo_, TakesConstReference(Ref(a)))
.WillOnce(Return("Hello"));
EXPECT_EQ("Hello", this->foo_->TakesConstReference(a));
EXPECT_EQ("Hello", 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());
TEST_F(MockMethodFunctionMockerTest, MocksFunctionWithConstArgument) {
EXPECT_CALL(mock_foo_, TakesConst(Lt(10)))
.WillOnce(DoDefault());
EXPECT_FALSE(this->foo_->TakesConst(5));
EXPECT_FALSE(foo_->TakesConst(5));
}
// Tests mocking functions overloaded on the number of arguments.
TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentNumber) {
EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentNumber())
TEST_F(MockMethodFunctionMockerTest, MocksFunctionsOverloadedOnArgumentNumber) {
EXPECT_CALL(mock_foo_, OverloadedOnArgumentNumber())
.WillOnce(Return(1));
EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentNumber(_))
EXPECT_CALL(mock_foo_, OverloadedOnArgumentNumber(_))
.WillOnce(Return(2));
EXPECT_EQ(2, this->foo_->OverloadedOnArgumentNumber(1));
EXPECT_EQ(1, this->foo_->OverloadedOnArgumentNumber());
EXPECT_EQ(2, foo_->OverloadedOnArgumentNumber(1));
EXPECT_EQ(1, foo_->OverloadedOnArgumentNumber());
}
// Tests mocking functions overloaded on the types of argument.
TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentType) {
EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentType(An<int>()))
TEST_F(MockMethodFunctionMockerTest, MocksFunctionsOverloadedOnArgumentType) {
EXPECT_CALL(mock_foo_, OverloadedOnArgumentType(An<int>()))
.WillOnce(Return(1));
EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentType(TypedEq<char>('a')))
EXPECT_CALL(mock_foo_, OverloadedOnArgumentType(TypedEq<char>('a')))
.WillOnce(Return('b'));
EXPECT_EQ(1, this->foo_->OverloadedOnArgumentType(0));
EXPECT_EQ('b', this->foo_->OverloadedOnArgumentType('a'));
EXPECT_EQ(1, foo_->OverloadedOnArgumentType(0));
EXPECT_EQ('b', 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())
TEST_F(MockMethodFunctionMockerTest,
MocksFunctionsOverloadedOnConstnessOfThis) {
EXPECT_CALL(mock_foo_, OverloadedOnConstness());
EXPECT_CALL(Const(mock_foo_), OverloadedOnConstness())
.WillOnce(Return('a'));
EXPECT_EQ(0, this->foo_->OverloadedOnConstness());
EXPECT_EQ('a', Const(*this->foo_).OverloadedOnConstness());
EXPECT_EQ(0, foo_->OverloadedOnConstness());
EXPECT_EQ('a', Const(*foo_).OverloadedOnConstness());
}
TYPED_TEST(FunctionMockerTest, MocksReturnTypeWithComma) {
TEST_F(MockMethodFunctionMockerTest, 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_CALL(mock_foo_, ReturnTypeWithComma())
.WillOnce(Return(a_map));
EXPECT_CALL(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));
EXPECT_EQ(a_map, mock_foo_.ReturnTypeWithComma());
EXPECT_EQ(a_map, mock_foo_.ReturnTypeWithComma(42));
}
TYPED_TEST(FunctionMockerTest, MocksTypeWithTemplatedCopyCtor) {
EXPECT_CALL(this->mock_foo_, TypeWithTemplatedCopyCtor(_))
.WillOnce(Return(true));
EXPECT_TRUE(this->foo_->TypeWithTemplatedCopyCtor(TemplatedCopyable<int>()));
TEST_F(MockMethodFunctionMockerTest, MocksTypeWithTemplatedCopyCtor) {
EXPECT_CALL(mock_foo_, TypeWithTemplatedCopyCtor(_)).WillOnce(Return(true));
EXPECT_TRUE(foo_->TypeWithTemplatedCopyCtor(TemplatedCopyable<int>()));
}
#if GTEST_OS_WINDOWS
// Tests mocking a nullary function with calltype.
TYPED_TEST(FunctionMockerTest, MocksNullaryFunctionWithCallType) {
EXPECT_CALL(this->mock_foo_, CTNullary())
TEST_F(MockMethodFunctionMockerTest, MocksNullaryFunctionWithCallType) {
EXPECT_CALL(mock_foo_, CTNullary())
.WillOnce(Return(-1))
.WillOnce(Return(0));
EXPECT_EQ(-1, this->foo_->CTNullary());
EXPECT_EQ(0, this->foo_->CTNullary());
EXPECT_EQ(-1, foo_->CTNullary());
EXPECT_EQ(0, foo_->CTNullary());
}
// Tests mocking a unary function with calltype.
TYPED_TEST(FunctionMockerTest, MocksUnaryFunctionWithCallType) {
EXPECT_CALL(this->mock_foo_, CTUnary(Eq(2)))
TEST_F(MockMethodFunctionMockerTest, MocksUnaryFunctionWithCallType) {
EXPECT_CALL(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));
EXPECT_TRUE(foo_->CTUnary(2));
EXPECT_FALSE(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"))
TEST_F(MockMethodFunctionMockerTest, MocksDecimalFunctionWithCallType) {
EXPECT_CALL(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"));
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.
TYPED_TEST(FunctionMockerTest, MocksFunctionsConstFunctionWithCallType) {
EXPECT_CALL(Const(this->mock_foo_), CTConst(_)).WillOnce(Return('a'));
TEST_F(MockMethodFunctionMockerTest, MocksFunctionsConstFunctionWithCallType) {
EXPECT_CALL(Const(mock_foo_), CTConst(_))
.WillOnce(Return('a'));
EXPECT_EQ('a', Const(*this->foo_).CTConst(0));
EXPECT_EQ('a', Const(*foo_).CTConst(0));
}
TYPED_TEST(FunctionMockerTest, MocksReturnTypeWithCommaAndCallType) {
TEST_F(MockMethodFunctionMockerTest, MocksReturnTypeWithCommaAndCallType) {
const std::map<int, std::string> a_map;
EXPECT_CALL(this->mock_foo_, CTReturnTypeWithComma()).WillOnce(Return(a_map));
EXPECT_CALL(mock_foo_, CTReturnTypeWithComma())
.WillOnce(Return(a_map));
EXPECT_EQ(a_map, this->mock_foo_.CTReturnTypeWithComma());
EXPECT_EQ(a_map, 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() {}
@ -496,33 +364,20 @@ class MockB {
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockB);
};
class LegacyMockB {
public:
LegacyMockB() {}
MOCK_METHOD0(DoB, void());
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockB);
};
template <typename T>
class ExpectCallTest : public ::testing::Test {};
using ExpectCallTestTypes = ::testing::Types<MockB, LegacyMockB>;
TYPED_TEST_SUITE(ExpectCallTest, ExpectCallTestTypes);
// Tests that functions with no EXPECT_CALL() rules can be called any
// number of times.
TYPED_TEST(ExpectCallTest, UnmentionedFunctionCanBeCalledAnyNumberOfTimes) {
{ TypeParam b; }
TEST(MockMethodExpectCallTest, UnmentionedFunctionCanBeCalledAnyNumberOfTimes) {
{
MockB b;
}
{
TypeParam b;
MockB b;
b.DoB();
}
{
TypeParam b;
MockB b;
b.DoB();
b.DoB();
}
@ -561,33 +416,9 @@ class MockStack : public StackInterface<T> {
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockStack);
};
template <typename T>
class LegacyMockStack : public StackInterface<T> {
public:
LegacyMockStack() {}
MOCK_METHOD1_T(Push, void(const T& elem));
MOCK_METHOD0_T(Pop, void());
MOCK_CONST_METHOD0_T(GetSize, int()); // NOLINT
MOCK_CONST_METHOD0_T(GetTop, const T&());
// Tests that the function return type can contain unprotected comma.
MOCK_METHOD0_T(ReturnTypeWithComma, std::map<int, int>());
MOCK_CONST_METHOD1_T(ReturnTypeWithComma, std::map<int, int>(int)); // NOLINT
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockStack);
};
template <typename T>
class TemplateMockTest : public ::testing::Test {};
using TemplateMockTestTypes =
::testing::Types<MockStack<int>, LegacyMockStack<int>>;
TYPED_TEST_SUITE(TemplateMockTest, TemplateMockTestTypes);
// Tests that template mock works.
TYPED_TEST(TemplateMockTest, Works) {
TypeParam mock;
TEST(MockMethodTemplateMockTest, Works) {
MockStack<int> mock;
EXPECT_CALL(mock, GetSize())
.WillOnce(Return(0))
@ -608,8 +439,8 @@ TYPED_TEST(TemplateMockTest, Works) {
EXPECT_EQ(0, mock.GetSize());
}
TYPED_TEST(TemplateMockTest, MethodWithCommaInReturnTypeWorks) {
TypeParam mock;
TEST(MockMethodTemplateMockTest, MethodWithCommaInReturnTypeWorks) {
MockStack<int> mock;
const std::map<int, int> a_map;
EXPECT_CALL(mock, ReturnTypeWithComma())
@ -653,31 +484,9 @@ class MockStackWithCallType : public StackInterfaceWithCallType<T> {
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockStackWithCallType);
};
template <typename T>
class LegacyMockStackWithCallType : public StackInterfaceWithCallType<T> {
public:
LegacyMockStackWithCallType() {}
MOCK_METHOD1_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Push, void(const T& elem));
MOCK_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Pop, void());
MOCK_CONST_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, GetSize, int());
MOCK_CONST_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, GetTop, const T&());
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockStackWithCallType);
};
template <typename T>
class TemplateMockTestWithCallType : public ::testing::Test {};
using TemplateMockTestWithCallTypeTypes =
::testing::Types<MockStackWithCallType<int>,
LegacyMockStackWithCallType<int>>;
TYPED_TEST_SUITE(TemplateMockTestWithCallType,
TemplateMockTestWithCallTypeTypes);
// Tests that template mock with calltype works.
TYPED_TEST(TemplateMockTestWithCallType, Works) {
TypeParam mock;
TEST(MockMethodTemplateMockTestWithCallType, Works) {
MockStackWithCallType<int> mock;
EXPECT_CALL(mock, GetSize())
.WillOnce(Return(0))
@ -704,11 +513,6 @@ TYPED_TEST(TemplateMockTestWithCallType, Works) {
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() {}
@ -719,25 +523,8 @@ class MockOverloadedOnArgNumber {
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockOverloadedOnArgNumber);
};
class LegacyMockOverloadedOnArgNumber {
public:
LegacyMockOverloadedOnArgNumber() {}
LEGACY_MY_MOCK_METHODS1_;
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockOverloadedOnArgNumber);
};
template <typename T>
class OverloadedMockMethodTest : public ::testing::Test {};
using OverloadedMockMethodTestTypes =
::testing::Types<MockOverloadedOnArgNumber,
LegacyMockOverloadedOnArgNumber>;
TYPED_TEST_SUITE(OverloadedMockMethodTest, OverloadedMockMethodTestTypes);
TYPED_TEST(OverloadedMockMethodTest, CanOverloadOnArgNumberInMacroBody) {
TypeParam mock;
TEST(MockMethodOverloadedMockMethodTest, CanOverloadOnArgNumberInMacroBody) {
MockOverloadedOnArgNumber mock;
EXPECT_CALL(mock, Overloaded());
EXPECT_CALL(mock, Overloaded(1)).WillOnce(Return(2));
EXPECT_CALL(mock, Overloaded(true, 1)).WillOnce(Return(true));
@ -845,68 +632,6 @@ TEST(MockMethodMockFunctionTest, AsStdFunctionWithReferenceParameter) {
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, ());
@ -924,62 +649,11 @@ struct MockMethodSizes4 {
MOCK_METHOD(void, func, (int, int, int, int));
};
struct LegacyMockMethodSizes0 {
MOCK_METHOD0(func, void());
};
struct LegacyMockMethodSizes1 {
MOCK_METHOD1(func, void(int));
};
struct LegacyMockMethodSizes2 {
MOCK_METHOD2(func, void(int, int));
};
struct LegacyMockMethodSizes3 {
MOCK_METHOD3(func, void(int, int, int));
};
struct LegacyMockMethodSizes4 {
MOCK_METHOD4(func, void(int, int, int, int));
};
TEST(MockMethodMockFunctionTest, MockMethodSizeOverhead) {
EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes1));
EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes2));
EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes3));
EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes4));
EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes1));
EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes2));
EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes3));
EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes4));
EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(MockMethodSizes0));
}
void hasTwoParams(int, int);
void MaybeThrows();
void DoesntThrow() noexcept;
struct MockMethodNoexceptSpecifier {
MOCK_METHOD(void, func1, (), (noexcept));
MOCK_METHOD(void, func2, (), (noexcept(true)));
MOCK_METHOD(void, func3, (), (noexcept(false)));
MOCK_METHOD(void, func4, (), (noexcept(noexcept(MaybeThrows()))));
MOCK_METHOD(void, func5, (), (noexcept(noexcept(DoesntThrow()))));
MOCK_METHOD(void, func6, (), (noexcept(noexcept(DoesntThrow())), const));
MOCK_METHOD(void, func7, (), (const, noexcept(noexcept(DoesntThrow()))));
// Put commas in the noexcept expression
MOCK_METHOD(void, func8, (), (noexcept(noexcept(hasTwoParams(1, 2))), const));
};
TEST(MockMethodMockFunctionTest, NoexceptSpecifierPreserved) {
EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func1()));
EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func2()));
EXPECT_FALSE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func3()));
EXPECT_FALSE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func4()));
EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func5()));
EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func6()));
EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func7()));
EXPECT_EQ(noexcept(std::declval<MockMethodNoexceptSpecifier>().func8()),
noexcept(hasTwoParams(1, 2)));
}
} // namespace gmock_function_mocker_test

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,659 @@
// 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"
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;
template<typename T>
class TemplatedCopyable {
public:
TemplatedCopyable() {}
template <typename U>
TemplatedCopyable(const U& other) {} // NOLINT
};
class FooInterface {
public:
virtual ~FooInterface() {}
virtual void VoidReturning(int x) = 0;
virtual int Nullary() = 0;
virtual bool Unary(int x) = 0;
virtual long Binary(short x, int y) = 0; // NOLINT
virtual int Decimal(bool b, char c, short d, int e, long f, // NOLINT
float g, double h, unsigned i, char* j,
const std::string& k) = 0;
virtual bool TakesNonConstReference(int& n) = 0; // NOLINT
virtual std::string TakesConstReference(const int& n) = 0;
virtual bool TakesConst(const int x) = 0;
virtual int OverloadedOnArgumentNumber() = 0;
virtual int OverloadedOnArgumentNumber(int n) = 0;
virtual int OverloadedOnArgumentType(int n) = 0;
virtual char OverloadedOnArgumentType(char c) = 0;
virtual int OverloadedOnConstness() = 0;
virtual char OverloadedOnConstness() const = 0;
virtual int TypeWithHole(int (*func)()) = 0;
virtual int TypeWithComma(const std::map<int, std::string>& a_map) = 0;
virtual int TypeWithTemplatedCopyCtor(
const TemplatedCopyable<int>& a_vector) = 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&));
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
#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,
nullptr, "hi"))
.WillOnce(Return(5));
EXPECT_EQ(5, foo_->Decimal(true, 'a', 0, 0, 1, 0, 0, 5, nullptr, "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));
}
// 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));
}
// 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));
}
TEST_F(FunctionMockerTest, MocksTypeWithTemplatedCopyCtor) {
EXPECT_CALL(mock_foo_, TypeWithTemplatedCopyCtor(_)).WillOnce(Return(true));
EXPECT_TRUE(foo_->TypeWithTemplatedCopyCtor(TemplatedCopyable<int>()));
}
#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,
nullptr, "hi"))
.WillOnce(Return(10));
EXPECT_EQ(10, foo_->CTDecimal(true, 'a', 0, 0, 1, 0, 0, 5, nullptr, "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));
}
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);
}
TEST(MockFunctionTest, 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));
}
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

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More