Merge pull request #163 from DanielSWolf/feature/maintenance
Maintenance
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.2)
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
|
||||
include(appInfo.cmake)
|
||||
|
||||
|
|
15
LICENSE.md
|
@ -79,21 +79,6 @@ The [CMU Flite](http://www.festvox.org/flite/) engine is released under a **BSD*
|
|||
>
|
||||
> CARNEGIE MELLON UNIVERSITY AND THE CONTRIBUTORS TO THIS WORK DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY NOR THE CONTRIBUTORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
### `[googletest]` Google Test
|
||||
|
||||
The [Google Test](https://github.com/google/googletest) framework is released under the **3-clause BSD License**.
|
||||
|
||||
> 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.
|
||||
|
||||
### `[gsl]` Guidelines Support Library
|
||||
|
||||
The [Guidelines Support Library](https://github.com/Microsoft/GSL) is released under the **MIT License (MIT)**.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.2)
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
|
||||
set(appName "Rhubarb Lip Sync")
|
||||
set(appVersionMajor 1)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.2)
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
|
||||
set(afterEffectsFiles
|
||||
"Rhubarb Lip Sync.jsx"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.2)
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
|
||||
add_custom_target(
|
||||
rhubarbForSpine ALL
|
||||
|
|
|
@ -15,7 +15,7 @@ class MainApp : App(MainView::class) {
|
|||
|
||||
private fun setIcon() {
|
||||
// Set icon for windows
|
||||
for (iconSize in listOf(16, 32, 48, 256)) {
|
||||
for (iconSize in listOf(16, 20, 24, 32, 48, 64, 256)) {
|
||||
addStageIcon(Image(this.javaClass.getResourceAsStream("/icon-$iconSize.png")))
|
||||
}
|
||||
|
||||
|
|
Before Width: | Height: | Size: 386 B After Width: | Height: | Size: 742 B |
After Width: | Height: | Size: 847 B |
After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 942 B After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.9 KiB |
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.2)
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
|
||||
set(vegasFiles
|
||||
"Debug Rhubarb.cs"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.10)
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
|
||||
include(FetchContent)
|
||||
include("../appInfo.cmake")
|
||||
|
||||
# Support legacy OS X versions
|
||||
|
@ -33,6 +34,9 @@ elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
|||
|
||||
# Assume UTF-8 encoding for source files and encode string constants in UTF-8
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8")
|
||||
|
||||
# Ignore warnings we can't fix right now
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING")
|
||||
endif()
|
||||
|
||||
# Use UTF-8 throughout
|
||||
|
@ -50,13 +54,10 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
|||
# Define libraries
|
||||
|
||||
# ... Boost
|
||||
set(Boost_USE_STATIC_LIBS ON) # Use static libs
|
||||
set(Boost_USE_MULTITHREADED ON) # Enable multithreading support
|
||||
set(Boost_USE_STATIC_RUNTIME ON) # Use static C++ runtime
|
||||
set(Boost_NO_BOOST_CMAKE ON) # Workaround for https://gitlab.kitware.com/cmake/cmake/-/issues/18865
|
||||
cmake_policy(SET CMP0167 OLD) # Use the legacy Boost CMake integration
|
||||
find_package(Boost 1.54 REQUIRED)
|
||||
include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
|
||||
link_libraries(${Boost_LIBRARIES}) # Just about every project needs Boost
|
||||
link_libraries(Boost::headers) # Just about every project needs Boost, but just the headers
|
||||
|
||||
# ... C++ Format
|
||||
FILE(GLOB cppFormatFiles "lib/cppformat/*.cc")
|
||||
|
@ -93,7 +94,13 @@ set_target_properties(pocketSphinx PROPERTIES FOLDER lib)
|
|||
include_directories(SYSTEM "lib/tclap-1.2.1/include")
|
||||
|
||||
# ... Google Test
|
||||
add_subdirectory("lib/googletest")
|
||||
FetchContent_Declare(googletest
|
||||
GIT_REPOSITORY https://github.com/google/googletest.git
|
||||
GIT_TAG v1.16.0
|
||||
)
|
||||
# For Windows: Prevent overriding the parent project's compiler/linker settings
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||
FetchContent_MakeAvailable(googletest)
|
||||
target_compile_options(gmock PRIVATE ${disableWarningsFlags})
|
||||
set_target_properties(gmock PROPERTIES FOLDER lib)
|
||||
target_compile_options(gmock_main PRIVATE ${disableWarningsFlags})
|
||||
|
@ -508,7 +515,6 @@ target_link_libraries(rhubarb
|
|||
target_compile_options(rhubarb PUBLIC ${enableWarningsFlags})
|
||||
|
||||
# Define test project
|
||||
#include_directories("${gtest_SOURCE_DIR}/include")
|
||||
set(TEST_FILES
|
||||
tests/stringToolsTests.cpp
|
||||
tests/TimelineTests.cpp
|
||||
|
@ -534,7 +540,7 @@ target_link_libraries(runTests
|
|||
function(copy_and_install sourceGlob relativeTargetDirectory)
|
||||
# Set `sourcePaths`
|
||||
file(GLOB sourcePaths "${sourceGlob}")
|
||||
|
||||
|
||||
foreach(sourcePath ${sourcePaths})
|
||||
if(NOT IS_DIRECTORY ${sourcePath})
|
||||
# Set `fileName`
|
||||
|
@ -559,7 +565,7 @@ endfunction()
|
|||
function(copy sourceGlob relativeTargetDirectory)
|
||||
# Set `sourcePaths`
|
||||
file(GLOB sourcePaths "${sourceGlob}")
|
||||
|
||||
|
||||
foreach(sourcePath ${sourcePaths})
|
||||
if(NOT IS_DIRECTORY ${sourcePath})
|
||||
# Set `fileName`
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
# Run manually to reformat a file:
|
||||
# clang-format -i --style=file <file>
|
||||
Language: Cpp
|
||||
BasedOnStyle: Google
|
|
@ -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.
|
|
@ -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.
|
||||
|
|
@ -1 +0,0 @@
|
|||
blank_issues_enabled: false
|
|
@ -1,84 +0,0 @@
|
|||
# Ignore CI build directory
|
||||
build/
|
||||
xcuserdata
|
||||
cmake-build-debug/
|
||||
.idea/
|
||||
bazel-bin
|
||||
bazel-genfiles
|
||||
bazel-googletest
|
||||
bazel-out
|
||||
bazel-testlogs
|
||||
# python
|
||||
*.pyc
|
||||
|
||||
# Visual Studio files
|
||||
.vs
|
||||
*.sdf
|
||||
*.opensdf
|
||||
*.VC.opendb
|
||||
*.suo
|
||||
*.user
|
||||
_ReSharper.Caches/
|
||||
Win32-Debug/
|
||||
Win32-Release/
|
||||
x64-Debug/
|
||||
x64-Release/
|
||||
|
||||
# Ignore autoconf / automake files
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
configure
|
||||
build-aux/
|
||||
autom4te.cache/
|
||||
googletest/m4/libtool.m4
|
||||
googletest/m4/ltoptions.m4
|
||||
googletest/m4/ltsugar.m4
|
||||
googletest/m4/ltversion.m4
|
||||
googletest/m4/lt~obsolete.m4
|
||||
googlemock/m4
|
||||
|
||||
# Ignore generated directories.
|
||||
googlemock/fused-src/
|
||||
googletest/fused-src/
|
||||
|
||||
# macOS files
|
||||
.DS_Store
|
||||
googletest/.DS_Store
|
||||
googletest/xcode/.DS_Store
|
||||
|
||||
# Ignore cmake generated directories and files.
|
||||
CMakeFiles
|
||||
CTestTestfile.cmake
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
googlemock/CMakeFiles
|
||||
googlemock/CTestTestfile.cmake
|
||||
googlemock/Makefile
|
||||
googlemock/cmake_install.cmake
|
||||
googlemock/gtest
|
||||
/bin
|
||||
/googlemock/gmock.dir
|
||||
/googlemock/gmock_main.dir
|
||||
/googlemock/RUN_TESTS.vcxproj.filters
|
||||
/googlemock/RUN_TESTS.vcxproj
|
||||
/googlemock/INSTALL.vcxproj.filters
|
||||
/googlemock/INSTALL.vcxproj
|
||||
/googlemock/gmock_main.vcxproj.filters
|
||||
/googlemock/gmock_main.vcxproj
|
||||
/googlemock/gmock.vcxproj.filters
|
||||
/googlemock/gmock.vcxproj
|
||||
/googlemock/gmock.sln
|
||||
/googlemock/ALL_BUILD.vcxproj.filters
|
||||
/googlemock/ALL_BUILD.vcxproj
|
||||
/lib
|
||||
/Win32
|
||||
/ZERO_CHECK.vcxproj.filters
|
||||
/ZERO_CHECK.vcxproj
|
||||
/RUN_TESTS.vcxproj.filters
|
||||
/RUN_TESTS.vcxproj
|
||||
/INSTALL.vcxproj.filters
|
||||
/INSTALL.vcxproj
|
||||
/googletest-distribution.sln
|
||||
/CMakeCache.txt
|
||||
/ALL_BUILD.vcxproj.filters
|
||||
/ALL_BUILD.vcxproj
|
|
@ -1,190 +0,0 @@
|
|||
# Copyright 2017 Google Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Bazel Build for Google C++ Testing Framework(Google Test)
|
||||
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
exports_files(["LICENSE"])
|
||||
|
||||
config_setting(
|
||||
name = "windows",
|
||||
constraint_values = ["@platforms//os:windows"],
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name = "msvc_compiler",
|
||||
flag_values = {
|
||||
"@bazel_tools//tools/cpp:compiler": "msvc-cl",
|
||||
},
|
||||
visibility = [":__subpackages__"],
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name = "has_absl",
|
||||
values = {"define": "absl=1"},
|
||||
)
|
||||
|
||||
# Library that defines the FRIEND_TEST macro.
|
||||
cc_library(
|
||||
name = "gtest_prod",
|
||||
hdrs = ["googletest/include/gtest/gtest_prod.h"],
|
||||
includes = ["googletest/include"],
|
||||
)
|
||||
|
||||
# Google Test including Google Mock
|
||||
cc_library(
|
||||
name = "gtest",
|
||||
srcs = glob(
|
||||
include = [
|
||||
"googletest/src/*.cc",
|
||||
"googletest/src/*.h",
|
||||
"googletest/include/gtest/**/*.h",
|
||||
"googlemock/src/*.cc",
|
||||
"googlemock/include/gmock/**/*.h",
|
||||
],
|
||||
exclude = [
|
||||
"googletest/src/gtest-all.cc",
|
||||
"googletest/src/gtest_main.cc",
|
||||
"googlemock/src/gmock-all.cc",
|
||||
"googlemock/src/gmock_main.cc",
|
||||
],
|
||||
),
|
||||
hdrs = glob([
|
||||
"googletest/include/gtest/*.h",
|
||||
"googlemock/include/gmock/*.h",
|
||||
]),
|
||||
copts = select({
|
||||
":windows": [],
|
||||
"//conditions:default": ["-pthread"],
|
||||
}),
|
||||
defines = select({
|
||||
":has_absl": ["GTEST_HAS_ABSL=1"],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
features = select({
|
||||
":windows": ["windows_export_all_symbols"],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
includes = [
|
||||
"googlemock",
|
||||
"googlemock/include",
|
||||
"googletest",
|
||||
"googletest/include",
|
||||
],
|
||||
linkopts = select({
|
||||
":windows": [],
|
||||
"//conditions:default": ["-pthread"],
|
||||
}),
|
||||
deps = select({
|
||||
":has_absl": [
|
||||
"@com_google_absl//absl/debugging:failure_signal_handler",
|
||||
"@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",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "gtest_main",
|
||||
srcs = ["googlemock/src/gmock_main.cc"],
|
||||
features = select({
|
||||
":windows": ["windows_export_all_symbols"],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
deps = [":gtest"],
|
||||
)
|
||||
|
||||
# The following rules build samples of how to use gTest.
|
||||
cc_library(
|
||||
name = "gtest_sample_lib",
|
||||
srcs = [
|
||||
"googletest/samples/sample1.cc",
|
||||
"googletest/samples/sample2.cc",
|
||||
"googletest/samples/sample4.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"googletest/samples/prime_tables.h",
|
||||
"googletest/samples/sample1.h",
|
||||
"googletest/samples/sample2.h",
|
||||
"googletest/samples/sample3-inl.h",
|
||||
"googletest/samples/sample4.h",
|
||||
],
|
||||
features = select({
|
||||
":windows": ["windows_export_all_symbols"],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "gtest_samples",
|
||||
size = "small",
|
||||
# All Samples except:
|
||||
# sample9 (main)
|
||||
# sample10 (main and takes a command line option and needs to be separate)
|
||||
srcs = [
|
||||
"googletest/samples/sample1_unittest.cc",
|
||||
"googletest/samples/sample2_unittest.cc",
|
||||
"googletest/samples/sample3_unittest.cc",
|
||||
"googletest/samples/sample4_unittest.cc",
|
||||
"googletest/samples/sample5_unittest.cc",
|
||||
"googletest/samples/sample6_unittest.cc",
|
||||
"googletest/samples/sample7_unittest.cc",
|
||||
"googletest/samples/sample8_unittest.cc",
|
||||
],
|
||||
linkstatic = 0,
|
||||
deps = [
|
||||
"gtest_sample_lib",
|
||||
":gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "sample9_unittest",
|
||||
size = "small",
|
||||
srcs = ["googletest/samples/sample9_unittest.cc"],
|
||||
deps = [":gtest"],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "sample10_unittest",
|
||||
size = "small",
|
||||
srcs = ["googletest/samples/sample10_unittest.cc"],
|
||||
deps = [":gtest"],
|
||||
)
|
|
@ -1,32 +0,0 @@
|
|||
# Note: CMake support is community-based. The maintainers do not use CMake
|
||||
# internally.
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
if (POLICY CMP0048)
|
||||
cmake_policy(SET CMP0048 NEW)
|
||||
endif (POLICY CMP0048)
|
||||
|
||||
project(googletest-distribution)
|
||||
set(GOOGLETEST_VERSION 1.11.0)
|
||||
|
||||
if (CMAKE_VERSION VERSION_GREATER "3.0.2")
|
||||
if(NOT CYGWIN AND NOT MSYS AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL QNX)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
enable_testing()
|
||||
|
||||
include(CMakeDependentOption)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
#Note that googlemock target already builds googletest
|
||||
option(BUILD_GMOCK "Builds the googlemock subproject" ON)
|
||||
option(INSTALL_GTEST "Enable installation of googletest. (Projects embedding googletest may want to turn this OFF.)" ON)
|
||||
|
||||
if(BUILD_GMOCK)
|
||||
add_subdirectory( googlemock )
|
||||
else()
|
||||
add_subdirectory( googletest )
|
||||
endif()
|
|
@ -1,130 +0,0 @@
|
|||
# How to become a contributor and submit your own code
|
||||
|
||||
## Contributor License Agreements
|
||||
|
||||
We'd love to accept your patches! Before we can take them, we have to jump a
|
||||
couple of legal hurdles.
|
||||
|
||||
Please fill out either the individual or corporate Contributor License Agreement
|
||||
(CLA).
|
||||
|
||||
* If you are an individual writing original source code and you're sure you
|
||||
own the intellectual property, then you'll need to sign an
|
||||
[individual CLA](https://developers.google.com/open-source/cla/individual).
|
||||
* If you work for a company that wants to allow you to contribute your work,
|
||||
then you'll need to sign a
|
||||
[corporate CLA](https://developers.google.com/open-source/cla/corporate).
|
||||
|
||||
Follow either of the two links above to access the appropriate CLA and
|
||||
instructions for how to sign and return it. Once we receive it, we'll be able to
|
||||
accept your pull requests.
|
||||
|
||||
## Are you a Googler?
|
||||
|
||||
If you are a Googler, please make an attempt to submit an internal change rather
|
||||
than a GitHub Pull Request. If you are not able to submit an internal change a
|
||||
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).
|
||||
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.
|
||||
3. Also, coordinate with team members that are listed on the issue in question.
|
||||
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).
|
||||
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.
|
||||
7. Ensure that your code has an appropriate set of unit tests which all pass.
|
||||
8. Submit a pull request.
|
||||
|
||||
## The Google Test and Google Mock Communities
|
||||
|
||||
The Google Test community exists primarily through the
|
||||
[discussion group](http://groups.google.com/group/googletestframework) and the
|
||||
GitHub repository. Likewise, the Google Mock community exists primarily through
|
||||
their own [discussion group](http://groups.google.com/group/googlemock). You are
|
||||
definitely encouraged to contribute to the discussion and you can also help us
|
||||
to keep the effectiveness of the group high by following and promoting the
|
||||
guidelines listed here.
|
||||
|
||||
### Please Be Friendly
|
||||
|
||||
Showing courtesy and respect to others is a vital part of the Google culture,
|
||||
and we strongly encourage everyone participating in Google Test development to
|
||||
join us in accepting nothing less. Of course, being courteous is not the same as
|
||||
failing to constructively disagree with each other, but it does mean that we
|
||||
should be respectful of each other when enumerating the 42 technical reasons
|
||||
that a particular proposal may not be the best choice. There's never a reason to
|
||||
be antagonistic or dismissive toward anyone who is sincerely trying to
|
||||
contribute to a discussion.
|
||||
|
||||
Sure, C++ testing is serious business and all that, but it's also a lot of fun.
|
||||
Let's keep it that way. Let's strive to be one of the friendliest communities in
|
||||
all of open source.
|
||||
|
||||
As always, discuss Google Test in the official GoogleTest discussion group. You
|
||||
don't have to actually submit code in order to sign up. Your participation
|
||||
itself is a valuable contribution.
|
||||
|
||||
## Style
|
||||
|
||||
To keep the source consistent, readable, diffable and easy to merge, we use a
|
||||
fairly rigid coding style, as defined by the
|
||||
[google-styleguide](https://github.com/google/styleguide) project. All patches
|
||||
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.
|
||||
|
||||
## Requirements for Contributors
|
||||
|
||||
If you plan to contribute a patch, you need to build Google Test, Google Mock,
|
||||
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
|
||||
|
||||
## Developing Google Test and Google Mock
|
||||
|
||||
This section discusses how to make your own changes to the Google Test project.
|
||||
|
||||
### Testing Google Test and Google Mock Themselves
|
||||
|
||||
To make sure your changes work as intended and don't break existing
|
||||
functionality, you'll want to compile and run Google Test and GoogleMock's own
|
||||
tests. For that you can use CMake:
|
||||
|
||||
mkdir mybuild
|
||||
cd mybuild
|
||||
cmake -Dgtest_build_tests=ON -Dgmock_build_tests=ON ${GTEST_REPO_DIR}
|
||||
|
||||
To choose between building only Google Test or Google Mock, you may modify your
|
||||
cmake command to be one of each
|
||||
|
||||
cmake -Dgtest_build_tests=ON ${GTEST_DIR} # sets up Google Test tests
|
||||
cmake -Dgmock_build_tests=ON ${GMOCK_DIR} # sets up Google Mock tests
|
||||
|
||||
Make sure you have Python installed, as some of Google Test's tests are written
|
||||
in Python. If the cmake command complains about not being able to find Python
|
||||
(`Could NOT find PythonInterp (missing: PYTHON_EXECUTABLE)`), try telling it
|
||||
explicitly where your Python executable can be found:
|
||||
|
||||
cmake -DPYTHON_EXECUTABLE=path/to/python ...
|
||||
|
||||
Next, you can build Google Test and / or Google Mock and all desired tests. On
|
||||
\*nix, this is usually done by
|
||||
|
||||
make
|
||||
|
||||
To run the tests, do
|
||||
|
||||
make test
|
||||
|
||||
All tests should pass.
|
|
@ -1,63 +0,0 @@
|
|||
# This file contains a list of people who've made non-trivial
|
||||
# contribution to the Google C++ Testing Framework project. People
|
||||
# who commit code to the project are encouraged to add their names
|
||||
# here. Please keep the list sorted by first names.
|
||||
|
||||
Ajay Joshi <jaj@google.com>
|
||||
Balázs Dán <balazs.dan@gmail.com>
|
||||
Benoit Sigoure <tsuna@google.com>
|
||||
Bharat Mediratta <bharat@menalto.com>
|
||||
Bogdan Piloca <boo@google.com>
|
||||
Chandler Carruth <chandlerc@google.com>
|
||||
Chris Prince <cprince@google.com>
|
||||
Chris Taylor <taylorc@google.com>
|
||||
Dan Egnor <egnor@google.com>
|
||||
Dave MacLachlan <dmaclach@gmail.com>
|
||||
David Anderson <danderson@google.com>
|
||||
Dean Sturtevant
|
||||
Eric Roman <eroman@chromium.org>
|
||||
Gene Volovich <gv@cite.com>
|
||||
Hady Zalek <hady.zalek@gmail.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>
|
||||
Jói Sigurðsson <joi@google.com>
|
||||
Keir Mierle <mierle@gmail.com>
|
||||
Keith Ray <keith.ray@gmail.com>
|
||||
Kenton Varda <kenton@google.com>
|
||||
Kostya Serebryany <kcc@google.com>
|
||||
Krystian Kuzniarek <krystian.kuzniarek@gmail.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>
|
||||
Mika Raento <mikie@iki.fi>
|
||||
Mike Bland <mbland@google.com>
|
||||
Miklós Fazekas <mfazekas@szemafor.com>
|
||||
Neal Norwitz <nnorwitz@gmail.com>
|
||||
Nermin Ozkiranartli <nermin@google.com>
|
||||
Owen Carlsen <ocarlsen@google.com>
|
||||
Paneendra Ba <paneendra@google.com>
|
||||
Pasi Valminen <pasi.valminen@gmail.com>
|
||||
Patrick Hanna <phanna@google.com>
|
||||
Patrick Riley <pfr@google.com>
|
||||
Paul Menage <menage@google.com>
|
||||
Peter Kaminski <piotrk@google.com>
|
||||
Piotr Kaminski <piotrk@google.com>
|
||||
Preston Jackson <preston.a.jackson@gmail.com>
|
||||
Rainer Klaffenboeck <rainer.klaffenboeck@dynatrace.com>
|
||||
Russ Cox <rsc@google.com>
|
||||
Russ Rufer <russ@pentad.com>
|
||||
Sean Mcafee <eefacm@gmail.com>
|
||||
Sigurður Ásgeirsson <siggi@google.com>
|
||||
Sverre Sundsdal <sundsdal@gmail.com>
|
||||
Takeshi Yoshino <tyoshino@google.com>
|
||||
Tracy Bialik <tracy@pentad.com>
|
||||
Vadim Berman <vadimb@google.com>
|
||||
Vlad Losev <vladl@google.com>
|
||||
Wolfgang Klier <wklier@google.com>
|
||||
Zhanyong Wan <wan@google.com>
|
|
@ -1,28 +0,0 @@
|
|||
Copyright 2008, Google Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -1,140 +0,0 @@
|
|||
# GoogleTest
|
||||
|
||||
### Announcements
|
||||
|
||||
#### Live at Head
|
||||
|
||||
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.
|
||||
|
||||
#### Documentation Updates
|
||||
|
||||
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.
|
||||
|
||||
#### Release 1.10.x
|
||||
|
||||
[Release 1.10.x](https://github.com/google/googletest/releases/tag/release-1.10.0)
|
||||
is now available.
|
||||
|
||||
#### Coming Soon
|
||||
|
||||
* We are planning to take a dependency on
|
||||
[Abseil](https://github.com/abseil/abseil-cpp).
|
||||
* More documentation improvements are planned.
|
||||
|
||||
## Welcome to **GoogleTest**, 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
|
||||
|
||||
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).
|
||||
|
||||
More information about building GoogleTest can be found at
|
||||
[googletest/README.md](googletest/README.md).
|
||||
|
||||
## Features
|
||||
|
||||
* An [xUnit](https://en.wikipedia.org/wiki/XUnit) test framework.
|
||||
* Test discovery.
|
||||
* A rich set of assertions.
|
||||
* User-defined assertions.
|
||||
* Death tests.
|
||||
* Fatal and non-fatal failures.
|
||||
* Value-parameterized tests.
|
||||
* Type-parameterized tests.
|
||||
* Various options for running the tests.
|
||||
* XML test report generation.
|
||||
|
||||
## 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/)
|
||||
|
||||
**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
|
||||
following notable projects:
|
||||
|
||||
* The [Chromium projects](http://www.chromium.org/) (behind the Chrome browser
|
||||
and Chrome OS).
|
||||
* The [LLVM](http://llvm.org/) compiler.
|
||||
* [Protocol Buffers](https://github.com/google/protobuf), Google's data
|
||||
interchange format.
|
||||
* The [OpenCV](http://opencv.org/) computer vision library.
|
||||
|
||||
## Related Open Source Projects
|
||||
|
||||
[GTest Runner](https://github.com/nholthaus/gtest-runner) is a Qt5 based
|
||||
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
|
||||
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. 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
|
||||
[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.
|
||||
|
||||
[gtest-parallel](https://github.com/google/gtest-parallel) is a test runner that
|
||||
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.
|
||||
|
||||
[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.
|
||||
|
||||
[Cornichon](https://pypi.org/project/cornichon/) is a small Gherkin DSL parser
|
||||
that generates stub code for GoogleTest.
|
||||
|
||||
## Contributing Changes
|
||||
|
||||
Please read
|
||||
[`CONTRIBUTING.md`](https://github.com/google/googletest/blob/master/CONTRIBUTING.md)
|
||||
for details on how to contribute to this project.
|
||||
|
||||
Happy testing!
|
|
@ -1,24 +0,0 @@
|
|||
workspace(name = "com_google_googletest")
|
||||
|
||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
|
||||
http_archive(
|
||||
name = "com_google_absl",
|
||||
urls = ["https://github.com/abseil/abseil-cpp/archive/7971fb358ae376e016d2d4fc9327aad95659b25e.zip"], # 2021-05-20T02:59:16Z
|
||||
strip_prefix = "abseil-cpp-7971fb358ae376e016d2d4fc9327aad95659b25e",
|
||||
sha256 = "aeba534f7307e36fe084b452299e49b97420667a8d28102cf9a0daeed340b859",
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "rules_cc",
|
||||
urls = ["https://github.com/bazelbuild/rules_cc/archive/68cb652a71e7e7e2858c50593e5a9e3b94e5b9a9.zip"], # 2021-05-14T14:51:14Z
|
||||
strip_prefix = "rules_cc-68cb652a71e7e7e2858c50593e5a9e3b94e5b9a9",
|
||||
sha256 = "1e19e9a3bc3d4ee91d7fcad00653485ee6c798efbbf9588d40b34cbfbded143d",
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "rules_python",
|
||||
urls = ["https://github.com/bazelbuild/rules_python/archive/ed6cc8f2c3692a6a7f013ff8bc185ba77eb9b4d2.zip"], # 2021-05-17T00:24:16Z
|
||||
strip_prefix = "rules_python-ed6cc8f2c3692a6a7f013ff8bc185ba77eb9b4d2",
|
||||
sha256 = "98b3c592faea9636ac8444bfd9de7f3fb4c60590932d6e6ac5946e3f8dbd5ff6",
|
||||
)
|
|
@ -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:20210525"
|
||||
readonly LINUX_GCC_FLOOR_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-floor:20201015"
|
||||
|
||||
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
|
|
@ -1,73 +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
|
||||
|
||||
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}
|
||||
else
|
||||
BAZEL_BIN="bazel"
|
||||
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
|
|
@ -1 +0,0 @@
|
|||
title: GoogleTest
|
|
@ -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"
|
|
@ -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 ·
|
||||
<a href="https://github.com/google/googletest">GitHub Repository</a> ·
|
||||
<a href="https://github.com/google/googletest/blob/master/LICENSE">License</a> ·
|
||||
<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>
|
|
@ -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%;
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
---
|
||||
|
||||
@import "jekyll-theme-primer";
|
||||
@import "main";
|
|
@ -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)
|
|
@ -1,693 +0,0 @@
|
|||
# Googletest FAQ
|
||||
|
||||
## Why should test suite names and test names not contain underscore?
|
||||
|
||||
{: .callout .note}
|
||||
Note: Googletest reserves underscore (`_`) for special purpose keywords, such as
|
||||
[the `DISABLED_` prefix](advanced.md#temporarily-disabling-tests), in addition
|
||||
to the following rationale.
|
||||
|
||||
Underscore (`_`) is special, as C++ reserves the following to be used by the
|
||||
compiler and the standard library:
|
||||
|
||||
1. any identifier that starts with an `_` followed by an upper-case letter, and
|
||||
2. any identifier that contains two consecutive underscores (i.e. `__`)
|
||||
*anywhere* in its name.
|
||||
|
||||
User code is *prohibited* from using such identifiers.
|
||||
|
||||
Now let's look at what this means for `TEST` and `TEST_F`.
|
||||
|
||||
Currently `TEST(TestSuiteName, TestName)` generates a class named
|
||||
`TestSuiteName_TestName_Test`. What happens if `TestSuiteName` or `TestName`
|
||||
contains `_`?
|
||||
|
||||
1. If `TestSuiteName` starts with an `_` followed by an upper-case letter (say,
|
||||
`_Foo`), we end up with `_Foo_TestName_Test`, which is reserved and thus
|
||||
invalid.
|
||||
2. If `TestSuiteName` ends with an `_` (say, `Foo_`), we get
|
||||
`Foo__TestName_Test`, which is invalid.
|
||||
3. If `TestName` starts with an `_` (say, `_Bar`), we get
|
||||
`TestSuiteName__Bar_Test`, which is invalid.
|
||||
4. If `TestName` ends with an `_` (say, `Bar_`), we get
|
||||
`TestSuiteName_Bar__Test`, which is invalid.
|
||||
|
||||
So clearly `TestSuiteName` and `TestName` cannot start or end with `_`
|
||||
(Actually, `TestSuiteName` can start with `_` -- as long as the `_` isn't
|
||||
followed by an upper-case letter. But that's getting complicated. So for
|
||||
simplicity we just say that it cannot start with `_`.).
|
||||
|
||||
It may seem fine for `TestSuiteName` and `TestName` to contain `_` in the
|
||||
middle. However, consider this:
|
||||
|
||||
```c++
|
||||
TEST(Time, Flies_Like_An_Arrow) { ... }
|
||||
TEST(Time_Flies, Like_An_Arrow) { ... }
|
||||
```
|
||||
|
||||
Now, the two `TEST`s will both generate the same class
|
||||
(`Time_Flies_Like_An_Arrow_Test`). That's not good.
|
||||
|
||||
So for simplicity, we just ask the users to avoid `_` in `TestSuiteName` and
|
||||
`TestName`. The rule is more constraining than necessary, but it's simple and
|
||||
easy to remember. It also gives googletest some wiggle room in case its
|
||||
implementation needs to change in the future.
|
||||
|
||||
If you violate the rule, there may not be immediate consequences, but your test
|
||||
may (just may) break with a new compiler (or a new version of the compiler you
|
||||
are using) or with a new version of googletest. Therefore it's best to follow
|
||||
the rule.
|
||||
|
||||
## Why does googletest support `EXPECT_EQ(NULL, ptr)` and `ASSERT_EQ(NULL, ptr)` but not `EXPECT_NE(NULL, ptr)` and `ASSERT_NE(NULL, ptr)`?
|
||||
|
||||
First of all, you can use `nullptr` with each of these macros, e.g.
|
||||
`EXPECT_EQ(ptr, nullptr)`, `EXPECT_NE(ptr, nullptr)`, `ASSERT_EQ(ptr, nullptr)`,
|
||||
`ASSERT_NE(ptr, nullptr)`. This is the preferred syntax in the style guide
|
||||
because `nullptr` does not have the type problems that `NULL` does.
|
||||
|
||||
Due to some peculiarity of C++, it requires some non-trivial template meta
|
||||
programming tricks to support using `NULL` as an argument of the `EXPECT_XX()`
|
||||
and `ASSERT_XX()` macros. Therefore we only do it where it's most needed
|
||||
(otherwise we make the implementation of googletest harder to maintain and more
|
||||
error-prone than necessary).
|
||||
|
||||
Historically, the `EXPECT_EQ()` macro took the *expected* value as its first
|
||||
argument and the *actual* value as the second, though this argument order is now
|
||||
discouraged. It was reasonable that someone wanted
|
||||
to write `EXPECT_EQ(NULL, some_expression)`, and this indeed was requested
|
||||
several times. Therefore we implemented it.
|
||||
|
||||
The need for `EXPECT_NE(NULL, ptr)` wasn't nearly as strong. When the assertion
|
||||
fails, you already know that `ptr` must be `NULL`, so it doesn't add any
|
||||
information to print `ptr` in this case. That means `EXPECT_TRUE(ptr != NULL)`
|
||||
works just as well.
|
||||
|
||||
If we were to support `EXPECT_NE(NULL, ptr)`, for consistency we'd have to
|
||||
support `EXPECT_NE(ptr, NULL)` as well. This means using the template meta
|
||||
programming tricks twice in the implementation, making it even harder to
|
||||
understand and maintain. We believe the benefit doesn't justify the cost.
|
||||
|
||||
Finally, with the growth of the gMock matcher library, we are encouraging people
|
||||
to use the unified `EXPECT_THAT(value, matcher)` syntax more often in tests. One
|
||||
significant advantage of the matcher approach is that matchers can be easily
|
||||
combined to form new matchers, while the `EXPECT_NE`, etc, macros cannot be
|
||||
easily combined. Therefore we want to invest more in the matchers than in the
|
||||
`EXPECT_XX()` macros.
|
||||
|
||||
## I need to test that different implementations of an interface satisfy some common requirements. Should I use typed tests or value-parameterized tests?
|
||||
|
||||
For testing various implementations of the same interface, either typed tests or
|
||||
value-parameterized tests can get it done. It's really up to you the user to
|
||||
decide which is more convenient for you, depending on your particular case. Some
|
||||
rough guidelines:
|
||||
|
||||
* Typed tests can be easier to write if instances of the different
|
||||
implementations can be created the same way, modulo the type. For example,
|
||||
if all these implementations have a public default constructor (such that
|
||||
you can write `new TypeParam`), or if their factory functions have the same
|
||||
form (e.g. `CreateInstance<TypeParam>()`).
|
||||
* Value-parameterized tests can be easier to write if you need different code
|
||||
patterns to create different implementations' instances, e.g. `new Foo` vs
|
||||
`new Bar(5)`. To accommodate for the differences, you can write factory
|
||||
function wrappers and pass these function pointers to the tests as their
|
||||
parameters.
|
||||
* When a typed test fails, the default output includes the name of the type,
|
||||
which can help you quickly identify which implementation is wrong.
|
||||
Value-parameterized tests only show the number of the failed iteration by
|
||||
default. You will need to define a function that returns the iteration name
|
||||
and pass it as the third parameter to INSTANTIATE_TEST_SUITE_P to have more
|
||||
useful output.
|
||||
* When using typed tests, you need to make sure you are testing against the
|
||||
interface type, not the concrete types (in other words, you want to make
|
||||
sure `implicit_cast<MyInterface*>(my_concrete_impl)` works, not just that
|
||||
`my_concrete_impl` works). It's less likely to make mistakes in this area
|
||||
when using value-parameterized tests.
|
||||
|
||||
I hope I didn't confuse you more. :-) If you don't mind, I'd suggest you to give
|
||||
both approaches a try. Practice is a much better way to grasp the subtle
|
||||
differences between the two tools. Once you have some concrete experience, you
|
||||
can much more easily decide which one to use the next time.
|
||||
|
||||
## I got some run-time errors about invalid proto descriptors when using `ProtocolMessageEquals`. Help!
|
||||
|
||||
{: .callout .note}
|
||||
**Note:** `ProtocolMessageEquals` and `ProtocolMessageEquiv` are *deprecated*
|
||||
now. Please use `EqualsProto`, etc instead.
|
||||
|
||||
`ProtocolMessageEquals` and `ProtocolMessageEquiv` were redefined recently and
|
||||
are now less tolerant of invalid protocol buffer definitions. In particular, if
|
||||
you have a `foo.proto` that doesn't fully qualify the type of a protocol message
|
||||
it references (e.g. `message<Bar>` where it should be `message<blah.Bar>`), you
|
||||
will now get run-time errors like:
|
||||
|
||||
```
|
||||
... descriptor.cc:...] Invalid proto descriptor for file "path/to/foo.proto":
|
||||
... descriptor.cc:...] blah.MyMessage.my_field: ".Bar" is not defined.
|
||||
```
|
||||
|
||||
If you see this, your `.proto` file is broken and needs to be fixed by making
|
||||
the types fully qualified. The new definition of `ProtocolMessageEquals` and
|
||||
`ProtocolMessageEquiv` just happen to reveal your bug.
|
||||
|
||||
## My death test modifies some state, but the change seems lost after the death test finishes. Why?
|
||||
|
||||
Death tests (`EXPECT_DEATH`, etc) are executed in a sub-process s.t. the
|
||||
expected crash won't kill the test program (i.e. the parent process). As a
|
||||
result, any in-memory side effects they incur are observable in their respective
|
||||
sub-processes, but not in the parent process. You can think of them as running
|
||||
in a parallel universe, more or less.
|
||||
|
||||
In particular, if you use mocking and the death test statement invokes some mock
|
||||
methods, the parent process will think the calls have never occurred. Therefore,
|
||||
you may want to move your `EXPECT_CALL` statements inside the `EXPECT_DEATH`
|
||||
macro.
|
||||
|
||||
## EXPECT_EQ(htonl(blah), blah_blah) generates weird compiler errors in opt mode. Is this a googletest bug?
|
||||
|
||||
Actually, the bug is in `htonl()`.
|
||||
|
||||
According to `'man htonl'`, `htonl()` is a *function*, which means it's valid to
|
||||
use `htonl` as a function pointer. However, in opt mode `htonl()` is defined as
|
||||
a *macro*, which breaks this usage.
|
||||
|
||||
Worse, the macro definition of `htonl()` uses a `gcc` extension and is *not*
|
||||
standard C++. That hacky implementation has some ad hoc limitations. In
|
||||
particular, it prevents you from writing `Foo<sizeof(htonl(x))>()`, where `Foo`
|
||||
is a template that has an integral argument.
|
||||
|
||||
The implementation of `EXPECT_EQ(a, b)` uses `sizeof(... a ...)` inside a
|
||||
template argument, and thus doesn't compile in opt mode when `a` contains a call
|
||||
to `htonl()`. It is difficult to make `EXPECT_EQ` bypass the `htonl()` bug, as
|
||||
the solution must work with different compilers on various platforms.
|
||||
|
||||
## The compiler complains about "undefined references" to some static const member variables, but I did define them in the class body. What's wrong?
|
||||
|
||||
If your class has a static data member:
|
||||
|
||||
```c++
|
||||
// foo.h
|
||||
class Foo {
|
||||
...
|
||||
static const int kBar = 100;
|
||||
};
|
||||
```
|
||||
|
||||
You also need to define it *outside* of the class body in `foo.cc`:
|
||||
|
||||
```c++
|
||||
const int Foo::kBar; // No initializer here.
|
||||
```
|
||||
|
||||
Otherwise your code is **invalid C++**, and may break in unexpected ways. In
|
||||
particular, using it in googletest comparison assertions (`EXPECT_EQ`, etc) will
|
||||
generate an "undefined reference" linker error. The fact that "it used to work"
|
||||
doesn't mean it's valid. It just means that you were lucky. :-)
|
||||
|
||||
If the declaration of the static data member is `constexpr` then it is
|
||||
implicitly an `inline` definition, and a separate definition in `foo.cc` is not
|
||||
needed:
|
||||
|
||||
```c++
|
||||
// foo.h
|
||||
class Foo {
|
||||
...
|
||||
static constexpr int kBar = 100; // Defines kBar, no need to do it in foo.cc.
|
||||
};
|
||||
```
|
||||
|
||||
## Can I derive a test fixture from another?
|
||||
|
||||
Yes.
|
||||
|
||||
Each test fixture has a corresponding and same named test suite. This means only
|
||||
one test suite can use a particular fixture. Sometimes, however, multiple test
|
||||
cases may want to use the same or slightly different fixtures. For example, you
|
||||
may want to make sure that all of a GUI library's test suites don't leak
|
||||
important system resources like fonts and brushes.
|
||||
|
||||
In googletest, you share a fixture among test suites by putting the shared logic
|
||||
in a base test fixture, then deriving from that base a separate fixture for each
|
||||
test suite that wants to use this common logic. You then use `TEST_F()` to write
|
||||
tests using each derived fixture.
|
||||
|
||||
Typically, your code looks like this:
|
||||
|
||||
```c++
|
||||
// Defines a base test fixture.
|
||||
class BaseTest : public ::testing::Test {
|
||||
protected:
|
||||
...
|
||||
};
|
||||
|
||||
// Derives a fixture FooTest from BaseTest.
|
||||
class FooTest : public BaseTest {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
BaseTest::SetUp(); // Sets up the base fixture first.
|
||||
... additional set-up work ...
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
... clean-up work for FooTest ...
|
||||
BaseTest::TearDown(); // Remember to tear down the base fixture
|
||||
// after cleaning up FooTest!
|
||||
}
|
||||
|
||||
... functions and variables for FooTest ...
|
||||
};
|
||||
|
||||
// Tests that use the fixture FooTest.
|
||||
TEST_F(FooTest, Bar) { ... }
|
||||
TEST_F(FooTest, Baz) { ... }
|
||||
|
||||
... additional fixtures derived from BaseTest ...
|
||||
```
|
||||
|
||||
If necessary, you can continue to derive test fixtures from a derived fixture.
|
||||
googletest has no limit on how deep the hierarchy can be.
|
||||
|
||||
For a complete example using derived test fixtures, see
|
||||
[sample5_unittest.cc](https://github.com/google/googletest/blob/master/googletest/samples/sample5_unittest.cc).
|
||||
|
||||
## My compiler complains "void value not ignored as it ought to be." What does this mean?
|
||||
|
||||
You're probably using an `ASSERT_*()` in a function that doesn't return `void`.
|
||||
`ASSERT_*()` can only be used in `void` functions, due to exceptions being
|
||||
disabled by our build system. Please see more details
|
||||
[here](advanced.md#assertion-placement).
|
||||
|
||||
## My death test hangs (or seg-faults). How do I fix it?
|
||||
|
||||
In googletest, death tests are run in a child process and the way they work is
|
||||
delicate. To write death tests you really need to understand how they work—see
|
||||
the details at [Death Assertions](reference/assertions.md#death) in the
|
||||
Assertions Reference.
|
||||
|
||||
In particular, death tests don't like having multiple threads in the parent
|
||||
process. So the first thing you can try is to eliminate creating threads outside
|
||||
of `EXPECT_DEATH()`. For example, you may want to use mocks or fake objects
|
||||
instead of real ones in your tests.
|
||||
|
||||
Sometimes this is impossible as some library you must use may be creating
|
||||
threads before `main()` is even reached. In this case, you can try to minimize
|
||||
the chance of conflicts by either moving as many activities as possible inside
|
||||
`EXPECT_DEATH()` (in the extreme case, you want to move everything inside), or
|
||||
leaving as few things as possible in it. Also, you can try to set the death test
|
||||
style to `"threadsafe"`, which is safer but slower, and see if it helps.
|
||||
|
||||
If you go with thread-safe death tests, remember that they rerun the test
|
||||
program from the beginning in the child process. Therefore make sure your
|
||||
program can run side-by-side with itself and is deterministic.
|
||||
|
||||
In the end, this boils down to good concurrent programming. You have to make
|
||||
sure that there are no race conditions or deadlocks in your program. No silver
|
||||
bullet - sorry!
|
||||
|
||||
## Should I use the constructor/destructor of the test fixture or SetUp()/TearDown()? {#CtorVsSetUp}
|
||||
|
||||
The first thing to remember is that googletest does **not** reuse the same test
|
||||
fixture object across multiple tests. For each `TEST_F`, googletest will create
|
||||
a **fresh** test fixture object, immediately call `SetUp()`, run the test body,
|
||||
call `TearDown()`, and then delete the test fixture object.
|
||||
|
||||
When you need to write per-test set-up and tear-down logic, you have the choice
|
||||
between using the test fixture constructor/destructor or `SetUp()/TearDown()`.
|
||||
The former is usually preferred, as it has the following benefits:
|
||||
|
||||
* By initializing a member variable in the constructor, we have the option to
|
||||
make it `const`, which helps prevent accidental changes to its value and
|
||||
makes the tests more obviously correct.
|
||||
* In case we need to subclass the test fixture class, the subclass'
|
||||
constructor is guaranteed to call the base class' constructor *first*, and
|
||||
the subclass' destructor is guaranteed to call the base class' destructor
|
||||
*afterward*. With `SetUp()/TearDown()`, a subclass may make the mistake of
|
||||
forgetting to call the base class' `SetUp()/TearDown()` or call them at the
|
||||
wrong time.
|
||||
|
||||
You may still want to use `SetUp()/TearDown()` in the following cases:
|
||||
|
||||
* C++ does not allow virtual function calls in constructors and destructors.
|
||||
You can call a method declared as virtual, but it will not use dynamic
|
||||
dispatch, it will use the definition from the class the constructor of which
|
||||
is currently executing. This is because calling a virtual method before the
|
||||
derived class constructor has a chance to run is very dangerous - the
|
||||
virtual method might operate on uninitialized data. Therefore, if you need
|
||||
to call a method that will be overridden in a derived class, you have to use
|
||||
`SetUp()/TearDown()`.
|
||||
* In the body of a constructor (or destructor), it's not possible to use the
|
||||
`ASSERT_xx` macros. Therefore, if the set-up operation could cause a fatal
|
||||
test failure that should prevent the test from running, it's necessary to
|
||||
use `abort` and abort the whole test
|
||||
executable, or to use `SetUp()` instead of a constructor.
|
||||
* If the tear-down operation could throw an exception, you must use
|
||||
`TearDown()` as opposed to the destructor, as throwing in a destructor leads
|
||||
to undefined behavior and usually will kill your program right away. Note
|
||||
that many standard libraries (like STL) may throw when exceptions are
|
||||
enabled in the compiler. Therefore you should prefer `TearDown()` if you
|
||||
want to write portable tests that work with or without exceptions.
|
||||
* The googletest team is considering making the assertion macros throw on
|
||||
platforms where exceptions are enabled (e.g. Windows, Mac OS, and Linux
|
||||
client-side), which will eliminate the need for the user to propagate
|
||||
failures from a subroutine to its caller. Therefore, you shouldn't use
|
||||
googletest assertions in a destructor if your code could run on such a
|
||||
platform.
|
||||
|
||||
## The compiler complains "no matching function to call" when I use ASSERT_PRED*. How do I fix it?
|
||||
|
||||
See details for [`EXPECT_PRED*`](reference/assertions.md#EXPECT_PRED) in the
|
||||
Assertions Reference.
|
||||
|
||||
## My compiler complains about "ignoring return value" when I call RUN_ALL_TESTS(). Why?
|
||||
|
||||
Some people had been ignoring the return value of `RUN_ALL_TESTS()`. That is,
|
||||
instead of
|
||||
|
||||
```c++
|
||||
return RUN_ALL_TESTS();
|
||||
```
|
||||
|
||||
they write
|
||||
|
||||
```c++
|
||||
RUN_ALL_TESTS();
|
||||
```
|
||||
|
||||
This is **wrong and dangerous**. The testing services needs to see the return
|
||||
value of `RUN_ALL_TESTS()` in order to determine if a test has passed. If your
|
||||
`main()` function ignores it, your test will be considered successful even if it
|
||||
has a googletest assertion failure. Very bad.
|
||||
|
||||
We have decided to fix this (thanks to Michael Chastain for the idea). Now, your
|
||||
code will no longer be able to ignore `RUN_ALL_TESTS()` when compiled with
|
||||
`gcc`. If you do so, you'll get a compiler error.
|
||||
|
||||
If you see the compiler complaining about you ignoring the return value of
|
||||
`RUN_ALL_TESTS()`, the fix is simple: just make sure its value is used as the
|
||||
return value of `main()`.
|
||||
|
||||
But how could we introduce a change that breaks existing tests? Well, in this
|
||||
case, the code was already broken in the first place, so we didn't break it. :-)
|
||||
|
||||
## My compiler complains that a constructor (or destructor) cannot return a value. What's going on?
|
||||
|
||||
Due to a peculiarity of C++, in order to support the syntax for streaming
|
||||
messages to an `ASSERT_*`, e.g.
|
||||
|
||||
```c++
|
||||
ASSERT_EQ(1, Foo()) << "blah blah" << foo;
|
||||
```
|
||||
|
||||
we had to give up using `ASSERT*` and `FAIL*` (but not `EXPECT*` and
|
||||
`ADD_FAILURE*`) in constructors and destructors. The workaround is to move the
|
||||
content of your constructor/destructor to a private void member function, or
|
||||
switch to `EXPECT_*()` if that works. This
|
||||
[section](advanced.md#assertion-placement) in the user's guide explains it.
|
||||
|
||||
## My SetUp() function is not called. Why?
|
||||
|
||||
C++ is case-sensitive. Did you spell it as `Setup()`?
|
||||
|
||||
Similarly, sometimes people spell `SetUpTestSuite()` as `SetupTestSuite()` and
|
||||
wonder why it's never called.
|
||||
|
||||
|
||||
## I have several test suites which share the same test fixture logic, do I have to define a new test fixture class for each of them? This seems pretty tedious.
|
||||
|
||||
You don't have to. Instead of
|
||||
|
||||
```c++
|
||||
class FooTest : public BaseTest {};
|
||||
|
||||
TEST_F(FooTest, Abc) { ... }
|
||||
TEST_F(FooTest, Def) { ... }
|
||||
|
||||
class BarTest : public BaseTest {};
|
||||
|
||||
TEST_F(BarTest, Abc) { ... }
|
||||
TEST_F(BarTest, Def) { ... }
|
||||
```
|
||||
|
||||
you can simply `typedef` the test fixtures:
|
||||
|
||||
```c++
|
||||
typedef BaseTest FooTest;
|
||||
|
||||
TEST_F(FooTest, Abc) { ... }
|
||||
TEST_F(FooTest, Def) { ... }
|
||||
|
||||
typedef BaseTest BarTest;
|
||||
|
||||
TEST_F(BarTest, Abc) { ... }
|
||||
TEST_F(BarTest, Def) { ... }
|
||||
```
|
||||
|
||||
## googletest output is buried in a whole bunch of LOG messages. What do I do?
|
||||
|
||||
The googletest output is meant to be a concise and human-friendly report. If
|
||||
your test generates textual output itself, it will mix with the googletest
|
||||
output, making it hard to read. However, there is an easy solution to this
|
||||
problem.
|
||||
|
||||
Since `LOG` messages go to stderr, we decided to let googletest output go to
|
||||
stdout. This way, you can easily separate the two using redirection. For
|
||||
example:
|
||||
|
||||
```shell
|
||||
$ ./my_test > gtest_output.txt
|
||||
```
|
||||
|
||||
## Why should I prefer test fixtures over global variables?
|
||||
|
||||
There are several good reasons:
|
||||
|
||||
1. It's likely your test needs to change the states of its global variables.
|
||||
This makes it difficult to keep side effects from escaping one test and
|
||||
contaminating others, making debugging difficult. By using fixtures, each
|
||||
test has a fresh set of variables that's different (but with the same
|
||||
names). Thus, tests are kept independent of each other.
|
||||
2. Global variables pollute the global namespace.
|
||||
3. Test fixtures can be reused via subclassing, which cannot be done easily
|
||||
with global variables. This is useful if many test suites have something in
|
||||
common.
|
||||
|
||||
## What can the statement argument in ASSERT_DEATH() be?
|
||||
|
||||
`ASSERT_DEATH(statement, matcher)` (or any death assertion macro) can be used
|
||||
wherever *`statement`* is valid. So basically *`statement`* can be any C++
|
||||
statement that makes sense in the current context. In particular, it can
|
||||
reference global and/or local variables, and can be:
|
||||
|
||||
* a simple function call (often the case),
|
||||
* a complex expression, or
|
||||
* a compound statement.
|
||||
|
||||
Some examples are shown here:
|
||||
|
||||
```c++
|
||||
// A death test can be a simple function call.
|
||||
TEST(MyDeathTest, FunctionCall) {
|
||||
ASSERT_DEATH(Xyz(5), "Xyz failed");
|
||||
}
|
||||
|
||||
// Or a complex expression that references variables and functions.
|
||||
TEST(MyDeathTest, ComplexExpression) {
|
||||
const bool c = Condition();
|
||||
ASSERT_DEATH((c ? Func1(0) : object2.Method("test")),
|
||||
"(Func1|Method) failed");
|
||||
}
|
||||
|
||||
// Death assertions can be used anywhere in a function. In
|
||||
// particular, they can be inside a loop.
|
||||
TEST(MyDeathTest, InsideLoop) {
|
||||
// Verifies that Foo(0), Foo(1), ..., and Foo(4) all die.
|
||||
for (int i = 0; i < 5; i++) {
|
||||
EXPECT_DEATH_M(Foo(i), "Foo has \\d+ errors",
|
||||
::testing::Message() << "where i is " << i);
|
||||
}
|
||||
}
|
||||
|
||||
// A death assertion can contain a compound statement.
|
||||
TEST(MyDeathTest, CompoundStatement) {
|
||||
// Verifies that at lease one of Bar(0), Bar(1), ..., and
|
||||
// Bar(4) dies.
|
||||
ASSERT_DEATH({
|
||||
for (int i = 0; i < 5; i++) {
|
||||
Bar(i);
|
||||
}
|
||||
},
|
||||
"Bar has \\d+ errors");
|
||||
}
|
||||
```
|
||||
|
||||
## I have a fixture class `FooTest`, but `TEST_F(FooTest, Bar)` gives me error ``"no matching function for call to `FooTest::FooTest()'"``. Why?
|
||||
|
||||
Googletest needs to be able to create objects of your test fixture class, so it
|
||||
must have a default constructor. Normally the compiler will define one for you.
|
||||
However, there are cases where you have to define your own:
|
||||
|
||||
* If you explicitly declare a non-default constructor for class `FooTest`
|
||||
(`DISALLOW_EVIL_CONSTRUCTORS()` does this), then you need to define a
|
||||
default constructor, even if it would be empty.
|
||||
* If `FooTest` has a const non-static data member, then you have to define the
|
||||
default constructor *and* initialize the const member in the initializer
|
||||
list of the constructor. (Early versions of `gcc` doesn't force you to
|
||||
initialize the const member. It's a bug that has been fixed in `gcc 4`.)
|
||||
|
||||
## Why does ASSERT_DEATH complain about previous threads that were already joined?
|
||||
|
||||
With the Linux pthread library, there is no turning back once you cross the line
|
||||
from a single thread to multiple threads. The first time you create a thread, a
|
||||
manager thread is created in addition, so you get 3, not 2, threads. Later when
|
||||
the thread you create joins the main thread, the thread count decrements by 1,
|
||||
but the manager thread will never be killed, so you still have 2 threads, which
|
||||
means you cannot safely run a death test.
|
||||
|
||||
The new NPTL thread library doesn't suffer from this problem, as it doesn't
|
||||
create a manager thread. However, if you don't control which machine your test
|
||||
runs on, you shouldn't depend on this.
|
||||
|
||||
## Why does googletest require the entire test suite, instead of individual tests, to be named *DeathTest when it uses ASSERT_DEATH?
|
||||
|
||||
googletest does not interleave tests from different test suites. That is, it
|
||||
runs all tests in one test suite first, and then runs all tests in the next test
|
||||
suite, and so on. googletest does this because it needs to set up a test suite
|
||||
before the first test in it is run, and tear it down afterwards. Splitting up
|
||||
the test case would require multiple set-up and tear-down processes, which is
|
||||
inefficient and makes the semantics unclean.
|
||||
|
||||
If we were to determine the order of tests based on test name instead of test
|
||||
case name, then we would have a problem with the following situation:
|
||||
|
||||
```c++
|
||||
TEST_F(FooTest, AbcDeathTest) { ... }
|
||||
TEST_F(FooTest, Uvw) { ... }
|
||||
|
||||
TEST_F(BarTest, DefDeathTest) { ... }
|
||||
TEST_F(BarTest, Xyz) { ... }
|
||||
```
|
||||
|
||||
Since `FooTest.AbcDeathTest` needs to run before `BarTest.Xyz`, and we don't
|
||||
interleave tests from different test suites, we need to run all tests in the
|
||||
`FooTest` case before running any test in the `BarTest` case. This contradicts
|
||||
with the requirement to run `BarTest.DefDeathTest` before `FooTest.Uvw`.
|
||||
|
||||
## But I don't like calling my entire test suite \*DeathTest when it contains both death tests and non-death tests. What do I do?
|
||||
|
||||
You don't have to, but if you like, you may split up the test suite into
|
||||
`FooTest` and `FooDeathTest`, where the names make it clear that they are
|
||||
related:
|
||||
|
||||
```c++
|
||||
class FooTest : public ::testing::Test { ... };
|
||||
|
||||
TEST_F(FooTest, Abc) { ... }
|
||||
TEST_F(FooTest, Def) { ... }
|
||||
|
||||
using FooDeathTest = FooTest;
|
||||
|
||||
TEST_F(FooDeathTest, Uvw) { ... EXPECT_DEATH(...) ... }
|
||||
TEST_F(FooDeathTest, Xyz) { ... ASSERT_DEATH(...) ... }
|
||||
```
|
||||
|
||||
## googletest prints the LOG messages in a death test's child process only when the test fails. How can I see the LOG messages when the death test succeeds?
|
||||
|
||||
Printing the LOG messages generated by the statement inside `EXPECT_DEATH()`
|
||||
makes it harder to search for real problems in the parent's log. Therefore,
|
||||
googletest only prints them when the death test has failed.
|
||||
|
||||
If you really need to see such LOG messages, a workaround is to temporarily
|
||||
break the death test (e.g. by changing the regex pattern it is expected to
|
||||
match). Admittedly, this is a hack. We'll consider a more permanent solution
|
||||
after the fork-and-exec-style death tests are implemented.
|
||||
|
||||
## The compiler complains about `no match for 'operator<<'` when I use an assertion. What gives?
|
||||
|
||||
If you use a user-defined type `FooType` in an assertion, you must make sure
|
||||
there is an `std::ostream& operator<<(std::ostream&, const FooType&)` function
|
||||
defined such that we can print a value of `FooType`.
|
||||
|
||||
In addition, if `FooType` is declared in a name space, the `<<` operator also
|
||||
needs to be defined in the *same* name space. See
|
||||
[Tip of the Week #49](http://abseil.io/tips/49) for details.
|
||||
|
||||
## How do I suppress the memory leak messages on Windows?
|
||||
|
||||
Since the statically initialized googletest singleton requires allocations on
|
||||
the heap, the Visual C++ memory leak detector will report memory leaks at the
|
||||
end of the program run. The easiest way to avoid this is to use the
|
||||
`_CrtMemCheckpoint` and `_CrtMemDumpAllObjectsSince` calls to not report any
|
||||
statically initialized heap objects. See MSDN for more details and additional
|
||||
heap check/debug routines.
|
||||
|
||||
## How can my code detect if it is running in a test?
|
||||
|
||||
If you write code that sniffs whether it's running in a test and does different
|
||||
things accordingly, you are leaking test-only logic into production code and
|
||||
there is no easy way to ensure that the test-only code paths aren't run by
|
||||
mistake in production. Such cleverness also leads to
|
||||
[Heisenbugs](https://en.wikipedia.org/wiki/Heisenbug). Therefore we strongly
|
||||
advise against the practice, and googletest doesn't provide a way to do it.
|
||||
|
||||
In general, the recommended way to cause the code to behave differently under
|
||||
test is [Dependency Injection](http://en.wikipedia.org/wiki/Dependency_injection). You can inject
|
||||
different functionality from the test and from the production code. Since your
|
||||
production code doesn't link in the for-test logic at all (the
|
||||
[`testonly`](http://docs.bazel.build/versions/master/be/common-definitions.html#common.testonly) attribute for BUILD targets helps to ensure
|
||||
that), there is no danger in accidentally running it.
|
||||
|
||||
However, if you *really*, *really*, *really* have no choice, and if you follow
|
||||
the rule of ending your test program names with `_test`, you can use the
|
||||
*horrible* hack of sniffing your executable name (`argv[0]` in `main()`) to know
|
||||
whether the code is under test.
|
||||
|
||||
## How do I temporarily disable a test?
|
||||
|
||||
If you have a broken test that you cannot fix right away, you can add the
|
||||
`DISABLED_` prefix to its name. This will exclude it from execution. This is
|
||||
better than commenting out the code or using `#if 0`, as disabled tests are
|
||||
still compiled (and thus won't rot).
|
||||
|
||||
To include disabled tests in test execution, just invoke the test program with
|
||||
the `--gtest_also_run_disabled_tests` flag.
|
||||
|
||||
## Is it OK if I have two separate `TEST(Foo, Bar)` test methods defined in different namespaces?
|
||||
|
||||
Yes.
|
||||
|
||||
The rule is **all test methods in the same test suite must use the same fixture
|
||||
class.** This means that the following is **allowed** because both tests use the
|
||||
same fixture class (`::testing::Test`).
|
||||
|
||||
```c++
|
||||
namespace foo {
|
||||
TEST(CoolTest, DoSomething) {
|
||||
SUCCEED();
|
||||
}
|
||||
} // namespace foo
|
||||
|
||||
namespace bar {
|
||||
TEST(CoolTest, DoSomething) {
|
||||
SUCCEED();
|
||||
}
|
||||
} // namespace bar
|
||||
```
|
||||
|
||||
However, the following code is **not allowed** and will produce a runtime error
|
||||
from googletest because the test methods are using different test fixture
|
||||
classes with the same test suite name.
|
||||
|
||||
```c++
|
||||
namespace foo {
|
||||
class CoolTest : public ::testing::Test {}; // Fixture foo::CoolTest
|
||||
TEST_F(CoolTest, DoSomething) {
|
||||
SUCCEED();
|
||||
}
|
||||
} // namespace foo
|
||||
|
||||
namespace bar {
|
||||
class CoolTest : public ::testing::Test {}; // Fixture: bar::CoolTest
|
||||
TEST_F(CoolTest, DoSomething) {
|
||||
SUCCEED();
|
||||
}
|
||||
} // namespace bar
|
||||
```
|
|
@ -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#using-check-points) 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. |
|
|
@ -1,390 +0,0 @@
|
|||
# Legacy gMock FAQ
|
||||
|
||||
### 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).
|
||||
|
||||
### Can I mock a variadic function?
|
||||
|
||||
You cannot mock a variadic function (i.e. a function taking ellipsis (`...`)
|
||||
arguments) directly in gMock.
|
||||
|
||||
The problem is that in general, there is *no way* for a mock object to know how
|
||||
many arguments are passed to the variadic method, and what the arguments' types
|
||||
are. Only the *author of the base class* knows the protocol, and we cannot look
|
||||
into his or her head.
|
||||
|
||||
Therefore, to mock such a function, the *user* must teach the mock object how to
|
||||
figure out the number of arguments and their types. One way to do it is to
|
||||
provide overloaded versions of the function.
|
||||
|
||||
Ellipsis arguments are inherited from C and not really a C++ feature. They are
|
||||
unsafe to use and don't work with arguments that have constructors or
|
||||
destructors. Therefore we recommend to avoid them in C++ as much as possible.
|
||||
|
||||
### MSVC gives me warning C4301 or C4373 when I define a mock method with a const parameter. Why?
|
||||
|
||||
If you compile this using Microsoft Visual C++ 2005 SP1:
|
||||
|
||||
```cpp
|
||||
class Foo {
|
||||
...
|
||||
virtual void Bar(const int i) = 0;
|
||||
};
|
||||
|
||||
class MockFoo : public Foo {
|
||||
...
|
||||
MOCK_METHOD(void, Bar, (const int i), (override));
|
||||
};
|
||||
```
|
||||
|
||||
You may get the following warning:
|
||||
|
||||
```shell
|
||||
warning C4301: 'MockFoo::Bar': overriding virtual function only differs from 'Foo::Bar' by const/volatile qualifier
|
||||
```
|
||||
|
||||
This is a MSVC bug. The same code compiles fine with gcc, for example. If you
|
||||
use Visual C++ 2008 SP1, you would get the warning:
|
||||
|
||||
```shell
|
||||
warning C4373: 'MockFoo::Bar': virtual function overrides 'Foo::Bar', previous versions of the compiler did not override when parameters only differed by const/volatile qualifiers
|
||||
```
|
||||
|
||||
In C++, if you *declare* a function with a `const` parameter, the `const`
|
||||
modifier is ignored. Therefore, the `Foo` base class above is equivalent to:
|
||||
|
||||
```cpp
|
||||
class Foo {
|
||||
...
|
||||
virtual void Bar(int i) = 0; // int or const int? Makes no difference.
|
||||
};
|
||||
```
|
||||
|
||||
In fact, you can *declare* `Bar()` with an `int` parameter, and define it with a
|
||||
`const int` parameter. The compiler will still match them up.
|
||||
|
||||
Since making a parameter `const` is meaningless in the method declaration, we
|
||||
recommend to remove it in both `Foo` and `MockFoo`. That should workaround the
|
||||
VC bug.
|
||||
|
||||
Note that we are talking about the *top-level* `const` modifier here. If the
|
||||
function parameter is passed by pointer or reference, declaring the pointee or
|
||||
referee as `const` is still meaningful. For example, the following two
|
||||
declarations are *not* equivalent:
|
||||
|
||||
```cpp
|
||||
void Bar(int* p); // Neither p nor *p is const.
|
||||
void Bar(const int* p); // p is not const, but *p is.
|
||||
```
|
||||
|
||||
### I can't figure out why gMock thinks my expectations are not satisfied. What should I do?
|
||||
|
||||
You might want to run your test with `--gmock_verbose=info`. This flag lets
|
||||
gMock print a trace of every mock function call it receives. By studying the
|
||||
trace, you'll gain insights on why the expectations you set are not met.
|
||||
|
||||
If you see the message "The mock function has no default action set, and its
|
||||
return type has no default value set.", then try
|
||||
[adding a default action](gmock_cheat_sheet.md#OnCall). Due to a known issue,
|
||||
unexpected calls on mocks without default actions don't print out a detailed
|
||||
comparison between the actual arguments and the expected arguments.
|
||||
|
||||
### My program crashed and `ScopedMockLog` spit out tons of messages. Is it a gMock bug?
|
||||
|
||||
gMock and `ScopedMockLog` are likely doing the right thing here.
|
||||
|
||||
When a test crashes, the failure signal handler will try to log a lot of
|
||||
information (the stack trace, and the address map, for example). The messages
|
||||
are compounded if you have many threads with depth stacks. When `ScopedMockLog`
|
||||
intercepts these messages and finds that they don't match any expectations, it
|
||||
prints an error for each of them.
|
||||
|
||||
You can learn to ignore the errors, or you can rewrite your expectations to make
|
||||
your test more robust, for example, by adding something like:
|
||||
|
||||
```cpp
|
||||
using ::testing::AnyNumber;
|
||||
using ::testing::Not;
|
||||
...
|
||||
// Ignores any log not done by us.
|
||||
EXPECT_CALL(log, Log(_, Not(EndsWith("/my_file.cc")), _))
|
||||
.Times(AnyNumber());
|
||||
```
|
||||
|
||||
### How can I assert that a function is NEVER called?
|
||||
|
||||
```cpp
|
||||
using ::testing::_;
|
||||
...
|
||||
EXPECT_CALL(foo, Bar(_))
|
||||
.Times(0);
|
||||
```
|
||||
|
||||
### I have a failed test where gMock tells me TWICE that a particular expectation is not satisfied. Isn't this redundant?
|
||||
|
||||
When gMock detects a failure, it prints relevant information (the mock function
|
||||
arguments, the state of relevant expectations, and etc) to help the user debug.
|
||||
If another failure is detected, gMock will do the same, including printing the
|
||||
state of relevant expectations.
|
||||
|
||||
Sometimes an expectation's state didn't change between two failures, and you'll
|
||||
see the same description of the state twice. They are however *not* redundant,
|
||||
as they refer to *different points in time*. The fact they are the same *is*
|
||||
interesting information.
|
||||
|
||||
### I get a heapcheck failure when using a mock object, but using a real object is fine. What can be wrong?
|
||||
|
||||
Does the class (hopefully a pure interface) you are mocking have a virtual
|
||||
destructor?
|
||||
|
||||
Whenever you derive from a base class, make sure its destructor is virtual.
|
||||
Otherwise Bad Things will happen. Consider the following code:
|
||||
|
||||
```cpp
|
||||
class Base {
|
||||
public:
|
||||
// Not virtual, but should be.
|
||||
~Base() { ... }
|
||||
...
|
||||
};
|
||||
|
||||
class Derived : public Base {
|
||||
public:
|
||||
...
|
||||
private:
|
||||
std::string value_;
|
||||
};
|
||||
|
||||
...
|
||||
Base* p = new Derived;
|
||||
...
|
||||
delete p; // Surprise! ~Base() will be called, but ~Derived() will not
|
||||
// - value_ is leaked.
|
||||
```
|
||||
|
||||
By changing `~Base()` to virtual, `~Derived()` will be correctly called when
|
||||
`delete p` is executed, and the heap checker will be happy.
|
||||
|
||||
### The "newer expectations override older ones" rule makes writing expectations awkward. Why does gMock do that?
|
||||
|
||||
When people complain about this, often they are referring to code like:
|
||||
|
||||
```cpp
|
||||
using ::testing::Return;
|
||||
...
|
||||
// foo.Bar() should be called twice, return 1 the first time, and return
|
||||
// 2 the second time. However, I have to write the expectations in the
|
||||
// reverse order. This sucks big time!!!
|
||||
EXPECT_CALL(foo, Bar())
|
||||
.WillOnce(Return(2))
|
||||
.RetiresOnSaturation();
|
||||
EXPECT_CALL(foo, Bar())
|
||||
.WillOnce(Return(1))
|
||||
.RetiresOnSaturation();
|
||||
```
|
||||
|
||||
The problem, is that they didn't pick the **best** way to express the test's
|
||||
intent.
|
||||
|
||||
By default, expectations don't have to be matched in *any* particular order. If
|
||||
you want them to match in a certain order, you need to be explicit. This is
|
||||
gMock's (and jMock's) fundamental philosophy: it's easy to accidentally
|
||||
over-specify your tests, and we want to make it harder to do so.
|
||||
|
||||
There are two better ways to write the test spec. You could either put the
|
||||
expectations in sequence:
|
||||
|
||||
```cpp
|
||||
using ::testing::Return;
|
||||
...
|
||||
// foo.Bar() should be called twice, return 1 the first time, and return
|
||||
// 2 the second time. Using a sequence, we can write the expectations
|
||||
// in their natural order.
|
||||
{
|
||||
InSequence s;
|
||||
EXPECT_CALL(foo, Bar())
|
||||
.WillOnce(Return(1))
|
||||
.RetiresOnSaturation();
|
||||
EXPECT_CALL(foo, Bar())
|
||||
.WillOnce(Return(2))
|
||||
.RetiresOnSaturation();
|
||||
}
|
||||
```
|
||||
|
||||
or you can put the sequence of actions in the same expectation:
|
||||
|
||||
```cpp
|
||||
using ::testing::Return;
|
||||
...
|
||||
// foo.Bar() should be called twice, return 1 the first time, and return
|
||||
// 2 the second time.
|
||||
EXPECT_CALL(foo, Bar())
|
||||
.WillOnce(Return(1))
|
||||
.WillOnce(Return(2))
|
||||
.RetiresOnSaturation();
|
||||
```
|
||||
|
||||
Back to the original questions: why does gMock search the expectations (and
|
||||
`ON_CALL`s) from back to front? Because this allows a user to set up a mock's
|
||||
behavior for the common case early (e.g. in the mock's constructor or the test
|
||||
fixture's set-up phase) and customize it with more specific rules later. If
|
||||
gMock searches from front to back, this very useful pattern won't be possible.
|
||||
|
||||
### gMock prints a warning when a function without EXPECT_CALL is called, even if I have set its behavior using ON_CALL. Would it be reasonable not to show the warning in this case?
|
||||
|
||||
When choosing between being neat and being safe, we lean toward the latter. So
|
||||
the answer is that we think it's better to show the warning.
|
||||
|
||||
Often people write `ON_CALL`s in the mock object's constructor or `SetUp()`, as
|
||||
the default behavior rarely changes from test to test. Then in the test body
|
||||
they set the expectations, which are often different for each test. Having an
|
||||
`ON_CALL` in the set-up part of a test doesn't mean that the calls are expected.
|
||||
If there's no `EXPECT_CALL` and the method is called, it's possibly an error. If
|
||||
we quietly let the call go through without notifying the user, bugs may creep in
|
||||
unnoticed.
|
||||
|
||||
If, however, you are sure that the calls are OK, you can write
|
||||
|
||||
```cpp
|
||||
using ::testing::_;
|
||||
...
|
||||
EXPECT_CALL(foo, Bar(_))
|
||||
.WillRepeatedly(...);
|
||||
```
|
||||
|
||||
instead of
|
||||
|
||||
```cpp
|
||||
using ::testing::_;
|
||||
...
|
||||
ON_CALL(foo, Bar(_))
|
||||
.WillByDefault(...);
|
||||
```
|
||||
|
||||
This tells gMock that you do expect the calls and no warning should be printed.
|
||||
|
||||
Also, you can control the verbosity by specifying `--gmock_verbose=error`. Other
|
||||
values are `info` and `warning`. If you find the output too noisy when
|
||||
debugging, just choose a less verbose level.
|
||||
|
||||
### How can I delete the mock function's argument in an action?
|
||||
|
||||
If your mock function takes a pointer argument and you want to delete that
|
||||
argument, you can use testing::DeleteArg<N>() to delete the N'th (zero-indexed)
|
||||
argument:
|
||||
|
||||
```cpp
|
||||
using ::testing::_;
|
||||
...
|
||||
MOCK_METHOD(void, Bar, (X* x, const Y& y));
|
||||
...
|
||||
EXPECT_CALL(mock_foo_, Bar(_, _))
|
||||
.WillOnce(testing::DeleteArg<0>()));
|
||||
```
|
||||
|
||||
### How can I perform an arbitrary action on a mock function's argument?
|
||||
|
||||
If you find yourself needing to perform some action that's not supported by
|
||||
gMock directly, remember that you can define your own actions using
|
||||
[`MakeAction()`](#NewMonoActions) or
|
||||
[`MakePolymorphicAction()`](#NewPolyActions), or you can write a stub function
|
||||
and invoke it using [`Invoke()`](#FunctionsAsActions).
|
||||
|
||||
```cpp
|
||||
using ::testing::_;
|
||||
using ::testing::Invoke;
|
||||
...
|
||||
MOCK_METHOD(void, Bar, (X* p));
|
||||
...
|
||||
EXPECT_CALL(mock_foo_, Bar(_))
|
||||
.WillOnce(Invoke(MyAction(...)));
|
||||
```
|
||||
|
||||
### My code calls a static/global function. Can I mock it?
|
||||
|
||||
You can, but you need to make some changes.
|
||||
|
||||
In general, if you find yourself needing to mock a static function, it's a sign
|
||||
that your modules are too tightly coupled (and less flexible, less reusable,
|
||||
less testable, etc). You are probably better off defining a small interface and
|
||||
call the function through that interface, which then can be easily mocked. It's
|
||||
a bit of work initially, but usually pays for itself quickly.
|
||||
|
||||
This Google Testing Blog
|
||||
[post](https://testing.googleblog.com/2008/06/defeat-static-cling.html) says it
|
||||
excellently. Check it out.
|
||||
|
||||
### My mock object needs to do complex stuff. It's a lot of pain to specify the actions. gMock sucks!
|
||||
|
||||
I know it's not a question, but you get an answer for free any way. :-)
|
||||
|
||||
With gMock, you can create mocks in C++ easily. And people might be tempted to
|
||||
use them everywhere. Sometimes they work great, and sometimes you may find them,
|
||||
well, a pain to use. So, what's wrong in the latter case?
|
||||
|
||||
When you write a test without using mocks, you exercise the code and assert that
|
||||
it returns the correct value or that the system is in an expected state. This is
|
||||
sometimes called "state-based testing".
|
||||
|
||||
Mocks are great for what some call "interaction-based" testing: instead of
|
||||
checking the system state at the very end, mock objects verify that they are
|
||||
invoked the right way and report an error as soon as it arises, giving you a
|
||||
handle on the precise context in which the error was triggered. This is often
|
||||
more effective and economical to do than state-based testing.
|
||||
|
||||
If you are doing state-based testing and using a test double just to simulate
|
||||
the real object, you are probably better off using a fake. Using a mock in this
|
||||
case causes pain, as it's not a strong point for mocks to perform complex
|
||||
actions. If you experience this and think that mocks suck, you are just not
|
||||
using the right tool for your problem. Or, you might be trying to solve the
|
||||
wrong problem. :-)
|
||||
|
||||
### I got a warning "Uninteresting function call encountered - default action taken.." Should I panic?
|
||||
|
||||
By all means, NO! It's just an FYI. :-)
|
||||
|
||||
What it means is that you have a mock function, you haven't set any expectations
|
||||
on it (by gMock's rule this means that you are not interested in calls to this
|
||||
function and therefore it can be called any number of times), and it is called.
|
||||
That's OK - you didn't say it's not OK to call the function!
|
||||
|
||||
What if you actually meant to disallow this function to be called, but forgot to
|
||||
write `EXPECT_CALL(foo, Bar()).Times(0)`? While one can argue that it's the
|
||||
user's fault, gMock tries to be nice and prints you a note.
|
||||
|
||||
So, when you see the message and believe that there shouldn't be any
|
||||
uninteresting calls, you should investigate what's going on. To make your life
|
||||
easier, gMock dumps the stack trace when an uninteresting call is encountered.
|
||||
From that you can figure out which mock function it is, and how it is called.
|
||||
|
||||
### I want to define a custom action. Should I use Invoke() or implement the ActionInterface interface?
|
||||
|
||||
Either way is fine - you want to choose the one that's more convenient for your
|
||||
circumstance.
|
||||
|
||||
Usually, if your action is for a particular function type, defining it using
|
||||
`Invoke()` should be easier; if your action can be used in functions of
|
||||
different types (e.g. if you are defining `Return(*value*)`),
|
||||
`MakePolymorphicAction()` is easiest. Sometimes you want precise control on what
|
||||
types of functions the action can be used in, and implementing `ActionInterface`
|
||||
is the way to go here. See the implementation of `Return()` in
|
||||
`testing/base/public/gmock-actions.h` for an example.
|
||||
|
||||
### I use SetArgPointee() in WillOnce(), but gcc complains about "conflicting return type specified". What does it mean?
|
||||
|
||||
You got this error as gMock has no idea what value it should return when the
|
||||
mock method is called. `SetArgPointee()` says what the side effect is, but
|
||||
doesn't say what the return value should be. You need `DoAll()` to chain a
|
||||
`SetArgPointee()` with a `Return()` that provides a value appropriate to the API
|
||||
being mocked.
|
||||
|
||||
See this [recipe](gmock_cook_book.md#mocking-side-effects) for more details and
|
||||
an example.
|
||||
|
||||
### I have a huge mock class, and Microsoft Visual C++ runs out of memory when compiling it. What can I do?
|
||||
|
||||
We've noticed that when the `/clr` compiler flag is used, Visual C++ uses 5~6
|
||||
times as much memory when compiling a mock class. We suggest to avoid `/clr`
|
||||
when compiling native C++ mocks.
|
|
@ -1,700 +0,0 @@
|
|||
# gMock for Dummies
|
||||
|
||||
## What Is gMock?
|
||||
|
||||
When you write a prototype or test, often it's not feasible or wise to rely on
|
||||
real objects entirely. A **mock object** implements the same interface as a real
|
||||
object (so it can be used as one), but lets you specify at run time how it will
|
||||
be used and what it should do (which methods will be called? in which order? how
|
||||
many times? with what arguments? what will they return? etc).
|
||||
|
||||
It is easy to confuse the term *fake objects* with mock objects. Fakes and mocks
|
||||
actually mean very different things in the Test-Driven Development (TDD)
|
||||
community:
|
||||
|
||||
* **Fake** objects have working implementations, but usually take some
|
||||
shortcut (perhaps to make the operations less expensive), which makes them
|
||||
not suitable for production. An in-memory file system would be an example of
|
||||
a fake.
|
||||
* **Mocks** are objects pre-programmed with *expectations*, which form a
|
||||
specification of the calls they are expected to receive.
|
||||
|
||||
If all this seems too abstract for you, don't worry - the most important thing
|
||||
to remember is that a mock allows you to check the *interaction* between itself
|
||||
and code that uses it. The difference between fakes and mocks shall become much
|
||||
clearer once you start to use mocks.
|
||||
|
||||
**gMock** is a library (sometimes we also call it a "framework" to make it sound
|
||||
cool) for creating mock classes and using them. It does to C++ what
|
||||
jMock/EasyMock does to Java (well, more or less).
|
||||
|
||||
When using gMock,
|
||||
|
||||
1. first, you use some simple macros to describe the interface you want to
|
||||
mock, and they will expand to the implementation of your mock class;
|
||||
2. next, you create some mock objects and specify its expectations and behavior
|
||||
using an intuitive syntax;
|
||||
3. then you exercise code that uses the mock objects. gMock will catch any
|
||||
violation to the expectations as soon as it arises.
|
||||
|
||||
## Why gMock?
|
||||
|
||||
While mock objects help you remove unnecessary dependencies in tests and make
|
||||
them fast and reliable, using mocks manually in C++ is *hard*:
|
||||
|
||||
* Someone has to implement the mocks. The job is usually tedious and
|
||||
error-prone. No wonder people go great distance to avoid it.
|
||||
* The quality of those manually written mocks is a bit, uh, unpredictable. You
|
||||
may see some really polished ones, but you may also see some that were
|
||||
hacked up in a hurry and have all sorts of ad hoc restrictions.
|
||||
* The knowledge you gained from using one mock doesn't transfer to the next
|
||||
one.
|
||||
|
||||
In contrast, Java and Python programmers have some fine mock frameworks (jMock,
|
||||
EasyMock, etc), which automate the creation of mocks. As a result, mocking is a
|
||||
proven effective technique and widely adopted practice in those communities.
|
||||
Having the right tool absolutely makes the difference.
|
||||
|
||||
gMock was built to help C++ programmers. It was inspired by jMock and EasyMock,
|
||||
but designed with C++'s specifics in mind. It is your friend if any of the
|
||||
following problems is bothering you:
|
||||
|
||||
* You are stuck with a sub-optimal design and wish you had done more
|
||||
prototyping before it was too late, but prototyping in C++ is by no means
|
||||
"rapid".
|
||||
* Your tests are slow as they depend on too many libraries or use expensive
|
||||
resources (e.g. a database).
|
||||
* Your tests are brittle as some resources they use are unreliable (e.g. the
|
||||
network).
|
||||
* You want to test how your code handles a failure (e.g. a file checksum
|
||||
error), but it's not easy to cause one.
|
||||
* You need to make sure that your module interacts with other modules in the
|
||||
right way, but it's hard to observe the interaction; therefore you resort to
|
||||
observing the side effects at the end of the action, but it's awkward at
|
||||
best.
|
||||
* You want to "mock out" your dependencies, except that they don't have mock
|
||||
implementations yet; and, frankly, you aren't thrilled by some of those
|
||||
hand-written mocks.
|
||||
|
||||
We encourage you to use gMock as
|
||||
|
||||
* a *design* tool, for it lets you experiment with your interface design early
|
||||
and often. More iterations lead to better designs!
|
||||
* a *testing* tool to cut your tests' outbound dependencies and probe the
|
||||
interaction between your module and its collaborators.
|
||||
|
||||
## Getting Started
|
||||
|
||||
gMock is bundled with googletest.
|
||||
|
||||
## A Case for Mock Turtles
|
||||
|
||||
Let's look at an example. Suppose you are developing a graphics program that
|
||||
relies on a [LOGO](http://en.wikipedia.org/wiki/Logo_programming_language)-like
|
||||
API for drawing. How would you test that it does the right thing? Well, you can
|
||||
run it and compare the screen with a golden screen snapshot, but let's admit it:
|
||||
tests like this are expensive to run and fragile (What if you just upgraded to a
|
||||
shiny new graphics card that has better anti-aliasing? Suddenly you have to
|
||||
update all your golden images.). It would be too painful if all your tests are
|
||||
like this. Fortunately, you learned about
|
||||
[Dependency Injection](http://en.wikipedia.org/wiki/Dependency_injection) and know the right thing
|
||||
to do: instead of having your application talk to the system API directly, wrap
|
||||
the API in an interface (say, `Turtle`) and code to that interface:
|
||||
|
||||
```cpp
|
||||
class Turtle {
|
||||
...
|
||||
virtual ~Turtle() {}
|
||||
virtual void PenUp() = 0;
|
||||
virtual void PenDown() = 0;
|
||||
virtual void Forward(int distance) = 0;
|
||||
virtual void Turn(int degrees) = 0;
|
||||
virtual void GoTo(int x, int y) = 0;
|
||||
virtual int GetX() const = 0;
|
||||
virtual int GetY() const = 0;
|
||||
};
|
||||
```
|
||||
|
||||
(Note that the destructor of `Turtle` **must** be virtual, as is the case for
|
||||
**all** classes you intend to inherit from - otherwise the destructor of the
|
||||
derived class will not be called when you delete an object through a base
|
||||
pointer, and you'll get corrupted program states like memory leaks.)
|
||||
|
||||
You can control whether the turtle's movement will leave a trace using `PenUp()`
|
||||
and `PenDown()`, and control its movement using `Forward()`, `Turn()`, and
|
||||
`GoTo()`. Finally, `GetX()` and `GetY()` tell you the current position of the
|
||||
turtle.
|
||||
|
||||
Your program will normally use a real implementation of this interface. In
|
||||
tests, you can use a mock implementation instead. This allows you to easily
|
||||
check what drawing primitives your program is calling, with what arguments, and
|
||||
in which order. Tests written this way are much more robust (they won't break
|
||||
because your new machine does anti-aliasing differently), easier to read and
|
||||
maintain (the intent of a test is expressed in the code, not in some binary
|
||||
images), and run *much, much faster*.
|
||||
|
||||
## Writing the Mock Class
|
||||
|
||||
If you are lucky, the mocks you need to use have already been implemented by
|
||||
some nice people. If, however, you find yourself in the position to write a mock
|
||||
class, relax - gMock turns this task into a fun game! (Well, almost.)
|
||||
|
||||
### How to Define It
|
||||
|
||||
Using the `Turtle` interface as example, here are the simple steps you need to
|
||||
follow:
|
||||
|
||||
* Derive a class `MockTurtle` from `Turtle`.
|
||||
* Take a *virtual* function of `Turtle` (while it's possible to
|
||||
[mock non-virtual methods using templates](gmock_cook_book.md#MockingNonVirtualMethods),
|
||||
it's much more involved).
|
||||
* In the `public:` section of the child class, write `MOCK_METHOD();`
|
||||
* Now comes the fun part: you take the function signature, cut-and-paste it
|
||||
into the macro, and add two commas - one between the return type and the
|
||||
name, another between the name and the argument list.
|
||||
* If you're mocking a const method, add a 4th parameter containing `(const)`
|
||||
(the parentheses are required).
|
||||
* Since you're overriding a virtual method, we suggest adding the `override`
|
||||
keyword. For const methods the 4th parameter becomes `(const, override)`,
|
||||
for non-const methods just `(override)`. This isn't mandatory.
|
||||
* Repeat until all virtual functions you want to mock are done. (It goes
|
||||
without saying that *all* pure virtual methods in your abstract class must
|
||||
be either mocked or overridden.)
|
||||
|
||||
After the process, you should have something like:
|
||||
|
||||
```cpp
|
||||
#include "gmock/gmock.h" // Brings in gMock.
|
||||
|
||||
class MockTurtle : public Turtle {
|
||||
public:
|
||||
...
|
||||
MOCK_METHOD(void, PenUp, (), (override));
|
||||
MOCK_METHOD(void, PenDown, (), (override));
|
||||
MOCK_METHOD(void, Forward, (int distance), (override));
|
||||
MOCK_METHOD(void, Turn, (int degrees), (override));
|
||||
MOCK_METHOD(void, GoTo, (int x, int y), (override));
|
||||
MOCK_METHOD(int, GetX, (), (const, override));
|
||||
MOCK_METHOD(int, GetY, (), (const, override));
|
||||
};
|
||||
```
|
||||
|
||||
You don't need to define these mock methods somewhere else - the `MOCK_METHOD`
|
||||
macro will generate the definitions for you. It's that simple!
|
||||
|
||||
### Where to Put It
|
||||
|
||||
When you define a mock class, you need to decide where to put its definition.
|
||||
Some people put it in a `_test.cc`. This is fine when the interface being mocked
|
||||
(say, `Foo`) is owned by the same person or team. Otherwise, when the owner of
|
||||
`Foo` changes it, your test could break. (You can't really expect `Foo`'s
|
||||
maintainer to fix every test that uses `Foo`, can you?)
|
||||
|
||||
So, the rule of thumb is: if you need to mock `Foo` and it's owned by others,
|
||||
define the mock class in `Foo`'s package (better, in a `testing` sub-package
|
||||
such that you can clearly separate production code and testing utilities), put
|
||||
it in a `.h` and a `cc_library`. Then everyone can reference them from their
|
||||
tests. If `Foo` ever changes, there is only one copy of `MockFoo` to change, and
|
||||
only tests that depend on the changed methods need to be fixed.
|
||||
|
||||
Another way to do it: you can introduce a thin layer `FooAdaptor` on top of
|
||||
`Foo` and code to this new interface. Since you own `FooAdaptor`, you can absorb
|
||||
changes in `Foo` much more easily. While this is more work initially, carefully
|
||||
choosing the adaptor interface can make your code easier to write and more
|
||||
readable (a net win in the long run), as you can choose `FooAdaptor` to fit your
|
||||
specific domain much better than `Foo` does.
|
||||
|
||||
## Using Mocks in Tests
|
||||
|
||||
Once you have a mock class, using it is easy. The typical work flow is:
|
||||
|
||||
1. Import the gMock names from the `testing` namespace such that you can use
|
||||
them unqualified (You only have to do it once per file). Remember that
|
||||
namespaces are a good idea.
|
||||
2. Create some mock objects.
|
||||
3. Specify your expectations on them (How many times will a method be called?
|
||||
With what arguments? What should it do? etc.).
|
||||
4. Exercise some code that uses the mocks; optionally, check the result using
|
||||
googletest assertions. If a mock method is called more than expected or with
|
||||
wrong arguments, you'll get an error immediately.
|
||||
5. When a mock is destructed, gMock will automatically check whether all
|
||||
expectations on it have been satisfied.
|
||||
|
||||
Here's an example:
|
||||
|
||||
```cpp
|
||||
#include "path/to/mock-turtle.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using ::testing::AtLeast; // #1
|
||||
|
||||
TEST(PainterTest, CanDrawSomething) {
|
||||
MockTurtle turtle; // #2
|
||||
EXPECT_CALL(turtle, PenDown()) // #3
|
||||
.Times(AtLeast(1));
|
||||
|
||||
Painter painter(&turtle); // #4
|
||||
|
||||
EXPECT_TRUE(painter.DrawCircle(0, 0, 10)); // #5
|
||||
}
|
||||
```
|
||||
|
||||
As you might have guessed, this test checks that `PenDown()` is called at least
|
||||
once. If the `painter` object didn't call this method, your test will fail with
|
||||
a message like this:
|
||||
|
||||
```text
|
||||
path/to/my_test.cc:119: Failure
|
||||
Actual function call count doesn't match this expectation:
|
||||
Actually: never called;
|
||||
Expected: called at least once.
|
||||
Stack trace:
|
||||
...
|
||||
```
|
||||
|
||||
**Tip 1:** If you run the test from an Emacs buffer, you can hit `<Enter>` on
|
||||
the line number to jump right to the failed expectation.
|
||||
|
||||
**Tip 2:** If your mock objects are never deleted, the final verification won't
|
||||
happen. Therefore it's a good idea to turn on the heap checker in your tests
|
||||
when you allocate mocks on the heap. You get that automatically if you use the
|
||||
`gtest_main` library already.
|
||||
|
||||
**Important note:** gMock requires expectations to be set **before** the mock
|
||||
functions are called, otherwise the behavior is **undefined**. 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.
|
||||
|
||||
This means `EXPECT_CALL()` should be read as expecting that a call will occur
|
||||
*in the future*, not that a call has occurred. Why does gMock work like that?
|
||||
Well, specifying the expectation beforehand allows gMock to report a violation
|
||||
as soon as it rises, when the context (stack trace, etc) is still available.
|
||||
This makes debugging much easier.
|
||||
|
||||
Admittedly, this test is contrived and doesn't do much. You can easily achieve
|
||||
the same effect without using gMock. However, as we shall reveal soon, gMock
|
||||
allows you to do *so much more* with the mocks.
|
||||
|
||||
## Setting Expectations
|
||||
|
||||
The key to using a mock object successfully is to set the *right expectations*
|
||||
on it. If you set the expectations too strict, your test will fail as the result
|
||||
of unrelated changes. If you set them too loose, bugs can slip through. You want
|
||||
to do it just right such that your test can catch exactly the kind of bugs you
|
||||
intend it to catch. gMock provides the necessary means for you to do it "just
|
||||
right."
|
||||
|
||||
### General Syntax
|
||||
|
||||
In gMock we use the `EXPECT_CALL()` macro to set an expectation on a mock
|
||||
method. The general syntax is:
|
||||
|
||||
```cpp
|
||||
EXPECT_CALL(mock_object, method(matchers))
|
||||
.Times(cardinality)
|
||||
.WillOnce(action)
|
||||
.WillRepeatedly(action);
|
||||
```
|
||||
|
||||
The macro has two arguments: first the mock object, and then the method and its
|
||||
arguments. Note that the two are separated by a comma (`,`), not a period (`.`).
|
||||
(Why using a comma? The answer is that it was necessary for technical reasons.)
|
||||
If the method is not overloaded, the macro can also be called without matchers:
|
||||
|
||||
```cpp
|
||||
EXPECT_CALL(mock_object, non-overloaded-method)
|
||||
.Times(cardinality)
|
||||
.WillOnce(action)
|
||||
.WillRepeatedly(action);
|
||||
```
|
||||
|
||||
This syntax allows the test writer to specify "called with any arguments"
|
||||
without explicitly specifying the number or types of arguments. To avoid
|
||||
unintended ambiguity, this syntax may only be used for methods that are not
|
||||
overloaded.
|
||||
|
||||
Either form of the macro can be followed by some optional *clauses* that provide
|
||||
more information about the expectation. We'll discuss how each clause works in
|
||||
the coming sections.
|
||||
|
||||
This syntax is designed to make an expectation read like English. For example,
|
||||
you can probably guess that
|
||||
|
||||
```cpp
|
||||
using ::testing::Return;
|
||||
...
|
||||
EXPECT_CALL(turtle, GetX())
|
||||
.Times(5)
|
||||
.WillOnce(Return(100))
|
||||
.WillOnce(Return(150))
|
||||
.WillRepeatedly(Return(200));
|
||||
```
|
||||
|
||||
says that the `turtle` object's `GetX()` method will be called five times, it
|
||||
will return 100 the first time, 150 the second time, and then 200 every time.
|
||||
Some people like to call this style of syntax a Domain-Specific Language (DSL).
|
||||
|
||||
{: .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
|
||||
reader), and second it allows gMock to include the source file location of a
|
||||
failed expectation in messages, making debugging easier.
|
||||
|
||||
### Matchers: What Arguments Do We Expect?
|
||||
|
||||
When a mock function takes arguments, we may specify what arguments we are
|
||||
expecting, for example:
|
||||
|
||||
```cpp
|
||||
// Expects the turtle to move forward by 100 units.
|
||||
EXPECT_CALL(turtle, Forward(100));
|
||||
```
|
||||
|
||||
Oftentimes you do not want to be too specific. Remember that talk about tests
|
||||
being too rigid? Over specification leads to brittle tests and obscures the
|
||||
intent of tests. Therefore we encourage you to specify only what's necessary—no
|
||||
more, no less. If you aren't interested in the value of an argument, write `_`
|
||||
as the argument, which means "anything goes":
|
||||
|
||||
```cpp
|
||||
using ::testing::_;
|
||||
...
|
||||
// Expects that the turtle jumps to somewhere on the x=50 line.
|
||||
EXPECT_CALL(turtle, GoTo(50, _));
|
||||
```
|
||||
|
||||
`_` is an instance of what we call **matchers**. A matcher is like a predicate
|
||||
and can test whether an argument is what we'd expect. You can use a matcher
|
||||
inside `EXPECT_CALL()` wherever a function argument is expected. `_` is a
|
||||
convenient way of saying "any value".
|
||||
|
||||
In the above examples, `100` and `50` are also matchers; implicitly, they are
|
||||
the same as `Eq(100)` and `Eq(50)`, which specify that the argument must be
|
||||
equal (using `operator==`) to the matcher argument. There are many
|
||||
[built-in matchers](reference/matchers.md) for common types (as well as
|
||||
[custom matchers](gmock_cook_book.md#NewMatchers)); for example:
|
||||
|
||||
```cpp
|
||||
using ::testing::Ge;
|
||||
...
|
||||
// Expects the turtle moves forward by at least 100.
|
||||
EXPECT_CALL(turtle, Forward(Ge(100)));
|
||||
```
|
||||
|
||||
If you don't care about *any* arguments, rather than specify `_` for each of
|
||||
them you may instead omit the parameter list:
|
||||
|
||||
```cpp
|
||||
// Expects the turtle to move forward.
|
||||
EXPECT_CALL(turtle, Forward);
|
||||
// Expects the turtle to jump somewhere.
|
||||
EXPECT_CALL(turtle, GoTo);
|
||||
```
|
||||
|
||||
This works for all non-overloaded methods; if a method is overloaded, you need
|
||||
to help gMock resolve which overload is expected by specifying the number of
|
||||
arguments and possibly also the
|
||||
[types of the arguments](gmock_cook_book.md#SelectOverload).
|
||||
|
||||
### Cardinalities: How Many Times Will It Be Called?
|
||||
|
||||
The first clause we can specify following an `EXPECT_CALL()` is `Times()`. We
|
||||
call its argument a **cardinality** as it tells *how many times* the call should
|
||||
occur. It allows us to repeat an expectation many times without actually writing
|
||||
it as many times. More importantly, a cardinality can be "fuzzy", just like a
|
||||
matcher can be. This allows a user to express the intent of a test exactly.
|
||||
|
||||
An interesting special case is when we say `Times(0)`. You may have guessed - it
|
||||
means that the function shouldn't be called with the given arguments at all, and
|
||||
gMock will report a googletest failure whenever the function is (wrongfully)
|
||||
called.
|
||||
|
||||
We've seen `AtLeast(n)` as an example of fuzzy cardinalities earlier. For the
|
||||
list of built-in cardinalities you can use, see
|
||||
[here](gmock_cheat_sheet.md#CardinalityList).
|
||||
|
||||
The `Times()` clause can be omitted. **If you omit `Times()`, gMock will infer
|
||||
the cardinality for you.** The rules are easy to remember:
|
||||
|
||||
* If **neither** `WillOnce()` **nor** `WillRepeatedly()` is in the
|
||||
`EXPECT_CALL()`, the inferred cardinality is `Times(1)`.
|
||||
* If there are *n* `WillOnce()`'s but **no** `WillRepeatedly()`, where *n* >=
|
||||
1, the cardinality is `Times(n)`.
|
||||
* If there are *n* `WillOnce()`'s and **one** `WillRepeatedly()`, where *n* >=
|
||||
0, the cardinality is `Times(AtLeast(n))`.
|
||||
|
||||
**Quick quiz:** what do you think will happen if a function is expected to be
|
||||
called twice but actually called four times?
|
||||
|
||||
### Actions: What Should It Do?
|
||||
|
||||
Remember that a mock object doesn't really have a working implementation? We as
|
||||
users have to tell it what to do when a method is invoked. This is easy in
|
||||
gMock.
|
||||
|
||||
First, if the return type of a mock function is a built-in type or a pointer,
|
||||
the function has a **default action** (a `void` function will just return, a
|
||||
`bool` function will return `false`, and other functions will return 0). In
|
||||
addition, in C++ 11 and above, a mock function whose return type is
|
||||
default-constructible (i.e. has a default constructor) has a default action of
|
||||
returning a default-constructed value. If you don't say anything, this behavior
|
||||
will be used.
|
||||
|
||||
Second, if a mock function doesn't have a default action, or the default action
|
||||
doesn't suit you, you can specify the action to be taken each time the
|
||||
expectation matches using a series of `WillOnce()` clauses followed by an
|
||||
optional `WillRepeatedly()`. For example,
|
||||
|
||||
```cpp
|
||||
using ::testing::Return;
|
||||
...
|
||||
EXPECT_CALL(turtle, GetX())
|
||||
.WillOnce(Return(100))
|
||||
.WillOnce(Return(200))
|
||||
.WillOnce(Return(300));
|
||||
```
|
||||
|
||||
says that `turtle.GetX()` will be called *exactly three times* (gMock inferred
|
||||
this from how many `WillOnce()` clauses we've written, since we didn't
|
||||
explicitly write `Times()`), and will return 100, 200, and 300 respectively.
|
||||
|
||||
```cpp
|
||||
using ::testing::Return;
|
||||
...
|
||||
EXPECT_CALL(turtle, GetY())
|
||||
.WillOnce(Return(100))
|
||||
.WillOnce(Return(200))
|
||||
.WillRepeatedly(Return(300));
|
||||
```
|
||||
|
||||
says that `turtle.GetY()` will be called *at least twice* (gMock knows this as
|
||||
we've written two `WillOnce()` clauses and a `WillRepeatedly()` while having no
|
||||
explicit `Times()`), will return 100 and 200 respectively the first two times,
|
||||
and 300 from the third time on.
|
||||
|
||||
Of course, if you explicitly write a `Times()`, gMock will not try to infer the
|
||||
cardinality itself. What if the number you specified is larger than there are
|
||||
`WillOnce()` clauses? Well, after all `WillOnce()`s are used up, gMock will do
|
||||
the *default* action for the function every time (unless, of course, you have a
|
||||
`WillRepeatedly()`.).
|
||||
|
||||
What can we do inside `WillOnce()` besides `Return()`? You can return a
|
||||
reference using `ReturnRef(*variable*)`, or invoke a pre-defined function, among
|
||||
[others](gmock_cook_book.md#using-actions).
|
||||
|
||||
**Important note:** The `EXPECT_CALL()` statement evaluates the action clause
|
||||
only once, even though the action may be performed many times. Therefore you
|
||||
must be careful about side effects. The following may not do what you want:
|
||||
|
||||
```cpp
|
||||
using ::testing::Return;
|
||||
...
|
||||
int n = 100;
|
||||
EXPECT_CALL(turtle, GetX())
|
||||
.Times(4)
|
||||
.WillRepeatedly(Return(n++));
|
||||
```
|
||||
|
||||
Instead of returning 100, 101, 102, ..., consecutively, this mock function will
|
||||
always return 100 as `n++` is only evaluated once. Similarly, `Return(new Foo)`
|
||||
will create a new `Foo` object when the `EXPECT_CALL()` is executed, and will
|
||||
return the same pointer every time. If you want the side effect to happen every
|
||||
time, you need to define a custom action, which we'll teach in the
|
||||
[cook book](gmock_cook_book.md).
|
||||
|
||||
Time for another quiz! What do you think the following means?
|
||||
|
||||
```cpp
|
||||
using ::testing::Return;
|
||||
...
|
||||
EXPECT_CALL(turtle, GetY())
|
||||
.Times(4)
|
||||
.WillOnce(Return(100));
|
||||
```
|
||||
|
||||
Obviously `turtle.GetY()` is expected to be called four times. But if you think
|
||||
it will return 100 every time, think twice! Remember that one `WillOnce()`
|
||||
clause will be consumed each time the function is invoked and the default action
|
||||
will be taken afterwards. So the right answer is that `turtle.GetY()` will
|
||||
return 100 the first time, but **return 0 from the second time on**, as
|
||||
returning 0 is the default action for `int` functions.
|
||||
|
||||
### Using Multiple Expectations {#MultiExpectations}
|
||||
|
||||
So far we've only shown examples where you have a single expectation. More
|
||||
realistically, you'll specify expectations on multiple mock methods which may be
|
||||
from multiple mock objects.
|
||||
|
||||
By default, when a mock method is invoked, gMock will search the expectations in
|
||||
the **reverse order** they are defined, and stop when an active expectation that
|
||||
matches the arguments is found (you can think of it as "newer rules override
|
||||
older ones."). If the matching expectation cannot take any more calls, you will
|
||||
get an upper-bound-violated failure. Here's an example:
|
||||
|
||||
```cpp
|
||||
using ::testing::_;
|
||||
...
|
||||
EXPECT_CALL(turtle, Forward(_)); // #1
|
||||
EXPECT_CALL(turtle, Forward(10)) // #2
|
||||
.Times(2);
|
||||
```
|
||||
|
||||
If `Forward(10)` is called three times in a row, the third time it will be an
|
||||
error, as the last matching expectation (#2) has been saturated. If, however,
|
||||
the third `Forward(10)` call is replaced by `Forward(20)`, then it would be OK,
|
||||
as now #1 will be the matching expectation.
|
||||
|
||||
{: .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
|
||||
and then customize the mock by writing more specific expectations in the test
|
||||
body. So, if you have two expectations on the same method, you want to put the
|
||||
one with more specific matchers **after** the other, or the more specific rule
|
||||
would be shadowed by the more general one that comes after it.
|
||||
|
||||
{: .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).
|
||||
|
||||
### Ordered vs Unordered Calls {#OrderedCalls}
|
||||
|
||||
By default, an expectation can match a call even though an earlier expectation
|
||||
hasn't been satisfied. In other words, the calls don't have to occur in the
|
||||
order the expectations are specified.
|
||||
|
||||
Sometimes, you may want all the expected calls to occur in a strict order. To
|
||||
say this in gMock is easy:
|
||||
|
||||
```cpp
|
||||
using ::testing::InSequence;
|
||||
...
|
||||
TEST(FooTest, DrawsLineSegment) {
|
||||
...
|
||||
{
|
||||
InSequence seq;
|
||||
|
||||
EXPECT_CALL(turtle, PenDown());
|
||||
EXPECT_CALL(turtle, Forward(100));
|
||||
EXPECT_CALL(turtle, PenUp());
|
||||
}
|
||||
Foo();
|
||||
}
|
||||
```
|
||||
|
||||
By creating an object of type `InSequence`, all expectations in its scope are
|
||||
put into a *sequence* and have to occur *sequentially*. Since we are just
|
||||
relying on the constructor and destructor of this object to do the actual work,
|
||||
its name is really irrelevant.
|
||||
|
||||
In this example, we test that `Foo()` calls the three expected functions in the
|
||||
order as written. If a call is made out-of-order, it will be an error.
|
||||
|
||||
(What if you care about the relative order of some of the calls, but not all of
|
||||
them? Can you specify an arbitrary partial order? The answer is ... yes! The
|
||||
details can be found [here](gmock_cook_book.md#OrderedCalls).)
|
||||
|
||||
### All Expectations Are Sticky (Unless Said Otherwise) {#StickyExpectations}
|
||||
|
||||
Now let's do a quick quiz to see how well you can use this mock stuff already.
|
||||
How would you test that the turtle is asked to go to the origin *exactly twice*
|
||||
(you want to ignore any other instructions it receives)?
|
||||
|
||||
After you've come up with your answer, take a look at ours and compare notes
|
||||
(solve it yourself first - don't cheat!):
|
||||
|
||||
```cpp
|
||||
using ::testing::_;
|
||||
using ::testing::AnyNumber;
|
||||
...
|
||||
EXPECT_CALL(turtle, GoTo(_, _)) // #1
|
||||
.Times(AnyNumber());
|
||||
EXPECT_CALL(turtle, GoTo(0, 0)) // #2
|
||||
.Times(2);
|
||||
```
|
||||
|
||||
Suppose `turtle.GoTo(0, 0)` is called three times. In the third time, gMock will
|
||||
see that the arguments match expectation #2 (remember that we always pick the
|
||||
last matching expectation). Now, since we said that there should be only two
|
||||
such calls, gMock will report an error immediately. This is basically what we've
|
||||
told you in the [Using Multiple Expectations](#MultiExpectations) section above.
|
||||
|
||||
This example shows that **expectations in gMock are "sticky" by default**, in
|
||||
the sense that they remain active even after we have reached their invocation
|
||||
upper bounds. This is an important rule to remember, as it affects the meaning
|
||||
of the spec, and is **different** to how it's done in many other mocking
|
||||
frameworks (Why'd we do that? Because we think our rule makes the common cases
|
||||
easier to express and understand.).
|
||||
|
||||
Simple? Let's see if you've really understood it: what does the following code
|
||||
say?
|
||||
|
||||
```cpp
|
||||
using ::testing::Return;
|
||||
...
|
||||
for (int i = n; i > 0; i--) {
|
||||
EXPECT_CALL(turtle, GetX())
|
||||
.WillOnce(Return(10*i));
|
||||
}
|
||||
```
|
||||
|
||||
If you think it says that `turtle.GetX()` will be called `n` times and will
|
||||
return 10, 20, 30, ..., consecutively, think twice! The problem is that, as we
|
||||
said, expectations are sticky. So, the second time `turtle.GetX()` is called,
|
||||
the last (latest) `EXPECT_CALL()` statement will match, and will immediately
|
||||
lead to an "upper bound violated" error - this piece of code is not very useful!
|
||||
|
||||
One correct way of saying that `turtle.GetX()` will return 10, 20, 30, ..., is
|
||||
to explicitly say that the expectations are *not* sticky. In other words, they
|
||||
should *retire* as soon as they are saturated:
|
||||
|
||||
```cpp
|
||||
using ::testing::Return;
|
||||
...
|
||||
for (int i = n; i > 0; i--) {
|
||||
EXPECT_CALL(turtle, GetX())
|
||||
.WillOnce(Return(10*i))
|
||||
.RetiresOnSaturation();
|
||||
}
|
||||
```
|
||||
|
||||
And, there's a better way to do it: in this case, we expect the calls to occur
|
||||
in a specific order, and we line up the actions to match the order. Since the
|
||||
order is important here, we should make it explicit using a sequence:
|
||||
|
||||
```cpp
|
||||
using ::testing::InSequence;
|
||||
using ::testing::Return;
|
||||
...
|
||||
{
|
||||
InSequence s;
|
||||
|
||||
for (int i = 1; i <= n; i++) {
|
||||
EXPECT_CALL(turtle, GetX())
|
||||
.WillOnce(Return(10*i))
|
||||
.RetiresOnSaturation();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
By the way, the other situation where an expectation may *not* be sticky is when
|
||||
it's in a sequence - as soon as another expectation that comes after it in the
|
||||
sequence has been used, it automatically retires (and will never be used to
|
||||
match any call).
|
||||
|
||||
### Uninteresting Calls
|
||||
|
||||
A mock object may have many methods, and not all of them are that interesting.
|
||||
For example, in some tests we may not care about how many times `GetX()` and
|
||||
`GetY()` get called.
|
||||
|
||||
In gMock, if you are not interested in a method, just don't say anything about
|
||||
it. If a call to this method occurs, you'll see a warning in the test output,
|
||||
but it won't be a failure. This is called "naggy" behavior; to change, see
|
||||
[The Nice, the Strict, and the Naggy](gmock_cook_book.md#NiceStrictNaggy).
|
|
@ -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.
|
|
@ -1,148 +0,0 @@
|
|||
## Using GoogleTest from various build systems
|
||||
|
||||
GoogleTest comes with pkg-config files that can be used to determine all
|
||||
necessary flags for compiling and linking to GoogleTest (and GoogleMock).
|
||||
Pkg-config is a standardised plain-text format containing
|
||||
|
||||
* the includedir (-I) path
|
||||
* necessary macro (-D) definitions
|
||||
* further required flags (-pthread)
|
||||
* the library (-L) path
|
||||
* the library (-l) to link to
|
||||
|
||||
All current build systems support pkg-config in one way or another. For all
|
||||
examples here we assume you want to compile the sample
|
||||
`samples/sample3_unittest.cc`.
|
||||
|
||||
### CMake
|
||||
|
||||
Using `pkg-config` in CMake is fairly easy:
|
||||
|
||||
```cmake
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
cmake_policy(SET CMP0048 NEW)
|
||||
project(my_gtest_pkgconfig VERSION 0.0.1 LANGUAGES CXX)
|
||||
|
||||
find_package(PkgConfig)
|
||||
pkg_search_module(GTEST REQUIRED gtest_main)
|
||||
|
||||
add_executable(testapp samples/sample3_unittest.cc)
|
||||
target_link_libraries(testapp ${GTEST_LDFLAGS})
|
||||
target_compile_options(testapp PUBLIC ${GTEST_CFLAGS})
|
||||
|
||||
include(CTest)
|
||||
add_test(first_and_only_test testapp)
|
||||
```
|
||||
|
||||
It is generally recommended that you use `target_compile_options` + `_CFLAGS`
|
||||
over `target_include_directories` + `_INCLUDE_DIRS` as the former includes not
|
||||
just -I flags (GoogleTest might require a macro indicating to internal headers
|
||||
that all libraries have been compiled with threading enabled. In addition,
|
||||
GoogleTest might also require `-pthread` in the compiling step, and as such
|
||||
splitting the pkg-config `Cflags` variable into include dirs and macros for
|
||||
`target_compile_definitions()` might still miss this). The same recommendation
|
||||
goes for using `_LDFLAGS` over the more commonplace `_LIBRARIES`, which happens
|
||||
to discard `-L` flags and `-pthread`.
|
||||
|
||||
### Help! pkg-config can't find GoogleTest!
|
||||
|
||||
Let's say you have a `CMakeLists.txt` along the lines of the one in this
|
||||
tutorial and you try to run `cmake`. It is very possible that you get a failure
|
||||
along the lines of:
|
||||
|
||||
```
|
||||
-- Checking for one of the modules 'gtest_main'
|
||||
CMake Error at /usr/share/cmake/Modules/FindPkgConfig.cmake:640 (message):
|
||||
None of the required 'gtest_main' found
|
||||
```
|
||||
|
||||
These failures are common if you installed GoogleTest yourself and have not
|
||||
sourced it from a distro or other package manager. If so, you need to tell
|
||||
pkg-config where it can find the `.pc` files containing the information. Say you
|
||||
installed GoogleTest to `/usr/local`, then it might be that the `.pc` files are
|
||||
installed under `/usr/local/lib64/pkgconfig`. If you set
|
||||
|
||||
```
|
||||
export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig
|
||||
```
|
||||
|
||||
pkg-config will also try to look in `PKG_CONFIG_PATH` to find `gtest_main.pc`.
|
||||
|
||||
### Using pkg-config in a cross-compilation setting
|
||||
|
||||
Pkg-config can be used in a cross-compilation setting too. To do this, let's
|
||||
assume the final prefix of the cross-compiled installation will be `/usr`, and
|
||||
your sysroot is `/home/MYUSER/sysroot`. Configure and install GTest using
|
||||
|
||||
```
|
||||
mkdir build && cmake -DCMAKE_INSTALL_PREFIX=/usr ..
|
||||
```
|
||||
|
||||
Install into the sysroot using `DESTDIR`:
|
||||
|
||||
```
|
||||
make -j install DESTDIR=/home/MYUSER/sysroot
|
||||
```
|
||||
|
||||
Before we continue, it is recommended to **always** define the following two
|
||||
variables for pkg-config in a cross-compilation setting:
|
||||
|
||||
```
|
||||
export PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=yes
|
||||
export PKG_CONFIG_ALLOW_SYSTEM_LIBS=yes
|
||||
```
|
||||
|
||||
otherwise `pkg-config` will filter `-I` and `-L` flags against standard prefixes
|
||||
such as `/usr` (see https://bugs.freedesktop.org/show_bug.cgi?id=28264#c3 for
|
||||
reasons why this stripping needs to occur usually).
|
||||
|
||||
If you look at the generated pkg-config file, it will look something like
|
||||
|
||||
```
|
||||
libdir=/usr/lib64
|
||||
includedir=/usr/include
|
||||
|
||||
Name: gtest
|
||||
Description: GoogleTest (without main() function)
|
||||
Version: 1.10.0
|
||||
URL: https://github.com/google/googletest
|
||||
Libs: -L${libdir} -lgtest -lpthread
|
||||
Cflags: -I${includedir} -DGTEST_HAS_PTHREAD=1 -lpthread
|
||||
```
|
||||
|
||||
Notice that the sysroot is not included in `libdir` and `includedir`! If you try
|
||||
to run `pkg-config` with the correct
|
||||
`PKG_CONFIG_LIBDIR=/home/MYUSER/sysroot/usr/lib64/pkgconfig` against this `.pc`
|
||||
file, you will get
|
||||
|
||||
```
|
||||
$ pkg-config --cflags gtest
|
||||
-DGTEST_HAS_PTHREAD=1 -lpthread -I/usr/include
|
||||
$ pkg-config --libs gtest
|
||||
-L/usr/lib64 -lgtest -lpthread
|
||||
```
|
||||
|
||||
which is obviously wrong and points to the `CBUILD` and not `CHOST` root. In
|
||||
order to use this in a cross-compilation setting, we need to tell pkg-config to
|
||||
inject the actual sysroot into `-I` and `-L` variables. Let us now tell
|
||||
pkg-config about the actual sysroot
|
||||
|
||||
```
|
||||
export PKG_CONFIG_DIR=
|
||||
export PKG_CONFIG_SYSROOT_DIR=/home/MYUSER/sysroot
|
||||
export PKG_CONFIG_LIBDIR=${PKG_CONFIG_SYSROOT_DIR}/usr/lib64/pkgconfig
|
||||
```
|
||||
|
||||
and running `pkg-config` again we get
|
||||
|
||||
```
|
||||
$ pkg-config --cflags gtest
|
||||
-DGTEST_HAS_PTHREAD=1 -lpthread -I/home/MYUSER/sysroot/usr/include
|
||||
$ pkg-config --libs gtest
|
||||
-L/home/MYUSER/sysroot/usr/lib64 -lgtest -lpthread
|
||||
```
|
||||
|
||||
which contains the correct sysroot now. For a more comprehensive guide to also
|
||||
including `${CHOST}` in build system calls, see the excellent tutorial by Diego
|
||||
Elio Pettenò: <https://autotools.io/pkgconfig/cross-compiling.html>
|
|
@ -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.
|
|
@ -1,482 +0,0 @@
|
|||
# Googletest Primer
|
||||
|
||||
## Introduction: Why googletest?
|
||||
|
||||
*googletest* helps you write better C++ tests.
|
||||
|
||||
googletest is a testing framework developed by the Testing Technology team with
|
||||
Google's specific requirements and constraints in mind. Whether you work on
|
||||
Linux, Windows, or a Mac, if you write C++ code, googletest can help you. And it
|
||||
supports *any* kind of tests, not just unit tests.
|
||||
|
||||
So what makes a good test, and how does googletest fit in? We believe:
|
||||
|
||||
1. Tests should be *independent* and *repeatable*. It's a pain to debug a test
|
||||
that succeeds or fails as a result of other tests. googletest isolates the
|
||||
tests by running each of them on a different object. When a test fails,
|
||||
googletest allows you to run it in isolation for quick debugging.
|
||||
2. Tests should be well *organized* and reflect the structure of the tested
|
||||
code. googletest groups related tests into test suites that can share data
|
||||
and subroutines. This common pattern is easy to recognize and makes tests
|
||||
easy to maintain. Such consistency is especially helpful when people switch
|
||||
projects and start to work on a new code base.
|
||||
3. Tests should be *portable* and *reusable*. Google has a lot of code that is
|
||||
platform-neutral; its tests should also be platform-neutral. googletest
|
||||
works on different OSes, with different compilers, with or without
|
||||
exceptions, so googletest tests can work with a variety of configurations.
|
||||
4. When tests fail, they should provide as much *information* about the problem
|
||||
as possible. googletest doesn't stop at the first test failure. Instead, it
|
||||
only stops the current test and continues with the next. You can also set up
|
||||
tests that report non-fatal failures after which the current test continues.
|
||||
Thus, you can detect and fix multiple bugs in a single run-edit-compile
|
||||
cycle.
|
||||
5. The testing framework should liberate test writers from housekeeping chores
|
||||
and let them focus on the test *content*. googletest automatically keeps
|
||||
track of all tests defined, and doesn't require the user to enumerate them
|
||||
in order to run them.
|
||||
6. Tests should be *fast*. With googletest, you can reuse shared resources
|
||||
across tests and pay for the set-up/tear-down only once, without making
|
||||
tests depend on each other.
|
||||
|
||||
Since googletest is based on the popular xUnit architecture, you'll feel right
|
||||
at home if you've used JUnit or PyUnit before. If not, it will take you about 10
|
||||
minutes to learn the basics and get started. So let's go!
|
||||
|
||||
## Beware of the nomenclature
|
||||
|
||||
{: .callout .note}
|
||||
_Note:_ There might be some confusion arising from different definitions of the
|
||||
terms _Test_, _Test Case_ and _Test Suite_, so beware of misunderstanding these.
|
||||
|
||||
Historically, googletest started to use the term _Test Case_ for grouping
|
||||
related tests, whereas current publications, including International Software
|
||||
Testing Qualifications Board ([ISTQB](http://www.istqb.org/)) materials and
|
||||
various textbooks on software quality, use the term
|
||||
_[Test Suite][istqb test suite]_ for this.
|
||||
|
||||
The related term _Test_, as it is used in googletest, corresponds to the term
|
||||
_[Test Case][istqb test case]_ of ISTQB and others.
|
||||
|
||||
The term _Test_ is commonly of broad enough sense, including ISTQB's definition
|
||||
of _Test Case_, so it's not much of a problem here. But the term _Test Case_ as
|
||||
was used in Google Test is of contradictory sense and thus confusing.
|
||||
|
||||
googletest recently started replacing the term _Test Case_ with _Test Suite_.
|
||||
The preferred API is *TestSuite*. The older TestCase API is being slowly
|
||||
deprecated and refactored away.
|
||||
|
||||
So please be aware of the different definitions of the terms:
|
||||
|
||||
|
||||
Meaning | googletest Term | [ISTQB](http://www.istqb.org/) Term
|
||||
:----------------------------------------------------------------------------------- | :---------------------- | :----------------------------------
|
||||
Exercise a particular program path with specific input values and verify the results | [TEST()](#simple-tests) | [Test Case][istqb test case]
|
||||
|
||||
|
||||
[istqb test case]: http://glossary.istqb.org/en/search/test%20case
|
||||
[istqb test suite]: http://glossary.istqb.org/en/search/test%20suite
|
||||
|
||||
## Basic Concepts
|
||||
|
||||
When using googletest, you start by writing *assertions*, which are statements
|
||||
that check whether a condition is true. An assertion's result can be *success*,
|
||||
*nonfatal failure*, or *fatal failure*. If a fatal failure occurs, it aborts the
|
||||
current function; otherwise the program continues normally.
|
||||
|
||||
*Tests* use assertions to verify the tested code's behavior. If a test crashes
|
||||
or has a failed assertion, then it *fails*; otherwise it *succeeds*.
|
||||
|
||||
A *test suite* contains one or many tests. You should group your tests into test
|
||||
suites that reflect the structure of the tested code. When multiple tests in a
|
||||
test suite need to share common objects and subroutines, you can put them into a
|
||||
*test fixture* class.
|
||||
|
||||
A *test program* can contain multiple test suites.
|
||||
|
||||
We'll now explain how to write a test program, starting at the individual
|
||||
assertion level and building up to tests and test suites.
|
||||
|
||||
## Assertions
|
||||
|
||||
googletest assertions are macros that resemble function calls. You test a class
|
||||
or function by making assertions about its behavior. When an assertion fails,
|
||||
googletest prints the assertion's source file and line number location, along
|
||||
with a failure message. You may also supply a custom failure message which will
|
||||
be appended to googletest's message.
|
||||
|
||||
The assertions come in pairs that test the same thing but have different effects
|
||||
on the current function. `ASSERT_*` versions generate fatal failures when they
|
||||
fail, and **abort the current function**. `EXPECT_*` versions generate nonfatal
|
||||
failures, which don't abort the current function. Usually `EXPECT_*` are
|
||||
preferred, as they allow more than one failure to be reported in a test.
|
||||
However, you should use `ASSERT_*` if it doesn't make sense to continue when the
|
||||
assertion in question fails.
|
||||
|
||||
Since a failed `ASSERT_*` returns from the current function immediately,
|
||||
possibly skipping clean-up code that comes after it, it may cause a space leak.
|
||||
Depending on the nature of the leak, it may or may not be worth fixing - so keep
|
||||
this in mind if you get a heap checker error in addition to assertion errors.
|
||||
|
||||
To provide a custom failure message, simply stream it into the macro using the
|
||||
`<<` operator or a sequence of such operators. See the following example, using
|
||||
the [`ASSERT_EQ` and `EXPECT_EQ`](reference/assertions.md#EXPECT_EQ) macros to
|
||||
verify value equality:
|
||||
|
||||
```c++
|
||||
ASSERT_EQ(x.size(), y.size()) << "Vectors x and y are of unequal length";
|
||||
|
||||
for (int i = 0; i < x.size(); ++i) {
|
||||
EXPECT_EQ(x[i], y[i]) << "Vectors x and y differ at index " << i;
|
||||
}
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
GoogleTest provides a collection of assertions for verifying the behavior of
|
||||
your code in various ways. You can check Boolean conditions, compare values
|
||||
based on relational operators, verify string values, floating-point values, and
|
||||
much more. There are even assertions that enable you to verify more complex
|
||||
states by providing custom predicates. For the complete list of assertions
|
||||
provided by GoogleTest, see the [Assertions Reference](reference/assertions.md).
|
||||
|
||||
## Simple Tests
|
||||
|
||||
To create a test:
|
||||
|
||||
1. Use the `TEST()` macro to define and name a test function. These are
|
||||
ordinary C++ functions that don't return a value.
|
||||
2. In this function, along with any valid C++ statements you want to include,
|
||||
use the various googletest assertions to check values.
|
||||
3. The test's result is determined by the assertions; if any assertion in the
|
||||
test fails (either fatally or non-fatally), or if the test crashes, the
|
||||
entire test fails. Otherwise, it succeeds.
|
||||
|
||||
```c++
|
||||
TEST(TestSuiteName, TestName) {
|
||||
... test body ...
|
||||
}
|
||||
```
|
||||
|
||||
`TEST()` arguments go from general to specific. The *first* argument is the name
|
||||
of the test suite, and the *second* argument is the test's name within the test
|
||||
suite. Both names must be valid C++ identifiers, and they should not contain
|
||||
any underscores (`_`). A test's *full name* consists of its containing test suite and
|
||||
its individual name. Tests from different test suites can have the same
|
||||
individual name.
|
||||
|
||||
For example, let's take a simple integer function:
|
||||
|
||||
```c++
|
||||
int Factorial(int n); // Returns the factorial of n
|
||||
```
|
||||
|
||||
A test suite for this function might look like:
|
||||
|
||||
```c++
|
||||
// Tests factorial of 0.
|
||||
TEST(FactorialTest, HandlesZeroInput) {
|
||||
EXPECT_EQ(Factorial(0), 1);
|
||||
}
|
||||
|
||||
// Tests factorial of positive numbers.
|
||||
TEST(FactorialTest, HandlesPositiveInput) {
|
||||
EXPECT_EQ(Factorial(1), 1);
|
||||
EXPECT_EQ(Factorial(2), 2);
|
||||
EXPECT_EQ(Factorial(3), 6);
|
||||
EXPECT_EQ(Factorial(8), 40320);
|
||||
}
|
||||
```
|
||||
|
||||
googletest groups the test results by test suites, so logically related tests
|
||||
should be in the same test suite; in other words, the first argument to their
|
||||
`TEST()` should be the same. In the above example, we have two tests,
|
||||
`HandlesZeroInput` and `HandlesPositiveInput`, that belong to the same test
|
||||
suite `FactorialTest`.
|
||||
|
||||
When naming your test suites and tests, you should follow the same convention as
|
||||
for
|
||||
[naming functions and classes](https://google.github.io/styleguide/cppguide.html#Function_Names).
|
||||
|
||||
**Availability**: Linux, Windows, Mac.
|
||||
|
||||
## Test Fixtures: Using the Same Data Configuration for Multiple Tests {#same-data-multiple-tests}
|
||||
|
||||
If you find yourself writing two or more tests that operate on similar data, you
|
||||
can use a *test fixture*. This allows you to reuse the same configuration of
|
||||
objects for several different tests.
|
||||
|
||||
To create a fixture:
|
||||
|
||||
1. Derive a class from `::testing::Test` . Start its body with `protected:`, as
|
||||
we'll want to access fixture members from sub-classes.
|
||||
2. Inside the class, declare any objects you plan to use.
|
||||
3. If necessary, write a default constructor or `SetUp()` function to prepare
|
||||
the objects for each test. A common mistake is to spell `SetUp()` as
|
||||
**`Setup()`** with a small `u` - Use `override` in C++11 to make sure you
|
||||
spelled it correctly.
|
||||
4. If necessary, write a destructor or `TearDown()` function to release any
|
||||
resources you allocated in `SetUp()` . To learn when you should use the
|
||||
constructor/destructor and when you should use `SetUp()/TearDown()`, read
|
||||
the [FAQ](faq.md#CtorVsSetUp).
|
||||
5. If needed, define subroutines for your tests to share.
|
||||
|
||||
When using a fixture, use `TEST_F()` instead of `TEST()` as it allows you to
|
||||
access objects and subroutines in the test fixture:
|
||||
|
||||
```c++
|
||||
TEST_F(TestFixtureName, TestName) {
|
||||
... test body ...
|
||||
}
|
||||
```
|
||||
|
||||
Like `TEST()`, the first argument is the test suite name, but for `TEST_F()`
|
||||
this must be the name of the test fixture class. You've probably guessed: `_F`
|
||||
is for fixture.
|
||||
|
||||
Unfortunately, the C++ macro system does not allow us to create a single macro
|
||||
that can handle both types of tests. Using the wrong macro causes a compiler
|
||||
error.
|
||||
|
||||
Also, you must first define a test fixture class before using it in a
|
||||
`TEST_F()`, or you'll get the compiler error "`virtual outside class
|
||||
declaration`".
|
||||
|
||||
For each test defined with `TEST_F()`, googletest will create a *fresh* test
|
||||
fixture at runtime, immediately initialize it via `SetUp()`, run the test,
|
||||
clean up by calling `TearDown()`, and then delete the test fixture. Note that
|
||||
different tests in the same test suite have different test fixture objects, and
|
||||
googletest always deletes a test fixture before it creates the next one.
|
||||
googletest does **not** reuse the same test fixture for multiple tests. Any
|
||||
changes one test makes to the fixture do not affect other tests.
|
||||
|
||||
As an example, let's write tests for a FIFO queue class named `Queue`, which has
|
||||
the following interface:
|
||||
|
||||
```c++
|
||||
template <typename E> // E is the element type.
|
||||
class Queue {
|
||||
public:
|
||||
Queue();
|
||||
void Enqueue(const E& element);
|
||||
E* Dequeue(); // Returns NULL if the queue is empty.
|
||||
size_t size() const;
|
||||
...
|
||||
};
|
||||
```
|
||||
|
||||
First, define a fixture class. By convention, you should give it the name
|
||||
`FooTest` where `Foo` is the class being tested.
|
||||
|
||||
```c++
|
||||
class QueueTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
q1_.Enqueue(1);
|
||||
q2_.Enqueue(2);
|
||||
q2_.Enqueue(3);
|
||||
}
|
||||
|
||||
// void TearDown() override {}
|
||||
|
||||
Queue<int> q0_;
|
||||
Queue<int> q1_;
|
||||
Queue<int> q2_;
|
||||
};
|
||||
```
|
||||
|
||||
In this case, `TearDown()` is not needed since we don't have to clean up after
|
||||
each test, other than what's already done by the destructor.
|
||||
|
||||
Now we'll write tests using `TEST_F()` and this fixture.
|
||||
|
||||
```c++
|
||||
TEST_F(QueueTest, IsEmptyInitially) {
|
||||
EXPECT_EQ(q0_.size(), 0);
|
||||
}
|
||||
|
||||
TEST_F(QueueTest, DequeueWorks) {
|
||||
int* n = q0_.Dequeue();
|
||||
EXPECT_EQ(n, nullptr);
|
||||
|
||||
n = q1_.Dequeue();
|
||||
ASSERT_NE(n, nullptr);
|
||||
EXPECT_EQ(*n, 1);
|
||||
EXPECT_EQ(q1_.size(), 0);
|
||||
delete n;
|
||||
|
||||
n = q2_.Dequeue();
|
||||
ASSERT_NE(n, nullptr);
|
||||
EXPECT_EQ(*n, 2);
|
||||
EXPECT_EQ(q2_.size(), 1);
|
||||
delete n;
|
||||
}
|
||||
```
|
||||
|
||||
The above uses both `ASSERT_*` and `EXPECT_*` assertions. The rule of thumb is
|
||||
to use `EXPECT_*` when you want the test to continue to reveal more errors after
|
||||
the assertion failure, and use `ASSERT_*` when continuing after failure doesn't
|
||||
make sense. For example, the second assertion in the `Dequeue` test is
|
||||
`ASSERT_NE(n, nullptr)`, as we need to dereference the pointer `n` later, which
|
||||
would lead to a segfault when `n` is `NULL`.
|
||||
|
||||
When these tests run, the following happens:
|
||||
|
||||
1. googletest constructs a `QueueTest` object (let's call it `t1`).
|
||||
2. `t1.SetUp()` initializes `t1`.
|
||||
3. The first test (`IsEmptyInitially`) runs on `t1`.
|
||||
4. `t1.TearDown()` cleans up after the test finishes.
|
||||
5. `t1` is destructed.
|
||||
6. The above steps are repeated on another `QueueTest` object, this time
|
||||
running the `DequeueWorks` test.
|
||||
|
||||
**Availability**: Linux, Windows, Mac.
|
||||
|
||||
## Invoking the Tests
|
||||
|
||||
`TEST()` and `TEST_F()` implicitly register their tests with googletest. So,
|
||||
unlike with many other C++ testing frameworks, you don't have to re-list all
|
||||
your defined tests in order to run them.
|
||||
|
||||
After defining your tests, you can run them with `RUN_ALL_TESTS()`, which
|
||||
returns `0` if all the tests are successful, or `1` otherwise. Note that
|
||||
`RUN_ALL_TESTS()` runs *all tests* in your link unit--they can be from
|
||||
different test suites, or even different source files.
|
||||
|
||||
When invoked, the `RUN_ALL_TESTS()` macro:
|
||||
|
||||
* Saves the state of all googletest flags.
|
||||
|
||||
* Creates a test fixture object for the first test.
|
||||
|
||||
* Initializes it via `SetUp()`.
|
||||
|
||||
* Runs the test on the fixture object.
|
||||
|
||||
* Cleans up the fixture via `TearDown()`.
|
||||
|
||||
* Deletes the fixture.
|
||||
|
||||
* Restores the state of all googletest flags.
|
||||
|
||||
* Repeats the above steps for the next test, until all tests have run.
|
||||
|
||||
If a fatal failure happens the subsequent steps will be skipped.
|
||||
|
||||
{: .callout .important}
|
||||
> IMPORTANT: You must **not** ignore the return value of `RUN_ALL_TESTS()`, or
|
||||
> you will get a compiler error. The rationale for this design is that the
|
||||
> automated testing service determines whether a test has passed based on its
|
||||
> exit code, not on its stdout/stderr output; thus your `main()` function must
|
||||
> return the value of `RUN_ALL_TESTS()`.
|
||||
>
|
||||
> Also, you should call `RUN_ALL_TESTS()` only **once**. Calling it more than
|
||||
> once conflicts with some advanced googletest features (e.g., thread-safe
|
||||
> [death tests](advanced.md#death-tests)) and thus is not supported.
|
||||
|
||||
**Availability**: Linux, Windows, Mac.
|
||||
|
||||
## Writing the main() Function
|
||||
|
||||
Most users should _not_ need to write their own `main` function and instead link
|
||||
with `gtest_main` (as opposed to with `gtest`), which defines a suitable entry
|
||||
point. See the end of this section for details. The remainder of this section
|
||||
should only apply when you need to do something custom before the tests run that
|
||||
cannot be expressed within the framework of fixtures and test suites.
|
||||
|
||||
If you write your own `main` function, it should return the value of
|
||||
`RUN_ALL_TESTS()`.
|
||||
|
||||
You can start from this boilerplate:
|
||||
|
||||
```c++
|
||||
#include "this/package/foo.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace my {
|
||||
namespace project {
|
||||
namespace {
|
||||
|
||||
// The fixture for testing class Foo.
|
||||
class FooTest : public ::testing::Test {
|
||||
protected:
|
||||
// You can remove any or all of the following functions if their bodies would
|
||||
// be empty.
|
||||
|
||||
FooTest() {
|
||||
// You can do set-up work for each test here.
|
||||
}
|
||||
|
||||
~FooTest() override {
|
||||
// You can do clean-up work that doesn't throw exceptions here.
|
||||
}
|
||||
|
||||
// If the constructor and destructor are not enough for setting up
|
||||
// and cleaning up each test, you can define the following methods:
|
||||
|
||||
void SetUp() override {
|
||||
// Code here will be called immediately after the constructor (right
|
||||
// before each test).
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
// Code here will be called immediately after each test (right
|
||||
// before the destructor).
|
||||
}
|
||||
|
||||
// Class members declared here can be used by all tests in the test suite
|
||||
// for Foo.
|
||||
};
|
||||
|
||||
// Tests that the Foo::Bar() method does Abc.
|
||||
TEST_F(FooTest, MethodBarDoesAbc) {
|
||||
const std::string input_filepath = "this/package/testdata/myinputfile.dat";
|
||||
const std::string output_filepath = "this/package/testdata/myoutputfile.dat";
|
||||
Foo f;
|
||||
EXPECT_EQ(f.Bar(input_filepath, output_filepath), 0);
|
||||
}
|
||||
|
||||
// Tests that Foo does Xyz.
|
||||
TEST_F(FooTest, DoesXyz) {
|
||||
// Exercises the Xyz feature of Foo.
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace project
|
||||
} // namespace my
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
```
|
||||
|
||||
The `::testing::InitGoogleTest()` function parses the command line for
|
||||
googletest flags, and removes all recognized flags. This allows the user to
|
||||
control a test program's behavior via various flags, which we'll cover in
|
||||
the [AdvancedGuide](advanced.md). You **must** call this function before calling
|
||||
`RUN_ALL_TESTS()`, or the flags won't be properly initialized.
|
||||
|
||||
On Windows, `InitGoogleTest()` also works with wide strings, so it can be used
|
||||
in programs compiled in `UNICODE` mode as well.
|
||||
|
||||
But maybe you think that writing all those `main` functions is too much work? We
|
||||
agree with you completely, and that's why Google Test provides a basic
|
||||
implementation of main(). If it fits your needs, then just link your test with
|
||||
the `gtest_main` library and you are good to go.
|
||||
|
||||
{: .callout .note}
|
||||
NOTE: `ParseGUnitFlags()` is deprecated in favor of `InitGoogleTest()`.
|
||||
|
||||
## Known Limitations
|
||||
|
||||
* Google Test is designed to be thread-safe. The implementation is thread-safe
|
||||
on systems where the `pthreads` library is available. It is currently
|
||||
_unsafe_ to use Google Test assertions from two threads concurrently on
|
||||
other systems (e.g. Windows). In most tests this is not an issue as usually
|
||||
the assertions are done in the main thread. If you want to help, you can
|
||||
volunteer to implement the necessary synchronization primitives in
|
||||
`gtest-port.h` for your platform.
|
|
@ -1,161 +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/master/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/master/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, you’ll 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/master/external.html)
|
||||
via the
|
||||
[`http_archive` rule](https://docs.bazel.build/versions/master/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.
|
||||
|
||||
Bazel also needs a dependency on the
|
||||
[`rules_cc` repository](https://github.com/bazelbuild/rules_cc) to build C++
|
||||
code, so add the following to the `WORKSPACE` file:
|
||||
|
||||
```
|
||||
http_archive(
|
||||
name = "rules_cc",
|
||||
urls = ["https://github.com/bazelbuild/rules_cc/archive/40548a2974f1aea06215272d9c2b47a14a24e556.zip"],
|
||||
strip_prefix = "rules_cc-40548a2974f1aea06215272d9c2b47a14a24e556",
|
||||
)
|
||||
```
|
||||
|
||||
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:
|
||||
|
||||
```
|
||||
load("@rules_cc//cc:defs.bzl", "cc_test")
|
||||
|
||||
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/master/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.
|
|
@ -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.
|
|
@ -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
|
||||
|
||||
| | |
|
||||
| :-------------------------------- | :-------------------------------------------- |
|
||||
| `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
|
||||
|
||||
| | |
|
||||
| :--------------------------------- | :-------------------------------------- |
|
||||
| `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.
|
||||
|
||||
| | |
|
||||
| :---------------------------------- | :------------------------------------- |
|
||||
| `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
|
||||
|
||||
| Matcher | 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
|
||||
|
||||
| | |
|
||||
| :----------------------------- | :------------------------------------------ |
|
||||
| `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
|
||||
|
||||
| | |
|
||||
| :--------------------------------- | :-------------------------------------- |
|
||||
| `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.
|
|
@ -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");
|
||||
```
|
|
@ -1,283 +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`. |
|
||||
|
||||
`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. |
|
||||
| `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
|
||||
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
|
||||
|
||||
| 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`. |
|
||||
|
||||
## 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
|
||||
|
||||
| Matcher | Description |
|
||||
| :----------------------------------- | :------------------------------------ |
|
||||
| `MATCHER(IsEven, "") { return (arg % 2) == 0; }` | Defines a matcher `IsEven()` to match an even number. |
|
||||
| `MATCHER_P(IsDivisibleBy, n, "") { *result_listener << "where the remainder is " << (arg % n); return (arg % n) == 0; }` | Defines a matcher `IsDivisibleBy(n)` to match a number divisible by `n`. |
|
||||
| `MATCHER_P2(IsBetween, a, b, absl::StrCat(negation ? "isn't" : "is", " between ", PrintToString(a), " and ", PrintToString(b))) { return a <= arg && arg <= b; }` | Defines a matcher `IsBetween(a, b)` to match a value in the range [`a`, `b`]. |
|
||||
|
||||
**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);
|
||||
}
|
||||
```
|
|
@ -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`.
|
|
@ -1,22 +0,0 @@
|
|||
# Googletest Samples
|
||||
|
||||
If you're like us, you'd like to look at
|
||||
[googletest samples.](https://github.com/google/googletest/tree/master/googletest/samples)
|
||||
The sample directory has a number of well-commented samples showing how to use a
|
||||
variety of googletest features.
|
||||
|
||||
* Sample #1 shows the basic steps of using googletest to test C++ functions.
|
||||
* Sample #2 shows a more complex unit test for a class with multiple member
|
||||
functions.
|
||||
* Sample #3 uses a test fixture.
|
||||
* Sample #4 teaches you how to use googletest and `googletest.h` together to
|
||||
get the best of both libraries.
|
||||
* Sample #5 puts shared testing logic in a base test fixture, and reuses it in
|
||||
derived fixtures.
|
||||
* Sample #6 demonstrates type-parameterized tests.
|
||||
* Sample #7 teaches the basics of value-parameterized tests.
|
||||
* Sample #8 shows using `Combine()` in value-parameterized tests.
|
||||
* Sample #9 shows use of the listener API to modify Google Test's console
|
||||
output and the use of its reflection API to inspect test results.
|
||||
* Sample #10 shows use of the listener API to implement a primitive memory
|
||||
leak checker.
|
|
@ -1,218 +0,0 @@
|
|||
########################################################################
|
||||
# Note: CMake support is community-based. The maintainers do not use CMake
|
||||
# internally.
|
||||
#
|
||||
# CMake build script for Google Mock.
|
||||
#
|
||||
# To run the tests for Google Mock itself on Linux, use 'make test' or
|
||||
# ctest. You can select which tests to run using 'ctest -R regex'.
|
||||
# For more options, run 'ctest --help'.
|
||||
|
||||
option(gmock_build_tests "Build all of Google Mock's own tests." OFF)
|
||||
|
||||
# A directory to find Google Test sources.
|
||||
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/gtest/CMakeLists.txt")
|
||||
set(gtest_dir gtest)
|
||||
else()
|
||||
set(gtest_dir ../googletest)
|
||||
endif()
|
||||
|
||||
# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build().
|
||||
include("${gtest_dir}/cmake/hermetic_build.cmake" OPTIONAL)
|
||||
|
||||
if (COMMAND pre_project_set_up_hermetic_build)
|
||||
# Google Test also calls hermetic setup functions from add_subdirectory,
|
||||
# although its changes will not affect things at the current scope.
|
||||
pre_project_set_up_hermetic_build()
|
||||
endif()
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Project-wide settings
|
||||
|
||||
# Name of the project.
|
||||
#
|
||||
# CMake files in this project can refer to the root source directory
|
||||
# as ${gmock_SOURCE_DIR} and to the root binary directory as
|
||||
# ${gmock_BINARY_DIR}.
|
||||
# Language "C" is required for find_package(Threads).
|
||||
if (CMAKE_VERSION VERSION_LESS 3.0)
|
||||
project(gmock CXX C)
|
||||
else()
|
||||
cmake_policy(SET CMP0048 NEW)
|
||||
project(gmock VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)
|
||||
endif()
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
if (COMMAND set_up_hermetic_build)
|
||||
set_up_hermetic_build()
|
||||
endif()
|
||||
|
||||
# Instructs CMake to process Google Test's CMakeLists.txt and add its
|
||||
# targets to the current scope. We are placing Google Test's binary
|
||||
# directory in a subdirectory of our own as VC compilation may break
|
||||
# if they are the same (the default).
|
||||
add_subdirectory("${gtest_dir}" "${gmock_BINARY_DIR}/${gtest_dir}")
|
||||
|
||||
|
||||
# These commands only run if this is the main project
|
||||
if(CMAKE_PROJECT_NAME STREQUAL "gmock" OR CMAKE_PROJECT_NAME STREQUAL "googletest-distribution")
|
||||
# BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to
|
||||
# make it prominent in the GUI.
|
||||
option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF)
|
||||
else()
|
||||
mark_as_advanced(gmock_build_tests)
|
||||
endif()
|
||||
|
||||
# Although Google Test's CMakeLists.txt calls this function, the
|
||||
# changes there don't affect the current scope. Therefore we have to
|
||||
# call it again here.
|
||||
config_compiler_and_linker() # from ${gtest_dir}/cmake/internal_utils.cmake
|
||||
|
||||
# Adds Google Mock's and Google Test's header directories to the search path.
|
||||
set(gmock_build_include_dirs
|
||||
"${gmock_SOURCE_DIR}/include"
|
||||
"${gmock_SOURCE_DIR}"
|
||||
"${gtest_SOURCE_DIR}/include"
|
||||
# This directory is needed to build directly from Google Test sources.
|
||||
"${gtest_SOURCE_DIR}")
|
||||
include_directories(${gmock_build_include_dirs})
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Defines the gmock & gmock_main libraries. User tests should link
|
||||
# with one of them.
|
||||
|
||||
# Google Mock libraries. We build them using more strict warnings than what
|
||||
# are used for other targets, to ensure that Google Mock can be compiled by
|
||||
# a user aggressive about warnings.
|
||||
if (MSVC)
|
||||
cxx_library(gmock
|
||||
"${cxx_strict}"
|
||||
"${gtest_dir}/src/gtest-all.cc"
|
||||
src/gmock-all.cc)
|
||||
|
||||
cxx_library(gmock_main
|
||||
"${cxx_strict}"
|
||||
"${gtest_dir}/src/gtest-all.cc"
|
||||
src/gmock-all.cc
|
||||
src/gmock_main.cc)
|
||||
else()
|
||||
cxx_library(gmock "${cxx_strict}" src/gmock-all.cc)
|
||||
target_link_libraries(gmock PUBLIC gtest)
|
||||
set_target_properties(gmock PROPERTIES VERSION ${GOOGLETEST_VERSION})
|
||||
cxx_library(gmock_main "${cxx_strict}" src/gmock_main.cc)
|
||||
target_link_libraries(gmock_main PUBLIC gmock)
|
||||
set_target_properties(gmock_main PROPERTIES VERSION ${GOOGLETEST_VERSION})
|
||||
endif()
|
||||
# If the CMake version supports it, attach header directory information
|
||||
# to the targets for when we are part of a parent build (ie being pulled
|
||||
# in via add_subdirectory() rather than being a standalone build).
|
||||
if (DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11")
|
||||
target_include_directories(gmock SYSTEM INTERFACE
|
||||
"$<BUILD_INTERFACE:${gmock_build_include_dirs}>"
|
||||
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
|
||||
target_include_directories(gmock_main SYSTEM INTERFACE
|
||||
"$<BUILD_INTERFACE:${gmock_build_include_dirs}>"
|
||||
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
|
||||
endif()
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Install rules
|
||||
install_project(gmock gmock_main)
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Google Mock's own tests.
|
||||
#
|
||||
# You can skip this section if you aren't interested in testing
|
||||
# Google Mock itself.
|
||||
#
|
||||
# The tests are not built by default. To build them, set the
|
||||
# gmock_build_tests option to ON. You can do it by running ccmake
|
||||
# or specifying the -Dgmock_build_tests=ON flag when running cmake.
|
||||
|
||||
if (gmock_build_tests)
|
||||
# This must be set in the root directory for the tests to be run by
|
||||
# 'make test' or ctest.
|
||||
enable_testing()
|
||||
|
||||
if (MINGW OR CYGWIN)
|
||||
if (CMAKE_VERSION VERSION_LESS "2.8.12")
|
||||
add_compile_options("-Wa,-mbig-obj")
|
||||
else()
|
||||
add_definitions("-Wa,-mbig-obj")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
############################################################
|
||||
# C++ tests built with standard compiler flags.
|
||||
|
||||
cxx_test(gmock-actions_test gmock_main)
|
||||
cxx_test(gmock-cardinalities_test gmock_main)
|
||||
cxx_test(gmock_ex_test gmock_main)
|
||||
cxx_test(gmock-function-mocker_test gmock_main)
|
||||
cxx_test(gmock-internal-utils_test gmock_main)
|
||||
cxx_test(gmock-matchers_test gmock_main)
|
||||
cxx_test(gmock-more-actions_test gmock_main)
|
||||
cxx_test(gmock-nice-strict_test gmock_main)
|
||||
cxx_test(gmock-port_test gmock_main)
|
||||
cxx_test(gmock-spec-builders_test gmock_main)
|
||||
cxx_test(gmock_link_test gmock_main test/gmock_link2_test.cc)
|
||||
cxx_test(gmock_test gmock_main)
|
||||
|
||||
if (DEFINED GTEST_HAS_PTHREAD)
|
||||
cxx_test(gmock_stress_test gmock)
|
||||
endif()
|
||||
|
||||
# gmock_all_test is commented to save time building and running tests.
|
||||
# Uncomment if necessary.
|
||||
# cxx_test(gmock_all_test gmock_main)
|
||||
|
||||
############################################################
|
||||
# C++ tests built with non-standard compiler flags.
|
||||
|
||||
if (MSVC)
|
||||
cxx_library(gmock_main_no_exception "${cxx_no_exception}"
|
||||
"${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc)
|
||||
|
||||
cxx_library(gmock_main_no_rtti "${cxx_no_rtti}"
|
||||
"${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc)
|
||||
|
||||
else()
|
||||
cxx_library(gmock_main_no_exception "${cxx_no_exception}" src/gmock_main.cc)
|
||||
target_link_libraries(gmock_main_no_exception PUBLIC gmock)
|
||||
|
||||
cxx_library(gmock_main_no_rtti "${cxx_no_rtti}" src/gmock_main.cc)
|
||||
target_link_libraries(gmock_main_no_rtti PUBLIC gmock)
|
||||
endif()
|
||||
cxx_test_with_flags(gmock-more-actions_no_exception_test "${cxx_no_exception}"
|
||||
gmock_main_no_exception test/gmock-more-actions_test.cc)
|
||||
|
||||
cxx_test_with_flags(gmock_no_rtti_test "${cxx_no_rtti}"
|
||||
gmock_main_no_rtti test/gmock-spec-builders_test.cc)
|
||||
|
||||
cxx_shared_library(shared_gmock_main "${cxx_default}"
|
||||
"${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc)
|
||||
|
||||
# Tests that a binary can be built with Google Mock as a shared library. On
|
||||
# some system configurations, it may not possible to run the binary without
|
||||
# knowing more details about the system configurations. We do not try to run
|
||||
# this binary. To get a more robust shared library coverage, configure with
|
||||
# -DBUILD_SHARED_LIBS=ON.
|
||||
cxx_executable_with_flags(shared_gmock_test_ "${cxx_default}"
|
||||
shared_gmock_main test/gmock-spec-builders_test.cc)
|
||||
set_target_properties(shared_gmock_test_
|
||||
PROPERTIES
|
||||
COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1")
|
||||
|
||||
############################################################
|
||||
# Python tests.
|
||||
|
||||
cxx_executable(gmock_leak_test_ test gmock_main)
|
||||
py_test(gmock_leak_test)
|
||||
|
||||
cxx_executable(gmock_output_test_ test gmock)
|
||||
py_test(gmock_output_test)
|
||||
endif()
|
|
@ -1,44 +0,0 @@
|
|||
# Googletest Mocking (gMock) Framework
|
||||
|
||||
### Overview
|
||||
|
||||
Google's framework for writing and using C++ mock classes. It can help you
|
||||
derive better designs of your system and write better tests.
|
||||
|
||||
It is inspired by:
|
||||
|
||||
* [jMock](http://www.jmock.org/)
|
||||
* [EasyMock](http://www.easymock.org/)
|
||||
* [Hamcrest](http://code.google.com/p/hamcrest/)
|
||||
|
||||
It is designed with C++'s specifics in mind.
|
||||
|
||||
gMock:
|
||||
|
||||
- Provides a declarative syntax for defining mocks.
|
||||
- Can define partial (hybrid) mocks, which are a cross of real and mock
|
||||
objects.
|
||||
- Handles functions of arbitrary types and overloaded functions.
|
||||
- Comes with a rich set of matchers for validating function arguments.
|
||||
- Uses an intuitive syntax for controlling the behavior of a mock.
|
||||
- Does automatic verification of expectations (no record-and-replay needed).
|
||||
- Allows arbitrary (partial) ordering constraints on function calls to be
|
||||
expressed.
|
||||
- Lets a user extend it by defining new matchers and actions.
|
||||
- Does not use exceptions.
|
||||
- Is easy to learn and use.
|
||||
|
||||
Details and examples can be found here:
|
||||
|
||||
* [gMock for Dummies](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)
|
||||
|
||||
Please note that code under scripts/generator/ is from the
|
||||
[cppclean project](http://code.google.com/p/cppclean/) and under the Apache
|
||||
License, which is different from GoogleMock's license.
|
||||
|
||||
GoogleMock is a part of
|
||||
[GoogleTest C++ testing framework](http://github.com/google/googletest/) and a
|
||||
subject to the same requirements.
|
|
@ -1,10 +0,0 @@
|
|||
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
|
||||
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
||||
|
||||
Name: gmock
|
||||
Description: GoogleMock (without main() function)
|
||||
Version: @PROJECT_VERSION@
|
||||
URL: https://github.com/google/googletest
|
||||
Requires: gtest = @PROJECT_VERSION@
|
||||
Libs: -L${libdir} -lgmock @CMAKE_THREAD_LIBS_INIT@
|
||||
Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@
|
|
@ -1,10 +0,0 @@
|
|||
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
|
||||
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
||||
|
||||
Name: gmock_main
|
||||
Description: GoogleMock (with main() function)
|
||||
Version: @PROJECT_VERSION@
|
||||
URL: https://github.com/google/googletest
|
||||
Requires: gmock = @PROJECT_VERSION@
|
||||
Libs: -L${libdir} -lgmock_main @CMAKE_THREAD_LIBS_INIT@
|
||||
Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@
|
|
@ -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.
|
|
@ -1,157 +0,0 @@
|
|||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements some commonly used cardinalities. More
|
||||
// cardinalities can be defined by the user implementing the
|
||||
// CardinalityInterface interface if necessary.
|
||||
|
||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
||||
|
||||
#include <limits.h>
|
||||
#include <memory>
|
||||
#include <ostream> // NOLINT
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||
/* class A needs to have dll-interface to be used by clients of class B */)
|
||||
|
||||
namespace testing {
|
||||
|
||||
// To implement a cardinality Foo, define:
|
||||
// 1. a class FooCardinality that implements the
|
||||
// CardinalityInterface interface, and
|
||||
// 2. a factory function that creates a Cardinality object from a
|
||||
// const FooCardinality*.
|
||||
//
|
||||
// The two-level delegation design follows that of Matcher, providing
|
||||
// consistency for extension developers. It also eases ownership
|
||||
// management as Cardinality objects can now be copied like plain values.
|
||||
|
||||
// The implementation of a cardinality.
|
||||
class CardinalityInterface {
|
||||
public:
|
||||
virtual ~CardinalityInterface() {}
|
||||
|
||||
// Conservative estimate on the lower/upper bound of the number of
|
||||
// calls allowed.
|
||||
virtual int ConservativeLowerBound() const { return 0; }
|
||||
virtual int ConservativeUpperBound() const { return INT_MAX; }
|
||||
|
||||
// Returns true if and only if call_count calls will satisfy this
|
||||
// cardinality.
|
||||
virtual bool IsSatisfiedByCallCount(int call_count) const = 0;
|
||||
|
||||
// Returns true if and only if call_count calls will saturate this
|
||||
// cardinality.
|
||||
virtual bool IsSaturatedByCallCount(int call_count) const = 0;
|
||||
|
||||
// Describes self to an ostream.
|
||||
virtual void DescribeTo(::std::ostream* os) const = 0;
|
||||
};
|
||||
|
||||
// A Cardinality is a copyable and IMMUTABLE (except by assignment)
|
||||
// object that specifies how many times a mock function is expected to
|
||||
// be called. The implementation of Cardinality is just a std::shared_ptr
|
||||
// to const CardinalityInterface. Don't inherit from Cardinality!
|
||||
class GTEST_API_ Cardinality {
|
||||
public:
|
||||
// Constructs a null cardinality. Needed for storing Cardinality
|
||||
// objects in STL containers.
|
||||
Cardinality() {}
|
||||
|
||||
// Constructs a Cardinality from its implementation.
|
||||
explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {}
|
||||
|
||||
// Conservative estimate on the lower/upper bound of the number of
|
||||
// calls allowed.
|
||||
int ConservativeLowerBound() const { return impl_->ConservativeLowerBound(); }
|
||||
int ConservativeUpperBound() const { return impl_->ConservativeUpperBound(); }
|
||||
|
||||
// Returns true if and only if call_count calls will satisfy this
|
||||
// cardinality.
|
||||
bool IsSatisfiedByCallCount(int call_count) const {
|
||||
return impl_->IsSatisfiedByCallCount(call_count);
|
||||
}
|
||||
|
||||
// Returns true if and only if call_count calls will saturate this
|
||||
// cardinality.
|
||||
bool IsSaturatedByCallCount(int call_count) const {
|
||||
return impl_->IsSaturatedByCallCount(call_count);
|
||||
}
|
||||
|
||||
// Returns true if and only if call_count calls will over-saturate this
|
||||
// cardinality, i.e. exceed the maximum number of allowed calls.
|
||||
bool IsOverSaturatedByCallCount(int call_count) const {
|
||||
return impl_->IsSaturatedByCallCount(call_count) &&
|
||||
!impl_->IsSatisfiedByCallCount(call_count);
|
||||
}
|
||||
|
||||
// Describes self to an ostream
|
||||
void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); }
|
||||
|
||||
// Describes the given actual call count to an ostream.
|
||||
static void DescribeActualCallCountTo(int actual_call_count,
|
||||
::std::ostream* os);
|
||||
|
||||
private:
|
||||
std::shared_ptr<const CardinalityInterface> impl_;
|
||||
};
|
||||
|
||||
// Creates a cardinality that allows at least n calls.
|
||||
GTEST_API_ Cardinality AtLeast(int n);
|
||||
|
||||
// Creates a cardinality that allows at most n calls.
|
||||
GTEST_API_ Cardinality AtMost(int n);
|
||||
|
||||
// Creates a cardinality that allows any number of calls.
|
||||
GTEST_API_ Cardinality AnyNumber();
|
||||
|
||||
// Creates a cardinality that allows between min and max calls.
|
||||
GTEST_API_ Cardinality Between(int min, int max);
|
||||
|
||||
// Creates a cardinality that allows exactly n calls.
|
||||
GTEST_API_ Cardinality Exactly(int n);
|
||||
|
||||
// Creates a cardinality from its implementation.
|
||||
inline Cardinality MakeCardinality(const CardinalityInterface* c) {
|
||||
return Cardinality(c);
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
|
@ -1,479 +0,0 @@
|
|||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements MOCK_METHOD.
|
||||
|
||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
|
||||
|
||||
#include <type_traits> // IWYU pragma: keep
|
||||
#include <utility> // IWYU pragma: keep
|
||||
|
||||
#include "gmock/gmock-spec-builders.h"
|
||||
#include "gmock/internal/gmock-internal-utils.h"
|
||||
#include "gmock/internal/gmock-pp.h"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
template <typename T>
|
||||
using identity_t = T;
|
||||
|
||||
template <typename Pattern>
|
||||
struct ThisRefAdjuster {
|
||||
template <typename T>
|
||||
using AdjustT = typename std::conditional<
|
||||
std::is_const<typename std::remove_reference<Pattern>::type>::value,
|
||||
typename std::conditional<std::is_lvalue_reference<Pattern>::value,
|
||||
const T&, const T&&>::type,
|
||||
typename std::conditional<std::is_lvalue_reference<Pattern>::value, T&,
|
||||
T&&>::type>::type;
|
||||
|
||||
template <typename MockType>
|
||||
static AdjustT<MockType> Adjust(const MockType& mock) {
|
||||
return static_cast<AdjustT<MockType>>(const_cast<MockType&>(mock));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// The style guide prohibits "using" statements in a namespace scope
|
||||
// inside a header file. However, the FunctionMocker class template
|
||||
// is meant to be defined in the ::testing namespace. The following
|
||||
// line is just a trick for working around a bug in MSVC 8.0, which
|
||||
// cannot handle it if we define FunctionMocker in ::testing.
|
||||
using internal::FunctionMocker;
|
||||
} // namespace testing
|
||||
|
||||
#define MOCK_METHOD(...) \
|
||||
GMOCK_PP_VARIADIC_CALL(GMOCK_INTERNAL_MOCK_METHOD_ARG_, __VA_ARGS__)
|
||||
|
||||
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_1(...) \
|
||||
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
|
||||
|
||||
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_2(...) \
|
||||
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
|
||||
|
||||
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_3(_Ret, _MethodName, _Args) \
|
||||
GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, ())
|
||||
|
||||
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, _Spec) \
|
||||
GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Args); \
|
||||
GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Spec); \
|
||||
GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE( \
|
||||
GMOCK_PP_NARG0 _Args, GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)); \
|
||||
GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \
|
||||
GMOCK_INTERNAL_MOCK_METHOD_IMPL( \
|
||||
GMOCK_PP_NARG0 _Args, _MethodName, GMOCK_INTERNAL_HAS_CONST(_Spec), \
|
||||
GMOCK_INTERNAL_HAS_OVERRIDE(_Spec), GMOCK_INTERNAL_HAS_FINAL(_Spec), \
|
||||
GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Spec), \
|
||||
GMOCK_INTERNAL_GET_CALLTYPE(_Spec), GMOCK_INTERNAL_GET_REF_SPEC(_Spec), \
|
||||
(GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)))
|
||||
|
||||
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_5(...) \
|
||||
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
|
||||
|
||||
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_6(...) \
|
||||
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
|
||||
|
||||
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_7(...) \
|
||||
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
|
||||
|
||||
#define GMOCK_INTERNAL_WRONG_ARITY(...) \
|
||||
static_assert( \
|
||||
false, \
|
||||
"MOCK_METHOD must be called with 3 or 4 arguments. _Ret, " \
|
||||
"_MethodName, _Args and optionally _Spec. _Args and _Spec must be " \
|
||||
"enclosed in parentheses. If _Ret is a type with unprotected commas, " \
|
||||
"it must also be enclosed in parentheses.")
|
||||
|
||||
#define GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Tuple) \
|
||||
static_assert( \
|
||||
GMOCK_PP_IS_ENCLOSED_PARENS(_Tuple), \
|
||||
GMOCK_PP_STRINGIZE(_Tuple) " should be enclosed in parentheses.")
|
||||
|
||||
#define GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE(_N, ...) \
|
||||
static_assert( \
|
||||
std::is_function<__VA_ARGS__>::value, \
|
||||
"Signature must be a function type, maybe return type contains " \
|
||||
"unprotected comma."); \
|
||||
static_assert( \
|
||||
::testing::tuple_size<typename ::testing::internal::Function< \
|
||||
__VA_ARGS__>::ArgumentTuple>::value == _N, \
|
||||
"This method does not take " GMOCK_PP_STRINGIZE( \
|
||||
_N) " arguments. Parenthesize all types with unprotected commas.")
|
||||
|
||||
#define GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \
|
||||
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT, ~, _Spec)
|
||||
|
||||
#define GMOCK_INTERNAL_MOCK_METHOD_IMPL(_N, _MethodName, _Constness, \
|
||||
_Override, _Final, _NoexceptSpec, \
|
||||
_CallType, _RefSpec, _Signature) \
|
||||
typename ::testing::internal::Function<GMOCK_PP_REMOVE_PARENS( \
|
||||
_Signature)>::Result \
|
||||
GMOCK_INTERNAL_EXPAND(_CallType) \
|
||||
_MethodName(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N)) \
|
||||
GMOCK_PP_IF(_Constness, const, ) _RefSpec _NoexceptSpec \
|
||||
GMOCK_PP_IF(_Override, override, ) GMOCK_PP_IF(_Final, final, ) { \
|
||||
GMOCK_MOCKER_(_N, _Constness, _MethodName) \
|
||||
.SetOwnerAndName(this, #_MethodName); \
|
||||
return GMOCK_MOCKER_(_N, _Constness, _MethodName) \
|
||||
.Invoke(GMOCK_PP_REPEAT(GMOCK_INTERNAL_FORWARD_ARG, _Signature, _N)); \
|
||||
} \
|
||||
::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \
|
||||
GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_PARAMETER, _Signature, _N)) \
|
||||
GMOCK_PP_IF(_Constness, const, ) _RefSpec { \
|
||||
GMOCK_MOCKER_(_N, _Constness, _MethodName).RegisterOwner(this); \
|
||||
return GMOCK_MOCKER_(_N, _Constness, _MethodName) \
|
||||
.With(GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_ARGUMENT, , _N)); \
|
||||
} \
|
||||
::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \
|
||||
const ::testing::internal::WithoutMatchers&, \
|
||||
GMOCK_PP_IF(_Constness, const, )::testing::internal::Function< \
|
||||
GMOCK_PP_REMOVE_PARENS(_Signature)>*) const _RefSpec _NoexceptSpec { \
|
||||
return ::testing::internal::ThisRefAdjuster<GMOCK_PP_IF( \
|
||||
_Constness, const, ) int _RefSpec>::Adjust(*this) \
|
||||
.gmock_##_MethodName(GMOCK_PP_REPEAT( \
|
||||
GMOCK_INTERNAL_A_MATCHER_ARGUMENT, _Signature, _N)); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<GMOCK_PP_REMOVE_PARENS(_Signature)> \
|
||||
GMOCK_MOCKER_(_N, _Constness, _MethodName)
|
||||
|
||||
#define GMOCK_INTERNAL_EXPAND(...) __VA_ARGS__
|
||||
|
||||
// Five Valid modifiers.
|
||||
#define GMOCK_INTERNAL_HAS_CONST(_Tuple) \
|
||||
GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_CONST, ~, _Tuple))
|
||||
|
||||
#define GMOCK_INTERNAL_HAS_OVERRIDE(_Tuple) \
|
||||
GMOCK_PP_HAS_COMMA( \
|
||||
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_OVERRIDE, ~, _Tuple))
|
||||
|
||||
#define GMOCK_INTERNAL_HAS_FINAL(_Tuple) \
|
||||
GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_FINAL, ~, _Tuple))
|
||||
|
||||
#define GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Tuple) \
|
||||
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_NOEXCEPT_SPEC_IF_NOEXCEPT, ~, _Tuple)
|
||||
|
||||
#define GMOCK_INTERNAL_NOEXCEPT_SPEC_IF_NOEXCEPT(_i, _, _elem) \
|
||||
GMOCK_PP_IF( \
|
||||
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)), \
|
||||
_elem, )
|
||||
|
||||
#define GMOCK_INTERNAL_GET_REF_SPEC(_Tuple) \
|
||||
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_REF_SPEC_IF_REF, ~, _Tuple)
|
||||
|
||||
#define GMOCK_INTERNAL_REF_SPEC_IF_REF(_i, _, _elem) \
|
||||
GMOCK_PP_IF(GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)), \
|
||||
GMOCK_PP_CAT(GMOCK_INTERNAL_UNPACK_, _elem), )
|
||||
|
||||
#define GMOCK_INTERNAL_GET_CALLTYPE(_Tuple) \
|
||||
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_CALLTYPE_IMPL, ~, _Tuple)
|
||||
|
||||
#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem) \
|
||||
static_assert( \
|
||||
(GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem)) + \
|
||||
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem)) + \
|
||||
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem)) + \
|
||||
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)) + \
|
||||
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)) + \
|
||||
GMOCK_INTERNAL_IS_CALLTYPE(_elem)) == 1, \
|
||||
GMOCK_PP_STRINGIZE( \
|
||||
_elem) " cannot be recognized as a valid specification modifier.");
|
||||
|
||||
// Modifiers implementation.
|
||||
#define GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem) \
|
||||
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_CONST_I_, _elem)
|
||||
|
||||
#define GMOCK_INTERNAL_DETECT_CONST_I_const ,
|
||||
|
||||
#define GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem) \
|
||||
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_OVERRIDE_I_, _elem)
|
||||
|
||||
#define GMOCK_INTERNAL_DETECT_OVERRIDE_I_override ,
|
||||
|
||||
#define GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem) \
|
||||
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_FINAL_I_, _elem)
|
||||
|
||||
#define GMOCK_INTERNAL_DETECT_FINAL_I_final ,
|
||||
|
||||
#define GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem) \
|
||||
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_NOEXCEPT_I_, _elem)
|
||||
|
||||
#define GMOCK_INTERNAL_DETECT_NOEXCEPT_I_noexcept ,
|
||||
|
||||
#define GMOCK_INTERNAL_DETECT_REF(_i, _, _elem) \
|
||||
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_REF_I_, _elem)
|
||||
|
||||
#define GMOCK_INTERNAL_DETECT_REF_I_ref ,
|
||||
|
||||
#define GMOCK_INTERNAL_UNPACK_ref(x) x
|
||||
|
||||
#define GMOCK_INTERNAL_GET_CALLTYPE_IMPL(_i, _, _elem) \
|
||||
GMOCK_PP_IF(GMOCK_INTERNAL_IS_CALLTYPE(_elem), \
|
||||
GMOCK_INTERNAL_GET_VALUE_CALLTYPE, GMOCK_PP_EMPTY) \
|
||||
(_elem)
|
||||
|
||||
// TODO(iserna): GMOCK_INTERNAL_IS_CALLTYPE and
|
||||
// GMOCK_INTERNAL_GET_VALUE_CALLTYPE needed more expansions to work on windows
|
||||
// maybe they can be simplified somehow.
|
||||
#define GMOCK_INTERNAL_IS_CALLTYPE(_arg) \
|
||||
GMOCK_INTERNAL_IS_CALLTYPE_I( \
|
||||
GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg))
|
||||
#define GMOCK_INTERNAL_IS_CALLTYPE_I(_arg) GMOCK_PP_IS_ENCLOSED_PARENS(_arg)
|
||||
|
||||
#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE(_arg) \
|
||||
GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I( \
|
||||
GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg))
|
||||
#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I(_arg) \
|
||||
GMOCK_PP_IDENTITY _arg
|
||||
|
||||
#define GMOCK_INTERNAL_IS_CALLTYPE_HELPER_Calltype
|
||||
|
||||
// Note: The use of `identity_t` here allows _Ret to represent return types that
|
||||
// would normally need to be specified in a different way. For example, a method
|
||||
// returning a function pointer must be written as
|
||||
//
|
||||
// fn_ptr_return_t (*method(method_args_t...))(fn_ptr_args_t...)
|
||||
//
|
||||
// But we only support placing the return type at the beginning. To handle this,
|
||||
// we wrap all calls in identity_t, so that a declaration will be expanded to
|
||||
//
|
||||
// identity_t<fn_ptr_return_t (*)(fn_ptr_args_t...)> method(method_args_t...)
|
||||
//
|
||||
// This allows us to work around the syntactic oddities of function/method
|
||||
// types.
|
||||
#define GMOCK_INTERNAL_SIGNATURE(_Ret, _Args) \
|
||||
::testing::internal::identity_t<GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_Ret), \
|
||||
GMOCK_PP_REMOVE_PARENS, \
|
||||
GMOCK_PP_IDENTITY)(_Ret)>( \
|
||||
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_TYPE, _, _Args))
|
||||
|
||||
#define GMOCK_INTERNAL_GET_TYPE(_i, _, _elem) \
|
||||
GMOCK_PP_COMMA_IF(_i) \
|
||||
GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_elem), GMOCK_PP_REMOVE_PARENS, \
|
||||
GMOCK_PP_IDENTITY) \
|
||||
(_elem)
|
||||
|
||||
#define GMOCK_INTERNAL_PARAMETER(_i, _Signature, _) \
|
||||
GMOCK_PP_COMMA_IF(_i) \
|
||||
GMOCK_INTERNAL_ARG_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature)) \
|
||||
gmock_a##_i
|
||||
|
||||
#define GMOCK_INTERNAL_FORWARD_ARG(_i, _Signature, _) \
|
||||
GMOCK_PP_COMMA_IF(_i) \
|
||||
::std::forward<GMOCK_INTERNAL_ARG_O( \
|
||||
_i, GMOCK_PP_REMOVE_PARENS(_Signature))>(gmock_a##_i)
|
||||
|
||||
#define GMOCK_INTERNAL_MATCHER_PARAMETER(_i, _Signature, _) \
|
||||
GMOCK_PP_COMMA_IF(_i) \
|
||||
GMOCK_INTERNAL_MATCHER_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature)) \
|
||||
gmock_a##_i
|
||||
|
||||
#define GMOCK_INTERNAL_MATCHER_ARGUMENT(_i, _1, _2) \
|
||||
GMOCK_PP_COMMA_IF(_i) \
|
||||
gmock_a##_i
|
||||
|
||||
#define GMOCK_INTERNAL_A_MATCHER_ARGUMENT(_i, _Signature, _) \
|
||||
GMOCK_PP_COMMA_IF(_i) \
|
||||
::testing::A<GMOCK_INTERNAL_ARG_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature))>()
|
||||
|
||||
#define GMOCK_INTERNAL_ARG_O(_i, ...) \
|
||||
typename ::testing::internal::Function<__VA_ARGS__>::template Arg<_i>::type
|
||||
|
||||
#define GMOCK_INTERNAL_MATCHER_O(_i, ...) \
|
||||
const ::testing::Matcher<typename ::testing::internal::Function< \
|
||||
__VA_ARGS__>::template Arg<_i>::type>&
|
||||
|
||||
#define MOCK_METHOD0(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 0, __VA_ARGS__)
|
||||
#define MOCK_METHOD1(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 1, __VA_ARGS__)
|
||||
#define MOCK_METHOD2(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 2, __VA_ARGS__)
|
||||
#define MOCK_METHOD3(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 3, __VA_ARGS__)
|
||||
#define MOCK_METHOD4(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 4, __VA_ARGS__)
|
||||
#define MOCK_METHOD5(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 5, __VA_ARGS__)
|
||||
#define MOCK_METHOD6(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 6, __VA_ARGS__)
|
||||
#define MOCK_METHOD7(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 7, __VA_ARGS__)
|
||||
#define MOCK_METHOD8(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 8, __VA_ARGS__)
|
||||
#define MOCK_METHOD9(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 9, __VA_ARGS__)
|
||||
#define MOCK_METHOD10(m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(, , m, 10, __VA_ARGS__)
|
||||
|
||||
#define MOCK_CONST_METHOD0(m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 0, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD1(m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 1, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD2(m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 2, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD3(m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 3, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD4(m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 4, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD5(m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 5, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD6(m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 6, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD7(m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 7, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD8(m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 8, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD9(m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 9, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD10(m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 10, __VA_ARGS__)
|
||||
|
||||
#define MOCK_METHOD0_T(m, ...) MOCK_METHOD0(m, __VA_ARGS__)
|
||||
#define MOCK_METHOD1_T(m, ...) MOCK_METHOD1(m, __VA_ARGS__)
|
||||
#define MOCK_METHOD2_T(m, ...) MOCK_METHOD2(m, __VA_ARGS__)
|
||||
#define MOCK_METHOD3_T(m, ...) MOCK_METHOD3(m, __VA_ARGS__)
|
||||
#define MOCK_METHOD4_T(m, ...) MOCK_METHOD4(m, __VA_ARGS__)
|
||||
#define MOCK_METHOD5_T(m, ...) MOCK_METHOD5(m, __VA_ARGS__)
|
||||
#define MOCK_METHOD6_T(m, ...) MOCK_METHOD6(m, __VA_ARGS__)
|
||||
#define MOCK_METHOD7_T(m, ...) MOCK_METHOD7(m, __VA_ARGS__)
|
||||
#define MOCK_METHOD8_T(m, ...) MOCK_METHOD8(m, __VA_ARGS__)
|
||||
#define MOCK_METHOD9_T(m, ...) MOCK_METHOD9(m, __VA_ARGS__)
|
||||
#define MOCK_METHOD10_T(m, ...) MOCK_METHOD10(m, __VA_ARGS__)
|
||||
|
||||
#define MOCK_CONST_METHOD0_T(m, ...) MOCK_CONST_METHOD0(m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD1_T(m, ...) MOCK_CONST_METHOD1(m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD2_T(m, ...) MOCK_CONST_METHOD2(m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD3_T(m, ...) MOCK_CONST_METHOD3(m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD4_T(m, ...) MOCK_CONST_METHOD4(m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD5_T(m, ...) MOCK_CONST_METHOD5(m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD6_T(m, ...) MOCK_CONST_METHOD6(m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD7_T(m, ...) MOCK_CONST_METHOD7(m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD8_T(m, ...) MOCK_CONST_METHOD8(m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD9_T(m, ...) MOCK_CONST_METHOD9(m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD10_T(m, ...) MOCK_CONST_METHOD10(m, __VA_ARGS__)
|
||||
|
||||
#define MOCK_METHOD0_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 0, __VA_ARGS__)
|
||||
#define MOCK_METHOD1_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 1, __VA_ARGS__)
|
||||
#define MOCK_METHOD2_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 2, __VA_ARGS__)
|
||||
#define MOCK_METHOD3_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 3, __VA_ARGS__)
|
||||
#define MOCK_METHOD4_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 4, __VA_ARGS__)
|
||||
#define MOCK_METHOD5_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 5, __VA_ARGS__)
|
||||
#define MOCK_METHOD6_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 6, __VA_ARGS__)
|
||||
#define MOCK_METHOD7_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 7, __VA_ARGS__)
|
||||
#define MOCK_METHOD8_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 8, __VA_ARGS__)
|
||||
#define MOCK_METHOD9_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 9, __VA_ARGS__)
|
||||
#define MOCK_METHOD10_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 10, __VA_ARGS__)
|
||||
|
||||
#define MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 0, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 1, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 2, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 3, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 4, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 5, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 6, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 7, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 8, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 9, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 10, __VA_ARGS__)
|
||||
|
||||
#define MOCK_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_METHOD0_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_METHOD1_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_METHOD2_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_METHOD3_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_METHOD4_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_METHOD5_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_METHOD6_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_METHOD7_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_METHOD8_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_METHOD9_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_METHOD10_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
|
||||
#define MOCK_CONST_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
|
||||
#define GMOCK_INTERNAL_MOCK_METHODN(constness, ct, Method, args_num, ...) \
|
||||
GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE( \
|
||||
args_num, ::testing::internal::identity_t<__VA_ARGS__>); \
|
||||
GMOCK_INTERNAL_MOCK_METHOD_IMPL( \
|
||||
args_num, Method, GMOCK_PP_NARG0(constness), 0, 0, , ct, , \
|
||||
(::testing::internal::identity_t<__VA_ARGS__>))
|
||||
|
||||
#define GMOCK_MOCKER_(arity, constness, Method) \
|
||||
GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_
|
|
@ -1,573 +0,0 @@
|
|||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements some commonly used variadic actions.
|
||||
|
||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "gmock/gmock-actions.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
|
||||
// Include any custom callback actions added by the local installation.
|
||||
#include "gmock/internal/custom/gmock-generated-actions.h"
|
||||
|
||||
// Sometimes you want to give an action explicit template parameters
|
||||
// that cannot be inferred from its value parameters. ACTION() and
|
||||
// ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that
|
||||
// and can be viewed as an extension to ACTION() and ACTION_P*().
|
||||
//
|
||||
// The syntax:
|
||||
//
|
||||
// ACTION_TEMPLATE(ActionName,
|
||||
// HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m),
|
||||
// AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; }
|
||||
//
|
||||
// defines an action template that takes m explicit template
|
||||
// parameters and n value parameters. name_i is the name of the i-th
|
||||
// template parameter, and kind_i specifies whether it's a typename,
|
||||
// an integral constant, or a template. p_i is the name of the i-th
|
||||
// value parameter.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // DuplicateArg<k, T>(output) converts the k-th argument of the mock
|
||||
// // function to type T and copies it to *output.
|
||||
// ACTION_TEMPLATE(DuplicateArg,
|
||||
// HAS_2_TEMPLATE_PARAMS(int, k, typename, T),
|
||||
// AND_1_VALUE_PARAMS(output)) {
|
||||
// *output = T(::std::get<k>(args));
|
||||
// }
|
||||
// ...
|
||||
// int n;
|
||||
// EXPECT_CALL(mock, Foo(_, _))
|
||||
// .WillOnce(DuplicateArg<1, unsigned char>(&n));
|
||||
//
|
||||
// To create an instance of an action template, write:
|
||||
//
|
||||
// ActionName<t1, ..., t_m>(v1, ..., v_n)
|
||||
//
|
||||
// where the ts are the template arguments and the vs are the value
|
||||
// arguments. The value argument types are inferred by the compiler.
|
||||
// If you want to explicitly specify the value argument types, you can
|
||||
// provide additional template arguments:
|
||||
//
|
||||
// ActionName<t1, ..., t_m, u1, ..., u_k>(v1, ..., v_n)
|
||||
//
|
||||
// where u_i is the desired type of v_i.
|
||||
//
|
||||
// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the
|
||||
// number of value parameters, but not on the number of template
|
||||
// parameters. Without the restriction, the meaning of the following
|
||||
// is unclear:
|
||||
//
|
||||
// OverloadedAction<int, bool>(x);
|
||||
//
|
||||
// Are we using a single-template-parameter action where 'bool' refers
|
||||
// to the type of x, or are we using a two-template-parameter action
|
||||
// where the compiler is asked to infer the type of x?
|
||||
//
|
||||
// Implementation notes:
|
||||
//
|
||||
// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and
|
||||
// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for
|
||||
// implementing ACTION_TEMPLATE. The main trick we use is to create
|
||||
// new macro invocations when expanding a macro. For example, we have
|
||||
//
|
||||
// #define ACTION_TEMPLATE(name, template_params, value_params)
|
||||
// ... GMOCK_INTERNAL_DECL_##template_params ...
|
||||
//
|
||||
// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...)
|
||||
// to expand to
|
||||
//
|
||||
// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ...
|
||||
//
|
||||
// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the
|
||||
// preprocessor will continue to expand it to
|
||||
//
|
||||
// ... typename T ...
|
||||
//
|
||||
// This technique conforms to the C++ standard and is portable. It
|
||||
// allows us to implement action templates using O(N) code, where N is
|
||||
// the maximum number of template/value parameters supported. Without
|
||||
// using it, we'd have to devote O(N^2) amount of code to implement all
|
||||
// combinations of m and n.
|
||||
|
||||
// Declares the template parameters.
|
||||
#define GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(kind0, name0) kind0 name0
|
||||
#define GMOCK_INTERNAL_DECL_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, \
|
||||
name1) kind0 name0, kind1 name1
|
||||
#define GMOCK_INTERNAL_DECL_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2) kind0 name0, kind1 name1, kind2 name2
|
||||
#define GMOCK_INTERNAL_DECL_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3) kind0 name0, kind1 name1, kind2 name2, \
|
||||
kind3 name3
|
||||
#define GMOCK_INTERNAL_DECL_HAS_5_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3, kind4, name4) kind0 name0, kind1 name1, \
|
||||
kind2 name2, kind3 name3, kind4 name4
|
||||
#define GMOCK_INTERNAL_DECL_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3, kind4, name4, kind5, name5) kind0 name0, \
|
||||
kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5
|
||||
#define GMOCK_INTERNAL_DECL_HAS_7_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \
|
||||
name6) kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4, \
|
||||
kind5 name5, kind6 name6
|
||||
#define GMOCK_INTERNAL_DECL_HAS_8_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \
|
||||
kind7, name7) kind0 name0, kind1 name1, kind2 name2, kind3 name3, \
|
||||
kind4 name4, kind5 name5, kind6 name6, kind7 name7
|
||||
#define GMOCK_INTERNAL_DECL_HAS_9_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \
|
||||
kind7, name7, kind8, name8) kind0 name0, kind1 name1, kind2 name2, \
|
||||
kind3 name3, kind4 name4, kind5 name5, kind6 name6, kind7 name7, \
|
||||
kind8 name8
|
||||
#define GMOCK_INTERNAL_DECL_HAS_10_TEMPLATE_PARAMS(kind0, name0, kind1, \
|
||||
name1, kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \
|
||||
name6, kind7, name7, kind8, name8, kind9, name9) kind0 name0, \
|
||||
kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5, \
|
||||
kind6 name6, kind7 name7, kind8 name8, kind9 name9
|
||||
|
||||
// Lists the template parameters.
|
||||
#define GMOCK_INTERNAL_LIST_HAS_1_TEMPLATE_PARAMS(kind0, name0) name0
|
||||
#define GMOCK_INTERNAL_LIST_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, \
|
||||
name1) name0, name1
|
||||
#define GMOCK_INTERNAL_LIST_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2) name0, name1, name2
|
||||
#define GMOCK_INTERNAL_LIST_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3) name0, name1, name2, name3
|
||||
#define GMOCK_INTERNAL_LIST_HAS_5_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3, kind4, name4) name0, name1, name2, name3, \
|
||||
name4
|
||||
#define GMOCK_INTERNAL_LIST_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3, kind4, name4, kind5, name5) name0, name1, \
|
||||
name2, name3, name4, name5
|
||||
#define GMOCK_INTERNAL_LIST_HAS_7_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \
|
||||
name6) name0, name1, name2, name3, name4, name5, name6
|
||||
#define GMOCK_INTERNAL_LIST_HAS_8_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \
|
||||
kind7, name7) name0, name1, name2, name3, name4, name5, name6, name7
|
||||
#define GMOCK_INTERNAL_LIST_HAS_9_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \
|
||||
kind7, name7, kind8, name8) name0, name1, name2, name3, name4, name5, \
|
||||
name6, name7, name8
|
||||
#define GMOCK_INTERNAL_LIST_HAS_10_TEMPLATE_PARAMS(kind0, name0, kind1, \
|
||||
name1, kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \
|
||||
name6, kind7, name7, kind8, name8, kind9, name9) name0, name1, name2, \
|
||||
name3, name4, name5, name6, name7, name8, name9
|
||||
|
||||
// Declares the types of value parameters.
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_0_VALUE_PARAMS()
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_1_VALUE_PARAMS(p0) , typename p0##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_2_VALUE_PARAMS(p0, p1) , \
|
||||
typename p0##_type, typename p1##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) , \
|
||||
typename p0##_type, typename p1##_type, typename p2##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) , \
|
||||
typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||
typename p3##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) , \
|
||||
typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||
typename p3##_type, typename p4##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) , \
|
||||
typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||
typename p3##_type, typename p4##_type, typename p5##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
|
||||
p6) , typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||
typename p3##_type, typename p4##_type, typename p5##_type, \
|
||||
typename p6##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
|
||||
p6, p7) , typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||
typename p3##_type, typename p4##_type, typename p5##_type, \
|
||||
typename p6##_type, typename p7##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
|
||||
p6, p7, p8) , typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||
typename p3##_type, typename p4##_type, typename p5##_type, \
|
||||
typename p6##_type, typename p7##_type, typename p8##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
|
||||
p6, p7, p8, p9) , typename p0##_type, typename p1##_type, \
|
||||
typename p2##_type, typename p3##_type, typename p4##_type, \
|
||||
typename p5##_type, typename p6##_type, typename p7##_type, \
|
||||
typename p8##_type, typename p9##_type
|
||||
|
||||
// Initializes the value parameters.
|
||||
#define GMOCK_INTERNAL_INIT_AND_0_VALUE_PARAMS()\
|
||||
()
|
||||
#define GMOCK_INTERNAL_INIT_AND_1_VALUE_PARAMS(p0)\
|
||||
(p0##_type gmock_p0) : p0(::std::move(gmock_p0))
|
||||
#define GMOCK_INTERNAL_INIT_AND_2_VALUE_PARAMS(p0, p1)\
|
||||
(p0##_type gmock_p0, p1##_type gmock_p1) : p0(::std::move(gmock_p0)), \
|
||||
p1(::std::move(gmock_p1))
|
||||
#define GMOCK_INTERNAL_INIT_AND_3_VALUE_PARAMS(p0, p1, p2)\
|
||||
(p0##_type gmock_p0, p1##_type gmock_p1, \
|
||||
p2##_type gmock_p2) : p0(::std::move(gmock_p0)), \
|
||||
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2))
|
||||
#define GMOCK_INTERNAL_INIT_AND_4_VALUE_PARAMS(p0, p1, p2, p3)\
|
||||
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
|
||||
p3##_type gmock_p3) : p0(::std::move(gmock_p0)), \
|
||||
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
|
||||
p3(::std::move(gmock_p3))
|
||||
#define GMOCK_INTERNAL_INIT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)\
|
||||
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
|
||||
p3##_type gmock_p3, p4##_type gmock_p4) : p0(::std::move(gmock_p0)), \
|
||||
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
|
||||
p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4))
|
||||
#define GMOCK_INTERNAL_INIT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)\
|
||||
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
|
||||
p3##_type gmock_p3, p4##_type gmock_p4, \
|
||||
p5##_type gmock_p5) : p0(::std::move(gmock_p0)), \
|
||||
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
|
||||
p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
|
||||
p5(::std::move(gmock_p5))
|
||||
#define GMOCK_INTERNAL_INIT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)\
|
||||
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
|
||||
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
|
||||
p6##_type gmock_p6) : p0(::std::move(gmock_p0)), \
|
||||
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
|
||||
p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
|
||||
p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6))
|
||||
#define GMOCK_INTERNAL_INIT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)\
|
||||
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
|
||||
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
|
||||
p6##_type gmock_p6, p7##_type gmock_p7) : p0(::std::move(gmock_p0)), \
|
||||
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
|
||||
p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
|
||||
p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \
|
||||
p7(::std::move(gmock_p7))
|
||||
#define GMOCK_INTERNAL_INIT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
|
||||
p7, p8)\
|
||||
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
|
||||
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
|
||||
p6##_type gmock_p6, p7##_type gmock_p7, \
|
||||
p8##_type gmock_p8) : p0(::std::move(gmock_p0)), \
|
||||
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
|
||||
p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
|
||||
p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \
|
||||
p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8))
|
||||
#define GMOCK_INTERNAL_INIT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
|
||||
p7, p8, p9)\
|
||||
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
|
||||
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
|
||||
p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \
|
||||
p9##_type gmock_p9) : p0(::std::move(gmock_p0)), \
|
||||
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
|
||||
p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
|
||||
p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \
|
||||
p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8)), \
|
||||
p9(::std::move(gmock_p9))
|
||||
|
||||
// Defines the copy constructor
|
||||
#define GMOCK_INTERNAL_DEFN_COPY_AND_0_VALUE_PARAMS() \
|
||||
{} // 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
|
||||
|
||||
namespace testing {
|
||||
|
||||
// The ACTION*() macros trigger warning C4100 (unreferenced formal
|
||||
// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
|
||||
// the macro definition, as the warnings are generated when the macro
|
||||
// is expanded and macro expansion cannot contain #pragma. Therefore
|
||||
// we suppress them here.
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4100)
|
||||
#endif
|
||||
|
||||
namespace internal {
|
||||
|
||||
// internal::InvokeArgument - a helper for InvokeArgument action.
|
||||
// The basic overloads are provided here for generic functors.
|
||||
// Overloads for other custom-callables are provided in the
|
||||
// internal/custom/gmock-generated-actions.h header.
|
||||
template <typename F, typename... Args>
|
||||
auto InvokeArgument(F f, Args... args) -> decltype(f(args...)) {
|
||||
return f(args...);
|
||||
}
|
||||
|
||||
template <std::size_t index, typename... Params>
|
||||
struct InvokeArgumentAction {
|
||||
template <typename... Args>
|
||||
auto operator()(Args&&... args) const -> decltype(internal::InvokeArgument(
|
||||
std::get<index>(std::forward_as_tuple(std::forward<Args>(args)...)),
|
||||
std::declval<const Params&>()...)) {
|
||||
internal::FlatTuple<Args&&...> args_tuple(FlatTupleConstructTag{},
|
||||
std::forward<Args>(args)...);
|
||||
return params.Apply([&](const Params&... unpacked_params) {
|
||||
auto&& callable = args_tuple.template Get<index>();
|
||||
return internal::InvokeArgument(
|
||||
std::forward<decltype(callable)>(callable), unpacked_params...);
|
||||
});
|
||||
}
|
||||
|
||||
internal::FlatTuple<Params...> params;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th
|
||||
// (0-based) argument, which must be a k-ary callable, of the mock
|
||||
// function, with arguments a1, a2, ..., a_k.
|
||||
//
|
||||
// Notes:
|
||||
//
|
||||
// 1. The arguments are passed by value by default. If you need to
|
||||
// pass an argument by reference, wrap it inside std::ref(). For
|
||||
// example,
|
||||
//
|
||||
// InvokeArgument<1>(5, string("Hello"), std::ref(foo))
|
||||
//
|
||||
// passes 5 and string("Hello") by value, and passes foo by
|
||||
// reference.
|
||||
//
|
||||
// 2. If the callable takes an argument by reference but std::ref() is
|
||||
// not used, it will receive the reference to a copy of the value,
|
||||
// instead of the original value. For example, when the 0-th
|
||||
// argument of the mock function takes a const string&, the action
|
||||
//
|
||||
// InvokeArgument<0>(string("Hello"))
|
||||
//
|
||||
// makes a copy of the temporary string("Hello") object and passes a
|
||||
// reference of the copy, instead of the original temporary object,
|
||||
// to the callable. This makes it easy for a user to define an
|
||||
// InvokeArgument action from temporary values and have it performed
|
||||
// later.
|
||||
template <std::size_t index, typename... Params>
|
||||
internal::InvokeArgumentAction<index, typename std::decay<Params>::type...>
|
||||
InvokeArgument(Params&&... params) {
|
||||
return {internal::FlatTuple<typename std::decay<Params>::type...>(
|
||||
internal::FlatTupleConstructTag{}, std::forward<Params>(params)...)};
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
|
@ -1,92 +0,0 @@
|
|||
// Copyright 2013, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements some matchers that depend on gmock-matchers.h.
|
||||
//
|
||||
// Note that tests are implemented in gmock-matchers_test.cc rather than
|
||||
// gmock-more-matchers-test.cc.
|
||||
|
||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_
|
||||
|
||||
#include "gmock/gmock-matchers.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Silence C4100 (unreferenced formal
|
||||
// parameter) for MSVC
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4100)
|
||||
#if (_MSC_VER == 1900)
|
||||
// and silence C4800 (C4800: 'int *const ': forcing value
|
||||
// to bool 'true' or 'false') for MSVC 14
|
||||
# pragma warning(disable:4800)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Defines a matcher that matches an empty container. The container must
|
||||
// support both size() and empty(), which all STL-like containers provide.
|
||||
MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") {
|
||||
if (arg.empty()) {
|
||||
return true;
|
||||
}
|
||||
*result_listener << "whose size is " << arg.size();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Define a matcher that matches a value that evaluates in boolean
|
||||
// context to true. Useful for types that define "explicit operator
|
||||
// bool" operators and so can't be compared for equality with true
|
||||
// and false.
|
||||
MATCHER(IsTrue, negation ? "is false" : "is true") {
|
||||
return static_cast<bool>(arg);
|
||||
}
|
||||
|
||||
// Define a matcher that matches a value that evaluates in boolean
|
||||
// context to false. Useful for types that define "explicit operator
|
||||
// bool" operators and so can't be compared for equality with true
|
||||
// and false.
|
||||
MATCHER(IsFalse, negation ? "is true" : "is false") {
|
||||
return !static_cast<bool>(arg);
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_
|
|
@ -1,261 +0,0 @@
|
|||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
// Implements class templates NiceMock, NaggyMock, and StrictMock.
|
||||
//
|
||||
// Given a mock class MockFoo that is created using Google Mock,
|
||||
// NiceMock<MockFoo> is a subclass of MockFoo that allows
|
||||
// uninteresting calls (i.e. calls to mock methods that have no
|
||||
// EXPECT_CALL specs), NaggyMock<MockFoo> is a subclass of MockFoo
|
||||
// that prints a warning when an uninteresting call occurs, and
|
||||
// StrictMock<MockFoo> is a subclass of MockFoo that treats all
|
||||
// uninteresting calls as errors.
|
||||
//
|
||||
// Currently a mock is naggy by default, so MockFoo and
|
||||
// NaggyMock<MockFoo> behave like the same. However, we will soon
|
||||
// switch the default behavior of mocks to be nice, as that in general
|
||||
// leads to more maintainable tests. When that happens, MockFoo will
|
||||
// stop behaving like NaggyMock<MockFoo> and start behaving like
|
||||
// NiceMock<MockFoo>.
|
||||
//
|
||||
// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of
|
||||
// their respective base class. Therefore you can write
|
||||
// NiceMock<MockFoo>(5, "a") to construct a nice mock where MockFoo
|
||||
// has a constructor that accepts (int, const char*), for example.
|
||||
//
|
||||
// A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>,
|
||||
// and StrictMock<MockFoo> only works for mock methods defined using
|
||||
// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class.
|
||||
// If a mock method is defined in a base class of MockFoo, the "nice"
|
||||
// or "strict" modifier may not affect it, depending on the compiler.
|
||||
// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
|
||||
// supported.
|
||||
|
||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "gmock/gmock-spec-builders.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
|
||||
namespace testing {
|
||||
template <class MockClass>
|
||||
class NiceMock;
|
||||
template <class MockClass>
|
||||
class NaggyMock;
|
||||
template <class MockClass>
|
||||
class StrictMock;
|
||||
|
||||
namespace internal {
|
||||
template <typename T>
|
||||
std::true_type StrictnessModifierProbe(const NiceMock<T>&);
|
||||
template <typename T>
|
||||
std::true_type StrictnessModifierProbe(const NaggyMock<T>&);
|
||||
template <typename T>
|
||||
std::true_type StrictnessModifierProbe(const StrictMock<T>&);
|
||||
std::false_type StrictnessModifierProbe(...);
|
||||
|
||||
template <typename T>
|
||||
constexpr bool HasStrictnessModifier() {
|
||||
return decltype(StrictnessModifierProbe(std::declval<const T&>()))::value;
|
||||
}
|
||||
|
||||
// Base classes that register and deregister with testing::Mock to alter the
|
||||
// default behavior around uninteresting calls. Inheriting from one of these
|
||||
// classes first and then MockClass ensures the MockClass constructor is run
|
||||
// after registration, and that the MockClass destructor runs before
|
||||
// deregistration. This guarantees that MockClass's constructor and destructor
|
||||
// run with the same level of strictness as its instance methods.
|
||||
|
||||
#if GTEST_OS_WINDOWS && !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 {
|
||||
public:
|
||||
static_assert(!internal::HasStrictnessModifier<MockClass>(),
|
||||
"Can't apply NiceMock to a class hierarchy that already has a "
|
||||
"strictness modifier. See "
|
||||
"https://google.github.io/googletest/"
|
||||
"gmock_cook_book.html#NiceStrictNaggy");
|
||||
NiceMock() : MockClass() {
|
||||
static_assert(sizeof(*this) == sizeof(MockClass),
|
||||
"The impl subclass shouldn't introduce any padding");
|
||||
}
|
||||
|
||||
// Ideally, we would inherit base class's constructors through a using
|
||||
// declaration, which would preserve their visibility. However, many existing
|
||||
// tests rely on the fact that current implementation reexports protected
|
||||
// constructors as public. These tests would need to be cleaned up first.
|
||||
|
||||
// Single argument constructor is special-cased so that it can be
|
||||
// made explicit.
|
||||
template <typename A>
|
||||
explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) {
|
||||
static_assert(sizeof(*this) == sizeof(MockClass),
|
||||
"The impl subclass shouldn't introduce any padding");
|
||||
}
|
||||
|
||||
template <typename TArg1, typename TArg2, typename... An>
|
||||
NiceMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
|
||||
: MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
|
||||
std::forward<An>(args)...) {
|
||||
static_assert(sizeof(*this) == sizeof(MockClass),
|
||||
"The impl subclass shouldn't introduce any padding");
|
||||
}
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(NiceMock);
|
||||
};
|
||||
|
||||
template <class MockClass>
|
||||
class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
|
||||
: private internal::NaggyMockImpl<MockClass>,
|
||||
public MockClass {
|
||||
static_assert(!internal::HasStrictnessModifier<MockClass>(),
|
||||
"Can't apply NaggyMock to a class hierarchy that already has a "
|
||||
"strictness modifier. See "
|
||||
"https://google.github.io/googletest/"
|
||||
"gmock_cook_book.html#NiceStrictNaggy");
|
||||
|
||||
public:
|
||||
NaggyMock() : MockClass() {
|
||||
static_assert(sizeof(*this) == sizeof(MockClass),
|
||||
"The impl subclass shouldn't introduce any padding");
|
||||
}
|
||||
|
||||
// Ideally, we would inherit base class's constructors through a using
|
||||
// declaration, which would preserve their visibility. However, many existing
|
||||
// tests rely on the fact that current implementation reexports protected
|
||||
// constructors as public. These tests would need to be cleaned up first.
|
||||
|
||||
// Single argument constructor is special-cased so that it can be
|
||||
// made explicit.
|
||||
template <typename A>
|
||||
explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) {
|
||||
static_assert(sizeof(*this) == sizeof(MockClass),
|
||||
"The impl subclass shouldn't introduce any padding");
|
||||
}
|
||||
|
||||
template <typename TArg1, typename TArg2, typename... An>
|
||||
NaggyMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
|
||||
: MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
|
||||
std::forward<An>(args)...) {
|
||||
static_assert(sizeof(*this) == sizeof(MockClass),
|
||||
"The impl subclass shouldn't introduce any padding");
|
||||
}
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(NaggyMock);
|
||||
};
|
||||
|
||||
template <class MockClass>
|
||||
class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock
|
||||
: private internal::StrictMockImpl<MockClass>,
|
||||
public MockClass {
|
||||
public:
|
||||
static_assert(
|
||||
!internal::HasStrictnessModifier<MockClass>(),
|
||||
"Can't apply StrictMock to a class hierarchy that already has a "
|
||||
"strictness modifier. See "
|
||||
"https://google.github.io/googletest/"
|
||||
"gmock_cook_book.html#NiceStrictNaggy");
|
||||
StrictMock() : MockClass() {
|
||||
static_assert(sizeof(*this) == sizeof(MockClass),
|
||||
"The impl subclass shouldn't introduce any padding");
|
||||
}
|
||||
|
||||
// Ideally, we would inherit base class's constructors through a using
|
||||
// declaration, which would preserve their visibility. However, many existing
|
||||
// tests rely on the fact that current implementation reexports protected
|
||||
// constructors as public. These tests would need to be cleaned up first.
|
||||
|
||||
// Single argument constructor is special-cased so that it can be
|
||||
// made explicit.
|
||||
template <typename A>
|
||||
explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) {
|
||||
static_assert(sizeof(*this) == sizeof(MockClass),
|
||||
"The impl subclass shouldn't introduce any padding");
|
||||
}
|
||||
|
||||
template <typename TArg1, typename TArg2, typename... An>
|
||||
StrictMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
|
||||
: MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
|
||||
std::forward<An>(args)...) {
|
||||
static_assert(sizeof(*this) == sizeof(MockClass),
|
||||
"The impl subclass shouldn't introduce any padding");
|
||||
}
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock);
|
||||
};
|
||||
|
||||
#undef GTEST_INTERNAL_EMPTY_BASE_CLASS
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
|
|
@ -1,98 +0,0 @@
|
|||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This is the main header file a user should include.
|
||||
|
||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_
|
||||
|
||||
// This file implements the following syntax:
|
||||
//
|
||||
// ON_CALL(mock_object, Method(...))
|
||||
// .With(...) ?
|
||||
// .WillByDefault(...);
|
||||
//
|
||||
// where With() is optional and WillByDefault() must appear exactly
|
||||
// once.
|
||||
//
|
||||
// EXPECT_CALL(mock_object, Method(...))
|
||||
// .With(...) ?
|
||||
// .Times(...) ?
|
||||
// .InSequence(...) *
|
||||
// .WillOnce(...) *
|
||||
// .WillRepeatedly(...) ?
|
||||
// .RetiresOnSaturation() ? ;
|
||||
//
|
||||
// where all clauses are optional and WillOnce() can be repeated.
|
||||
|
||||
#include "gmock/gmock-actions.h"
|
||||
#include "gmock/gmock-cardinalities.h"
|
||||
#include "gmock/gmock-function-mocker.h"
|
||||
#include "gmock/gmock-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);
|
||||
|
||||
// Initializes Google Mock. This must be called before running the
|
||||
// tests. In particular, it parses the command line for the flags
|
||||
// that Google Mock recognizes. Whenever a Google Mock flag is seen,
|
||||
// it is removed from argv, and *argc is decremented.
|
||||
//
|
||||
// No value is returned. Instead, the Google Mock flag variables are
|
||||
// updated.
|
||||
//
|
||||
// Since Google Test is needed for Google Mock to work, this function
|
||||
// also initializes Google Test and parses its flags, if that hasn't
|
||||
// been done.
|
||||
GTEST_API_ void InitGoogleMock(int* argc, char** argv);
|
||||
|
||||
// This overloaded version can be used in Windows programs compiled in
|
||||
// UNICODE mode.
|
||||
GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv);
|
||||
|
||||
// This overloaded version can be used on Arduino/embedded platforms where
|
||||
// there is no argc/argv.
|
||||
GTEST_API_ void InitGoogleMock();
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_
|
|
@ -1,16 +0,0 @@
|
|||
# Customization Points
|
||||
|
||||
The custom directory is an injection point for custom user configurations.
|
||||
|
||||
## Header `gmock-port.h`
|
||||
|
||||
The following macros can be defined:
|
||||
|
||||
### Flag related macros:
|
||||
|
||||
* `GMOCK_DECLARE_bool_(name)`
|
||||
* `GMOCK_DECLARE_int32_(name)`
|
||||
* `GMOCK_DECLARE_string_(name)`
|
||||
* `GMOCK_DEFINE_bool_(name, default_val, doc)`
|
||||
* `GMOCK_DEFINE_int32_(name, default_val, doc)`
|
||||
* `GMOCK_DEFINE_string_(name, default_val, doc)`
|
|
@ -1,6 +0,0 @@
|
|||
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
|
|
@ -1,36 +0,0 @@
|
|||
// Copyright 2015, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Injection point for custom user configurations. See README for details
|
||||
//
|
||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||
|
||||
#ifndef 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_
|
|
@ -1,39 +0,0 @@
|
|||
// Copyright 2015, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Injection point for custom user configurations. See README for details
|
||||
//
|
||||
// ** Custom implementation starts here **
|
||||
|
||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
|
|
@ -1,459 +0,0 @@
|
|||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file defines some utilities useful for implementing Google
|
||||
// Mock. They are subject to change without notice, so please DO NOT
|
||||
// USE THEM IN USER CODE.
|
||||
|
||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
template <typename>
|
||||
class Matcher;
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Silence MSVC C4100 (unreferenced formal parameter) and
|
||||
// C4805('==': unsafe mix of type 'const int' and type 'const bool')
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4100)
|
||||
# pragma warning(disable:4805)
|
||||
#endif
|
||||
|
||||
// Joins a vector of strings as if they are fields of a tuple; returns
|
||||
// the joined string.
|
||||
GTEST_API_ std::string JoinAsTuple(const Strings& fields);
|
||||
|
||||
// Converts an identifier name to a space-separated list of lower-case
|
||||
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
|
||||
// treated as one word. For example, both "FooBar123" and
|
||||
// "foo_bar_123" are converted to "foo bar 123".
|
||||
GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name);
|
||||
|
||||
// GetRawPointer(p) returns the raw pointer underlying p when p is a
|
||||
// smart pointer, or returns p itself when p is already a raw pointer.
|
||||
// The following default implementation is for the smart pointer case.
|
||||
template <typename Pointer>
|
||||
inline const typename Pointer::element_type* GetRawPointer(const Pointer& p) {
|
||||
return p.get();
|
||||
}
|
||||
// This overloaded version is for the raw pointer case.
|
||||
template <typename Element>
|
||||
inline Element* GetRawPointer(Element* p) { return p; }
|
||||
|
||||
// MSVC treats wchar_t as a native type usually, but treats it as the
|
||||
// same as unsigned short when the compiler option /Zc:wchar_t- is
|
||||
// specified. It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t
|
||||
// is a native type.
|
||||
#if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED)
|
||||
// wchar_t is a typedef.
|
||||
#else
|
||||
# define GMOCK_WCHAR_T_IS_NATIVE_ 1
|
||||
#endif
|
||||
|
||||
// In what follows, we use the term "kind" to indicate whether a type
|
||||
// is bool, an integer type (excluding bool), a floating-point type,
|
||||
// or none of them. This categorization is useful for determining
|
||||
// when a matcher argument type can be safely converted to another
|
||||
// type in the implementation of SafeMatcherCast.
|
||||
enum TypeKind {
|
||||
kBool, kInteger, kFloatingPoint, kOther
|
||||
};
|
||||
|
||||
// KindOf<T>::value is the kind of type T.
|
||||
template <typename T> struct KindOf {
|
||||
enum { value = kOther }; // The default kind.
|
||||
};
|
||||
|
||||
// This macro declares that the kind of 'type' is 'kind'.
|
||||
#define GMOCK_DECLARE_KIND_(type, kind) \
|
||||
template <> struct KindOf<type> { enum { value = kind }; }
|
||||
|
||||
GMOCK_DECLARE_KIND_(bool, kBool);
|
||||
|
||||
// All standard integer types.
|
||||
GMOCK_DECLARE_KIND_(char, kInteger);
|
||||
GMOCK_DECLARE_KIND_(signed char, kInteger);
|
||||
GMOCK_DECLARE_KIND_(unsigned char, kInteger);
|
||||
GMOCK_DECLARE_KIND_(short, kInteger); // NOLINT
|
||||
GMOCK_DECLARE_KIND_(unsigned short, kInteger); // NOLINT
|
||||
GMOCK_DECLARE_KIND_(int, kInteger);
|
||||
GMOCK_DECLARE_KIND_(unsigned int, kInteger);
|
||||
GMOCK_DECLARE_KIND_(long, kInteger); // NOLINT
|
||||
GMOCK_DECLARE_KIND_(unsigned long, kInteger); // NOLINT
|
||||
GMOCK_DECLARE_KIND_(long long, kInteger); // NOLINT
|
||||
GMOCK_DECLARE_KIND_(unsigned long long, kInteger); // NOLINT
|
||||
|
||||
#if GMOCK_WCHAR_T_IS_NATIVE_
|
||||
GMOCK_DECLARE_KIND_(wchar_t, kInteger);
|
||||
#endif
|
||||
|
||||
// All standard floating-point types.
|
||||
GMOCK_DECLARE_KIND_(float, kFloatingPoint);
|
||||
GMOCK_DECLARE_KIND_(double, kFloatingPoint);
|
||||
GMOCK_DECLARE_KIND_(long double, kFloatingPoint);
|
||||
|
||||
#undef GMOCK_DECLARE_KIND_
|
||||
|
||||
// Evaluates to the kind of 'type'.
|
||||
#define GMOCK_KIND_OF_(type) \
|
||||
static_cast< ::testing::internal::TypeKind>( \
|
||||
::testing::internal::KindOf<type>::value)
|
||||
|
||||
// LosslessArithmeticConvertibleImpl<kFromKind, From, kToKind, To>::value
|
||||
// is true if and only if arithmetic type From can be losslessly converted to
|
||||
// arithmetic type To.
|
||||
//
|
||||
// It's the user's responsibility to ensure that both From and To are
|
||||
// raw (i.e. has no CV modifier, is not a pointer, and is not a
|
||||
// reference) built-in arithmetic types, kFromKind is the kind of
|
||||
// From, and kToKind is the kind of To; the value is
|
||||
// implementation-defined when the above pre-condition is violated.
|
||||
template <TypeKind kFromKind, typename From, TypeKind kToKind, typename To>
|
||||
using LosslessArithmeticConvertibleImpl = std::integral_constant<
|
||||
bool,
|
||||
// clang-format off
|
||||
// Converting from bool is always lossless
|
||||
(kFromKind == kBool) ? true
|
||||
// Converting between any other type kinds will be lossy if the type
|
||||
// kinds are not the same.
|
||||
: (kFromKind != kToKind) ? false
|
||||
: (kFromKind == kInteger &&
|
||||
// Converting between integers of different widths is allowed so long
|
||||
// as the conversion does not go from signed to unsigned.
|
||||
(((sizeof(From) < sizeof(To)) &&
|
||||
!(std::is_signed<From>::value && !std::is_signed<To>::value)) ||
|
||||
// Converting between integers of the same width only requires the
|
||||
// two types to have the same signedness.
|
||||
((sizeof(From) == sizeof(To)) &&
|
||||
(std::is_signed<From>::value == std::is_signed<To>::value)))
|
||||
) ? true
|
||||
// Floating point conversions are lossless if and only if `To` is at least
|
||||
// as wide as `From`.
|
||||
: (kFromKind == kFloatingPoint && (sizeof(From) <= sizeof(To))) ? true
|
||||
: false
|
||||
// clang-format on
|
||||
>;
|
||||
|
||||
// LosslessArithmeticConvertible<From, To>::value is true if and only if
|
||||
// arithmetic type From can be losslessly converted to arithmetic type To.
|
||||
//
|
||||
// It's the user's responsibility to ensure that both From and To are
|
||||
// raw (i.e. has no CV modifier, is not a pointer, and is not a
|
||||
// reference) built-in arithmetic types; the value is
|
||||
// implementation-defined when the above pre-condition is violated.
|
||||
template <typename From, typename To>
|
||||
using LosslessArithmeticConvertible =
|
||||
LosslessArithmeticConvertibleImpl<GMOCK_KIND_OF_(From), From,
|
||||
GMOCK_KIND_OF_(To), To>;
|
||||
|
||||
// This interface knows how to report a Google Mock failure (either
|
||||
// non-fatal or fatal).
|
||||
class FailureReporterInterface {
|
||||
public:
|
||||
// The type of a failure (either non-fatal or fatal).
|
||||
enum FailureType {
|
||||
kNonfatal, kFatal
|
||||
};
|
||||
|
||||
virtual ~FailureReporterInterface() {}
|
||||
|
||||
// Reports a failure that occurred at the given source file location.
|
||||
virtual void ReportFailure(FailureType type, const char* file, int line,
|
||||
const std::string& message) = 0;
|
||||
};
|
||||
|
||||
// Returns the failure reporter used by Google Mock.
|
||||
GTEST_API_ FailureReporterInterface* GetFailureReporter();
|
||||
|
||||
// Asserts that condition is true; aborts the process with the given
|
||||
// message if condition is false. We cannot use LOG(FATAL) or CHECK()
|
||||
// as Google Mock might be used to mock the log sink itself. We
|
||||
// inline this function to prevent it from showing up in the stack
|
||||
// trace.
|
||||
inline void Assert(bool condition, const char* file, int line,
|
||||
const std::string& msg) {
|
||||
if (!condition) {
|
||||
GetFailureReporter()->ReportFailure(FailureReporterInterface::kFatal,
|
||||
file, line, msg);
|
||||
}
|
||||
}
|
||||
inline void Assert(bool condition, const char* file, int line) {
|
||||
Assert(condition, file, line, "Assertion failed.");
|
||||
}
|
||||
|
||||
// Verifies that condition is true; generates a non-fatal failure if
|
||||
// condition is false.
|
||||
inline void Expect(bool condition, const char* file, int line,
|
||||
const std::string& msg) {
|
||||
if (!condition) {
|
||||
GetFailureReporter()->ReportFailure(FailureReporterInterface::kNonfatal,
|
||||
file, line, msg);
|
||||
}
|
||||
}
|
||||
inline void Expect(bool condition, const char* file, int line) {
|
||||
Expect(condition, file, line, "Expectation failed.");
|
||||
}
|
||||
|
||||
// Severity level of a log.
|
||||
enum LogSeverity {
|
||||
kInfo = 0,
|
||||
kWarning = 1
|
||||
};
|
||||
|
||||
// Valid values for the --gmock_verbose flag.
|
||||
|
||||
// All logs (informational and warnings) are printed.
|
||||
const char kInfoVerbosity[] = "info";
|
||||
// Only warnings are printed.
|
||||
const char kWarningVerbosity[] = "warning";
|
||||
// No logs are printed.
|
||||
const char kErrorVerbosity[] = "error";
|
||||
|
||||
// Returns true if and only if a log with the given severity is visible
|
||||
// according to the --gmock_verbose flag.
|
||||
GTEST_API_ bool LogIsVisible(LogSeverity severity);
|
||||
|
||||
// Prints the given message to stdout if and only if 'severity' >= the level
|
||||
// specified by the --gmock_verbose flag. If stack_frames_to_skip >=
|
||||
// 0, also prints the stack trace excluding the top
|
||||
// stack_frames_to_skip frames. In opt mode, any positive
|
||||
// stack_frames_to_skip is treated as 0, since we don't know which
|
||||
// function calls will be inlined by the compiler and need to be
|
||||
// conservative.
|
||||
GTEST_API_ void Log(LogSeverity severity, const std::string& message,
|
||||
int stack_frames_to_skip);
|
||||
|
||||
// A marker class that is used to resolve parameterless expectations to the
|
||||
// correct overload. This must not be instantiable, to prevent client code from
|
||||
// accidentally resolving to the overload; for example:
|
||||
//
|
||||
// ON_CALL(mock, Method({}, nullptr))...
|
||||
//
|
||||
class WithoutMatchers {
|
||||
private:
|
||||
WithoutMatchers() {}
|
||||
friend GTEST_API_ WithoutMatchers GetWithoutMatchers();
|
||||
};
|
||||
|
||||
// Internal use only: access the singleton instance of WithoutMatchers.
|
||||
GTEST_API_ WithoutMatchers GetWithoutMatchers();
|
||||
|
||||
// Disable MSVC warnings for infinite recursion, since in this case the
|
||||
// the recursion is unreachable.
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4717)
|
||||
#endif
|
||||
|
||||
// Invalid<T>() is usable as an expression of type T, but will terminate
|
||||
// the program with an assertion failure if actually run. This is useful
|
||||
// when a value of type T is needed for compilation, but the statement
|
||||
// will not really be executed (or we don't care if the statement
|
||||
// crashes).
|
||||
template <typename T>
|
||||
inline T Invalid() {
|
||||
Assert(false, "", -1, "Internal error: attempt to return invalid value");
|
||||
// This statement is unreachable, and would never terminate even if it
|
||||
// could be reached. It is provided only to placate compiler warnings
|
||||
// about missing return statements.
|
||||
return Invalid<T>();
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
// Given a raw type (i.e. having no top-level reference or const
|
||||
// modifier) RawContainer that's either an STL-style container or a
|
||||
// native array, class StlContainerView<RawContainer> has the
|
||||
// following members:
|
||||
//
|
||||
// - type is a type that provides an STL-style container view to
|
||||
// (i.e. implements the STL container concept for) RawContainer;
|
||||
// - const_reference is a type that provides a reference to a const
|
||||
// RawContainer;
|
||||
// - ConstReference(raw_container) returns a const reference to an STL-style
|
||||
// container view to raw_container, which is a RawContainer.
|
||||
// - Copy(raw_container) returns an STL-style container view of a
|
||||
// copy of raw_container, which is a RawContainer.
|
||||
//
|
||||
// This generic version is used when RawContainer itself is already an
|
||||
// STL-style container.
|
||||
template <class RawContainer>
|
||||
class StlContainerView {
|
||||
public:
|
||||
typedef RawContainer type;
|
||||
typedef const type& const_reference;
|
||||
|
||||
static const_reference ConstReference(const RawContainer& container) {
|
||||
static_assert(!std::is_const<RawContainer>::value,
|
||||
"RawContainer type must not be const");
|
||||
return container;
|
||||
}
|
||||
static type Copy(const RawContainer& container) { return container; }
|
||||
};
|
||||
|
||||
// This specialization is used when RawContainer is a native array type.
|
||||
template <typename Element, size_t N>
|
||||
class StlContainerView<Element[N]> {
|
||||
public:
|
||||
typedef typename std::remove_const<Element>::type RawElement;
|
||||
typedef internal::NativeArray<RawElement> type;
|
||||
// NativeArray<T> can represent a native array either by value or by
|
||||
// reference (selected by a constructor argument), so 'const type'
|
||||
// can be used to reference a const native array. We cannot
|
||||
// 'typedef const type& const_reference' here, as that would mean
|
||||
// ConstReference() has to return a reference to a local variable.
|
||||
typedef const type const_reference;
|
||||
|
||||
static const_reference ConstReference(const Element (&array)[N]) {
|
||||
static_assert(std::is_same<Element, RawElement>::value,
|
||||
"Element type must not be const");
|
||||
return type(array, N, RelationToSourceReference());
|
||||
}
|
||||
static type Copy(const Element (&array)[N]) {
|
||||
return type(array, N, RelationToSourceCopy());
|
||||
}
|
||||
};
|
||||
|
||||
// This specialization is used when RawContainer is a native array
|
||||
// represented as a (pointer, size) tuple.
|
||||
template <typename ElementPointer, typename Size>
|
||||
class StlContainerView< ::std::tuple<ElementPointer, Size> > {
|
||||
public:
|
||||
typedef typename std::remove_const<
|
||||
typename std::pointer_traits<ElementPointer>::element_type>::type
|
||||
RawElement;
|
||||
typedef internal::NativeArray<RawElement> type;
|
||||
typedef const type const_reference;
|
||||
|
||||
static const_reference ConstReference(
|
||||
const ::std::tuple<ElementPointer, Size>& array) {
|
||||
return type(std::get<0>(array), std::get<1>(array),
|
||||
RelationToSourceReference());
|
||||
}
|
||||
static type Copy(const ::std::tuple<ElementPointer, Size>& array) {
|
||||
return type(std::get<0>(array), std::get<1>(array), RelationToSourceCopy());
|
||||
}
|
||||
};
|
||||
|
||||
// The following specialization prevents the user from instantiating
|
||||
// StlContainer with a reference type.
|
||||
template <typename T> class StlContainerView<T&>;
|
||||
|
||||
// A type transform to remove constness from the first part of a pair.
|
||||
// Pairs like that are used as the value_type of associative containers,
|
||||
// and this transform produces a similar but assignable pair.
|
||||
template <typename T>
|
||||
struct RemoveConstFromKey {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
// Partially specialized to remove constness from std::pair<const K, V>.
|
||||
template <typename K, typename V>
|
||||
struct RemoveConstFromKey<std::pair<const K, V> > {
|
||||
typedef std::pair<K, V> type;
|
||||
};
|
||||
|
||||
// Emit an assertion failure due to incorrect DoDefault() usage. Out-of-lined to
|
||||
// reduce code size.
|
||||
GTEST_API_ void IllegalDoDefault(const char* file, int line);
|
||||
|
||||
template <typename F, typename Tuple, size_t... Idx>
|
||||
auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>) -> decltype(
|
||||
std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...)) {
|
||||
return std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...);
|
||||
}
|
||||
|
||||
// Apply the function to a tuple of arguments.
|
||||
template <typename F, typename Tuple>
|
||||
auto Apply(F&& f, Tuple&& args) -> decltype(
|
||||
ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
|
||||
MakeIndexSequence<std::tuple_size<
|
||||
typename std::remove_reference<Tuple>::type>::value>())) {
|
||||
return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
|
||||
MakeIndexSequence<std::tuple_size<
|
||||
typename std::remove_reference<Tuple>::type>::value>());
|
||||
}
|
||||
|
||||
// Template struct Function<F>, where F must be a function type, contains
|
||||
// the following typedefs:
|
||||
//
|
||||
// Result: the function's return type.
|
||||
// Arg<N>: the type of the N-th argument, where N starts with 0.
|
||||
// ArgumentTuple: the tuple type consisting of all parameters of F.
|
||||
// ArgumentMatcherTuple: the tuple type consisting of Matchers for all
|
||||
// parameters of F.
|
||||
// MakeResultVoid: the function type obtained by substituting void
|
||||
// for the return type of F.
|
||||
// MakeResultIgnoredValue:
|
||||
// the function type obtained by substituting Something
|
||||
// for the return type of F.
|
||||
template <typename T>
|
||||
struct Function;
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct Function<R(Args...)> {
|
||||
using Result = R;
|
||||
static constexpr size_t ArgumentCount = sizeof...(Args);
|
||||
template <size_t I>
|
||||
using Arg = ElemFromList<I, Args...>;
|
||||
using ArgumentTuple = std::tuple<Args...>;
|
||||
using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;
|
||||
using MakeResultVoid = void(Args...);
|
||||
using MakeResultIgnoredValue = IgnoredValue(Args...);
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
constexpr size_t Function<R(Args...)>::ArgumentCount;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
|
@ -1,87 +0,0 @@
|
|||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
//
|
||||
// Low-level types and utilities for porting Google Mock to various
|
||||
// platforms. All macros ending with _ and symbols defined in an
|
||||
// internal namespace are subject to change without notice. Code
|
||||
// outside Google Mock MUST NOT USE THEM DIRECTLY. Macros that don't
|
||||
// end with _ are part of Google Mock's public API and can be used by
|
||||
// code outside Google Mock.
|
||||
|
||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
|
||||
// Most of the utilities needed for porting Google Mock are also
|
||||
// required for Google Test and are defined in gtest-port.h.
|
||||
//
|
||||
// Note to maintainers: to reduce code duplication, prefer adding
|
||||
// portability utilities to Google Test's gtest-port.h instead of
|
||||
// here, as Google Mock depends on Google Test. Only add a utility
|
||||
// here if it's truly specific to Google Mock.
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
#include "gmock/internal/custom/gmock-port.h"
|
||||
|
||||
// For MS Visual C++, check the compiler version. At least VS 2015 is
|
||||
// required to compile Google Mock.
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
# error "At least Visual C++ 2015 (14.0) is required to compile Google Mock."
|
||||
#endif
|
||||
|
||||
// Macro for referencing flags. This is public as we want the user to
|
||||
// use this syntax to reference Google Mock flags.
|
||||
#define GMOCK_FLAG(name) FLAGS_gmock_##name
|
||||
|
||||
#if !defined(GMOCK_DECLARE_bool_)
|
||||
|
||||
// Macros for declaring flags.
|
||||
# define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name)
|
||||
# define GMOCK_DECLARE_int32_(name) extern GTEST_API_ int32_t GMOCK_FLAG(name)
|
||||
# define GMOCK_DECLARE_string_(name) \
|
||||
extern GTEST_API_ ::std::string GMOCK_FLAG(name)
|
||||
|
||||
// Macros for defining flags.
|
||||
# define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||
GTEST_API_ bool GMOCK_FLAG(name) = (default_val)
|
||||
# define GMOCK_DEFINE_int32_(name, default_val, doc) \
|
||||
GTEST_API_ int32_t GMOCK_FLAG(name) = (default_val)
|
||||
# define GMOCK_DEFINE_string_(name, default_val, doc) \
|
||||
GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val)
|
||||
|
||||
#endif // !defined(GMOCK_DECLARE_bool_)
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
|
@ -1,279 +0,0 @@
|
|||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_
|
||||
|
||||
// Expands and concatenates the arguments. Constructed macros reevaluate.
|
||||
#define GMOCK_PP_CAT(_1, _2) GMOCK_PP_INTERNAL_CAT(_1, _2)
|
||||
|
||||
// Expands and stringifies the only argument.
|
||||
#define GMOCK_PP_STRINGIZE(...) GMOCK_PP_INTERNAL_STRINGIZE(__VA_ARGS__)
|
||||
|
||||
// Returns empty. Given a variadic number of arguments.
|
||||
#define GMOCK_PP_EMPTY(...)
|
||||
|
||||
// Returns a comma. Given a variadic number of arguments.
|
||||
#define GMOCK_PP_COMMA(...) ,
|
||||
|
||||
// Returns the only argument.
|
||||
#define GMOCK_PP_IDENTITY(_1) _1
|
||||
|
||||
// Evaluates to the number of arguments after expansion.
|
||||
//
|
||||
// #define PAIR x, y
|
||||
//
|
||||
// GMOCK_PP_NARG() => 1
|
||||
// GMOCK_PP_NARG(x) => 1
|
||||
// GMOCK_PP_NARG(x, y) => 2
|
||||
// GMOCK_PP_NARG(PAIR) => 2
|
||||
//
|
||||
// Requires: the number of arguments after expansion is at most 15.
|
||||
#define GMOCK_PP_NARG(...) \
|
||||
GMOCK_PP_INTERNAL_16TH( \
|
||||
(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
|
||||
|
||||
// Returns 1 if the expansion of arguments has an unprotected comma. Otherwise
|
||||
// returns 0. Requires no more than 15 unprotected commas.
|
||||
#define GMOCK_PP_HAS_COMMA(...) \
|
||||
GMOCK_PP_INTERNAL_16TH( \
|
||||
(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0))
|
||||
|
||||
// Returns the first argument.
|
||||
#define GMOCK_PP_HEAD(...) GMOCK_PP_INTERNAL_HEAD((__VA_ARGS__, unusedArg))
|
||||
|
||||
// Returns the tail. A variadic list of all arguments minus the first. Requires
|
||||
// at least one argument.
|
||||
#define GMOCK_PP_TAIL(...) GMOCK_PP_INTERNAL_TAIL((__VA_ARGS__))
|
||||
|
||||
// Calls CAT(_Macro, NARG(__VA_ARGS__))(__VA_ARGS__)
|
||||
#define GMOCK_PP_VARIADIC_CALL(_Macro, ...) \
|
||||
GMOCK_PP_IDENTITY( \
|
||||
GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__))
|
||||
|
||||
// If the arguments after expansion have no tokens, evaluates to `1`. Otherwise
|
||||
// evaluates to `0`.
|
||||
//
|
||||
// Requires: * the number of arguments after expansion is at most 15.
|
||||
// * If the argument is a macro, it must be able to be called with one
|
||||
// argument.
|
||||
//
|
||||
// Implementation details:
|
||||
//
|
||||
// There is one case when it generates a compile error: if the argument is macro
|
||||
// that cannot be called with one argument.
|
||||
//
|
||||
// #define M(a, b) // it doesn't matter what it expands to
|
||||
//
|
||||
// // Expected: expands to `0`.
|
||||
// // Actual: compile error.
|
||||
// GMOCK_PP_IS_EMPTY(M)
|
||||
//
|
||||
// There are 4 cases tested:
|
||||
//
|
||||
// * __VA_ARGS__ possible expansion has no unparen'd commas. Expected 0.
|
||||
// * __VA_ARGS__ possible expansion is not enclosed in parenthesis. Expected 0.
|
||||
// * __VA_ARGS__ possible expansion is not a macro that ()-evaluates to a comma.
|
||||
// Expected 0
|
||||
// * __VA_ARGS__ is empty, or has unparen'd commas, or is enclosed in
|
||||
// parenthesis, or is a macro that ()-evaluates to comma. Expected 1.
|
||||
//
|
||||
// We trigger detection on '0001', i.e. on empty.
|
||||
#define GMOCK_PP_IS_EMPTY(...) \
|
||||
GMOCK_PP_INTERNAL_IS_EMPTY(GMOCK_PP_HAS_COMMA(__VA_ARGS__), \
|
||||
GMOCK_PP_HAS_COMMA(GMOCK_PP_COMMA __VA_ARGS__), \
|
||||
GMOCK_PP_HAS_COMMA(__VA_ARGS__()), \
|
||||
GMOCK_PP_HAS_COMMA(GMOCK_PP_COMMA __VA_ARGS__()))
|
||||
|
||||
// Evaluates to _Then if _Cond is 1 and _Else if _Cond is 0.
|
||||
#define GMOCK_PP_IF(_Cond, _Then, _Else) \
|
||||
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IF_, _Cond)(_Then, _Else)
|
||||
|
||||
// Similar to GMOCK_PP_IF but takes _Then and _Else in parentheses.
|
||||
//
|
||||
// GMOCK_PP_GENERIC_IF(1, (a, b, c), (d, e, f)) => a, b, c
|
||||
// GMOCK_PP_GENERIC_IF(0, (a, b, c), (d, e, f)) => d, e, f
|
||||
//
|
||||
#define GMOCK_PP_GENERIC_IF(_Cond, _Then, _Else) \
|
||||
GMOCK_PP_REMOVE_PARENS(GMOCK_PP_IF(_Cond, _Then, _Else))
|
||||
|
||||
// Evaluates to the number of arguments after expansion. Identifies 'empty' as
|
||||
// 0.
|
||||
//
|
||||
// #define PAIR x, y
|
||||
//
|
||||
// GMOCK_PP_NARG0() => 0
|
||||
// GMOCK_PP_NARG0(x) => 1
|
||||
// GMOCK_PP_NARG0(x, y) => 2
|
||||
// GMOCK_PP_NARG0(PAIR) => 2
|
||||
//
|
||||
// Requires: * the number of arguments after expansion is at most 15.
|
||||
// * If the argument is a macro, it must be able to be called with one
|
||||
// argument.
|
||||
#define GMOCK_PP_NARG0(...) \
|
||||
GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(__VA_ARGS__), 0, GMOCK_PP_NARG(__VA_ARGS__))
|
||||
|
||||
// Expands to 1 if the first argument starts with something in parentheses,
|
||||
// otherwise to 0.
|
||||
#define GMOCK_PP_IS_BEGIN_PARENS(...) \
|
||||
GMOCK_PP_HEAD(GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_, \
|
||||
GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C __VA_ARGS__))
|
||||
|
||||
// Expands to 1 is there is only one argument and it is enclosed in parentheses.
|
||||
#define GMOCK_PP_IS_ENCLOSED_PARENS(...) \
|
||||
GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(__VA_ARGS__), \
|
||||
GMOCK_PP_IS_EMPTY(GMOCK_PP_EMPTY __VA_ARGS__), 0)
|
||||
|
||||
// Remove the parens, requires GMOCK_PP_IS_ENCLOSED_PARENS(args) => 1.
|
||||
#define GMOCK_PP_REMOVE_PARENS(...) GMOCK_PP_INTERNAL_REMOVE_PARENS __VA_ARGS__
|
||||
|
||||
// Expands to _Macro(0, _Data, e1) _Macro(1, _Data, e2) ... _Macro(K -1, _Data,
|
||||
// eK) as many of GMOCK_INTERNAL_NARG0 _Tuple.
|
||||
// Requires: * |_Macro| can be called with 3 arguments.
|
||||
// * |_Tuple| expansion has no more than 15 elements.
|
||||
#define GMOCK_PP_FOR_EACH(_Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, GMOCK_PP_NARG0 _Tuple) \
|
||||
(0, _Macro, _Data, _Tuple)
|
||||
|
||||
// Expands to _Macro(0, _Data, ) _Macro(1, _Data, ) ... _Macro(K - 1, _Data, )
|
||||
// Empty if _K = 0.
|
||||
// Requires: * |_Macro| can be called with 3 arguments.
|
||||
// * |_K| literal between 0 and 15
|
||||
#define GMOCK_PP_REPEAT(_Macro, _Data, _N) \
|
||||
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, _N) \
|
||||
(0, _Macro, _Data, GMOCK_PP_INTENRAL_EMPTY_TUPLE)
|
||||
|
||||
// Increments the argument, requires the argument to be between 0 and 15.
|
||||
#define GMOCK_PP_INC(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_INC_, _i)
|
||||
|
||||
// Returns comma if _i != 0. Requires _i to be between 0 and 15.
|
||||
#define GMOCK_PP_COMMA_IF(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_COMMA_IF_, _i)
|
||||
|
||||
// Internal details follow. Do not use any of these symbols outside of this
|
||||
// file or we will break your code.
|
||||
#define GMOCK_PP_INTENRAL_EMPTY_TUPLE (, , , , , , , , , , , , , , , )
|
||||
#define GMOCK_PP_INTERNAL_CAT(_1, _2) _1##_2
|
||||
#define GMOCK_PP_INTERNAL_STRINGIZE(...) #__VA_ARGS__
|
||||
#define GMOCK_PP_INTERNAL_CAT_5(_1, _2, _3, _4, _5) _1##_2##_3##_4##_5
|
||||
#define GMOCK_PP_INTERNAL_IS_EMPTY(_1, _2, _3, _4) \
|
||||
GMOCK_PP_HAS_COMMA(GMOCK_PP_INTERNAL_CAT_5(GMOCK_PP_INTERNAL_IS_EMPTY_CASE_, \
|
||||
_1, _2, _3, _4))
|
||||
#define GMOCK_PP_INTERNAL_IS_EMPTY_CASE_0001 ,
|
||||
#define GMOCK_PP_INTERNAL_IF_1(_Then, _Else) _Then
|
||||
#define GMOCK_PP_INTERNAL_IF_0(_Then, _Else) _Else
|
||||
|
||||
// Because of MSVC treating a token with a comma in it as a single token when
|
||||
// passed to another macro, we need to force it to evaluate it as multiple
|
||||
// tokens. We do that by using a "IDENTITY(MACRO PARENTHESIZED_ARGS)" macro. We
|
||||
// define one per possible macro that relies on this behavior. Note "_Args" must
|
||||
// be parenthesized.
|
||||
#define GMOCK_PP_INTERNAL_INTERNAL_16TH(_1, _2, _3, _4, _5, _6, _7, _8, _9, \
|
||||
_10, _11, _12, _13, _14, _15, _16, \
|
||||
...) \
|
||||
_16
|
||||
#define GMOCK_PP_INTERNAL_16TH(_Args) \
|
||||
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_16TH _Args)
|
||||
#define GMOCK_PP_INTERNAL_INTERNAL_HEAD(_1, ...) _1
|
||||
#define GMOCK_PP_INTERNAL_HEAD(_Args) \
|
||||
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_HEAD _Args)
|
||||
#define GMOCK_PP_INTERNAL_INTERNAL_TAIL(_1, ...) __VA_ARGS__
|
||||
#define GMOCK_PP_INTERNAL_TAIL(_Args) \
|
||||
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_TAIL _Args)
|
||||
|
||||
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C(...) 1 _
|
||||
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_1 1,
|
||||
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C \
|
||||
0,
|
||||
#define GMOCK_PP_INTERNAL_REMOVE_PARENS(...) __VA_ARGS__
|
||||
#define GMOCK_PP_INTERNAL_INC_0 1
|
||||
#define GMOCK_PP_INTERNAL_INC_1 2
|
||||
#define GMOCK_PP_INTERNAL_INC_2 3
|
||||
#define GMOCK_PP_INTERNAL_INC_3 4
|
||||
#define GMOCK_PP_INTERNAL_INC_4 5
|
||||
#define GMOCK_PP_INTERNAL_INC_5 6
|
||||
#define GMOCK_PP_INTERNAL_INC_6 7
|
||||
#define GMOCK_PP_INTERNAL_INC_7 8
|
||||
#define GMOCK_PP_INTERNAL_INC_8 9
|
||||
#define GMOCK_PP_INTERNAL_INC_9 10
|
||||
#define GMOCK_PP_INTERNAL_INC_10 11
|
||||
#define GMOCK_PP_INTERNAL_INC_11 12
|
||||
#define GMOCK_PP_INTERNAL_INC_12 13
|
||||
#define GMOCK_PP_INTERNAL_INC_13 14
|
||||
#define GMOCK_PP_INTERNAL_INC_14 15
|
||||
#define GMOCK_PP_INTERNAL_INC_15 16
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_0
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_1 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_2 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_3 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_4 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_5 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_6 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_7 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_8 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_9 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_10 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_11 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_12 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_13 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_14 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_15 ,
|
||||
#define GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, _element) \
|
||||
_Macro(_i, _Data, _element)
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_0(_i, _Macro, _Data, _Tuple)
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_1(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple)
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_2(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_1(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_3(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_2(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_4(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_3(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_5(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_4(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_6(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_5(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_7(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_6(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_8(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_7(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_9(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_8(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_10(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_9(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_11(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_10(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_12(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_11(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_13(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_12(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_13(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_15(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_
|
|
@ -1,5 +0,0 @@
|
|||
# Please Note:
|
||||
|
||||
Files in this directory are no longer supported by the maintainers. They
|
||||
represent mostly historical artifacts and supported by the community only. There
|
||||
is no guarantee whatsoever that these scripts still work.
|
|
@ -1,256 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2009, Google Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
"""fuse_gmock_files.py v0.1.0.
|
||||
|
||||
Fuses Google Mock and Google Test source code into two .h files and a .cc file.
|
||||
|
||||
SYNOPSIS
|
||||
fuse_gmock_files.py [GMOCK_ROOT_DIR] OUTPUT_DIR
|
||||
|
||||
Scans GMOCK_ROOT_DIR for Google Mock and Google Test source
|
||||
code, assuming Google Test is in the GMOCK_ROOT_DIR/../googletest
|
||||
directory, and generates three files:
|
||||
OUTPUT_DIR/gtest/gtest.h, OUTPUT_DIR/gmock/gmock.h, and
|
||||
OUTPUT_DIR/gmock-gtest-all.cc. Then you can build your tests
|
||||
by adding OUTPUT_DIR to the include search path and linking
|
||||
with OUTPUT_DIR/gmock-gtest-all.cc. These three files contain
|
||||
everything you need to use Google Mock. Hence you can
|
||||
"install" Google Mock by copying them to wherever you want.
|
||||
|
||||
GMOCK_ROOT_DIR can be omitted and defaults to the parent
|
||||
directory of the directory holding this script.
|
||||
|
||||
EXAMPLES
|
||||
./fuse_gmock_files.py fused_gmock
|
||||
./fuse_gmock_files.py path/to/unpacked/gmock fused_gmock
|
||||
|
||||
This tool is experimental. In particular, it assumes that there is no
|
||||
conditional inclusion of Google Mock or Google Test headers. Please
|
||||
report any problems to googlemock@googlegroups.com. You can read
|
||||
https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md
|
||||
for more
|
||||
information.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
||||
|
||||
# We assume that this file is in the scripts/ directory in the Google
|
||||
# Mock root directory.
|
||||
DEFAULT_GMOCK_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..')
|
||||
|
||||
# We need to call into googletest/scripts/fuse_gtest_files.py.
|
||||
sys.path.append(os.path.join(DEFAULT_GMOCK_ROOT_DIR, '../googletest/scripts'))
|
||||
import fuse_gtest_files as gtest # pylint:disable=g-import-not-at-top
|
||||
|
||||
# Regex for matching
|
||||
# '#include "gmock/..."'.
|
||||
INCLUDE_GMOCK_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(gmock/.+)"')
|
||||
|
||||
# Where to find the source seed files.
|
||||
GMOCK_H_SEED = 'include/gmock/gmock.h'
|
||||
GMOCK_ALL_CC_SEED = 'src/gmock-all.cc'
|
||||
|
||||
# Where to put the generated files.
|
||||
GTEST_H_OUTPUT = 'gtest/gtest.h'
|
||||
GMOCK_H_OUTPUT = 'gmock/gmock.h'
|
||||
GMOCK_GTEST_ALL_CC_OUTPUT = 'gmock-gtest-all.cc'
|
||||
|
||||
|
||||
def GetGTestRootDir(gmock_root):
|
||||
"""Returns the root directory of Google Test."""
|
||||
|
||||
return os.path.join(gmock_root, '../googletest')
|
||||
|
||||
|
||||
def ValidateGMockRootDir(gmock_root):
|
||||
"""Makes sure gmock_root points to a valid gmock root directory.
|
||||
|
||||
The function aborts the program on failure.
|
||||
|
||||
Args:
|
||||
gmock_root: A string with the mock root directory.
|
||||
"""
|
||||
|
||||
gtest.ValidateGTestRootDir(GetGTestRootDir(gmock_root))
|
||||
gtest.VerifyFileExists(gmock_root, GMOCK_H_SEED)
|
||||
gtest.VerifyFileExists(gmock_root, GMOCK_ALL_CC_SEED)
|
||||
|
||||
|
||||
def ValidateOutputDir(output_dir):
|
||||
"""Makes sure output_dir points to a valid output directory.
|
||||
|
||||
The function aborts the program on failure.
|
||||
|
||||
Args:
|
||||
output_dir: A string representing the output directory.
|
||||
"""
|
||||
|
||||
gtest.VerifyOutputFile(output_dir, gtest.GTEST_H_OUTPUT)
|
||||
gtest.VerifyOutputFile(output_dir, GMOCK_H_OUTPUT)
|
||||
gtest.VerifyOutputFile(output_dir, GMOCK_GTEST_ALL_CC_OUTPUT)
|
||||
|
||||
|
||||
def FuseGMockH(gmock_root, output_dir):
|
||||
"""Scans folder gmock_root to generate gmock/gmock.h in output_dir."""
|
||||
|
||||
output_file = open(os.path.join(output_dir, GMOCK_H_OUTPUT), 'w')
|
||||
processed_files = set() # Holds all gmock headers we've processed.
|
||||
|
||||
def ProcessFile(gmock_header_path):
|
||||
"""Processes the given gmock header file."""
|
||||
|
||||
# We don't process the same header twice.
|
||||
if gmock_header_path in processed_files:
|
||||
return
|
||||
|
||||
processed_files.add(gmock_header_path)
|
||||
|
||||
# Reads each line in the given gmock header.
|
||||
|
||||
with open(os.path.join(gmock_root, gmock_header_path), 'r') as fh:
|
||||
for line in fh:
|
||||
m = INCLUDE_GMOCK_FILE_REGEX.match(line)
|
||||
if m:
|
||||
# '#include "gmock/..."'
|
||||
# - let's process it recursively.
|
||||
ProcessFile('include/' + m.group(1))
|
||||
else:
|
||||
m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line)
|
||||
if m:
|
||||
# '#include "gtest/foo.h"'
|
||||
# We translate it to "gtest/gtest.h", regardless of what foo is,
|
||||
# since all gtest headers are fused into gtest/gtest.h.
|
||||
|
||||
# There is no need to #include gtest.h twice.
|
||||
if gtest.GTEST_H_SEED not in processed_files:
|
||||
processed_files.add(gtest.GTEST_H_SEED)
|
||||
output_file.write('#include "%s"\n' % (gtest.GTEST_H_OUTPUT,))
|
||||
else:
|
||||
# Otherwise we copy the line unchanged to the output file.
|
||||
output_file.write(line)
|
||||
|
||||
ProcessFile(GMOCK_H_SEED)
|
||||
output_file.close()
|
||||
|
||||
|
||||
def FuseGMockAllCcToFile(gmock_root, output_file):
|
||||
"""Scans folder gmock_root to fuse gmock-all.cc into output_file."""
|
||||
|
||||
processed_files = set()
|
||||
|
||||
def ProcessFile(gmock_source_file):
|
||||
"""Processes the given gmock source file."""
|
||||
|
||||
# We don't process the same #included file twice.
|
||||
if gmock_source_file in processed_files:
|
||||
return
|
||||
|
||||
processed_files.add(gmock_source_file)
|
||||
|
||||
# Reads each line in the given gmock source file.
|
||||
|
||||
with open(os.path.join(gmock_root, gmock_source_file), 'r') as fh:
|
||||
for line in fh:
|
||||
m = INCLUDE_GMOCK_FILE_REGEX.match(line)
|
||||
if m:
|
||||
# '#include "gmock/foo.h"'
|
||||
# We treat it as '#include "gmock/gmock.h"', as all other gmock
|
||||
# headers are being fused into gmock.h and cannot be
|
||||
# included directly. No need to
|
||||
# #include "gmock/gmock.h"
|
||||
# more than once.
|
||||
|
||||
if GMOCK_H_SEED not in processed_files:
|
||||
processed_files.add(GMOCK_H_SEED)
|
||||
output_file.write('#include "%s"\n' % (GMOCK_H_OUTPUT,))
|
||||
else:
|
||||
m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line)
|
||||
if m:
|
||||
# '#include "gtest/..."'
|
||||
# There is no need to #include gtest.h as it has been
|
||||
# #included by gtest-all.cc.
|
||||
|
||||
pass
|
||||
else:
|
||||
m = gtest.INCLUDE_SRC_FILE_REGEX.match(line)
|
||||
if m:
|
||||
# It's '#include "src/foo"' - let's process it recursively.
|
||||
ProcessFile(m.group(1))
|
||||
else:
|
||||
# Otherwise we copy the line unchanged to the output file.
|
||||
output_file.write(line)
|
||||
|
||||
ProcessFile(GMOCK_ALL_CC_SEED)
|
||||
|
||||
|
||||
def FuseGMockGTestAllCc(gmock_root, output_dir):
|
||||
"""Scans folder gmock_root to generate gmock-gtest-all.cc in output_dir."""
|
||||
|
||||
with open(os.path.join(output_dir, GMOCK_GTEST_ALL_CC_OUTPUT),
|
||||
'w') as output_file:
|
||||
# First, fuse gtest-all.cc into gmock-gtest-all.cc.
|
||||
gtest.FuseGTestAllCcToFile(GetGTestRootDir(gmock_root), output_file)
|
||||
# Next, append fused gmock-all.cc to gmock-gtest-all.cc.
|
||||
FuseGMockAllCcToFile(gmock_root, output_file)
|
||||
|
||||
|
||||
def FuseGMock(gmock_root, output_dir):
|
||||
"""Fuses gtest.h, gmock.h, and gmock-gtest-all.h."""
|
||||
|
||||
ValidateGMockRootDir(gmock_root)
|
||||
ValidateOutputDir(output_dir)
|
||||
|
||||
gtest.FuseGTestH(GetGTestRootDir(gmock_root), output_dir)
|
||||
FuseGMockH(gmock_root, output_dir)
|
||||
FuseGMockGTestAllCc(gmock_root, output_dir)
|
||||
|
||||
|
||||
def main():
|
||||
argc = len(sys.argv)
|
||||
if argc == 2:
|
||||
# fuse_gmock_files.py OUTPUT_DIR
|
||||
FuseGMock(DEFAULT_GMOCK_ROOT_DIR, sys.argv[1])
|
||||
elif argc == 3:
|
||||
# fuse_gmock_files.py GMOCK_ROOT_DIR OUTPUT_DIR
|
||||
FuseGMock(sys.argv[1], sys.argv[2])
|
||||
else:
|
||||
print(__doc__)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,203 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [2007] Neal Norwitz
|
||||
Portions Copyright [2007] Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
|
@ -1,34 +0,0 @@
|
|||
|
||||
The Google Mock class generator is an application that is part of cppclean.
|
||||
For more information about cppclean, visit http://code.google.com/p/cppclean/
|
||||
|
||||
The mock generator requires Python 2.3.5 or later. If you don't have Python
|
||||
installed on your system, you will also need to install it. You can download
|
||||
Python from: http://www.python.org/download/releases/
|
||||
|
||||
To use the Google Mock class generator, you need to call it
|
||||
on the command line passing the header file and class for which you want
|
||||
to generate a Google Mock class.
|
||||
|
||||
Make sure to install the scripts somewhere in your path. Then you can
|
||||
run the program.
|
||||
|
||||
gmock_gen.py header-file.h [ClassName]...
|
||||
|
||||
If no ClassNames are specified, all classes in the file are emitted.
|
||||
|
||||
To change the indentation from the default of 2, set INDENT in
|
||||
the environment. For example to use an indent of 4 spaces:
|
||||
|
||||
INDENT=4 gmock_gen.py header-file.h ClassName
|
||||
|
||||
This version was made from SVN revision 281 in the cppclean repository.
|
||||
|
||||
Known Limitations
|
||||
-----------------
|
||||
Not all code will be generated properly. For example, when mocking templated
|
||||
classes, the template information is lost. You will need to add the template
|
||||
information manually.
|
||||
|
||||
Not all permutations of using multiple pointers/references will be rendered
|
||||
properly. These will also have to be fixed manually.
|
|
@ -1,115 +0,0 @@
|
|||
Goal:
|
||||
-----
|
||||
CppClean attempts to find problems in C++ source that slow development
|
||||
in large code bases, for example various forms of unused code.
|
||||
Unused code can be unused functions, methods, data members, types, etc
|
||||
to unnecessary #include directives. Unnecessary #includes can cause
|
||||
considerable extra compiles increasing the edit-compile-run cycle.
|
||||
|
||||
The project home page is: http://code.google.com/p/cppclean/
|
||||
|
||||
|
||||
Features:
|
||||
---------
|
||||
* Find and print C++ language constructs: classes, methods, functions, etc.
|
||||
* Find classes with virtual methods, no virtual destructor, and no bases
|
||||
* Find global/static data that are potential problems when using threads
|
||||
* Unnecessary forward class declarations
|
||||
* Unnecessary function declarations
|
||||
* Undeclared function definitions
|
||||
* (planned) Find unnecessary header files #included
|
||||
- No direct reference to anything in the header
|
||||
- Header is unnecessary if classes were forward declared instead
|
||||
* (planned) Source files that reference headers not directly #included,
|
||||
ie, files that rely on a transitive #include from another header
|
||||
* (planned) Unused members (private, protected, & public) methods and data
|
||||
* (planned) Store AST in a SQL database so relationships can be queried
|
||||
|
||||
AST is Abstract Syntax Tree, a representation of parsed source code.
|
||||
http://en.wikipedia.org/wiki/Abstract_syntax_tree
|
||||
|
||||
|
||||
System Requirements:
|
||||
--------------------
|
||||
* Python 2.4 or later (2.3 probably works too)
|
||||
* Works on Windows (untested), Mac OS X, and Unix
|
||||
|
||||
|
||||
How to Run:
|
||||
-----------
|
||||
For all examples, it is assumed that cppclean resides in a directory called
|
||||
/cppclean.
|
||||
|
||||
To print warnings for classes with virtual methods, no virtual destructor and
|
||||
no base classes:
|
||||
|
||||
/cppclean/run.sh nonvirtual_dtors.py file1.h file2.h file3.cc ...
|
||||
|
||||
To print all the functions defined in header file(s):
|
||||
|
||||
/cppclean/run.sh functions.py file1.h file2.h ...
|
||||
|
||||
All the commands take multiple files on the command line. Other programs
|
||||
include: find_warnings, headers, methods, and types. Some other programs
|
||||
are available, but used primarily for debugging.
|
||||
|
||||
run.sh is a simple wrapper that sets PYTHONPATH to /cppclean and then
|
||||
runs the program in /cppclean/cpp/PROGRAM.py. There is currently
|
||||
no equivalent for Windows. Contributions for a run.bat file
|
||||
would be greatly appreciated.
|
||||
|
||||
|
||||
How to Configure:
|
||||
-----------------
|
||||
You can add a siteheaders.py file in /cppclean/cpp to configure where
|
||||
to look for other headers (typically -I options passed to a compiler).
|
||||
Currently two values are supported: _TRANSITIVE and GetIncludeDirs.
|
||||
_TRANSITIVE should be set to a boolean value (True or False) indicating
|
||||
whether to transitively process all header files. The default is False.
|
||||
|
||||
GetIncludeDirs is a function that takes a single argument and returns
|
||||
a sequence of directories to include. This can be a generator or
|
||||
return a static list.
|
||||
|
||||
def GetIncludeDirs(filename):
|
||||
return ['/some/path/with/other/headers']
|
||||
|
||||
# Here is a more complicated example.
|
||||
def GetIncludeDirs(filename):
|
||||
yield '/path1'
|
||||
yield os.path.join('/path2', os.path.dirname(filename))
|
||||
yield '/path3'
|
||||
|
||||
|
||||
How to Test:
|
||||
------------
|
||||
For all examples, it is assumed that cppclean resides in a directory called
|
||||
/cppclean. The tests require
|
||||
|
||||
cd /cppclean
|
||||
make test
|
||||
# To generate expected results after a change:
|
||||
make expected
|
||||
|
||||
|
||||
Current Status:
|
||||
---------------
|
||||
The parser works pretty well for header files, parsing about 99% of Google's
|
||||
header files. Anything which inspects structure of C++ source files should
|
||||
work reasonably well. Function bodies are not transformed to an AST,
|
||||
but left as tokens. Much work is still needed on finding unused header files
|
||||
and storing an AST in a database.
|
||||
|
||||
|
||||
Non-goals:
|
||||
----------
|
||||
* Parsing all valid C++ source
|
||||
* Handling invalid C++ source gracefully
|
||||
* Compiling to machine code (or anything beyond an AST)
|
||||
|
||||
|
||||
Contact:
|
||||
--------
|
||||
If you used cppclean, I would love to hear about your experiences
|
||||
cppclean@googlegroups.com. Even if you don't use cppclean, I'd like to
|
||||
hear from you. :-) (You can contact me directly at: nnorwitz@gmail.com)
|
|
@ -1,247 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2008 Google Inc. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Generate Google Mock classes from base classes.
|
||||
|
||||
This program will read in a C++ source file and output the Google Mock
|
||||
classes for the specified classes. If no class is specified, all
|
||||
classes in the source file are emitted.
|
||||
|
||||
Usage:
|
||||
gmock_class.py header-file.h [ClassName]...
|
||||
|
||||
Output is sent to stdout.
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
from cpp import ast
|
||||
from cpp import utils
|
||||
|
||||
# Preserve compatibility with Python 2.3.
|
||||
try:
|
||||
_dummy = set
|
||||
except NameError:
|
||||
import sets
|
||||
|
||||
set = sets.Set
|
||||
|
||||
_VERSION = (1, 0, 1) # The version of this script.
|
||||
# How many spaces to indent. Can set me with the INDENT environment variable.
|
||||
_INDENT = 2
|
||||
|
||||
|
||||
def _RenderType(ast_type):
|
||||
"""Renders the potentially recursively templated type into a string.
|
||||
|
||||
Args:
|
||||
ast_type: The AST of the type.
|
||||
|
||||
Returns:
|
||||
Rendered string of the type.
|
||||
"""
|
||||
# Add modifiers like 'const'.
|
||||
modifiers = ''
|
||||
if ast_type.modifiers:
|
||||
modifiers = ' '.join(ast_type.modifiers) + ' '
|
||||
return_type = modifiers + ast_type.name
|
||||
if ast_type.templated_types:
|
||||
# Collect template args.
|
||||
template_args = []
|
||||
for arg in ast_type.templated_types:
|
||||
rendered_arg = _RenderType(arg)
|
||||
template_args.append(rendered_arg)
|
||||
return_type += '<' + ', '.join(template_args) + '>'
|
||||
if ast_type.pointer:
|
||||
return_type += '*'
|
||||
if ast_type.reference:
|
||||
return_type += '&'
|
||||
return return_type
|
||||
|
||||
|
||||
def _GenerateArg(source):
|
||||
"""Strips out comments, default arguments, and redundant spaces from a single argument.
|
||||
|
||||
Args:
|
||||
source: A string for a single argument.
|
||||
|
||||
Returns:
|
||||
Rendered string of the argument.
|
||||
"""
|
||||
# Remove end of line comments before eliminating newlines.
|
||||
arg = re.sub(r'//.*', '', source)
|
||||
|
||||
# Remove c-style comments.
|
||||
arg = re.sub(r'/\*.*\*/', '', arg)
|
||||
|
||||
# Remove default arguments.
|
||||
arg = re.sub(r'=.*', '', arg)
|
||||
|
||||
# Collapse spaces and newlines into a single space.
|
||||
arg = re.sub(r'\s+', ' ', arg)
|
||||
return arg.strip()
|
||||
|
||||
|
||||
def _EscapeForMacro(s):
|
||||
"""Escapes a string for use as an argument to a C++ macro."""
|
||||
paren_count = 0
|
||||
for c in s:
|
||||
if c == '(':
|
||||
paren_count += 1
|
||||
elif c == ')':
|
||||
paren_count -= 1
|
||||
elif c == ',' and paren_count == 0:
|
||||
return '(' + s + ')'
|
||||
return s
|
||||
|
||||
|
||||
def _GenerateMethods(output_lines, source, class_node):
|
||||
function_type = (
|
||||
ast.FUNCTION_VIRTUAL | ast.FUNCTION_PURE_VIRTUAL | ast.FUNCTION_OVERRIDE)
|
||||
ctor_or_dtor = ast.FUNCTION_CTOR | ast.FUNCTION_DTOR
|
||||
indent = ' ' * _INDENT
|
||||
|
||||
for node in class_node.body:
|
||||
# We only care about virtual functions.
|
||||
if (isinstance(node, ast.Function) and node.modifiers & function_type and
|
||||
not node.modifiers & ctor_or_dtor):
|
||||
# Pick out all the elements we need from the original function.
|
||||
modifiers = 'override'
|
||||
if node.modifiers & ast.FUNCTION_CONST:
|
||||
modifiers = 'const, ' + modifiers
|
||||
|
||||
return_type = 'void'
|
||||
if node.return_type:
|
||||
return_type = _EscapeForMacro(_RenderType(node.return_type))
|
||||
|
||||
args = []
|
||||
for p in node.parameters:
|
||||
arg = _GenerateArg(source[p.start:p.end])
|
||||
if arg != 'void':
|
||||
args.append(_EscapeForMacro(arg))
|
||||
|
||||
# Create the mock method definition.
|
||||
output_lines.extend([
|
||||
'%sMOCK_METHOD(%s, %s, (%s), (%s));' %
|
||||
(indent, return_type, node.name, ', '.join(args), modifiers)
|
||||
])
|
||||
|
||||
|
||||
def _GenerateMocks(filename, source, ast_list, desired_class_names):
|
||||
processed_class_names = set()
|
||||
lines = []
|
||||
for node in ast_list:
|
||||
if (isinstance(node, ast.Class) and node.body and
|
||||
# desired_class_names being None means that all classes are selected.
|
||||
(not desired_class_names or node.name in desired_class_names)):
|
||||
class_name = node.name
|
||||
parent_name = class_name
|
||||
processed_class_names.add(class_name)
|
||||
class_node = node
|
||||
# Add namespace before the class.
|
||||
if class_node.namespace:
|
||||
lines.extend(['namespace %s {' % n for n in class_node.namespace]) # }
|
||||
lines.append('')
|
||||
|
||||
# Add template args for templated classes.
|
||||
if class_node.templated_types:
|
||||
# TODO(paulchang): Handle non-type template arguments (e.g.
|
||||
# template<typename T, int N>).
|
||||
|
||||
# class_node.templated_types is an OrderedDict from strings to a tuples.
|
||||
# The key is the name of the template, and the value is
|
||||
# (type_name, default). Both type_name and default could be None.
|
||||
template_args = class_node.templated_types.keys()
|
||||
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)
|
|
@ -1,570 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2009 Neal Norwitz All Rights Reserved.
|
||||
# Portions Copyright 2009 Google Inc. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Tests for gmock.scripts.generator.cpp.gmock_class."""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
# Allow the cpp imports below to work when run as a standalone script.
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
||||
|
||||
from cpp import ast
|
||||
from cpp import gmock_class
|
||||
|
||||
|
||||
class TestCase(unittest.TestCase):
|
||||
"""Helper class that adds assert methods."""
|
||||
|
||||
@staticmethod
|
||||
def StripLeadingWhitespace(lines):
|
||||
"""Strip leading whitespace in each line in 'lines'."""
|
||||
return '\n'.join([s.lstrip() for s in lines.split('\n')])
|
||||
|
||||
def assertEqualIgnoreLeadingWhitespace(self, expected_lines, lines):
|
||||
"""Specialized assert that ignores the indent level."""
|
||||
self.assertEqual(expected_lines, self.StripLeadingWhitespace(lines))
|
||||
|
||||
|
||||
class GenerateMethodsTest(TestCase):
|
||||
|
||||
@staticmethod
|
||||
def GenerateMethodSource(cpp_source):
|
||||
"""Convert C++ source to Google Mock output source lines."""
|
||||
method_source_lines = []
|
||||
# <test> is a pseudo-filename, it is not read or written.
|
||||
builder = ast.BuilderFromSource(cpp_source, '<test>')
|
||||
ast_list = list(builder.Generate())
|
||||
gmock_class._GenerateMethods(method_source_lines, cpp_source, ast_list[0])
|
||||
return '\n'.join(method_source_lines)
|
||||
|
||||
def testSimpleMethod(self):
|
||||
source = """
|
||||
class Foo {
|
||||
public:
|
||||
virtual int Bar();
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(
|
||||
'MOCK_METHOD(int, Bar, (), (override));',
|
||||
self.GenerateMethodSource(source))
|
||||
|
||||
def testSimpleConstructorsAndDestructor(self):
|
||||
source = """
|
||||
class Foo {
|
||||
public:
|
||||
Foo();
|
||||
Foo(int x);
|
||||
Foo(const Foo& f);
|
||||
Foo(Foo&& f);
|
||||
~Foo();
|
||||
virtual int Bar() = 0;
|
||||
};
|
||||
"""
|
||||
# The constructors and destructor should be ignored.
|
||||
self.assertEqualIgnoreLeadingWhitespace(
|
||||
'MOCK_METHOD(int, Bar, (), (override));',
|
||||
self.GenerateMethodSource(source))
|
||||
|
||||
def testVirtualDestructor(self):
|
||||
source = """
|
||||
class Foo {
|
||||
public:
|
||||
virtual ~Foo();
|
||||
virtual int Bar() = 0;
|
||||
};
|
||||
"""
|
||||
# The destructor should be ignored.
|
||||
self.assertEqualIgnoreLeadingWhitespace(
|
||||
'MOCK_METHOD(int, Bar, (), (override));',
|
||||
self.GenerateMethodSource(source))
|
||||
|
||||
def testExplicitlyDefaultedConstructorsAndDestructor(self):
|
||||
source = """
|
||||
class Foo {
|
||||
public:
|
||||
Foo() = default;
|
||||
Foo(const Foo& f) = default;
|
||||
Foo(Foo&& f) = default;
|
||||
~Foo() = default;
|
||||
virtual int Bar() = 0;
|
||||
};
|
||||
"""
|
||||
# The constructors and destructor should be ignored.
|
||||
self.assertEqualIgnoreLeadingWhitespace(
|
||||
'MOCK_METHOD(int, Bar, (), (override));',
|
||||
self.GenerateMethodSource(source))
|
||||
|
||||
def testExplicitlyDeletedConstructorsAndDestructor(self):
|
||||
source = """
|
||||
class Foo {
|
||||
public:
|
||||
Foo() = delete;
|
||||
Foo(const Foo& f) = delete;
|
||||
Foo(Foo&& f) = delete;
|
||||
~Foo() = delete;
|
||||
virtual int Bar() = 0;
|
||||
};
|
||||
"""
|
||||
# The constructors and destructor should be ignored.
|
||||
self.assertEqualIgnoreLeadingWhitespace(
|
||||
'MOCK_METHOD(int, Bar, (), (override));',
|
||||
self.GenerateMethodSource(source))
|
||||
|
||||
def testSimpleOverrideMethod(self):
|
||||
source = """
|
||||
class Foo {
|
||||
public:
|
||||
int Bar() override;
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(
|
||||
'MOCK_METHOD(int, Bar, (), (override));',
|
||||
self.GenerateMethodSource(source))
|
||||
|
||||
def testSimpleConstMethod(self):
|
||||
source = """
|
||||
class Foo {
|
||||
public:
|
||||
virtual void Bar(bool flag) const;
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(
|
||||
'MOCK_METHOD(void, Bar, (bool flag), (const, override));',
|
||||
self.GenerateMethodSource(source))
|
||||
|
||||
def testExplicitVoid(self):
|
||||
source = """
|
||||
class Foo {
|
||||
public:
|
||||
virtual int Bar(void);
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(
|
||||
'MOCK_METHOD(int, Bar, (), (override));',
|
||||
self.GenerateMethodSource(source))
|
||||
|
||||
def testStrangeNewlineInParameter(self):
|
||||
source = """
|
||||
class Foo {
|
||||
public:
|
||||
virtual void Bar(int
|
||||
a) = 0;
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(
|
||||
'MOCK_METHOD(void, Bar, (int a), (override));',
|
||||
self.GenerateMethodSource(source))
|
||||
|
||||
def testDefaultParameters(self):
|
||||
source = """
|
||||
class Foo {
|
||||
public:
|
||||
virtual void Bar(int a, char c = 'x') = 0;
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(
|
||||
'MOCK_METHOD(void, Bar, (int a, char c), (override));',
|
||||
self.GenerateMethodSource(source))
|
||||
|
||||
def testMultipleDefaultParameters(self):
|
||||
source = """
|
||||
class Foo {
|
||||
public:
|
||||
virtual void Bar(
|
||||
int a = 42,
|
||||
char c = 'x',
|
||||
const int* const p = nullptr,
|
||||
const std::string& s = "42",
|
||||
char tab[] = {'4','2'},
|
||||
int const *& rp = aDefaultPointer) = 0;
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(
|
||||
'MOCK_METHOD(void, Bar, '
|
||||
'(int a, char c, const int* const p, const std::string& s, char tab[], int const *& rp), '
|
||||
'(override));', self.GenerateMethodSource(source))
|
||||
|
||||
def testMultipleSingleLineDefaultParameters(self):
|
||||
source = """
|
||||
class Foo {
|
||||
public:
|
||||
virtual void Bar(int a = 42, int b = 43, int c = 44) = 0;
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(
|
||||
'MOCK_METHOD(void, Bar, (int a, int b, int c), (override));',
|
||||
self.GenerateMethodSource(source))
|
||||
|
||||
def testConstDefaultParameter(self):
|
||||
source = """
|
||||
class Test {
|
||||
public:
|
||||
virtual bool Bar(const int test_arg = 42) = 0;
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(
|
||||
'MOCK_METHOD(bool, Bar, (const int test_arg), (override));',
|
||||
self.GenerateMethodSource(source))
|
||||
|
||||
def testConstRefDefaultParameter(self):
|
||||
source = """
|
||||
class Test {
|
||||
public:
|
||||
virtual bool Bar(const std::string& test_arg = "42" ) = 0;
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(
|
||||
'MOCK_METHOD(bool, Bar, (const std::string& test_arg), (override));',
|
||||
self.GenerateMethodSource(source))
|
||||
|
||||
def testRemovesCommentsWhenDefaultsArePresent(self):
|
||||
source = """
|
||||
class Foo {
|
||||
public:
|
||||
virtual void Bar(int a = 42 /* a comment */,
|
||||
char /* other comment */ c= 'x') = 0;
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(
|
||||
'MOCK_METHOD(void, Bar, (int a, char c), (override));',
|
||||
self.GenerateMethodSource(source))
|
||||
|
||||
def testDoubleSlashCommentsInParameterListAreRemoved(self):
|
||||
source = """
|
||||
class Foo {
|
||||
public:
|
||||
virtual void Bar(int a, // inline comments should be elided.
|
||||
int b // inline comments should be elided.
|
||||
) const = 0;
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(
|
||||
'MOCK_METHOD(void, Bar, (int a, int b), (const, override));',
|
||||
self.GenerateMethodSource(source))
|
||||
|
||||
def testCStyleCommentsInParameterListAreNotRemoved(self):
|
||||
# NOTE(nnorwitz): I'm not sure if it's the best behavior to keep these
|
||||
# comments. Also note that C style comments after the last parameter
|
||||
# are still elided.
|
||||
source = """
|
||||
class Foo {
|
||||
public:
|
||||
virtual const string& Bar(int /* keeper */, int b);
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(
|
||||
'MOCK_METHOD(const string&, Bar, (int, int b), (override));',
|
||||
self.GenerateMethodSource(source))
|
||||
|
||||
def testArgsOfTemplateTypes(self):
|
||||
source = """
|
||||
class Foo {
|
||||
public:
|
||||
virtual int Bar(const vector<int>& v, map<int, string>* output);
|
||||
};"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(
|
||||
'MOCK_METHOD(int, Bar, (const vector<int>& v, (map<int, string>* output)), (override));',
|
||||
self.GenerateMethodSource(source))
|
||||
|
||||
def testReturnTypeWithOneTemplateArg(self):
|
||||
source = """
|
||||
class Foo {
|
||||
public:
|
||||
virtual vector<int>* Bar(int n);
|
||||
};"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(
|
||||
'MOCK_METHOD(vector<int>*, Bar, (int n), (override));',
|
||||
self.GenerateMethodSource(source))
|
||||
|
||||
def testReturnTypeWithManyTemplateArgs(self):
|
||||
source = """
|
||||
class Foo {
|
||||
public:
|
||||
virtual map<int, string> Bar();
|
||||
};"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(
|
||||
'MOCK_METHOD((map<int, string>), Bar, (), (override));',
|
||||
self.GenerateMethodSource(source))
|
||||
|
||||
def testSimpleMethodInTemplatedClass(self):
|
||||
source = """
|
||||
template<class T>
|
||||
class Foo {
|
||||
public:
|
||||
virtual int Bar();
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(
|
||||
'MOCK_METHOD(int, Bar, (), (override));',
|
||||
self.GenerateMethodSource(source))
|
||||
|
||||
def testPointerArgWithoutNames(self):
|
||||
source = """
|
||||
class Foo {
|
||||
virtual int Bar(C*);
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(
|
||||
'MOCK_METHOD(int, Bar, (C*), (override));',
|
||||
self.GenerateMethodSource(source))
|
||||
|
||||
def testReferenceArgWithoutNames(self):
|
||||
source = """
|
||||
class Foo {
|
||||
virtual int Bar(C&);
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(
|
||||
'MOCK_METHOD(int, Bar, (C&), (override));',
|
||||
self.GenerateMethodSource(source))
|
||||
|
||||
def testArrayArgWithoutNames(self):
|
||||
source = """
|
||||
class Foo {
|
||||
virtual int Bar(C[]);
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(
|
||||
'MOCK_METHOD(int, Bar, (C[]), (override));',
|
||||
self.GenerateMethodSource(source))
|
||||
|
||||
|
||||
class GenerateMocksTest(TestCase):
|
||||
|
||||
@staticmethod
|
||||
def GenerateMocks(cpp_source):
|
||||
"""Convert C++ source to complete Google Mock output source."""
|
||||
# <test> is a pseudo-filename, it is not read or written.
|
||||
filename = '<test>'
|
||||
builder = ast.BuilderFromSource(cpp_source, filename)
|
||||
ast_list = list(builder.Generate())
|
||||
lines = gmock_class._GenerateMocks(filename, cpp_source, ast_list, None)
|
||||
return '\n'.join(lines)
|
||||
|
||||
def testNamespaces(self):
|
||||
source = """
|
||||
namespace Foo {
|
||||
namespace Bar { class Forward; }
|
||||
namespace Baz::Qux {
|
||||
|
||||
class Test {
|
||||
public:
|
||||
virtual void Foo();
|
||||
};
|
||||
|
||||
} // namespace Baz::Qux
|
||||
} // namespace Foo
|
||||
"""
|
||||
expected = """\
|
||||
namespace Foo {
|
||||
namespace Baz::Qux {
|
||||
|
||||
class MockTest : public Test {
|
||||
public:
|
||||
MOCK_METHOD(void, Foo, (), (override));
|
||||
};
|
||||
|
||||
} // namespace Baz::Qux
|
||||
} // namespace Foo
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
||||
self.GenerateMocks(source))
|
||||
|
||||
def testClassWithStorageSpecifierMacro(self):
|
||||
source = """
|
||||
class STORAGE_SPECIFIER Test {
|
||||
public:
|
||||
virtual void Foo();
|
||||
};
|
||||
"""
|
||||
expected = """\
|
||||
class MockTest : public Test {
|
||||
public:
|
||||
MOCK_METHOD(void, Foo, (), (override));
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
||||
self.GenerateMocks(source))
|
||||
|
||||
def testTemplatedForwardDeclaration(self):
|
||||
source = """
|
||||
template <class T> class Forward; // Forward declaration should be ignored.
|
||||
class Test {
|
||||
public:
|
||||
virtual void Foo();
|
||||
};
|
||||
"""
|
||||
expected = """\
|
||||
class MockTest : public Test {
|
||||
public:
|
||||
MOCK_METHOD(void, Foo, (), (override));
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
||||
self.GenerateMocks(source))
|
||||
|
||||
def testTemplatedClass(self):
|
||||
source = """
|
||||
template <typename S, typename T>
|
||||
class Test {
|
||||
public:
|
||||
virtual void Foo();
|
||||
};
|
||||
"""
|
||||
expected = """\
|
||||
template <typename S, typename T>
|
||||
class MockTest : public Test<S, T> {
|
||||
public:
|
||||
MOCK_METHOD(void, Foo, (), (override));
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
||||
self.GenerateMocks(source))
|
||||
|
||||
def testTemplateInATemplateTypedef(self):
|
||||
source = """
|
||||
class Test {
|
||||
public:
|
||||
typedef std::vector<std::list<int>> FooType;
|
||||
virtual void Bar(const FooType& test_arg);
|
||||
};
|
||||
"""
|
||||
expected = """\
|
||||
class MockTest : public Test {
|
||||
public:
|
||||
MOCK_METHOD(void, Bar, (const FooType& test_arg), (override));
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
||||
self.GenerateMocks(source))
|
||||
|
||||
def testTemplatedClassWithTemplatedArguments(self):
|
||||
source = """
|
||||
template <typename S, typename T, typename U, typename V, typename W>
|
||||
class Test {
|
||||
public:
|
||||
virtual U Foo(T some_arg);
|
||||
};
|
||||
"""
|
||||
expected = """\
|
||||
template <typename S, typename T, typename U, typename V, typename W>
|
||||
class MockTest : public Test<S, T, U, V, W> {
|
||||
public:
|
||||
MOCK_METHOD(U, Foo, (T some_arg), (override));
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
||||
self.GenerateMocks(source))
|
||||
|
||||
def testTemplateInATemplateTypedefWithComma(self):
|
||||
source = """
|
||||
class Test {
|
||||
public:
|
||||
typedef std::function<void(
|
||||
const vector<std::list<int>>&, int> FooType;
|
||||
virtual void Bar(const FooType& test_arg);
|
||||
};
|
||||
"""
|
||||
expected = """\
|
||||
class MockTest : public Test {
|
||||
public:
|
||||
MOCK_METHOD(void, Bar, (const FooType& test_arg), (override));
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
||||
self.GenerateMocks(source))
|
||||
|
||||
def testParenthesizedCommaInArg(self):
|
||||
source = """
|
||||
class Test {
|
||||
public:
|
||||
virtual void Bar(std::function<void(int, int)> f);
|
||||
};
|
||||
"""
|
||||
expected = """\
|
||||
class MockTest : public Test {
|
||||
public:
|
||||
MOCK_METHOD(void, Bar, (std::function<void(int, int)> f), (override));
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
||||
self.GenerateMocks(source))
|
||||
|
||||
def testEnumType(self):
|
||||
source = """
|
||||
class Test {
|
||||
public:
|
||||
enum Bar {
|
||||
BAZ, QUX, QUUX, QUUUX
|
||||
};
|
||||
virtual void Foo();
|
||||
};
|
||||
"""
|
||||
expected = """\
|
||||
class MockTest : public Test {
|
||||
public:
|
||||
MOCK_METHOD(void, Foo, (), (override));
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
||||
self.GenerateMocks(source))
|
||||
|
||||
def testEnumClassType(self):
|
||||
source = """
|
||||
class Test {
|
||||
public:
|
||||
enum class Bar {
|
||||
BAZ, QUX, QUUX, QUUUX
|
||||
};
|
||||
virtual void Foo();
|
||||
};
|
||||
"""
|
||||
expected = """\
|
||||
class MockTest : public Test {
|
||||
public:
|
||||
MOCK_METHOD(void, Foo, (), (override));
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
||||
self.GenerateMocks(source))
|
||||
|
||||
def testStdFunction(self):
|
||||
source = """
|
||||
class Test {
|
||||
public:
|
||||
Test(std::function<int(std::string)> foo) : foo_(foo) {}
|
||||
|
||||
virtual std::function<int(std::string)> foo();
|
||||
|
||||
private:
|
||||
std::function<int(std::string)> foo_;
|
||||
};
|
||||
"""
|
||||
expected = """\
|
||||
class MockTest : public Test {
|
||||
public:
|
||||
MOCK_METHOD(std::function<int (std::string)>, foo, (), (override));
|
||||
};
|
||||
"""
|
||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
||||
self.GenerateMocks(source))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,56 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2007 Neal Norwitz
|
||||
# Portions Copyright 2007 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""C++ keywords and helper utilities for determining keywords."""
|
||||
|
||||
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
|
|
@ -1,284 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2007 Neal Norwitz
|
||||
# Portions Copyright 2007 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Tokenize C++ source code."""
|
||||
|
||||
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)
|
|
@ -1,37 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2007 Neal Norwitz
|
||||
# Portions Copyright 2007 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Generic utilities for C++ parsing."""
|
||||
|
||||
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
|
|
@ -1,30 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2008 Google Inc. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Driver for starting up Google Mock class generator."""
|
||||
|
||||
|
||||
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()
|
|
@ -1,46 +0,0 @@
|
|||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
//
|
||||
// Google C++ Mocking Framework (Google Mock)
|
||||
//
|
||||
// This file #includes all Google Mock implementation .cc files. The
|
||||
// purpose is to allow a user to build Google Mock by compiling this
|
||||
// file alone.
|
||||
|
||||
// This line ensures that gmock.h can be compiled on its own, even
|
||||
// when it's fused.
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
// The following lines pull in the real gmock *.cc files.
|
||||
#include "src/gmock-cardinalities.cc"
|
||||
#include "src/gmock-internal-utils.cc"
|
||||
#include "src/gmock-matchers.cc"
|
||||
#include "src/gmock-spec-builders.cc"
|
||||
#include "src/gmock.cc"
|
|
@ -1,155 +0,0 @@
|
|||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements cardinalities.
|
||||
|
||||
#include "gmock/gmock-cardinalities.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <ostream> // NOLINT
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include "gmock/internal/gmock-internal-utils.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
namespace {
|
||||
|
||||
// Implements the Between(m, n) cardinality.
|
||||
class BetweenCardinalityImpl : public CardinalityInterface {
|
||||
public:
|
||||
BetweenCardinalityImpl(int min, int max)
|
||||
: min_(min >= 0 ? min : 0),
|
||||
max_(max >= min_ ? max : min_) {
|
||||
std::stringstream ss;
|
||||
if (min < 0) {
|
||||
ss << "The invocation lower bound must be >= 0, "
|
||||
<< "but is actually " << min << ".";
|
||||
internal::Expect(false, __FILE__, __LINE__, ss.str());
|
||||
} else if (max < 0) {
|
||||
ss << "The invocation upper bound must be >= 0, "
|
||||
<< "but is actually " << max << ".";
|
||||
internal::Expect(false, __FILE__, __LINE__, ss.str());
|
||||
} else if (min > max) {
|
||||
ss << "The invocation upper bound (" << max
|
||||
<< ") must be >= the invocation lower bound (" << min
|
||||
<< ").";
|
||||
internal::Expect(false, __FILE__, __LINE__, ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
// Conservative estimate on the lower/upper bound of the number of
|
||||
// calls allowed.
|
||||
int ConservativeLowerBound() const override { return min_; }
|
||||
int ConservativeUpperBound() const override { return max_; }
|
||||
|
||||
bool IsSatisfiedByCallCount(int call_count) const override {
|
||||
return min_ <= call_count && call_count <= max_;
|
||||
}
|
||||
|
||||
bool IsSaturatedByCallCount(int call_count) const override {
|
||||
return call_count >= max_;
|
||||
}
|
||||
|
||||
void DescribeTo(::std::ostream* os) const override;
|
||||
|
||||
private:
|
||||
const int min_;
|
||||
const int max_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(BetweenCardinalityImpl);
|
||||
};
|
||||
|
||||
// Formats "n times" in a human-friendly way.
|
||||
inline std::string FormatTimes(int n) {
|
||||
if (n == 1) {
|
||||
return "once";
|
||||
} else if (n == 2) {
|
||||
return "twice";
|
||||
} else {
|
||||
std::stringstream ss;
|
||||
ss << n << " times";
|
||||
return ss.str();
|
||||
}
|
||||
}
|
||||
|
||||
// Describes the Between(m, n) cardinality in human-friendly text.
|
||||
void BetweenCardinalityImpl::DescribeTo(::std::ostream* os) const {
|
||||
if (min_ == 0) {
|
||||
if (max_ == 0) {
|
||||
*os << "never called";
|
||||
} else if (max_ == INT_MAX) {
|
||||
*os << "called any number of times";
|
||||
} else {
|
||||
*os << "called at most " << FormatTimes(max_);
|
||||
}
|
||||
} else if (min_ == max_) {
|
||||
*os << "called " << FormatTimes(min_);
|
||||
} else if (max_ == INT_MAX) {
|
||||
*os << "called at least " << FormatTimes(min_);
|
||||
} else {
|
||||
// 0 < min_ < max_ < INT_MAX
|
||||
*os << "called between " << min_ << " and " << max_ << " times";
|
||||
}
|
||||
}
|
||||
|
||||
} // Unnamed namespace
|
||||
|
||||
// Describes the given call count to an ostream.
|
||||
void Cardinality::DescribeActualCallCountTo(int actual_call_count,
|
||||
::std::ostream* os) {
|
||||
if (actual_call_count > 0) {
|
||||
*os << "called " << FormatTimes(actual_call_count);
|
||||
} else {
|
||||
*os << "never called";
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a cardinality that allows at least n calls.
|
||||
GTEST_API_ Cardinality AtLeast(int n) { return Between(n, INT_MAX); }
|
||||
|
||||
// Creates a cardinality that allows at most n calls.
|
||||
GTEST_API_ Cardinality AtMost(int n) { return Between(0, n); }
|
||||
|
||||
// Creates a cardinality that allows any number of calls.
|
||||
GTEST_API_ Cardinality AnyNumber() { return AtLeast(0); }
|
||||
|
||||
// Creates a cardinality that allows between min and max calls.
|
||||
GTEST_API_ Cardinality Between(int min, int max) {
|
||||
return Cardinality(new BetweenCardinalityImpl(min, max));
|
||||
}
|
||||
|
||||
// Creates a cardinality that allows exactly n calls.
|
||||
GTEST_API_ Cardinality Exactly(int n) { return Between(n, n); }
|
||||
|
||||
} // namespace testing
|
|
@ -1,200 +0,0 @@
|
|||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file defines some utilities useful for implementing Google
|
||||
// Mock. They are subject to change without notice, so please DO NOT
|
||||
// USE THEM IN USER CODE.
|
||||
|
||||
#include "gmock/internal/gmock-internal-utils.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
#include "gmock/gmock.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Joins a vector of strings as if they are fields of a tuple; returns
|
||||
// the joined string.
|
||||
GTEST_API_ std::string JoinAsTuple(const Strings& fields) {
|
||||
switch (fields.size()) {
|
||||
case 0:
|
||||
return "";
|
||||
case 1:
|
||||
return fields[0];
|
||||
default:
|
||||
std::string result = "(" + fields[0];
|
||||
for (size_t i = 1; i < fields.size(); i++) {
|
||||
result += ", ";
|
||||
result += fields[i];
|
||||
}
|
||||
result += ")";
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Converts an identifier name to a space-separated list of lower-case
|
||||
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
|
||||
// treated as one word. For example, both "FooBar123" and
|
||||
// "foo_bar_123" are converted to "foo bar 123".
|
||||
GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name) {
|
||||
std::string result;
|
||||
char prev_char = '\0';
|
||||
for (const char* p = id_name; *p != '\0'; prev_char = *(p++)) {
|
||||
// We don't care about the current locale as the input is
|
||||
// guaranteed to be a valid C++ identifier name.
|
||||
const bool starts_new_word = IsUpper(*p) ||
|
||||
(!IsAlpha(prev_char) && IsLower(*p)) ||
|
||||
(!IsDigit(prev_char) && IsDigit(*p));
|
||||
|
||||
if (IsAlNum(*p)) {
|
||||
if (starts_new_word && result != "")
|
||||
result += ' ';
|
||||
result += ToLower(*p);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// This class reports Google Mock failures as Google Test failures. A
|
||||
// user can define another class in a similar fashion if they intend to
|
||||
// use Google Mock with a testing framework other than Google Test.
|
||||
class GoogleTestFailureReporter : public FailureReporterInterface {
|
||||
public:
|
||||
void ReportFailure(FailureType type, const char* file, int line,
|
||||
const std::string& message) override {
|
||||
AssertHelper(type == kFatal ?
|
||||
TestPartResult::kFatalFailure :
|
||||
TestPartResult::kNonFatalFailure,
|
||||
file,
|
||||
line,
|
||||
message.c_str()) = Message();
|
||||
if (type == kFatal) {
|
||||
posix::Abort();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Returns the global failure reporter. Will create a
|
||||
// GoogleTestFailureReporter and return it the first time called.
|
||||
GTEST_API_ FailureReporterInterface* GetFailureReporter() {
|
||||
// Points to the global failure reporter used by Google Mock. gcc
|
||||
// guarantees that the following use of failure_reporter is
|
||||
// thread-safe. We may need to add additional synchronization to
|
||||
// protect failure_reporter if we port Google Mock to other
|
||||
// compilers.
|
||||
static FailureReporterInterface* const failure_reporter =
|
||||
new GoogleTestFailureReporter();
|
||||
return failure_reporter;
|
||||
}
|
||||
|
||||
// Protects global resources (stdout in particular) used by Log().
|
||||
static GTEST_DEFINE_STATIC_MUTEX_(g_log_mutex);
|
||||
|
||||
// Returns true if and only if a log with the given severity is visible
|
||||
// according to the --gmock_verbose flag.
|
||||
GTEST_API_ bool LogIsVisible(LogSeverity severity) {
|
||||
if (GMOCK_FLAG(verbose) == kInfoVerbosity) {
|
||||
// Always show the log if --gmock_verbose=info.
|
||||
return true;
|
||||
} else if (GMOCK_FLAG(verbose) == kErrorVerbosity) {
|
||||
// Always hide it if --gmock_verbose=error.
|
||||
return false;
|
||||
} else {
|
||||
// If --gmock_verbose is neither "info" nor "error", we treat it
|
||||
// as "warning" (its default value).
|
||||
return severity == kWarning;
|
||||
}
|
||||
}
|
||||
|
||||
// Prints the given message to stdout if and only if 'severity' >= the level
|
||||
// specified by the --gmock_verbose flag. If stack_frames_to_skip >=
|
||||
// 0, also prints the stack trace excluding the top
|
||||
// stack_frames_to_skip frames. In opt mode, any positive
|
||||
// stack_frames_to_skip is treated as 0, since we don't know which
|
||||
// function calls will be inlined by the compiler and need to be
|
||||
// conservative.
|
||||
GTEST_API_ void Log(LogSeverity severity, const std::string& message,
|
||||
int stack_frames_to_skip) {
|
||||
if (!LogIsVisible(severity))
|
||||
return;
|
||||
|
||||
// Ensures that logs from different threads don't interleave.
|
||||
MutexLock l(&g_log_mutex);
|
||||
|
||||
if (severity == kWarning) {
|
||||
// Prints a GMOCK WARNING marker to make the warnings easily searchable.
|
||||
std::cout << "\nGMOCK WARNING:";
|
||||
}
|
||||
// Pre-pends a new-line to message if it doesn't start with one.
|
||||
if (message.empty() || message[0] != '\n') {
|
||||
std::cout << "\n";
|
||||
}
|
||||
std::cout << message;
|
||||
if (stack_frames_to_skip >= 0) {
|
||||
#ifdef NDEBUG
|
||||
// In opt mode, we have to be conservative and skip no stack frame.
|
||||
const int actual_to_skip = 0;
|
||||
#else
|
||||
// In dbg mode, we can do what the caller tell us to do (plus one
|
||||
// for skipping this function's stack frame).
|
||||
const int actual_to_skip = stack_frames_to_skip + 1;
|
||||
#endif // NDEBUG
|
||||
|
||||
// Appends a new-line to message if it doesn't end with one.
|
||||
if (!message.empty() && *message.rbegin() != '\n') {
|
||||
std::cout << "\n";
|
||||
}
|
||||
std::cout << "Stack trace:\n"
|
||||
<< ::testing::internal::GetCurrentOsStackTraceExceptTop(
|
||||
::testing::UnitTest::GetInstance(), actual_to_skip);
|
||||
}
|
||||
std::cout << ::std::flush;
|
||||
}
|
||||
|
||||
GTEST_API_ WithoutMatchers GetWithoutMatchers() { return WithoutMatchers(); }
|
||||
|
||||
GTEST_API_ void IllegalDoDefault(const char* file, int line) {
|
||||
internal::Assert(
|
||||
false, file, line,
|
||||
"You are using DoDefault() inside a composite action like "
|
||||
"DoAll() or WithArgs(). This is not supported for technical "
|
||||
"reasons. Please instead spell out the default action, or "
|
||||
"assign the default action to an Action variable and use "
|
||||
"the variable in various places.");
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
|
@ -1,459 +0,0 @@
|
|||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements Matcher<const string&>, Matcher<string>, and
|
||||
// utilities for defining matchers.
|
||||
|
||||
#include "gmock/gmock-matchers.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Returns the description for a matcher defined using the MATCHER*()
|
||||
// macro where the user-supplied description string is "", if
|
||||
// 'negation' is false; otherwise returns the description of the
|
||||
// negation of the matcher. 'param_values' contains a list of strings
|
||||
// that are the print-out of the matcher's parameters.
|
||||
GTEST_API_ std::string FormatMatcherDescription(bool negation,
|
||||
const char* matcher_name,
|
||||
const Strings& param_values) {
|
||||
std::string result = ConvertIdentifierNameToWords(matcher_name);
|
||||
if (param_values.size() >= 1) result += " " + JoinAsTuple(param_values);
|
||||
return negation ? "not (" + result + ")" : result;
|
||||
}
|
||||
|
||||
// FindMaxBipartiteMatching and its helper class.
|
||||
//
|
||||
// Uses the well-known Ford-Fulkerson max flow method to find a maximum
|
||||
// bipartite matching. Flow is considered to be from left to right.
|
||||
// There is an implicit source node that is connected to all of the left
|
||||
// nodes, and an implicit sink node that is connected to all of the
|
||||
// right nodes. All edges have unit capacity.
|
||||
//
|
||||
// Neither the flow graph nor the residual flow graph are represented
|
||||
// explicitly. Instead, they are implied by the information in 'graph' and
|
||||
// a vector<int> called 'left_' whose elements are initialized to the
|
||||
// value kUnused. This represents the initial state of the algorithm,
|
||||
// where the flow graph is empty, and the residual flow graph has the
|
||||
// following edges:
|
||||
// - An edge from source to each left_ node
|
||||
// - An edge from each right_ node to sink
|
||||
// - An edge from each left_ node to each right_ node, if the
|
||||
// corresponding edge exists in 'graph'.
|
||||
//
|
||||
// When the TryAugment() method adds a flow, it sets left_[l] = r for some
|
||||
// nodes l and r. This induces the following changes:
|
||||
// - The edges (source, l), (l, r), and (r, sink) are added to the
|
||||
// flow graph.
|
||||
// - The same three edges are removed from the residual flow graph.
|
||||
// - The reverse edges (l, source), (r, l), and (sink, r) are added
|
||||
// to the residual flow graph, which is a directional graph
|
||||
// representing unused flow capacity.
|
||||
//
|
||||
// When the method augments a flow (moving left_[l] from some r1 to some
|
||||
// other r2), this can be thought of as "undoing" the above steps with
|
||||
// respect to r1 and "redoing" them with respect to r2.
|
||||
//
|
||||
// It bears repeating that the flow graph and residual flow graph are
|
||||
// never represented explicitly, but can be derived by looking at the
|
||||
// information in 'graph' and in left_.
|
||||
//
|
||||
// As an optimization, there is a second vector<int> called right_ which
|
||||
// does not provide any new information. Instead, it enables more
|
||||
// efficient queries about edges entering or leaving the right-side nodes
|
||||
// of the flow or residual flow graphs. The following invariants are
|
||||
// maintained:
|
||||
//
|
||||
// left[l] == kUnused or right[left[l]] == l
|
||||
// right[r] == kUnused or left[right[r]] == r
|
||||
//
|
||||
// . [ source ] .
|
||||
// . ||| .
|
||||
// . ||| .
|
||||
// . ||\--> left[0]=1 ---\ right[0]=-1 ----\ .
|
||||
// . || | | .
|
||||
// . |\---> left[1]=-1 \--> right[1]=0 ---\| .
|
||||
// . | || .
|
||||
// . \----> left[2]=2 ------> right[2]=2 --\|| .
|
||||
// . ||| .
|
||||
// . elements matchers vvv .
|
||||
// . [ sink ] .
|
||||
//
|
||||
// See Also:
|
||||
// [1] Cormen, et al (2001). "Section 26.2: The Ford-Fulkerson method".
|
||||
// "Introduction to Algorithms (Second ed.)", pp. 651-664.
|
||||
// [2] "Ford-Fulkerson algorithm", Wikipedia,
|
||||
// 'http://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm'
|
||||
class MaxBipartiteMatchState {
|
||||
public:
|
||||
explicit MaxBipartiteMatchState(const MatchMatrix& graph)
|
||||
: graph_(&graph),
|
||||
left_(graph_->LhsSize(), kUnused),
|
||||
right_(graph_->RhsSize(), kUnused) {}
|
||||
|
||||
// Returns the edges of a maximal match, each in the form {left, right}.
|
||||
ElementMatcherPairs Compute() {
|
||||
// 'seen' is used for path finding { 0: unseen, 1: seen }.
|
||||
::std::vector<char> seen;
|
||||
// Searches the residual flow graph for a path from each left node to
|
||||
// the sink in the residual flow graph, and if one is found, add flow
|
||||
// to the graph. It's okay to search through the left nodes once. The
|
||||
// edge from the implicit source node to each previously-visited left
|
||||
// node will have flow if that left node has any path to the sink
|
||||
// whatsoever. Subsequent augmentations can only add flow to the
|
||||
// network, and cannot take away that previous flow unit from the source.
|
||||
// Since the source-to-left edge can only carry one flow unit (or,
|
||||
// each element can be matched to only one matcher), there is no need
|
||||
// to visit the left nodes more than once looking for augmented paths.
|
||||
// The flow is known to be possible or impossible by looking at the
|
||||
// node once.
|
||||
for (size_t ilhs = 0; ilhs < graph_->LhsSize(); ++ilhs) {
|
||||
// Reset the path-marking vector and try to find a path from
|
||||
// source to sink starting at the left_[ilhs] node.
|
||||
GTEST_CHECK_(left_[ilhs] == kUnused)
|
||||
<< "ilhs: " << ilhs << ", left_[ilhs]: " << left_[ilhs];
|
||||
// 'seen' initialized to 'graph_->RhsSize()' copies of 0.
|
||||
seen.assign(graph_->RhsSize(), 0);
|
||||
TryAugment(ilhs, &seen);
|
||||
}
|
||||
ElementMatcherPairs result;
|
||||
for (size_t ilhs = 0; ilhs < left_.size(); ++ilhs) {
|
||||
size_t irhs = left_[ilhs];
|
||||
if (irhs == kUnused) continue;
|
||||
result.push_back(ElementMatcherPair(ilhs, irhs));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
static const size_t kUnused = static_cast<size_t>(-1);
|
||||
|
||||
// Perform a depth-first search from left node ilhs to the sink. If a
|
||||
// path is found, flow is added to the network by linking the left and
|
||||
// right vector elements corresponding each segment of the path.
|
||||
// Returns true if a path to sink was found, which means that a unit of
|
||||
// flow was added to the network. The 'seen' vector elements correspond
|
||||
// to right nodes and are marked to eliminate cycles from the search.
|
||||
//
|
||||
// Left nodes will only be explored at most once because they
|
||||
// are accessible from at most one right node in the residual flow
|
||||
// graph.
|
||||
//
|
||||
// Note that left_[ilhs] is the only element of left_ that TryAugment will
|
||||
// potentially transition from kUnused to another value. Any other
|
||||
// left_ element holding kUnused before TryAugment will be holding it
|
||||
// when TryAugment returns.
|
||||
//
|
||||
bool TryAugment(size_t ilhs, ::std::vector<char>* seen) {
|
||||
for (size_t irhs = 0; irhs < graph_->RhsSize(); ++irhs) {
|
||||
if ((*seen)[irhs]) continue;
|
||||
if (!graph_->HasEdge(ilhs, irhs)) continue;
|
||||
// There's an available edge from ilhs to irhs.
|
||||
(*seen)[irhs] = 1;
|
||||
// Next a search is performed to determine whether
|
||||
// this edge is a dead end or leads to the sink.
|
||||
//
|
||||
// right_[irhs] == kUnused means that there is residual flow from
|
||||
// right node irhs to the sink, so we can use that to finish this
|
||||
// flow path and return success.
|
||||
//
|
||||
// Otherwise there is residual flow to some ilhs. We push flow
|
||||
// along that path and call ourselves recursively to see if this
|
||||
// ultimately leads to sink.
|
||||
if (right_[irhs] == kUnused || TryAugment(right_[irhs], seen)) {
|
||||
// Add flow from left_[ilhs] to right_[irhs].
|
||||
left_[ilhs] = irhs;
|
||||
right_[irhs] = ilhs;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const MatchMatrix* graph_; // not owned
|
||||
// Each element of the left_ vector represents a left hand side node
|
||||
// (i.e. an element) and each element of right_ is a right hand side
|
||||
// node (i.e. a matcher). The values in the left_ vector indicate
|
||||
// outflow from that node to a node on the right_ side. The values
|
||||
// in the right_ indicate inflow, and specify which left_ node is
|
||||
// feeding that right_ node, if any. For example, left_[3] == 1 means
|
||||
// there's a flow from element #3 to matcher #1. Such a flow would also
|
||||
// be redundantly represented in the right_ vector as right_[1] == 3.
|
||||
// Elements of left_ and right_ are either kUnused or mutually
|
||||
// referent. Mutually referent means that left_[right_[i]] = i and
|
||||
// right_[left_[i]] = i.
|
||||
::std::vector<size_t> left_;
|
||||
::std::vector<size_t> right_;
|
||||
};
|
||||
|
||||
const size_t MaxBipartiteMatchState::kUnused;
|
||||
|
||||
GTEST_API_ ElementMatcherPairs FindMaxBipartiteMatching(const MatchMatrix& g) {
|
||||
return MaxBipartiteMatchState(g).Compute();
|
||||
}
|
||||
|
||||
static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs,
|
||||
::std::ostream* stream) {
|
||||
typedef ElementMatcherPairs::const_iterator Iter;
|
||||
::std::ostream& os = *stream;
|
||||
os << "{";
|
||||
const char* sep = "";
|
||||
for (Iter it = pairs.begin(); it != pairs.end(); ++it) {
|
||||
os << sep << "\n ("
|
||||
<< "element #" << it->first << ", "
|
||||
<< "matcher #" << it->second << ")";
|
||||
sep = ",";
|
||||
}
|
||||
os << "\n}";
|
||||
}
|
||||
|
||||
bool MatchMatrix::NextGraph() {
|
||||
for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
|
||||
for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {
|
||||
char& b = matched_[SpaceIndex(ilhs, irhs)];
|
||||
if (!b) {
|
||||
b = 1;
|
||||
return true;
|
||||
}
|
||||
b = 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MatchMatrix::Randomize() {
|
||||
for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
|
||||
for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {
|
||||
char& b = matched_[SpaceIndex(ilhs, irhs)];
|
||||
b = static_cast<char>(rand() & 1); // NOLINT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string MatchMatrix::DebugString() const {
|
||||
::std::stringstream ss;
|
||||
const char* sep = "";
|
||||
for (size_t i = 0; i < LhsSize(); ++i) {
|
||||
ss << sep;
|
||||
for (size_t j = 0; j < RhsSize(); ++j) {
|
||||
ss << HasEdge(i, j);
|
||||
}
|
||||
sep = ";";
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void UnorderedElementsAreMatcherImplBase::DescribeToImpl(
|
||||
::std::ostream* os) const {
|
||||
switch (match_flags()) {
|
||||
case UnorderedMatcherRequire::ExactMatch:
|
||||
if (matcher_describers_.empty()) {
|
||||
*os << "is empty";
|
||||
return;
|
||||
}
|
||||
if (matcher_describers_.size() == 1) {
|
||||
*os << "has " << Elements(1) << " and that element ";
|
||||
matcher_describers_[0]->DescribeTo(os);
|
||||
return;
|
||||
}
|
||||
*os << "has " << Elements(matcher_describers_.size())
|
||||
<< " and there exists some permutation of elements such that:\n";
|
||||
break;
|
||||
case UnorderedMatcherRequire::Superset:
|
||||
*os << "a surjection from elements to requirements exists such that:\n";
|
||||
break;
|
||||
case UnorderedMatcherRequire::Subset:
|
||||
*os << "an injection from elements to requirements exists such that:\n";
|
||||
break;
|
||||
}
|
||||
|
||||
const char* sep = "";
|
||||
for (size_t i = 0; i != matcher_describers_.size(); ++i) {
|
||||
*os << sep;
|
||||
if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
|
||||
*os << " - element #" << i << " ";
|
||||
} else {
|
||||
*os << " - an element ";
|
||||
}
|
||||
matcher_describers_[i]->DescribeTo(os);
|
||||
if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
|
||||
sep = ", and\n";
|
||||
} else {
|
||||
sep = "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(
|
||||
::std::ostream* os) const {
|
||||
switch (match_flags()) {
|
||||
case UnorderedMatcherRequire::ExactMatch:
|
||||
if (matcher_describers_.empty()) {
|
||||
*os << "isn't empty";
|
||||
return;
|
||||
}
|
||||
if (matcher_describers_.size() == 1) {
|
||||
*os << "doesn't have " << Elements(1) << ", or has " << Elements(1)
|
||||
<< " that ";
|
||||
matcher_describers_[0]->DescribeNegationTo(os);
|
||||
return;
|
||||
}
|
||||
*os << "doesn't have " << Elements(matcher_describers_.size())
|
||||
<< ", or there exists no permutation of elements such that:\n";
|
||||
break;
|
||||
case UnorderedMatcherRequire::Superset:
|
||||
*os << "no surjection from elements to requirements exists such that:\n";
|
||||
break;
|
||||
case UnorderedMatcherRequire::Subset:
|
||||
*os << "no injection from elements to requirements exists such that:\n";
|
||||
break;
|
||||
}
|
||||
const char* sep = "";
|
||||
for (size_t i = 0; i != matcher_describers_.size(); ++i) {
|
||||
*os << sep;
|
||||
if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
|
||||
*os << " - element #" << i << " ";
|
||||
} else {
|
||||
*os << " - an element ";
|
||||
}
|
||||
matcher_describers_[i]->DescribeTo(os);
|
||||
if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
|
||||
sep = ", and\n";
|
||||
} else {
|
||||
sep = "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Checks that all matchers match at least one element, and that all
|
||||
// elements match at least one matcher. This enables faster matching
|
||||
// and better error reporting.
|
||||
// Returns false, writing an explanation to 'listener', if and only
|
||||
// if the success criteria are not met.
|
||||
bool UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix(
|
||||
const ::std::vector<std::string>& element_printouts,
|
||||
const MatchMatrix& matrix, MatchResultListener* listener) const {
|
||||
bool result = true;
|
||||
::std::vector<char> element_matched(matrix.LhsSize(), 0);
|
||||
::std::vector<char> matcher_matched(matrix.RhsSize(), 0);
|
||||
|
||||
for (size_t ilhs = 0; ilhs < matrix.LhsSize(); ilhs++) {
|
||||
for (size_t irhs = 0; irhs < matrix.RhsSize(); irhs++) {
|
||||
char matched = matrix.HasEdge(ilhs, irhs);
|
||||
element_matched[ilhs] |= matched;
|
||||
matcher_matched[irhs] |= matched;
|
||||
}
|
||||
}
|
||||
|
||||
if (match_flags() & UnorderedMatcherRequire::Superset) {
|
||||
const char* sep =
|
||||
"where the following matchers don't match any elements:\n";
|
||||
for (size_t mi = 0; mi < matcher_matched.size(); ++mi) {
|
||||
if (matcher_matched[mi]) continue;
|
||||
result = false;
|
||||
if (listener->IsInterested()) {
|
||||
*listener << sep << "matcher #" << mi << ": ";
|
||||
matcher_describers_[mi]->DescribeTo(listener->stream());
|
||||
sep = ",\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (match_flags() & UnorderedMatcherRequire::Subset) {
|
||||
const char* sep =
|
||||
"where the following elements don't match any matchers:\n";
|
||||
const char* outer_sep = "";
|
||||
if (!result) {
|
||||
outer_sep = "\nand ";
|
||||
}
|
||||
for (size_t ei = 0; ei < element_matched.size(); ++ei) {
|
||||
if (element_matched[ei]) continue;
|
||||
result = false;
|
||||
if (listener->IsInterested()) {
|
||||
*listener << outer_sep << sep << "element #" << ei << ": "
|
||||
<< element_printouts[ei];
|
||||
sep = ",\n";
|
||||
outer_sep = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool UnorderedElementsAreMatcherImplBase::FindPairing(
|
||||
const MatchMatrix& matrix, MatchResultListener* listener) const {
|
||||
ElementMatcherPairs matches = FindMaxBipartiteMatching(matrix);
|
||||
|
||||
size_t max_flow = matches.size();
|
||||
if ((match_flags() & UnorderedMatcherRequire::Superset) &&
|
||||
max_flow < matrix.RhsSize()) {
|
||||
if (listener->IsInterested()) {
|
||||
*listener << "where no permutation of the elements can satisfy all "
|
||||
"matchers, and the closest match is "
|
||||
<< max_flow << " of " << matrix.RhsSize()
|
||||
<< " matchers with the pairings:\n";
|
||||
LogElementMatcherPairVec(matches, listener->stream());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if ((match_flags() & UnorderedMatcherRequire::Subset) &&
|
||||
max_flow < matrix.LhsSize()) {
|
||||
if (listener->IsInterested()) {
|
||||
*listener
|
||||
<< "where not all elements can be matched, and the closest match is "
|
||||
<< max_flow << " of " << matrix.RhsSize()
|
||||
<< " matchers with the pairings:\n";
|
||||
LogElementMatcherPairVec(matches, listener->stream());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (matches.size() > 1) {
|
||||
if (listener->IsInterested()) {
|
||||
const char* sep = "where:\n";
|
||||
for (size_t mi = 0; mi < matches.size(); ++mi) {
|
||||
*listener << sep << " - element #" << matches[mi].first
|
||||
<< " is matched by matcher #" << matches[mi].second;
|
||||
sep = ",\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
|
@ -1,908 +0,0 @@
|
|||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements the spec builder syntax (ON_CALL and
|
||||
// EXPECT_CALL).
|
||||
|
||||
#include "gmock/gmock-spec-builders.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <iostream> // NOLINT
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC
|
||||
# include <unistd.h> // NOLINT
|
||||
#endif
|
||||
|
||||
// Silence C4800 (C4800: 'int *const ': forcing value
|
||||
// to bool 'true' or 'false') for MSVC 15
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER == 1900
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4800)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Protects the mock object registry (in class Mock), all function
|
||||
// mockers, and all expectations.
|
||||
GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_gmock_mutex);
|
||||
|
||||
// Logs a message including file and line number information.
|
||||
GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity,
|
||||
const char* file, int line,
|
||||
const std::string& message) {
|
||||
::std::ostringstream s;
|
||||
s << internal::FormatFileLocation(file, line) << " " << message
|
||||
<< ::std::endl;
|
||||
Log(severity, s.str(), 0);
|
||||
}
|
||||
|
||||
// Constructs an ExpectationBase object.
|
||||
ExpectationBase::ExpectationBase(const char* a_file, int a_line,
|
||||
const std::string& a_source_text)
|
||||
: file_(a_file),
|
||||
line_(a_line),
|
||||
source_text_(a_source_text),
|
||||
cardinality_specified_(false),
|
||||
cardinality_(Exactly(1)),
|
||||
call_count_(0),
|
||||
retired_(false),
|
||||
extra_matcher_specified_(false),
|
||||
repeated_action_specified_(false),
|
||||
retires_on_saturation_(false),
|
||||
last_clause_(kNone),
|
||||
action_count_checked_(false) {}
|
||||
|
||||
// Destructs an ExpectationBase object.
|
||||
ExpectationBase::~ExpectationBase() {}
|
||||
|
||||
// Explicitly specifies the cardinality of this expectation. Used by
|
||||
// the subclasses to implement the .Times() clause.
|
||||
void ExpectationBase::SpecifyCardinality(const Cardinality& a_cardinality) {
|
||||
cardinality_specified_ = true;
|
||||
cardinality_ = a_cardinality;
|
||||
}
|
||||
|
||||
// Retires all pre-requisites of this expectation.
|
||||
void ExpectationBase::RetireAllPreRequisites()
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
if (is_retired()) {
|
||||
// We can take this short-cut as we never retire an expectation
|
||||
// until we have retired all its pre-requisites.
|
||||
return;
|
||||
}
|
||||
|
||||
::std::vector<ExpectationBase*> expectations(1, this);
|
||||
while (!expectations.empty()) {
|
||||
ExpectationBase* exp = expectations.back();
|
||||
expectations.pop_back();
|
||||
|
||||
for (ExpectationSet::const_iterator it =
|
||||
exp->immediate_prerequisites_.begin();
|
||||
it != exp->immediate_prerequisites_.end(); ++it) {
|
||||
ExpectationBase* next = it->expectation_base().get();
|
||||
if (!next->is_retired()) {
|
||||
next->Retire();
|
||||
expectations.push_back(next);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if and only if all pre-requisites of this expectation
|
||||
// have been satisfied.
|
||||
bool ExpectationBase::AllPrerequisitesAreSatisfied() const
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
g_gmock_mutex.AssertHeld();
|
||||
::std::vector<const ExpectationBase*> expectations(1, this);
|
||||
while (!expectations.empty()) {
|
||||
const ExpectationBase* exp = expectations.back();
|
||||
expectations.pop_back();
|
||||
|
||||
for (ExpectationSet::const_iterator it =
|
||||
exp->immediate_prerequisites_.begin();
|
||||
it != exp->immediate_prerequisites_.end(); ++it) {
|
||||
const ExpectationBase* next = it->expectation_base().get();
|
||||
if (!next->IsSatisfied()) return false;
|
||||
expectations.push_back(next);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Adds unsatisfied pre-requisites of this expectation to 'result'.
|
||||
void ExpectationBase::FindUnsatisfiedPrerequisites(ExpectationSet* result) const
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
g_gmock_mutex.AssertHeld();
|
||||
::std::vector<const ExpectationBase*> expectations(1, this);
|
||||
while (!expectations.empty()) {
|
||||
const ExpectationBase* exp = expectations.back();
|
||||
expectations.pop_back();
|
||||
|
||||
for (ExpectationSet::const_iterator it =
|
||||
exp->immediate_prerequisites_.begin();
|
||||
it != exp->immediate_prerequisites_.end(); ++it) {
|
||||
const ExpectationBase* next = it->expectation_base().get();
|
||||
|
||||
if (next->IsSatisfied()) {
|
||||
// If *it is satisfied and has a call count of 0, some of its
|
||||
// pre-requisites may not be satisfied yet.
|
||||
if (next->call_count_ == 0) {
|
||||
expectations.push_back(next);
|
||||
}
|
||||
} else {
|
||||
// Now that we know next is unsatisfied, we are not so interested
|
||||
// in whether its pre-requisites are satisfied. Therefore we
|
||||
// don't iterate into it here.
|
||||
*result += *it;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Describes how many times a function call matching this
|
||||
// expectation has occurred.
|
||||
void ExpectationBase::DescribeCallCountTo(::std::ostream* os) const
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
g_gmock_mutex.AssertHeld();
|
||||
|
||||
// Describes how many times the function is expected to be called.
|
||||
*os << " Expected: to be ";
|
||||
cardinality().DescribeTo(os);
|
||||
*os << "\n Actual: ";
|
||||
Cardinality::DescribeActualCallCountTo(call_count(), os);
|
||||
|
||||
// Describes the state of the expectation (e.g. is it satisfied?
|
||||
// is it active?).
|
||||
*os << " - " << (IsOverSaturated() ? "over-saturated" :
|
||||
IsSaturated() ? "saturated" :
|
||||
IsSatisfied() ? "satisfied" : "unsatisfied")
|
||||
<< " and "
|
||||
<< (is_retired() ? "retired" : "active");
|
||||
}
|
||||
|
||||
// Checks the action count (i.e. the number of WillOnce() and
|
||||
// WillRepeatedly() clauses) against the cardinality if this hasn't
|
||||
// been done before. Prints a warning if there are too many or too
|
||||
// few actions.
|
||||
void ExpectationBase::CheckActionCountIfNotDone() const
|
||||
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||
bool should_check = false;
|
||||
{
|
||||
MutexLock l(&mutex_);
|
||||
if (!action_count_checked_) {
|
||||
action_count_checked_ = true;
|
||||
should_check = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (should_check) {
|
||||
if (!cardinality_specified_) {
|
||||
// The cardinality was inferred - no need to check the action
|
||||
// count against it.
|
||||
return;
|
||||
}
|
||||
|
||||
// The cardinality was explicitly specified.
|
||||
const int action_count = static_cast<int>(untyped_actions_.size());
|
||||
const int upper_bound = cardinality().ConservativeUpperBound();
|
||||
const int lower_bound = cardinality().ConservativeLowerBound();
|
||||
bool too_many; // True if there are too many actions, or false
|
||||
// if there are too few.
|
||||
if (action_count > upper_bound ||
|
||||
(action_count == upper_bound && repeated_action_specified_)) {
|
||||
too_many = true;
|
||||
} else if (0 < action_count && action_count < lower_bound &&
|
||||
!repeated_action_specified_) {
|
||||
too_many = false;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
::std::stringstream ss;
|
||||
DescribeLocationTo(&ss);
|
||||
ss << "Too " << (too_many ? "many" : "few")
|
||||
<< " actions specified in " << source_text() << "...\n"
|
||||
<< "Expected to be ";
|
||||
cardinality().DescribeTo(&ss);
|
||||
ss << ", but has " << (too_many ? "" : "only ")
|
||||
<< action_count << " WillOnce()"
|
||||
<< (action_count == 1 ? "" : "s");
|
||||
if (repeated_action_specified_) {
|
||||
ss << " and a WillRepeatedly()";
|
||||
}
|
||||
ss << ".";
|
||||
Log(kWarning, ss.str(), -1); // -1 means "don't print stack trace".
|
||||
}
|
||||
}
|
||||
|
||||
// Implements the .Times() clause.
|
||||
void ExpectationBase::UntypedTimes(const Cardinality& a_cardinality) {
|
||||
if (last_clause_ == kTimes) {
|
||||
ExpectSpecProperty(false,
|
||||
".Times() cannot appear "
|
||||
"more than once in an EXPECT_CALL().");
|
||||
} else {
|
||||
ExpectSpecProperty(last_clause_ < kTimes,
|
||||
".Times() cannot appear after "
|
||||
".InSequence(), .WillOnce(), .WillRepeatedly(), "
|
||||
"or .RetiresOnSaturation().");
|
||||
}
|
||||
last_clause_ = kTimes;
|
||||
|
||||
SpecifyCardinality(a_cardinality);
|
||||
}
|
||||
|
||||
// Points to the implicit sequence introduced by a living InSequence
|
||||
// object (if any) in the current thread or NULL.
|
||||
GTEST_API_ ThreadLocal<Sequence*> g_gmock_implicit_sequence;
|
||||
|
||||
// Reports an uninteresting call (whose description is in msg) in the
|
||||
// manner specified by 'reaction'.
|
||||
void ReportUninterestingCall(CallReaction reaction, const std::string& msg) {
|
||||
// Include a stack trace only if --gmock_verbose=info is specified.
|
||||
const int stack_frames_to_skip =
|
||||
GMOCK_FLAG(verbose) == kInfoVerbosity ? 3 : -1;
|
||||
switch (reaction) {
|
||||
case kAllow:
|
||||
Log(kInfo, msg, stack_frames_to_skip);
|
||||
break;
|
||||
case kWarn:
|
||||
Log(kWarning,
|
||||
msg +
|
||||
"\nNOTE: You can safely ignore the above warning unless this "
|
||||
"call should not happen. Do not suppress it by blindly adding "
|
||||
"an EXPECT_CALL() if you don't mean to enforce the call. "
|
||||
"See "
|
||||
"https://github.com/google/googletest/blob/master/docs/"
|
||||
"gmock_cook_book.md#"
|
||||
"knowing-when-to-expect for details.\n",
|
||||
stack_frames_to_skip);
|
||||
break;
|
||||
default: // FAIL
|
||||
Expect(false, nullptr, -1, msg);
|
||||
}
|
||||
}
|
||||
|
||||
UntypedFunctionMockerBase::UntypedFunctionMockerBase()
|
||||
: mock_obj_(nullptr), name_("") {}
|
||||
|
||||
UntypedFunctionMockerBase::~UntypedFunctionMockerBase() {}
|
||||
|
||||
// Sets the mock object this mock method belongs to, and registers
|
||||
// this information in the global mock registry. Will be called
|
||||
// whenever an EXPECT_CALL() or ON_CALL() is executed on this mock
|
||||
// method.
|
||||
void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
{
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
mock_obj_ = mock_obj;
|
||||
}
|
||||
Mock::Register(mock_obj, this);
|
||||
}
|
||||
|
||||
// Sets the mock object this mock method belongs to, and sets the name
|
||||
// of the mock function. Will be called upon each invocation of this
|
||||
// mock function.
|
||||
void UntypedFunctionMockerBase::SetOwnerAndName(const void* mock_obj,
|
||||
const char* name)
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
// We protect name_ under g_gmock_mutex in case this mock function
|
||||
// is called from two threads concurrently.
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
mock_obj_ = mock_obj;
|
||||
name_ = name;
|
||||
}
|
||||
|
||||
// Returns the name of the function being mocked. Must be called
|
||||
// after RegisterOwner() or SetOwnerAndName() has been called.
|
||||
const void* UntypedFunctionMockerBase::MockObject() const
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
const void* mock_obj;
|
||||
{
|
||||
// We protect mock_obj_ under g_gmock_mutex in case this mock
|
||||
// function is called from two threads concurrently.
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
Assert(mock_obj_ != nullptr, __FILE__, __LINE__,
|
||||
"MockObject() must not be called before RegisterOwner() or "
|
||||
"SetOwnerAndName() has been called.");
|
||||
mock_obj = mock_obj_;
|
||||
}
|
||||
return mock_obj;
|
||||
}
|
||||
|
||||
// Returns the name of this mock method. Must be called after
|
||||
// SetOwnerAndName() has been called.
|
||||
const char* UntypedFunctionMockerBase::Name() const
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
const char* name;
|
||||
{
|
||||
// We protect name_ under g_gmock_mutex in case this mock
|
||||
// function is called from two threads concurrently.
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
Assert(name_ != nullptr, __FILE__, __LINE__,
|
||||
"Name() must not be called before SetOwnerAndName() has "
|
||||
"been called.");
|
||||
name = name_;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
// Calculates the result of invoking this mock function with the given
|
||||
// arguments, prints it, and returns it. The caller is responsible
|
||||
// for deleting the result.
|
||||
UntypedActionResultHolderBase* UntypedFunctionMockerBase::UntypedInvokeWith(
|
||||
void* const untyped_args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
// See the definition of untyped_expectations_ for why access to it
|
||||
// is unprotected here.
|
||||
if (untyped_expectations_.size() == 0) {
|
||||
// No expectation is set on this mock method - we have an
|
||||
// uninteresting call.
|
||||
|
||||
// We must get Google Mock's reaction on uninteresting calls
|
||||
// made on this mock object BEFORE performing the action,
|
||||
// because the action may DELETE the mock object and make the
|
||||
// following expression meaningless.
|
||||
const CallReaction reaction =
|
||||
Mock::GetReactionOnUninterestingCalls(MockObject());
|
||||
|
||||
// True if and only if we need to print this call's arguments and return
|
||||
// value. This definition must be kept in sync with
|
||||
// the behavior of ReportUninterestingCall().
|
||||
const bool need_to_report_uninteresting_call =
|
||||
// If the user allows this uninteresting call, we print it
|
||||
// only when they want informational messages.
|
||||
reaction == kAllow ? LogIsVisible(kInfo) :
|
||||
// If the user wants this to be a warning, we print
|
||||
// it only when they want to see warnings.
|
||||
reaction == kWarn
|
||||
? LogIsVisible(kWarning)
|
||||
:
|
||||
// Otherwise, the user wants this to be an error, and we
|
||||
// should always print detailed information in the error.
|
||||
true;
|
||||
|
||||
if (!need_to_report_uninteresting_call) {
|
||||
// Perform the action without printing the call information.
|
||||
return this->UntypedPerformDefaultAction(
|
||||
untyped_args, "Function call: " + std::string(Name()));
|
||||
}
|
||||
|
||||
// Warns about the uninteresting call.
|
||||
::std::stringstream ss;
|
||||
this->UntypedDescribeUninterestingCall(untyped_args, &ss);
|
||||
|
||||
// Calculates the function result.
|
||||
UntypedActionResultHolderBase* const result =
|
||||
this->UntypedPerformDefaultAction(untyped_args, ss.str());
|
||||
|
||||
// Prints the function result.
|
||||
if (result != nullptr) result->PrintAsActionResult(&ss);
|
||||
|
||||
ReportUninterestingCall(reaction, ss.str());
|
||||
return result;
|
||||
}
|
||||
|
||||
bool is_excessive = false;
|
||||
::std::stringstream ss;
|
||||
::std::stringstream why;
|
||||
::std::stringstream loc;
|
||||
const void* untyped_action = nullptr;
|
||||
|
||||
// The UntypedFindMatchingExpectation() function acquires and
|
||||
// releases g_gmock_mutex.
|
||||
|
||||
const ExpectationBase* const untyped_expectation =
|
||||
this->UntypedFindMatchingExpectation(untyped_args, &untyped_action,
|
||||
&is_excessive, &ss, &why);
|
||||
const bool found = untyped_expectation != nullptr;
|
||||
|
||||
// True if and only if we need to print the call's arguments
|
||||
// and return value.
|
||||
// This definition must be kept in sync with the uses of Expect()
|
||||
// and Log() in this function.
|
||||
const bool need_to_report_call =
|
||||
!found || is_excessive || LogIsVisible(kInfo);
|
||||
if (!need_to_report_call) {
|
||||
// Perform the action without printing the call information.
|
||||
return untyped_action == nullptr
|
||||
? this->UntypedPerformDefaultAction(untyped_args, "")
|
||||
: this->UntypedPerformAction(untyped_action, untyped_args);
|
||||
}
|
||||
|
||||
ss << " Function call: " << Name();
|
||||
this->UntypedPrintArgs(untyped_args, &ss);
|
||||
|
||||
// In case the action deletes a piece of the expectation, we
|
||||
// generate the message beforehand.
|
||||
if (found && !is_excessive) {
|
||||
untyped_expectation->DescribeLocationTo(&loc);
|
||||
}
|
||||
|
||||
UntypedActionResultHolderBase* result = nullptr;
|
||||
|
||||
auto perform_action = [&] {
|
||||
return untyped_action == nullptr
|
||||
? this->UntypedPerformDefaultAction(untyped_args, ss.str())
|
||||
: this->UntypedPerformAction(untyped_action, untyped_args);
|
||||
};
|
||||
auto handle_failures = [&] {
|
||||
ss << "\n" << why.str();
|
||||
|
||||
if (!found) {
|
||||
// No expectation matches this call - reports a failure.
|
||||
Expect(false, nullptr, -1, ss.str());
|
||||
} else if (is_excessive) {
|
||||
// We had an upper-bound violation and the failure message is in ss.
|
||||
Expect(false, untyped_expectation->file(), untyped_expectation->line(),
|
||||
ss.str());
|
||||
} else {
|
||||
// We had an expected call and the matching expectation is
|
||||
// described in ss.
|
||||
Log(kInfo, loc.str() + ss.str(), 2);
|
||||
}
|
||||
};
|
||||
#if GTEST_HAS_EXCEPTIONS
|
||||
try {
|
||||
result = perform_action();
|
||||
} catch (...) {
|
||||
handle_failures();
|
||||
throw;
|
||||
}
|
||||
#else
|
||||
result = perform_action();
|
||||
#endif
|
||||
|
||||
if (result != nullptr) result->PrintAsActionResult(&ss);
|
||||
handle_failures();
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns an Expectation object that references and co-owns exp,
|
||||
// which must be an expectation on this mock function.
|
||||
Expectation UntypedFunctionMockerBase::GetHandleOf(ExpectationBase* exp) {
|
||||
// See the definition of untyped_expectations_ for why access to it
|
||||
// is unprotected here.
|
||||
for (UntypedExpectations::const_iterator it =
|
||||
untyped_expectations_.begin();
|
||||
it != untyped_expectations_.end(); ++it) {
|
||||
if (it->get() == exp) {
|
||||
return Expectation(*it);
|
||||
}
|
||||
}
|
||||
|
||||
Assert(false, __FILE__, __LINE__, "Cannot find expectation.");
|
||||
return Expectation();
|
||||
// The above statement is just to make the code compile, and will
|
||||
// never be executed.
|
||||
}
|
||||
|
||||
// Verifies that all expectations on this mock function have been
|
||||
// satisfied. Reports one or more Google Test non-fatal failures
|
||||
// and returns false if not.
|
||||
bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
g_gmock_mutex.AssertHeld();
|
||||
bool expectations_met = true;
|
||||
for (UntypedExpectations::const_iterator it =
|
||||
untyped_expectations_.begin();
|
||||
it != untyped_expectations_.end(); ++it) {
|
||||
ExpectationBase* const untyped_expectation = it->get();
|
||||
if (untyped_expectation->IsOverSaturated()) {
|
||||
// There was an upper-bound violation. Since the error was
|
||||
// already reported when it occurred, there is no need to do
|
||||
// anything here.
|
||||
expectations_met = false;
|
||||
} else if (!untyped_expectation->IsSatisfied()) {
|
||||
expectations_met = false;
|
||||
::std::stringstream ss;
|
||||
ss << "Actual function call count doesn't match "
|
||||
<< untyped_expectation->source_text() << "...\n";
|
||||
// No need to show the source file location of the expectation
|
||||
// in the description, as the Expect() call that follows already
|
||||
// takes care of it.
|
||||
untyped_expectation->MaybeDescribeExtraMatcherTo(&ss);
|
||||
untyped_expectation->DescribeCallCountTo(&ss);
|
||||
Expect(false, untyped_expectation->file(),
|
||||
untyped_expectation->line(), ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
// Deleting our expectations may trigger other mock objects to be deleted, for
|
||||
// example if an action contains a reference counted smart pointer to that
|
||||
// mock object, and that is the last reference. So if we delete our
|
||||
// expectations within the context of the global mutex we may deadlock when
|
||||
// this method is called again. Instead, make a copy of the set of
|
||||
// expectations to delete, clear our set within the mutex, and then clear the
|
||||
// copied set outside of it.
|
||||
UntypedExpectations expectations_to_delete;
|
||||
untyped_expectations_.swap(expectations_to_delete);
|
||||
|
||||
g_gmock_mutex.Unlock();
|
||||
expectations_to_delete.clear();
|
||||
g_gmock_mutex.Lock();
|
||||
|
||||
return expectations_met;
|
||||
}
|
||||
|
||||
CallReaction intToCallReaction(int mock_behavior) {
|
||||
if (mock_behavior >= kAllow && mock_behavior <= kFail) {
|
||||
return static_cast<internal::CallReaction>(mock_behavior);
|
||||
}
|
||||
return kWarn;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Class Mock.
|
||||
|
||||
namespace {
|
||||
|
||||
typedef std::set<internal::UntypedFunctionMockerBase*> FunctionMockers;
|
||||
|
||||
// The current state of a mock object. Such information is needed for
|
||||
// detecting leaked mock objects and explicitly verifying a mock's
|
||||
// expectations.
|
||||
struct MockObjectState {
|
||||
MockObjectState()
|
||||
: first_used_file(nullptr), first_used_line(-1), leakable(false) {}
|
||||
|
||||
// Where in the source file an ON_CALL or EXPECT_CALL is first
|
||||
// invoked on this mock object.
|
||||
const char* first_used_file;
|
||||
int first_used_line;
|
||||
::std::string first_used_test_suite;
|
||||
::std::string first_used_test;
|
||||
bool leakable; // true if and only if it's OK to leak the object.
|
||||
FunctionMockers function_mockers; // All registered methods of the object.
|
||||
};
|
||||
|
||||
// A global registry holding the state of all mock objects that are
|
||||
// alive. A mock object is added to this registry the first time
|
||||
// Mock::AllowLeak(), ON_CALL(), or EXPECT_CALL() is called on it. It
|
||||
// is removed from the registry in the mock object's destructor.
|
||||
class MockObjectRegistry {
|
||||
public:
|
||||
// Maps a mock object (identified by its address) to its state.
|
||||
typedef std::map<const void*, MockObjectState> StateMap;
|
||||
|
||||
// This destructor will be called when a program exits, after all
|
||||
// tests in it have been run. By then, there should be no mock
|
||||
// object alive. Therefore we report any living object as test
|
||||
// failure, unless the user explicitly asked us to ignore it.
|
||||
~MockObjectRegistry() {
|
||||
if (!GMOCK_FLAG(catch_leaked_mocks))
|
||||
return;
|
||||
|
||||
int leaked_count = 0;
|
||||
for (StateMap::const_iterator it = states_.begin(); it != states_.end();
|
||||
++it) {
|
||||
if (it->second.leakable) // The user said it's fine to leak this object.
|
||||
continue;
|
||||
|
||||
// FIXME: Print the type of the leaked object.
|
||||
// This can help the user identify the leaked object.
|
||||
std::cout << "\n";
|
||||
const MockObjectState& state = it->second;
|
||||
std::cout << internal::FormatFileLocation(state.first_used_file,
|
||||
state.first_used_line);
|
||||
std::cout << " ERROR: this mock object";
|
||||
if (state.first_used_test != "") {
|
||||
std::cout << " (used in test " << state.first_used_test_suite << "."
|
||||
<< state.first_used_test << ")";
|
||||
}
|
||||
std::cout << " should be deleted but never is. Its address is @"
|
||||
<< it->first << ".";
|
||||
leaked_count++;
|
||||
}
|
||||
if (leaked_count > 0) {
|
||||
std::cout << "\nERROR: " << leaked_count << " leaked mock "
|
||||
<< (leaked_count == 1 ? "object" : "objects")
|
||||
<< " found at program exit. Expectations on a mock object are "
|
||||
"verified when the object is destructed. Leaking a mock "
|
||||
"means that its expectations aren't verified, which is "
|
||||
"usually a test bug. If you really intend to leak a mock, "
|
||||
"you can suppress this error using "
|
||||
"testing::Mock::AllowLeak(mock_object), or you may use a "
|
||||
"fake or stub instead of a mock.\n";
|
||||
std::cout.flush();
|
||||
::std::cerr.flush();
|
||||
// RUN_ALL_TESTS() has already returned when this destructor is
|
||||
// called. Therefore we cannot use the normal Google Test
|
||||
// failure reporting mechanism.
|
||||
_exit(1); // We cannot call exit() as it is not reentrant and
|
||||
// may already have been called.
|
||||
}
|
||||
}
|
||||
|
||||
StateMap& states() { return states_; }
|
||||
|
||||
private:
|
||||
StateMap states_;
|
||||
};
|
||||
|
||||
// Protected by g_gmock_mutex.
|
||||
MockObjectRegistry g_mock_object_registry;
|
||||
|
||||
// Maps a mock object to the reaction Google Mock should have when an
|
||||
// uninteresting method is called. Protected by g_gmock_mutex.
|
||||
std::map<const void*, internal::CallReaction> g_uninteresting_call_reaction;
|
||||
|
||||
// Sets the reaction Google Mock should have when an uninteresting
|
||||
// method of the given mock object is called.
|
||||
void SetReactionOnUninterestingCalls(const void* mock_obj,
|
||||
internal::CallReaction reaction)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
g_uninteresting_call_reaction[mock_obj] = reaction;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Tells Google Mock to allow uninteresting calls on the given mock
|
||||
// object.
|
||||
void Mock::AllowUninterestingCalls(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
SetReactionOnUninterestingCalls(mock_obj, internal::kAllow);
|
||||
}
|
||||
|
||||
// Tells Google Mock to warn the user about uninteresting calls on the
|
||||
// given mock object.
|
||||
void Mock::WarnUninterestingCalls(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
SetReactionOnUninterestingCalls(mock_obj, internal::kWarn);
|
||||
}
|
||||
|
||||
// Tells Google Mock to fail uninteresting calls on the given mock
|
||||
// object.
|
||||
void Mock::FailUninterestingCalls(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
SetReactionOnUninterestingCalls(mock_obj, internal::kFail);
|
||||
}
|
||||
|
||||
// Tells Google Mock the given mock object is being destroyed and its
|
||||
// entry in the call-reaction table should be removed.
|
||||
void Mock::UnregisterCallReaction(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
g_uninteresting_call_reaction.erase(mock_obj);
|
||||
}
|
||||
|
||||
// Returns the reaction Google Mock will have on uninteresting calls
|
||||
// made on the given mock object.
|
||||
internal::CallReaction Mock::GetReactionOnUninterestingCalls(
|
||||
const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
return (g_uninteresting_call_reaction.count(mock_obj) == 0) ?
|
||||
internal::intToCallReaction(GMOCK_FLAG(default_mock_behavior)) :
|
||||
g_uninteresting_call_reaction[mock_obj];
|
||||
}
|
||||
|
||||
// Tells Google Mock to ignore mock_obj when checking for leaked mock
|
||||
// objects.
|
||||
void Mock::AllowLeak(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
g_mock_object_registry.states()[mock_obj].leakable = true;
|
||||
}
|
||||
|
||||
// Verifies and clears all expectations on the given mock object. If
|
||||
// the expectations aren't satisfied, generates one or more Google
|
||||
// Test non-fatal failures and returns false.
|
||||
bool Mock::VerifyAndClearExpectations(void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
return VerifyAndClearExpectationsLocked(mock_obj);
|
||||
}
|
||||
|
||||
// Verifies all expectations on the given mock object and clears its
|
||||
// default actions and expectations. Returns true if and only if the
|
||||
// verification was successful.
|
||||
bool Mock::VerifyAndClear(void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
ClearDefaultActionsLocked(mock_obj);
|
||||
return VerifyAndClearExpectationsLocked(mock_obj);
|
||||
}
|
||||
|
||||
// Verifies and clears all expectations on the given mock object. If
|
||||
// the expectations aren't satisfied, generates one or more Google
|
||||
// Test non-fatal failures and returns false.
|
||||
bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj)
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
|
||||
internal::g_gmock_mutex.AssertHeld();
|
||||
if (g_mock_object_registry.states().count(mock_obj) == 0) {
|
||||
// No EXPECT_CALL() was set on the given mock object.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Verifies and clears the expectations on each mock method in the
|
||||
// given mock object.
|
||||
bool expectations_met = true;
|
||||
FunctionMockers& mockers =
|
||||
g_mock_object_registry.states()[mock_obj].function_mockers;
|
||||
for (FunctionMockers::const_iterator it = mockers.begin();
|
||||
it != mockers.end(); ++it) {
|
||||
if (!(*it)->VerifyAndClearExpectationsLocked()) {
|
||||
expectations_met = false;
|
||||
}
|
||||
}
|
||||
|
||||
// We don't clear the content of mockers, as they may still be
|
||||
// needed by ClearDefaultActionsLocked().
|
||||
return expectations_met;
|
||||
}
|
||||
|
||||
bool Mock::IsNaggy(void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kWarn;
|
||||
}
|
||||
bool Mock::IsNice(void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kAllow;
|
||||
}
|
||||
bool Mock::IsStrict(void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kFail;
|
||||
}
|
||||
|
||||
// Registers a mock object and a mock method it owns.
|
||||
void Mock::Register(const void* mock_obj,
|
||||
internal::UntypedFunctionMockerBase* mocker)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker);
|
||||
}
|
||||
|
||||
// Tells Google Mock where in the source code mock_obj is used in an
|
||||
// ON_CALL or EXPECT_CALL. In case mock_obj is leaked, this
|
||||
// information helps the user identify which object it is.
|
||||
void Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj,
|
||||
const char* file, int line)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
MockObjectState& state = g_mock_object_registry.states()[mock_obj];
|
||||
if (state.first_used_file == nullptr) {
|
||||
state.first_used_file = file;
|
||||
state.first_used_line = line;
|
||||
const TestInfo* const test_info =
|
||||
UnitTest::GetInstance()->current_test_info();
|
||||
if (test_info != nullptr) {
|
||||
state.first_used_test_suite = test_info->test_suite_name();
|
||||
state.first_used_test = test_info->name();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Unregisters a mock method; removes the owning mock object from the
|
||||
// registry when the last mock method associated with it has been
|
||||
// unregistered. This is called only in the destructor of
|
||||
// FunctionMockerBase.
|
||||
void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker)
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
|
||||
internal::g_gmock_mutex.AssertHeld();
|
||||
for (MockObjectRegistry::StateMap::iterator it =
|
||||
g_mock_object_registry.states().begin();
|
||||
it != g_mock_object_registry.states().end(); ++it) {
|
||||
FunctionMockers& mockers = it->second.function_mockers;
|
||||
if (mockers.erase(mocker) > 0) {
|
||||
// mocker was in mockers and has been just removed.
|
||||
if (mockers.empty()) {
|
||||
g_mock_object_registry.states().erase(it);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clears all ON_CALL()s set on the given mock object.
|
||||
void Mock::ClearDefaultActionsLocked(void* mock_obj)
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
|
||||
internal::g_gmock_mutex.AssertHeld();
|
||||
|
||||
if (g_mock_object_registry.states().count(mock_obj) == 0) {
|
||||
// No ON_CALL() was set on the given mock object.
|
||||
return;
|
||||
}
|
||||
|
||||
// Clears the default actions for each mock method in the given mock
|
||||
// object.
|
||||
FunctionMockers& mockers =
|
||||
g_mock_object_registry.states()[mock_obj].function_mockers;
|
||||
for (FunctionMockers::const_iterator it = mockers.begin();
|
||||
it != mockers.end(); ++it) {
|
||||
(*it)->ClearDefaultActionsLocked();
|
||||
}
|
||||
|
||||
// We don't clear the content of mockers, as they may still be
|
||||
// needed by VerifyAndClearExpectationsLocked().
|
||||
}
|
||||
|
||||
Expectation::Expectation() {}
|
||||
|
||||
Expectation::Expectation(
|
||||
const std::shared_ptr<internal::ExpectationBase>& an_expectation_base)
|
||||
: expectation_base_(an_expectation_base) {}
|
||||
|
||||
Expectation::~Expectation() {}
|
||||
|
||||
// Adds an expectation to a sequence.
|
||||
void Sequence::AddExpectation(const Expectation& expectation) const {
|
||||
if (*last_expectation_ != expectation) {
|
||||
if (last_expectation_->expectation_base() != nullptr) {
|
||||
expectation.expectation_base()->immediate_prerequisites_
|
||||
+= *last_expectation_;
|
||||
}
|
||||
*last_expectation_ = expectation;
|
||||
}
|
||||
}
|
||||
|
||||
// Creates the implicit sequence if there isn't one.
|
||||
InSequence::InSequence() {
|
||||
if (internal::g_gmock_implicit_sequence.get() == nullptr) {
|
||||
internal::g_gmock_implicit_sequence.set(new Sequence);
|
||||
sequence_created_ = true;
|
||||
} else {
|
||||
sequence_created_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Deletes the implicit sequence if it was created by the constructor
|
||||
// of this object.
|
||||
InSequence::~InSequence() {
|
||||
if (sequence_created_) {
|
||||
delete internal::g_gmock_implicit_sequence.get();
|
||||
internal::g_gmock_implicit_sequence.set(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER == 1900
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
#endif
|
|
@ -1,213 +0,0 @@
|
|||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
GMOCK_DEFINE_bool_(catch_leaked_mocks, true,
|
||||
"true if and only if Google Mock should report leaked "
|
||||
"mock objects as failures.");
|
||||
|
||||
GMOCK_DEFINE_string_(verbose, internal::kWarningVerbosity,
|
||||
"Controls how verbose Google Mock's output is."
|
||||
" Valid values:\n"
|
||||
" info - prints all messages.\n"
|
||||
" warning - prints warnings and errors.\n"
|
||||
" error - prints errors only.");
|
||||
|
||||
GMOCK_DEFINE_int32_(default_mock_behavior, 1,
|
||||
"Controls the default behavior of mocks."
|
||||
" Valid values:\n"
|
||||
" 0 - by default, mocks act as NiceMocks.\n"
|
||||
" 1 - by default, mocks act as NaggyMocks.\n"
|
||||
" 2 - by default, mocks act as StrictMocks.");
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Parses a string as a command line flag. The string should have the
|
||||
// format "--gmock_flag=value". When def_optional is true, the
|
||||
// "=value" part can be omitted.
|
||||
//
|
||||
// Returns the value of the flag, or NULL if the parsing failed.
|
||||
static const char* ParseGoogleMockFlagValue(const char* str,
|
||||
const char* flag,
|
||||
bool def_optional) {
|
||||
// str and flag must not be NULL.
|
||||
if (str == nullptr || flag == nullptr) return nullptr;
|
||||
|
||||
// The flag must start with "--gmock_".
|
||||
const std::string flag_str = std::string("--gmock_") + flag;
|
||||
const size_t flag_len = flag_str.length();
|
||||
if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr;
|
||||
|
||||
// Skips the flag name.
|
||||
const char* flag_end = str + flag_len;
|
||||
|
||||
// When def_optional is true, it's OK to not have a "=value" part.
|
||||
if (def_optional && (flag_end[0] == '\0')) {
|
||||
return flag_end;
|
||||
}
|
||||
|
||||
// If def_optional is true and there are more characters after the
|
||||
// flag name, or if def_optional is false, there must be a '=' after
|
||||
// the flag name.
|
||||
if (flag_end[0] != '=') return nullptr;
|
||||
|
||||
// Returns the string after "=".
|
||||
return flag_end + 1;
|
||||
}
|
||||
|
||||
// Parses a string for a Google Mock bool flag, in the form of
|
||||
// "--gmock_flag=value".
|
||||
//
|
||||
// On success, stores the value of the flag in *value, and returns
|
||||
// true. On failure, returns false without changing *value.
|
||||
static bool ParseGoogleMockBoolFlag(const char* str, const char* flag,
|
||||
bool* value) {
|
||||
// Gets the value of the flag as a string.
|
||||
const char* const value_str = ParseGoogleMockFlagValue(str, flag, true);
|
||||
|
||||
// Aborts if the parsing failed.
|
||||
if (value_str == nullptr) return false;
|
||||
|
||||
// Converts the string value to a bool.
|
||||
*value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');
|
||||
return true;
|
||||
}
|
||||
|
||||
// Parses a string for a Google Mock string flag, in the form of
|
||||
// "--gmock_flag=value".
|
||||
//
|
||||
// On success, stores the value of the flag in *value, and returns
|
||||
// true. On failure, returns false without changing *value.
|
||||
template <typename String>
|
||||
static bool ParseGoogleMockStringFlag(const char* str, const char* flag,
|
||||
String* value) {
|
||||
// Gets the value of the flag as a string.
|
||||
const char* const value_str = ParseGoogleMockFlagValue(str, flag, false);
|
||||
|
||||
// Aborts if the parsing failed.
|
||||
if (value_str == nullptr) return false;
|
||||
|
||||
// Sets *value to the value of the flag.
|
||||
*value = value_str;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ParseGoogleMockIntFlag(const char* str, const char* flag,
|
||||
int32_t* value) {
|
||||
// Gets the value of the flag as a string.
|
||||
const char* const value_str = ParseGoogleMockFlagValue(str, flag, true);
|
||||
|
||||
// Aborts if the parsing failed.
|
||||
if (value_str == nullptr) return false;
|
||||
|
||||
// Sets *value to the value of the flag.
|
||||
return ParseInt32(Message() << "The value of flag --" << flag,
|
||||
value_str, value);
|
||||
}
|
||||
|
||||
// The internal implementation of InitGoogleMock().
|
||||
//
|
||||
// The type parameter CharType can be instantiated to either char or
|
||||
// wchar_t.
|
||||
template <typename CharType>
|
||||
void InitGoogleMockImpl(int* argc, CharType** argv) {
|
||||
// Makes sure Google Test is initialized. InitGoogleTest() is
|
||||
// idempotent, so it's fine if the user has already called it.
|
||||
InitGoogleTest(argc, argv);
|
||||
if (*argc <= 0) return;
|
||||
|
||||
for (int i = 1; i != *argc; i++) {
|
||||
const std::string arg_string = StreamableToString(argv[i]);
|
||||
const char* const arg = arg_string.c_str();
|
||||
|
||||
// Do we see a Google Mock flag?
|
||||
if (ParseGoogleMockBoolFlag(arg, "catch_leaked_mocks",
|
||||
&GMOCK_FLAG(catch_leaked_mocks)) ||
|
||||
ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose)) ||
|
||||
ParseGoogleMockIntFlag(arg, "default_mock_behavior",
|
||||
&GMOCK_FLAG(default_mock_behavior))) {
|
||||
// Yes. Shift the remainder of the argv list left by one. Note
|
||||
// that argv has (*argc + 1) elements, the last one always being
|
||||
// NULL. The following loop moves the trailing NULL element as
|
||||
// well.
|
||||
for (int j = i; j != *argc; j++) {
|
||||
argv[j] = argv[j + 1];
|
||||
}
|
||||
|
||||
// Decrements the argument count.
|
||||
(*argc)--;
|
||||
|
||||
// We also need to decrement the iterator as we just removed
|
||||
// an element.
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Initializes Google Mock. This must be called before running the
|
||||
// tests. In particular, it parses a command line for the flags that
|
||||
// Google Mock recognizes. Whenever a Google Mock flag is seen, it is
|
||||
// removed from argv, and *argc is decremented.
|
||||
//
|
||||
// No value is returned. Instead, the Google Mock flag variables are
|
||||
// updated.
|
||||
//
|
||||
// Since Google Test is needed for Google Mock to work, this function
|
||||
// also initializes Google Test and parses its flags, if that hasn't
|
||||
// been done.
|
||||
GTEST_API_ void InitGoogleMock(int* argc, char** argv) {
|
||||
internal::InitGoogleMockImpl(argc, argv);
|
||||
}
|
||||
|
||||
// This overloaded version can be used in Windows programs compiled in
|
||||
// UNICODE mode.
|
||||
GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv) {
|
||||
internal::InitGoogleMockImpl(argc, argv);
|
||||
}
|
||||
|
||||
// This overloaded version can be used on Arduino/embedded platforms where
|
||||
// there is no argc/argv.
|
||||
GTEST_API_ void InitGoogleMock() {
|
||||
// Since Arduino doesn't have a command line, fake out the argc/argv arguments
|
||||
int argc = 1;
|
||||
const auto arg0 = "dummy";
|
||||
char* argv0 = const_cast<char*>(arg0);
|
||||
char** argv = &argv0;
|
||||
|
||||
internal::InitGoogleMockImpl(&argc, argv);
|
||||
}
|
||||
|
||||
} // namespace testing
|
|
@ -1,72 +0,0 @@
|
|||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#if GTEST_OS_ESP8266 || GTEST_OS_ESP32
|
||||
#if GTEST_OS_ESP8266
|
||||
extern "C" {
|
||||
#endif
|
||||
void setup() {
|
||||
// Since Google Mock depends on Google Test, InitGoogleMock() is
|
||||
// also responsible for initializing Google Test. Therefore there's
|
||||
// no need for calling testing::InitGoogleTest() separately.
|
||||
testing::InitGoogleMock();
|
||||
}
|
||||
void loop() { RUN_ALL_TESTS(); }
|
||||
#if GTEST_OS_ESP8266
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
// MS C++ compiler/linker has a bug on Windows (not on Windows CE), which
|
||||
// causes a link error when _tmain is defined in a static library and UNICODE
|
||||
// is enabled. For this reason instead of _tmain, main function is used on
|
||||
// Windows. See the following link to track the current status of this bug:
|
||||
// https://web.archive.org/web/20170912203238/connect.microsoft.com/VisualStudio/feedback/details/394464/wmain-link-error-in-the-static-library
|
||||
// // NOLINT
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
# include <tchar.h> // NOLINT
|
||||
|
||||
GTEST_API_ int _tmain(int argc, TCHAR** argv) {
|
||||
#else
|
||||
GTEST_API_ int main(int argc, char** argv) {
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
std::cout << "Running main() from gmock_main.cc\n";
|
||||
// Since Google Mock depends on Google Test, InitGoogleMock() is
|
||||
// also responsible for initializing Google Test. Therefore there's
|
||||
// no need for calling testing::InitGoogleTest() separately.
|
||||
testing::InitGoogleMock(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
#endif
|
|
@ -1,118 +0,0 @@
|
|||
# Copyright 2017 Google Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Bazel Build for Google C++ Testing Framework(Google Test)-googlemock
|
||||
|
||||
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test")
|
||||
load("@rules_python//python:defs.bzl", "py_library", "py_test")
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
# Tests for GMock itself
|
||||
cc_test(
|
||||
name = "gmock_all_test",
|
||||
size = "small",
|
||||
srcs = glob(include = ["gmock-*.cc"]),
|
||||
linkopts = select({
|
||||
"//:windows": [],
|
||||
"//conditions:default": ["-pthread"],
|
||||
}),
|
||||
deps = ["//:gtest"],
|
||||
)
|
||||
|
||||
# Python tests
|
||||
py_library(
|
||||
name = "gmock_test_utils",
|
||||
testonly = 1,
|
||||
srcs = ["gmock_test_utils.py"],
|
||||
deps = [
|
||||
"//googletest/test:gtest_test_utils",
|
||||
],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "gmock_leak_test_",
|
||||
testonly = 1,
|
||||
srcs = ["gmock_leak_test_.cc"],
|
||||
deps = ["//:gtest_main"],
|
||||
)
|
||||
|
||||
py_test(
|
||||
name = "gmock_leak_test",
|
||||
size = "medium",
|
||||
srcs = ["gmock_leak_test.py"],
|
||||
data = [
|
||||
":gmock_leak_test_",
|
||||
":gmock_test_utils",
|
||||
],
|
||||
tags = [
|
||||
"no_test_msvc2015",
|
||||
"no_test_msvc2017",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "gmock_link_test",
|
||||
size = "small",
|
||||
srcs = [
|
||||
"gmock_link2_test.cc",
|
||||
"gmock_link_test.cc",
|
||||
"gmock_link_test.h",
|
||||
],
|
||||
deps = ["//:gtest_main"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "gmock_output_test_",
|
||||
srcs = ["gmock_output_test_.cc"],
|
||||
deps = ["//:gtest"],
|
||||
)
|
||||
|
||||
py_test(
|
||||
name = "gmock_output_test",
|
||||
size = "medium",
|
||||
srcs = ["gmock_output_test.py"],
|
||||
data = [
|
||||
":gmock_output_test_",
|
||||
":gmock_output_test_golden.txt",
|
||||
],
|
||||
tags = [
|
||||
"no_test_msvc2015",
|
||||
"no_test_msvc2017",
|
||||
],
|
||||
deps = [":gmock_test_utils"],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "gmock_test",
|
||||
size = "small",
|
||||
srcs = ["gmock_test.cc"],
|
||||
deps = ["//:gtest_main"],
|
||||
)
|
|
@ -1,429 +0,0 @@
|
|||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file tests the built-in cardinalities.
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "gtest/gtest-spi.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using std::stringstream;
|
||||
using testing::AnyNumber;
|
||||
using testing::AtLeast;
|
||||
using testing::AtMost;
|
||||
using testing::Between;
|
||||
using testing::Cardinality;
|
||||
using testing::CardinalityInterface;
|
||||
using testing::Exactly;
|
||||
using testing::IsSubstring;
|
||||
using testing::MakeCardinality;
|
||||
|
||||
class MockFoo {
|
||||
public:
|
||||
MockFoo() {}
|
||||
MOCK_METHOD0(Bar, int()); // NOLINT
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo);
|
||||
};
|
||||
|
||||
// Tests that Cardinality objects can be default constructed.
|
||||
TEST(CardinalityTest, IsDefaultConstructable) {
|
||||
Cardinality c;
|
||||
}
|
||||
|
||||
// Tests that Cardinality objects are copyable.
|
||||
TEST(CardinalityTest, IsCopyable) {
|
||||
// Tests the copy constructor.
|
||||
Cardinality c = Exactly(1);
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(1));
|
||||
|
||||
// Tests the assignment operator.
|
||||
c = Exactly(2);
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(2));
|
||||
}
|
||||
|
||||
TEST(CardinalityTest, IsOverSaturatedByCallCountWorks) {
|
||||
const Cardinality c = AtMost(5);
|
||||
EXPECT_FALSE(c.IsOverSaturatedByCallCount(4));
|
||||
EXPECT_FALSE(c.IsOverSaturatedByCallCount(5));
|
||||
EXPECT_TRUE(c.IsOverSaturatedByCallCount(6));
|
||||
}
|
||||
|
||||
// Tests that Cardinality::DescribeActualCallCountTo() creates the
|
||||
// correct description.
|
||||
TEST(CardinalityTest, CanDescribeActualCallCount) {
|
||||
stringstream ss0;
|
||||
Cardinality::DescribeActualCallCountTo(0, &ss0);
|
||||
EXPECT_EQ("never called", ss0.str());
|
||||
|
||||
stringstream ss1;
|
||||
Cardinality::DescribeActualCallCountTo(1, &ss1);
|
||||
EXPECT_EQ("called once", ss1.str());
|
||||
|
||||
stringstream ss2;
|
||||
Cardinality::DescribeActualCallCountTo(2, &ss2);
|
||||
EXPECT_EQ("called twice", ss2.str());
|
||||
|
||||
stringstream ss3;
|
||||
Cardinality::DescribeActualCallCountTo(3, &ss3);
|
||||
EXPECT_EQ("called 3 times", ss3.str());
|
||||
}
|
||||
|
||||
// Tests AnyNumber()
|
||||
TEST(AnyNumber, Works) {
|
||||
const Cardinality c = AnyNumber();
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(1));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(9));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(9));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called any number of times",
|
||||
ss.str());
|
||||
}
|
||||
|
||||
TEST(AnyNumberTest, HasCorrectBounds) {
|
||||
const Cardinality c = AnyNumber();
|
||||
EXPECT_EQ(0, c.ConservativeLowerBound());
|
||||
EXPECT_EQ(INT_MAX, c.ConservativeUpperBound());
|
||||
}
|
||||
|
||||
// Tests AtLeast(n).
|
||||
|
||||
TEST(AtLeastTest, OnNegativeNumber) {
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
AtLeast(-1);
|
||||
}, "The invocation lower bound must be >= 0");
|
||||
}
|
||||
|
||||
TEST(AtLeastTest, OnZero) {
|
||||
const Cardinality c = AtLeast(0);
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(1));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "any number of times",
|
||||
ss.str());
|
||||
}
|
||||
|
||||
TEST(AtLeastTest, OnPositiveNumber) {
|
||||
const Cardinality c = AtLeast(2);
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(1));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(2));
|
||||
|
||||
stringstream ss1;
|
||||
AtLeast(1).DescribeTo(&ss1);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "at least once",
|
||||
ss1.str());
|
||||
|
||||
stringstream ss2;
|
||||
c.DescribeTo(&ss2);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "at least twice",
|
||||
ss2.str());
|
||||
|
||||
stringstream ss3;
|
||||
AtLeast(3).DescribeTo(&ss3);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "at least 3 times",
|
||||
ss3.str());
|
||||
}
|
||||
|
||||
TEST(AtLeastTest, HasCorrectBounds) {
|
||||
const Cardinality c = AtLeast(2);
|
||||
EXPECT_EQ(2, c.ConservativeLowerBound());
|
||||
EXPECT_EQ(INT_MAX, c.ConservativeUpperBound());
|
||||
}
|
||||
|
||||
// Tests AtMost(n).
|
||||
|
||||
TEST(AtMostTest, OnNegativeNumber) {
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
AtMost(-1);
|
||||
}, "The invocation upper bound must be >= 0");
|
||||
}
|
||||
|
||||
TEST(AtMostTest, OnZero) {
|
||||
const Cardinality c = AtMost(0);
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(1));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "never called",
|
||||
ss.str());
|
||||
}
|
||||
|
||||
TEST(AtMostTest, OnPositiveNumber) {
|
||||
const Cardinality c = AtMost(2);
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(1));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(2));
|
||||
|
||||
stringstream ss1;
|
||||
AtMost(1).DescribeTo(&ss1);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called at most once",
|
||||
ss1.str());
|
||||
|
||||
stringstream ss2;
|
||||
c.DescribeTo(&ss2);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called at most twice",
|
||||
ss2.str());
|
||||
|
||||
stringstream ss3;
|
||||
AtMost(3).DescribeTo(&ss3);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called at most 3 times",
|
||||
ss3.str());
|
||||
}
|
||||
|
||||
TEST(AtMostTest, HasCorrectBounds) {
|
||||
const Cardinality c = AtMost(2);
|
||||
EXPECT_EQ(0, c.ConservativeLowerBound());
|
||||
EXPECT_EQ(2, c.ConservativeUpperBound());
|
||||
}
|
||||
|
||||
// Tests Between(m, n).
|
||||
|
||||
TEST(BetweenTest, OnNegativeStart) {
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
Between(-1, 2);
|
||||
}, "The invocation lower bound must be >= 0, but is actually -1");
|
||||
}
|
||||
|
||||
TEST(BetweenTest, OnNegativeEnd) {
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
Between(1, -2);
|
||||
}, "The invocation upper bound must be >= 0, but is actually -2");
|
||||
}
|
||||
|
||||
TEST(BetweenTest, OnStartBiggerThanEnd) {
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
Between(2, 1);
|
||||
}, "The invocation upper bound (1) must be >= "
|
||||
"the invocation lower bound (2)");
|
||||
}
|
||||
|
||||
TEST(BetweenTest, OnZeroStartAndZeroEnd) {
|
||||
const Cardinality c = Between(0, 0);
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(1));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "never called",
|
||||
ss.str());
|
||||
}
|
||||
|
||||
TEST(BetweenTest, OnZeroStartAndNonZeroEnd) {
|
||||
const Cardinality c = Between(0, 2);
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(2));
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(4));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(4));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called at most twice",
|
||||
ss.str());
|
||||
}
|
||||
|
||||
TEST(BetweenTest, OnSameStartAndEnd) {
|
||||
const Cardinality c = Between(3, 3);
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(2));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(2));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(3));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(3));
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(4));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(4));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called 3 times",
|
||||
ss.str());
|
||||
}
|
||||
|
||||
TEST(BetweenTest, OnDifferentStartAndEnd) {
|
||||
const Cardinality c = Between(3, 5);
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(2));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(2));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(3));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(3));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(5));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(5));
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(6));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(6));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called between 3 and 5 times",
|
||||
ss.str());
|
||||
}
|
||||
|
||||
TEST(BetweenTest, HasCorrectBounds) {
|
||||
const Cardinality c = Between(3, 5);
|
||||
EXPECT_EQ(3, c.ConservativeLowerBound());
|
||||
EXPECT_EQ(5, c.ConservativeUpperBound());
|
||||
}
|
||||
|
||||
// Tests Exactly(n).
|
||||
|
||||
TEST(ExactlyTest, OnNegativeNumber) {
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
Exactly(-1);
|
||||
}, "The invocation lower bound must be >= 0");
|
||||
}
|
||||
|
||||
TEST(ExactlyTest, OnZero) {
|
||||
const Cardinality c = Exactly(0);
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(1));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "never called",
|
||||
ss.str());
|
||||
}
|
||||
|
||||
TEST(ExactlyTest, OnPositiveNumber) {
|
||||
const Cardinality c = Exactly(2);
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(2));
|
||||
|
||||
stringstream ss1;
|
||||
Exactly(1).DescribeTo(&ss1);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called once",
|
||||
ss1.str());
|
||||
|
||||
stringstream ss2;
|
||||
c.DescribeTo(&ss2);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called twice",
|
||||
ss2.str());
|
||||
|
||||
stringstream ss3;
|
||||
Exactly(3).DescribeTo(&ss3);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called 3 times",
|
||||
ss3.str());
|
||||
}
|
||||
|
||||
TEST(ExactlyTest, HasCorrectBounds) {
|
||||
const Cardinality c = Exactly(3);
|
||||
EXPECT_EQ(3, c.ConservativeLowerBound());
|
||||
EXPECT_EQ(3, c.ConservativeUpperBound());
|
||||
}
|
||||
|
||||
// Tests that a user can make their own cardinality by implementing
|
||||
// CardinalityInterface and calling MakeCardinality().
|
||||
|
||||
class EvenCardinality : public CardinalityInterface {
|
||||
public:
|
||||
// Returns true if and only if call_count calls will satisfy this
|
||||
// cardinality.
|
||||
bool IsSatisfiedByCallCount(int call_count) const override {
|
||||
return (call_count % 2 == 0);
|
||||
}
|
||||
|
||||
// Returns true if and only if call_count calls will saturate this
|
||||
// cardinality.
|
||||
bool IsSaturatedByCallCount(int /* call_count */) const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Describes self to an ostream.
|
||||
void DescribeTo(::std::ostream* ss) const override {
|
||||
*ss << "called even number of times";
|
||||
}
|
||||
};
|
||||
|
||||
TEST(MakeCardinalityTest, ConstructsCardinalityFromInterface) {
|
||||
const Cardinality c = MakeCardinality(new EvenCardinality);
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(3));
|
||||
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(10000));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_EQ("called even number of times", ss.str());
|
||||
}
|
||||
|
||||
} // Unnamed namespace
|
|
@ -1,986 +0,0 @@
|
|||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file tests the function mocker classes.
|
||||
#include "gmock/gmock-function-mocker.h"
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
// MSDN says the header file to be included for STDMETHOD is BaseTyps.h but
|
||||
// we are getting compiler errors if we use basetyps.h, hence including
|
||||
// objbase.h for definition of STDMETHOD.
|
||||
# include <objbase.h>
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace testing {
|
||||
namespace gmock_function_mocker_test {
|
||||
|
||||
using testing::_;
|
||||
using testing::A;
|
||||
using testing::An;
|
||||
using testing::AnyNumber;
|
||||
using testing::Const;
|
||||
using testing::DoDefault;
|
||||
using testing::Eq;
|
||||
using testing::Lt;
|
||||
using testing::MockFunction;
|
||||
using testing::Ref;
|
||||
using testing::Return;
|
||||
using testing::ReturnRef;
|
||||
using testing::TypedEq;
|
||||
|
||||
template<typename T>
|
||||
class TemplatedCopyable {
|
||||
public:
|
||||
TemplatedCopyable() {}
|
||||
|
||||
template <typename U>
|
||||
TemplatedCopyable(const U& other) {} // NOLINT
|
||||
};
|
||||
|
||||
class FooInterface {
|
||||
public:
|
||||
virtual ~FooInterface() {}
|
||||
|
||||
virtual void VoidReturning(int x) = 0;
|
||||
|
||||
virtual int Nullary() = 0;
|
||||
virtual bool Unary(int x) = 0;
|
||||
virtual long Binary(short x, int y) = 0; // NOLINT
|
||||
virtual int Decimal(bool b, char c, short d, int e, long f, // NOLINT
|
||||
float g, double h, unsigned i, char* j,
|
||||
const std::string& k) = 0;
|
||||
|
||||
virtual bool TakesNonConstReference(int& n) = 0; // NOLINT
|
||||
virtual std::string TakesConstReference(const int& n) = 0;
|
||||
virtual bool TakesConst(const int x) = 0;
|
||||
|
||||
virtual int OverloadedOnArgumentNumber() = 0;
|
||||
virtual int OverloadedOnArgumentNumber(int n) = 0;
|
||||
|
||||
virtual int OverloadedOnArgumentType(int n) = 0;
|
||||
virtual char OverloadedOnArgumentType(char c) = 0;
|
||||
|
||||
virtual int OverloadedOnConstness() = 0;
|
||||
virtual char OverloadedOnConstness() const = 0;
|
||||
|
||||
virtual int TypeWithHole(int (*func)()) = 0;
|
||||
virtual int TypeWithComma(const std::map<int, std::string>& a_map) = 0;
|
||||
virtual int TypeWithTemplatedCopyCtor(const TemplatedCopyable<int>&) = 0;
|
||||
|
||||
virtual int (*ReturnsFunctionPointer1(int))(bool) = 0;
|
||||
using fn_ptr = int (*)(bool);
|
||||
virtual fn_ptr ReturnsFunctionPointer2(int) = 0;
|
||||
|
||||
virtual int RefQualifiedConstRef() const& = 0;
|
||||
virtual int RefQualifiedConstRefRef() const&& = 0;
|
||||
virtual int RefQualifiedRef() & = 0;
|
||||
virtual int RefQualifiedRefRef() && = 0;
|
||||
|
||||
virtual int RefQualifiedOverloaded() const& = 0;
|
||||
virtual int RefQualifiedOverloaded() const&& = 0;
|
||||
virtual int RefQualifiedOverloaded() & = 0;
|
||||
virtual int RefQualifiedOverloaded() && = 0;
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
STDMETHOD_(int, CTNullary)() = 0;
|
||||
STDMETHOD_(bool, CTUnary)(int x) = 0;
|
||||
STDMETHOD_(int, CTDecimal)
|
||||
(bool b, char c, short d, int e, long f, // NOLINT
|
||||
float g, double h, unsigned i, char* j, const std::string& k) = 0;
|
||||
STDMETHOD_(char, CTConst)(int x) const = 0;
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
};
|
||||
|
||||
// Const qualifiers on arguments were once (incorrectly) considered
|
||||
// significant in determining whether two virtual functions had the same
|
||||
// signature. This was fixed in Visual Studio 2008. However, the compiler
|
||||
// still emits a warning that alerts about this change in behavior.
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4373)
|
||||
#endif
|
||||
class MockFoo : public FooInterface {
|
||||
public:
|
||||
MockFoo() {}
|
||||
|
||||
// Makes sure that a mock function parameter can be named.
|
||||
MOCK_METHOD(void, VoidReturning, (int n)); // NOLINT
|
||||
|
||||
MOCK_METHOD(int, Nullary, ()); // NOLINT
|
||||
|
||||
// Makes sure that a mock function parameter can be unnamed.
|
||||
MOCK_METHOD(bool, Unary, (int)); // NOLINT
|
||||
MOCK_METHOD(long, Binary, (short, int)); // NOLINT
|
||||
MOCK_METHOD(int, Decimal,
|
||||
(bool, char, short, int, long, float, // NOLINT
|
||||
double, unsigned, char*, const std::string& str),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(bool, TakesNonConstReference, (int&)); // NOLINT
|
||||
MOCK_METHOD(std::string, TakesConstReference, (const int&));
|
||||
MOCK_METHOD(bool, TakesConst, (const int)); // NOLINT
|
||||
|
||||
// Tests that the function return type can contain unprotected comma.
|
||||
MOCK_METHOD((std::map<int, std::string>), ReturnTypeWithComma, (), ());
|
||||
MOCK_METHOD((std::map<int, std::string>), ReturnTypeWithComma, (int),
|
||||
(const)); // NOLINT
|
||||
|
||||
MOCK_METHOD(int, OverloadedOnArgumentNumber, ()); // NOLINT
|
||||
MOCK_METHOD(int, OverloadedOnArgumentNumber, (int)); // NOLINT
|
||||
|
||||
MOCK_METHOD(int, OverloadedOnArgumentType, (int)); // NOLINT
|
||||
MOCK_METHOD(char, OverloadedOnArgumentType, (char)); // NOLINT
|
||||
|
||||
MOCK_METHOD(int, OverloadedOnConstness, (), (override)); // NOLINT
|
||||
MOCK_METHOD(char, OverloadedOnConstness, (), (override, const)); // NOLINT
|
||||
|
||||
MOCK_METHOD(int, TypeWithHole, (int (*)()), ()); // NOLINT
|
||||
MOCK_METHOD(int, TypeWithComma, ((const std::map<int, std::string>&)));
|
||||
MOCK_METHOD(int, TypeWithTemplatedCopyCtor,
|
||||
(const TemplatedCopyable<int>&)); // NOLINT
|
||||
|
||||
MOCK_METHOD(int (*)(bool), ReturnsFunctionPointer1, (int), ());
|
||||
MOCK_METHOD(fn_ptr, ReturnsFunctionPointer2, (int), ());
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
MOCK_METHOD(int, CTNullary, (), (Calltype(STDMETHODCALLTYPE)));
|
||||
MOCK_METHOD(bool, CTUnary, (int), (Calltype(STDMETHODCALLTYPE)));
|
||||
MOCK_METHOD(int, CTDecimal,
|
||||
(bool b, char c, short d, int e, long f, float g, double h,
|
||||
unsigned i, char* j, const std::string& k),
|
||||
(Calltype(STDMETHODCALLTYPE)));
|
||||
MOCK_METHOD(char, CTConst, (int), (const, Calltype(STDMETHODCALLTYPE)));
|
||||
MOCK_METHOD((std::map<int, std::string>), CTReturnTypeWithComma, (),
|
||||
(Calltype(STDMETHODCALLTYPE)));
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
// Test reference qualified functions.
|
||||
MOCK_METHOD(int, RefQualifiedConstRef, (), (const, ref(&), override));
|
||||
MOCK_METHOD(int, RefQualifiedConstRefRef, (), (const, ref(&&), override));
|
||||
MOCK_METHOD(int, RefQualifiedRef, (), (ref(&), override));
|
||||
MOCK_METHOD(int, RefQualifiedRefRef, (), (ref(&&), override));
|
||||
|
||||
MOCK_METHOD(int, RefQualifiedOverloaded, (), (const, ref(&), override));
|
||||
MOCK_METHOD(int, RefQualifiedOverloaded, (), (const, ref(&&), override));
|
||||
MOCK_METHOD(int, RefQualifiedOverloaded, (), (ref(&), override));
|
||||
MOCK_METHOD(int, RefQualifiedOverloaded, (), (ref(&&), override));
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo);
|
||||
};
|
||||
|
||||
class LegacyMockFoo : public FooInterface {
|
||||
public:
|
||||
LegacyMockFoo() {}
|
||||
|
||||
// Makes sure that a mock function parameter can be named.
|
||||
MOCK_METHOD1(VoidReturning, void(int n)); // NOLINT
|
||||
|
||||
MOCK_METHOD0(Nullary, int()); // NOLINT
|
||||
|
||||
// Makes sure that a mock function parameter can be unnamed.
|
||||
MOCK_METHOD1(Unary, bool(int)); // NOLINT
|
||||
MOCK_METHOD2(Binary, long(short, int)); // NOLINT
|
||||
MOCK_METHOD10(Decimal, int(bool, char, short, int, long, float, // NOLINT
|
||||
double, unsigned, char*, const std::string& str));
|
||||
|
||||
MOCK_METHOD1(TakesNonConstReference, bool(int&)); // NOLINT
|
||||
MOCK_METHOD1(TakesConstReference, std::string(const int&));
|
||||
MOCK_METHOD1(TakesConst, bool(const int)); // NOLINT
|
||||
|
||||
// Tests that the function return type can contain unprotected comma.
|
||||
MOCK_METHOD0(ReturnTypeWithComma, std::map<int, std::string>());
|
||||
MOCK_CONST_METHOD1(ReturnTypeWithComma,
|
||||
std::map<int, std::string>(int)); // NOLINT
|
||||
|
||||
MOCK_METHOD0(OverloadedOnArgumentNumber, int()); // NOLINT
|
||||
MOCK_METHOD1(OverloadedOnArgumentNumber, int(int)); // NOLINT
|
||||
|
||||
MOCK_METHOD1(OverloadedOnArgumentType, int(int)); // NOLINT
|
||||
MOCK_METHOD1(OverloadedOnArgumentType, char(char)); // NOLINT
|
||||
|
||||
MOCK_METHOD0(OverloadedOnConstness, int()); // NOLINT
|
||||
MOCK_CONST_METHOD0(OverloadedOnConstness, char()); // NOLINT
|
||||
|
||||
MOCK_METHOD1(TypeWithHole, int(int (*)())); // NOLINT
|
||||
MOCK_METHOD1(TypeWithComma,
|
||||
int(const std::map<int, std::string>&)); // NOLINT
|
||||
MOCK_METHOD1(TypeWithTemplatedCopyCtor,
|
||||
int(const TemplatedCopyable<int>&)); // NOLINT
|
||||
|
||||
MOCK_METHOD1(ReturnsFunctionPointer1, int (*(int))(bool));
|
||||
MOCK_METHOD1(ReturnsFunctionPointer2, fn_ptr(int));
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTNullary, int());
|
||||
MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTUnary, bool(int)); // NOLINT
|
||||
MOCK_METHOD10_WITH_CALLTYPE(STDMETHODCALLTYPE, CTDecimal,
|
||||
int(bool b, char c, short d, int e, // NOLINT
|
||||
long f, float g, double h, // NOLINT
|
||||
unsigned i, char* j, const std::string& k));
|
||||
MOCK_CONST_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTConst,
|
||||
char(int)); // NOLINT
|
||||
|
||||
// Tests that the function return type can contain unprotected comma.
|
||||
MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTReturnTypeWithComma,
|
||||
std::map<int, std::string>());
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
// We can't mock these with the old macros, but we need to define them to make
|
||||
// it concrete.
|
||||
int RefQualifiedConstRef() const& override { return 0; }
|
||||
int RefQualifiedConstRefRef() const&& override { return 0; }
|
||||
int RefQualifiedRef() & override { return 0; }
|
||||
int RefQualifiedRefRef() && override { return 0; }
|
||||
int RefQualifiedOverloaded() const& override { return 0; }
|
||||
int RefQualifiedOverloaded() const&& override { return 0; }
|
||||
int RefQualifiedOverloaded() & override { return 0; }
|
||||
int RefQualifiedOverloaded() && override { return 0; }
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockFoo);
|
||||
};
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
class FunctionMockerTest : public testing::Test {
|
||||
protected:
|
||||
FunctionMockerTest() : foo_(&mock_foo_) {}
|
||||
|
||||
FooInterface* const foo_;
|
||||
T mock_foo_;
|
||||
};
|
||||
using FunctionMockerTestTypes = ::testing::Types<MockFoo, LegacyMockFoo>;
|
||||
TYPED_TEST_SUITE(FunctionMockerTest, FunctionMockerTestTypes);
|
||||
|
||||
// Tests mocking a void-returning function.
|
||||
TYPED_TEST(FunctionMockerTest, MocksVoidFunction) {
|
||||
EXPECT_CALL(this->mock_foo_, VoidReturning(Lt(100)));
|
||||
this->foo_->VoidReturning(0);
|
||||
}
|
||||
|
||||
// Tests mocking a nullary function.
|
||||
TYPED_TEST(FunctionMockerTest, MocksNullaryFunction) {
|
||||
EXPECT_CALL(this->mock_foo_, Nullary())
|
||||
.WillOnce(DoDefault())
|
||||
.WillOnce(Return(1));
|
||||
|
||||
EXPECT_EQ(0, this->foo_->Nullary());
|
||||
EXPECT_EQ(1, this->foo_->Nullary());
|
||||
}
|
||||
|
||||
// Tests mocking a unary function.
|
||||
TYPED_TEST(FunctionMockerTest, MocksUnaryFunction) {
|
||||
EXPECT_CALL(this->mock_foo_, Unary(Eq(2))).Times(2).WillOnce(Return(true));
|
||||
|
||||
EXPECT_TRUE(this->foo_->Unary(2));
|
||||
EXPECT_FALSE(this->foo_->Unary(2));
|
||||
}
|
||||
|
||||
// Tests mocking a binary function.
|
||||
TYPED_TEST(FunctionMockerTest, MocksBinaryFunction) {
|
||||
EXPECT_CALL(this->mock_foo_, Binary(2, _)).WillOnce(Return(3));
|
||||
|
||||
EXPECT_EQ(3, this->foo_->Binary(2, 1));
|
||||
}
|
||||
|
||||
// Tests mocking a decimal function.
|
||||
TYPED_TEST(FunctionMockerTest, MocksDecimalFunction) {
|
||||
EXPECT_CALL(this->mock_foo_,
|
||||
Decimal(true, 'a', 0, 0, 1L, A<float>(), Lt(100), 5U, NULL, "hi"))
|
||||
.WillOnce(Return(5));
|
||||
|
||||
EXPECT_EQ(5, this->foo_->Decimal(true, 'a', 0, 0, 1, 0, 0, 5, nullptr, "hi"));
|
||||
}
|
||||
|
||||
// Tests mocking a function that takes a non-const reference.
|
||||
TYPED_TEST(FunctionMockerTest, MocksFunctionWithNonConstReferenceArgument) {
|
||||
int a = 0;
|
||||
EXPECT_CALL(this->mock_foo_, TakesNonConstReference(Ref(a)))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EXPECT_TRUE(this->foo_->TakesNonConstReference(a));
|
||||
}
|
||||
|
||||
// Tests mocking a function that takes a const reference.
|
||||
TYPED_TEST(FunctionMockerTest, MocksFunctionWithConstReferenceArgument) {
|
||||
int a = 0;
|
||||
EXPECT_CALL(this->mock_foo_, TakesConstReference(Ref(a)))
|
||||
.WillOnce(Return("Hello"));
|
||||
|
||||
EXPECT_EQ("Hello", this->foo_->TakesConstReference(a));
|
||||
}
|
||||
|
||||
// Tests mocking a function that takes a const variable.
|
||||
TYPED_TEST(FunctionMockerTest, MocksFunctionWithConstArgument) {
|
||||
EXPECT_CALL(this->mock_foo_, TakesConst(Lt(10))).WillOnce(DoDefault());
|
||||
|
||||
EXPECT_FALSE(this->foo_->TakesConst(5));
|
||||
}
|
||||
|
||||
// Tests mocking functions overloaded on the number of arguments.
|
||||
TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentNumber) {
|
||||
EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentNumber())
|
||||
.WillOnce(Return(1));
|
||||
EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentNumber(_))
|
||||
.WillOnce(Return(2));
|
||||
|
||||
EXPECT_EQ(2, this->foo_->OverloadedOnArgumentNumber(1));
|
||||
EXPECT_EQ(1, this->foo_->OverloadedOnArgumentNumber());
|
||||
}
|
||||
|
||||
// Tests mocking functions overloaded on the types of argument.
|
||||
TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentType) {
|
||||
EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentType(An<int>()))
|
||||
.WillOnce(Return(1));
|
||||
EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentType(TypedEq<char>('a')))
|
||||
.WillOnce(Return('b'));
|
||||
|
||||
EXPECT_EQ(1, this->foo_->OverloadedOnArgumentType(0));
|
||||
EXPECT_EQ('b', this->foo_->OverloadedOnArgumentType('a'));
|
||||
}
|
||||
|
||||
// Tests mocking functions overloaded on the const-ness of this object.
|
||||
TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnConstnessOfThis) {
|
||||
EXPECT_CALL(this->mock_foo_, OverloadedOnConstness());
|
||||
EXPECT_CALL(Const(this->mock_foo_), OverloadedOnConstness())
|
||||
.WillOnce(Return('a'));
|
||||
|
||||
EXPECT_EQ(0, this->foo_->OverloadedOnConstness());
|
||||
EXPECT_EQ('a', Const(*this->foo_).OverloadedOnConstness());
|
||||
}
|
||||
|
||||
TYPED_TEST(FunctionMockerTest, MocksReturnTypeWithComma) {
|
||||
const std::map<int, std::string> a_map;
|
||||
EXPECT_CALL(this->mock_foo_, ReturnTypeWithComma()).WillOnce(Return(a_map));
|
||||
EXPECT_CALL(this->mock_foo_, ReturnTypeWithComma(42)).WillOnce(Return(a_map));
|
||||
|
||||
EXPECT_EQ(a_map, this->mock_foo_.ReturnTypeWithComma());
|
||||
EXPECT_EQ(a_map, this->mock_foo_.ReturnTypeWithComma(42));
|
||||
}
|
||||
|
||||
TYPED_TEST(FunctionMockerTest, MocksTypeWithTemplatedCopyCtor) {
|
||||
EXPECT_CALL(this->mock_foo_, TypeWithTemplatedCopyCtor(_))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_TRUE(this->foo_->TypeWithTemplatedCopyCtor(TemplatedCopyable<int>()));
|
||||
}
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
// Tests mocking a nullary function with calltype.
|
||||
TYPED_TEST(FunctionMockerTest, MocksNullaryFunctionWithCallType) {
|
||||
EXPECT_CALL(this->mock_foo_, CTNullary())
|
||||
.WillOnce(Return(-1))
|
||||
.WillOnce(Return(0));
|
||||
|
||||
EXPECT_EQ(-1, this->foo_->CTNullary());
|
||||
EXPECT_EQ(0, this->foo_->CTNullary());
|
||||
}
|
||||
|
||||
// Tests mocking a unary function with calltype.
|
||||
TYPED_TEST(FunctionMockerTest, MocksUnaryFunctionWithCallType) {
|
||||
EXPECT_CALL(this->mock_foo_, CTUnary(Eq(2)))
|
||||
.Times(2)
|
||||
.WillOnce(Return(true))
|
||||
.WillOnce(Return(false));
|
||||
|
||||
EXPECT_TRUE(this->foo_->CTUnary(2));
|
||||
EXPECT_FALSE(this->foo_->CTUnary(2));
|
||||
}
|
||||
|
||||
// Tests mocking a decimal function with calltype.
|
||||
TYPED_TEST(FunctionMockerTest, MocksDecimalFunctionWithCallType) {
|
||||
EXPECT_CALL(this->mock_foo_, CTDecimal(true, 'a', 0, 0, 1L, A<float>(),
|
||||
Lt(100), 5U, NULL, "hi"))
|
||||
.WillOnce(Return(10));
|
||||
|
||||
EXPECT_EQ(10, this->foo_->CTDecimal(true, 'a', 0, 0, 1, 0, 0, 5, NULL, "hi"));
|
||||
}
|
||||
|
||||
// Tests mocking functions overloaded on the const-ness of this object.
|
||||
TYPED_TEST(FunctionMockerTest, MocksFunctionsConstFunctionWithCallType) {
|
||||
EXPECT_CALL(Const(this->mock_foo_), CTConst(_)).WillOnce(Return('a'));
|
||||
|
||||
EXPECT_EQ('a', Const(*this->foo_).CTConst(0));
|
||||
}
|
||||
|
||||
TYPED_TEST(FunctionMockerTest, MocksReturnTypeWithCommaAndCallType) {
|
||||
const std::map<int, std::string> a_map;
|
||||
EXPECT_CALL(this->mock_foo_, CTReturnTypeWithComma()).WillOnce(Return(a_map));
|
||||
|
||||
EXPECT_EQ(a_map, this->mock_foo_.CTReturnTypeWithComma());
|
||||
}
|
||||
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
TEST(FunctionMockerTest, RefQualified) {
|
||||
MockFoo mock_foo;
|
||||
|
||||
EXPECT_CALL(mock_foo, RefQualifiedConstRef).WillOnce(Return(1));
|
||||
EXPECT_CALL(std::move(mock_foo), // NOLINT
|
||||
RefQualifiedConstRefRef)
|
||||
.WillOnce(Return(2));
|
||||
EXPECT_CALL(mock_foo, RefQualifiedRef).WillOnce(Return(3));
|
||||
EXPECT_CALL(std::move(mock_foo), // NOLINT
|
||||
RefQualifiedRefRef)
|
||||
.WillOnce(Return(4));
|
||||
|
||||
EXPECT_CALL(static_cast<const MockFoo&>(mock_foo), RefQualifiedOverloaded())
|
||||
.WillOnce(Return(5));
|
||||
EXPECT_CALL(static_cast<const MockFoo&&>(mock_foo), RefQualifiedOverloaded())
|
||||
.WillOnce(Return(6));
|
||||
EXPECT_CALL(static_cast<MockFoo&>(mock_foo), RefQualifiedOverloaded())
|
||||
.WillOnce(Return(7));
|
||||
EXPECT_CALL(static_cast<MockFoo&&>(mock_foo), RefQualifiedOverloaded())
|
||||
.WillOnce(Return(8));
|
||||
|
||||
EXPECT_EQ(mock_foo.RefQualifiedConstRef(), 1);
|
||||
EXPECT_EQ(std::move(mock_foo).RefQualifiedConstRefRef(), 2); // NOLINT
|
||||
EXPECT_EQ(mock_foo.RefQualifiedRef(), 3);
|
||||
EXPECT_EQ(std::move(mock_foo).RefQualifiedRefRef(), 4); // NOLINT
|
||||
|
||||
EXPECT_EQ(std::cref(mock_foo).get().RefQualifiedOverloaded(), 5);
|
||||
EXPECT_EQ(std::move(std::cref(mock_foo).get()) // NOLINT
|
||||
.RefQualifiedOverloaded(),
|
||||
6);
|
||||
EXPECT_EQ(mock_foo.RefQualifiedOverloaded(), 7);
|
||||
EXPECT_EQ(std::move(mock_foo).RefQualifiedOverloaded(), 8); // NOLINT
|
||||
}
|
||||
|
||||
class MockB {
|
||||
public:
|
||||
MockB() {}
|
||||
|
||||
MOCK_METHOD(void, DoB, ());
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockB);
|
||||
};
|
||||
|
||||
class LegacyMockB {
|
||||
public:
|
||||
LegacyMockB() {}
|
||||
|
||||
MOCK_METHOD0(DoB, void());
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockB);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class ExpectCallTest : public ::testing::Test {};
|
||||
using ExpectCallTestTypes = ::testing::Types<MockB, LegacyMockB>;
|
||||
TYPED_TEST_SUITE(ExpectCallTest, ExpectCallTestTypes);
|
||||
|
||||
// Tests that functions with no EXPECT_CALL() rules can be called any
|
||||
// number of times.
|
||||
TYPED_TEST(ExpectCallTest, UnmentionedFunctionCanBeCalledAnyNumberOfTimes) {
|
||||
{ TypeParam b; }
|
||||
|
||||
{
|
||||
TypeParam b;
|
||||
b.DoB();
|
||||
}
|
||||
|
||||
{
|
||||
TypeParam b;
|
||||
b.DoB();
|
||||
b.DoB();
|
||||
}
|
||||
}
|
||||
|
||||
// Tests mocking template interfaces.
|
||||
|
||||
template <typename T>
|
||||
class StackInterface {
|
||||
public:
|
||||
virtual ~StackInterface() {}
|
||||
|
||||
// Template parameter appears in function parameter.
|
||||
virtual void Push(const T& value) = 0;
|
||||
virtual void Pop() = 0;
|
||||
virtual int GetSize() const = 0;
|
||||
// Template parameter appears in function return type.
|
||||
virtual const T& GetTop() const = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class MockStack : public StackInterface<T> {
|
||||
public:
|
||||
MockStack() {}
|
||||
|
||||
MOCK_METHOD(void, Push, (const T& elem), ());
|
||||
MOCK_METHOD(void, Pop, (), (final));
|
||||
MOCK_METHOD(int, GetSize, (), (const, override));
|
||||
MOCK_METHOD(const T&, GetTop, (), (const));
|
||||
|
||||
// Tests that the function return type can contain unprotected comma.
|
||||
MOCK_METHOD((std::map<int, int>), ReturnTypeWithComma, (), ());
|
||||
MOCK_METHOD((std::map<int, int>), ReturnTypeWithComma, (int), (const));
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockStack);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class LegacyMockStack : public StackInterface<T> {
|
||||
public:
|
||||
LegacyMockStack() {}
|
||||
|
||||
MOCK_METHOD1_T(Push, void(const T& elem));
|
||||
MOCK_METHOD0_T(Pop, void());
|
||||
MOCK_CONST_METHOD0_T(GetSize, int()); // NOLINT
|
||||
MOCK_CONST_METHOD0_T(GetTop, const T&());
|
||||
|
||||
// Tests that the function return type can contain unprotected comma.
|
||||
MOCK_METHOD0_T(ReturnTypeWithComma, std::map<int, int>());
|
||||
MOCK_CONST_METHOD1_T(ReturnTypeWithComma, std::map<int, int>(int)); // NOLINT
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockStack);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class TemplateMockTest : public ::testing::Test {};
|
||||
using TemplateMockTestTypes =
|
||||
::testing::Types<MockStack<int>, LegacyMockStack<int>>;
|
||||
TYPED_TEST_SUITE(TemplateMockTest, TemplateMockTestTypes);
|
||||
|
||||
// Tests that template mock works.
|
||||
TYPED_TEST(TemplateMockTest, Works) {
|
||||
TypeParam mock;
|
||||
|
||||
EXPECT_CALL(mock, GetSize())
|
||||
.WillOnce(Return(0))
|
||||
.WillOnce(Return(1))
|
||||
.WillOnce(Return(0));
|
||||
EXPECT_CALL(mock, Push(_));
|
||||
int n = 5;
|
||||
EXPECT_CALL(mock, GetTop())
|
||||
.WillOnce(ReturnRef(n));
|
||||
EXPECT_CALL(mock, Pop())
|
||||
.Times(AnyNumber());
|
||||
|
||||
EXPECT_EQ(0, mock.GetSize());
|
||||
mock.Push(5);
|
||||
EXPECT_EQ(1, mock.GetSize());
|
||||
EXPECT_EQ(5, mock.GetTop());
|
||||
mock.Pop();
|
||||
EXPECT_EQ(0, mock.GetSize());
|
||||
}
|
||||
|
||||
TYPED_TEST(TemplateMockTest, MethodWithCommaInReturnTypeWorks) {
|
||||
TypeParam mock;
|
||||
|
||||
const std::map<int, int> a_map;
|
||||
EXPECT_CALL(mock, ReturnTypeWithComma())
|
||||
.WillOnce(Return(a_map));
|
||||
EXPECT_CALL(mock, ReturnTypeWithComma(1))
|
||||
.WillOnce(Return(a_map));
|
||||
|
||||
EXPECT_EQ(a_map, mock.ReturnTypeWithComma());
|
||||
EXPECT_EQ(a_map, mock.ReturnTypeWithComma(1));
|
||||
}
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
// Tests mocking template interfaces with calltype.
|
||||
|
||||
template <typename T>
|
||||
class StackInterfaceWithCallType {
|
||||
public:
|
||||
virtual ~StackInterfaceWithCallType() {}
|
||||
|
||||
// Template parameter appears in function parameter.
|
||||
STDMETHOD_(void, Push)(const T& value) = 0;
|
||||
STDMETHOD_(void, Pop)() = 0;
|
||||
STDMETHOD_(int, GetSize)() const = 0;
|
||||
// Template parameter appears in function return type.
|
||||
STDMETHOD_(const T&, GetTop)() const = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class MockStackWithCallType : public StackInterfaceWithCallType<T> {
|
||||
public:
|
||||
MockStackWithCallType() {}
|
||||
|
||||
MOCK_METHOD(void, Push, (const T& elem),
|
||||
(Calltype(STDMETHODCALLTYPE), override));
|
||||
MOCK_METHOD(void, Pop, (), (Calltype(STDMETHODCALLTYPE), override));
|
||||
MOCK_METHOD(int, GetSize, (), (Calltype(STDMETHODCALLTYPE), override, const));
|
||||
MOCK_METHOD(const T&, GetTop, (),
|
||||
(Calltype(STDMETHODCALLTYPE), override, const));
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockStackWithCallType);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class LegacyMockStackWithCallType : public StackInterfaceWithCallType<T> {
|
||||
public:
|
||||
LegacyMockStackWithCallType() {}
|
||||
|
||||
MOCK_METHOD1_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Push, void(const T& elem));
|
||||
MOCK_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Pop, void());
|
||||
MOCK_CONST_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, GetSize, int());
|
||||
MOCK_CONST_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, GetTop, const T&());
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockStackWithCallType);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class TemplateMockTestWithCallType : public ::testing::Test {};
|
||||
using TemplateMockTestWithCallTypeTypes =
|
||||
::testing::Types<MockStackWithCallType<int>,
|
||||
LegacyMockStackWithCallType<int>>;
|
||||
TYPED_TEST_SUITE(TemplateMockTestWithCallType,
|
||||
TemplateMockTestWithCallTypeTypes);
|
||||
|
||||
// Tests that template mock with calltype works.
|
||||
TYPED_TEST(TemplateMockTestWithCallType, Works) {
|
||||
TypeParam mock;
|
||||
|
||||
EXPECT_CALL(mock, GetSize())
|
||||
.WillOnce(Return(0))
|
||||
.WillOnce(Return(1))
|
||||
.WillOnce(Return(0));
|
||||
EXPECT_CALL(mock, Push(_));
|
||||
int n = 5;
|
||||
EXPECT_CALL(mock, GetTop())
|
||||
.WillOnce(ReturnRef(n));
|
||||
EXPECT_CALL(mock, Pop())
|
||||
.Times(AnyNumber());
|
||||
|
||||
EXPECT_EQ(0, mock.GetSize());
|
||||
mock.Push(5);
|
||||
EXPECT_EQ(1, mock.GetSize());
|
||||
EXPECT_EQ(5, mock.GetTop());
|
||||
mock.Pop();
|
||||
EXPECT_EQ(0, mock.GetSize());
|
||||
}
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
#define MY_MOCK_METHODS1_ \
|
||||
MOCK_METHOD(void, Overloaded, ()); \
|
||||
MOCK_METHOD(int, Overloaded, (int), (const)); \
|
||||
MOCK_METHOD(bool, Overloaded, (bool f, int n))
|
||||
|
||||
#define LEGACY_MY_MOCK_METHODS1_ \
|
||||
MOCK_METHOD0(Overloaded, void()); \
|
||||
MOCK_CONST_METHOD1(Overloaded, int(int n)); \
|
||||
MOCK_METHOD2(Overloaded, bool(bool f, int n))
|
||||
|
||||
class MockOverloadedOnArgNumber {
|
||||
public:
|
||||
MockOverloadedOnArgNumber() {}
|
||||
|
||||
MY_MOCK_METHODS1_;
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockOverloadedOnArgNumber);
|
||||
};
|
||||
|
||||
class LegacyMockOverloadedOnArgNumber {
|
||||
public:
|
||||
LegacyMockOverloadedOnArgNumber() {}
|
||||
|
||||
LEGACY_MY_MOCK_METHODS1_;
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockOverloadedOnArgNumber);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class OverloadedMockMethodTest : public ::testing::Test {};
|
||||
using OverloadedMockMethodTestTypes =
|
||||
::testing::Types<MockOverloadedOnArgNumber,
|
||||
LegacyMockOverloadedOnArgNumber>;
|
||||
TYPED_TEST_SUITE(OverloadedMockMethodTest, OverloadedMockMethodTestTypes);
|
||||
|
||||
TYPED_TEST(OverloadedMockMethodTest, CanOverloadOnArgNumberInMacroBody) {
|
||||
TypeParam mock;
|
||||
EXPECT_CALL(mock, Overloaded());
|
||||
EXPECT_CALL(mock, Overloaded(1)).WillOnce(Return(2));
|
||||
EXPECT_CALL(mock, Overloaded(true, 1)).WillOnce(Return(true));
|
||||
|
||||
mock.Overloaded();
|
||||
EXPECT_EQ(2, mock.Overloaded(1));
|
||||
EXPECT_TRUE(mock.Overloaded(true, 1));
|
||||
}
|
||||
|
||||
#define MY_MOCK_METHODS2_ \
|
||||
MOCK_CONST_METHOD1(Overloaded, int(int n)); \
|
||||
MOCK_METHOD1(Overloaded, int(int n))
|
||||
|
||||
class MockOverloadedOnConstness {
|
||||
public:
|
||||
MockOverloadedOnConstness() {}
|
||||
|
||||
MY_MOCK_METHODS2_;
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockOverloadedOnConstness);
|
||||
};
|
||||
|
||||
TEST(MockMethodOverloadedMockMethodTest, CanOverloadOnConstnessInMacroBody) {
|
||||
MockOverloadedOnConstness mock;
|
||||
const MockOverloadedOnConstness* const_mock = &mock;
|
||||
EXPECT_CALL(mock, Overloaded(1)).WillOnce(Return(2));
|
||||
EXPECT_CALL(*const_mock, Overloaded(1)).WillOnce(Return(3));
|
||||
|
||||
EXPECT_EQ(2, mock.Overloaded(1));
|
||||
EXPECT_EQ(3, const_mock->Overloaded(1));
|
||||
}
|
||||
|
||||
TEST(MockMethodMockFunctionTest, WorksForVoidNullary) {
|
||||
MockFunction<void()> foo;
|
||||
EXPECT_CALL(foo, Call());
|
||||
foo.Call();
|
||||
}
|
||||
|
||||
TEST(MockMethodMockFunctionTest, WorksForNonVoidNullary) {
|
||||
MockFunction<int()> foo;
|
||||
EXPECT_CALL(foo, Call())
|
||||
.WillOnce(Return(1))
|
||||
.WillOnce(Return(2));
|
||||
EXPECT_EQ(1, foo.Call());
|
||||
EXPECT_EQ(2, foo.Call());
|
||||
}
|
||||
|
||||
TEST(MockMethodMockFunctionTest, WorksForVoidUnary) {
|
||||
MockFunction<void(int)> foo;
|
||||
EXPECT_CALL(foo, Call(1));
|
||||
foo.Call(1);
|
||||
}
|
||||
|
||||
TEST(MockMethodMockFunctionTest, WorksForNonVoidBinary) {
|
||||
MockFunction<int(bool, int)> foo;
|
||||
EXPECT_CALL(foo, Call(false, 42))
|
||||
.WillOnce(Return(1))
|
||||
.WillOnce(Return(2));
|
||||
EXPECT_CALL(foo, Call(true, Ge(100)))
|
||||
.WillOnce(Return(3));
|
||||
EXPECT_EQ(1, foo.Call(false, 42));
|
||||
EXPECT_EQ(2, foo.Call(false, 42));
|
||||
EXPECT_EQ(3, foo.Call(true, 120));
|
||||
}
|
||||
|
||||
TEST(MockMethodMockFunctionTest, WorksFor10Arguments) {
|
||||
MockFunction<int(bool a0, char a1, int a2, int a3, int a4,
|
||||
int a5, int a6, char a7, int a8, bool a9)> foo;
|
||||
EXPECT_CALL(foo, Call(_, 'a', _, _, _, _, _, _, _, _))
|
||||
.WillOnce(Return(1))
|
||||
.WillOnce(Return(2));
|
||||
EXPECT_EQ(1, foo.Call(false, 'a', 0, 0, 0, 0, 0, 'b', 0, true));
|
||||
EXPECT_EQ(2, foo.Call(true, 'a', 0, 0, 0, 0, 0, 'b', 1, false));
|
||||
}
|
||||
|
||||
TEST(MockMethodMockFunctionTest, AsStdFunction) {
|
||||
MockFunction<int(int)> foo;
|
||||
auto call = [](const std::function<int(int)> &f, int i) {
|
||||
return f(i);
|
||||
};
|
||||
EXPECT_CALL(foo, Call(1)).WillOnce(Return(-1));
|
||||
EXPECT_CALL(foo, Call(2)).WillOnce(Return(-2));
|
||||
EXPECT_EQ(-1, call(foo.AsStdFunction(), 1));
|
||||
EXPECT_EQ(-2, call(foo.AsStdFunction(), 2));
|
||||
}
|
||||
|
||||
TEST(MockMethodMockFunctionTest, AsStdFunctionReturnsReference) {
|
||||
MockFunction<int&()> foo;
|
||||
int value = 1;
|
||||
EXPECT_CALL(foo, Call()).WillOnce(ReturnRef(value));
|
||||
int& ref = foo.AsStdFunction()();
|
||||
EXPECT_EQ(1, ref);
|
||||
value = 2;
|
||||
EXPECT_EQ(2, ref);
|
||||
}
|
||||
|
||||
TEST(MockMethodMockFunctionTest, AsStdFunctionWithReferenceParameter) {
|
||||
MockFunction<int(int &)> foo;
|
||||
auto call = [](const std::function<int(int& )> &f, int &i) {
|
||||
return f(i);
|
||||
};
|
||||
int i = 42;
|
||||
EXPECT_CALL(foo, Call(i)).WillOnce(Return(-1));
|
||||
EXPECT_EQ(-1, call(foo.AsStdFunction(), i));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename Expected, typename F>
|
||||
static constexpr bool IsMockFunctionTemplateArgumentDeducedTo(
|
||||
const internal::MockFunction<F>&) {
|
||||
return std::is_same<F, Expected>::value;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
template <typename F>
|
||||
class MockMethodMockFunctionSignatureTest : public Test {};
|
||||
|
||||
using MockMethodMockFunctionSignatureTypes =
|
||||
Types<void(), int(), void(int), int(int), int(bool, int),
|
||||
int(bool, char, int, int, int, int, int, char, int, bool)>;
|
||||
TYPED_TEST_SUITE(MockMethodMockFunctionSignatureTest,
|
||||
MockMethodMockFunctionSignatureTypes);
|
||||
|
||||
TYPED_TEST(MockMethodMockFunctionSignatureTest,
|
||||
IsMockFunctionTemplateArgumentDeducedForRawSignature) {
|
||||
using Argument = TypeParam;
|
||||
MockFunction<Argument> foo;
|
||||
EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<TypeParam>(foo));
|
||||
}
|
||||
|
||||
TYPED_TEST(MockMethodMockFunctionSignatureTest,
|
||||
IsMockFunctionTemplateArgumentDeducedForStdFunction) {
|
||||
using Argument = std::function<TypeParam>;
|
||||
MockFunction<Argument> foo;
|
||||
EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<TypeParam>(foo));
|
||||
}
|
||||
|
||||
TYPED_TEST(
|
||||
MockMethodMockFunctionSignatureTest,
|
||||
IsMockFunctionCallMethodSignatureTheSameForRawSignatureAndStdFunction) {
|
||||
using ForRawSignature = decltype(&MockFunction<TypeParam>::Call);
|
||||
using ForStdFunction =
|
||||
decltype(&MockFunction<std::function<TypeParam>>::Call);
|
||||
EXPECT_TRUE((std::is_same<ForRawSignature, ForStdFunction>::value));
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
struct AlternateCallable {
|
||||
};
|
||||
|
||||
TYPED_TEST(MockMethodMockFunctionSignatureTest,
|
||||
IsMockFunctionTemplateArgumentDeducedForAlternateCallable) {
|
||||
using Argument = AlternateCallable<TypeParam>;
|
||||
MockFunction<Argument> foo;
|
||||
EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<TypeParam>(foo));
|
||||
}
|
||||
|
||||
TYPED_TEST(
|
||||
MockMethodMockFunctionSignatureTest,
|
||||
IsMockFunctionCallMethodSignatureTheSameForAlternateCallable) {
|
||||
using ForRawSignature = decltype(&MockFunction<TypeParam>::Call);
|
||||
using ForStdFunction =
|
||||
decltype(&MockFunction<std::function<TypeParam>>::Call);
|
||||
EXPECT_TRUE((std::is_same<ForRawSignature, ForStdFunction>::value));
|
||||
}
|
||||
|
||||
|
||||
struct MockMethodSizes0 {
|
||||
MOCK_METHOD(void, func, ());
|
||||
};
|
||||
struct MockMethodSizes1 {
|
||||
MOCK_METHOD(void, func, (int));
|
||||
};
|
||||
struct MockMethodSizes2 {
|
||||
MOCK_METHOD(void, func, (int, int));
|
||||
};
|
||||
struct MockMethodSizes3 {
|
||||
MOCK_METHOD(void, func, (int, int, int));
|
||||
};
|
||||
struct MockMethodSizes4 {
|
||||
MOCK_METHOD(void, func, (int, int, int, int));
|
||||
};
|
||||
|
||||
struct LegacyMockMethodSizes0 {
|
||||
MOCK_METHOD0(func, void());
|
||||
};
|
||||
struct LegacyMockMethodSizes1 {
|
||||
MOCK_METHOD1(func, void(int));
|
||||
};
|
||||
struct LegacyMockMethodSizes2 {
|
||||
MOCK_METHOD2(func, void(int, int));
|
||||
};
|
||||
struct LegacyMockMethodSizes3 {
|
||||
MOCK_METHOD3(func, void(int, int, int));
|
||||
};
|
||||
struct LegacyMockMethodSizes4 {
|
||||
MOCK_METHOD4(func, void(int, int, int, int));
|
||||
};
|
||||
|
||||
|
||||
TEST(MockMethodMockFunctionTest, MockMethodSizeOverhead) {
|
||||
EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes1));
|
||||
EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes2));
|
||||
EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes3));
|
||||
EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes4));
|
||||
|
||||
EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes1));
|
||||
EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes2));
|
||||
EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes3));
|
||||
EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes4));
|
||||
|
||||
EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(MockMethodSizes0));
|
||||
}
|
||||
|
||||
void hasTwoParams(int, int);
|
||||
void MaybeThrows();
|
||||
void DoesntThrow() noexcept;
|
||||
struct MockMethodNoexceptSpecifier {
|
||||
MOCK_METHOD(void, func1, (), (noexcept));
|
||||
MOCK_METHOD(void, func2, (), (noexcept(true)));
|
||||
MOCK_METHOD(void, func3, (), (noexcept(false)));
|
||||
MOCK_METHOD(void, func4, (), (noexcept(noexcept(MaybeThrows()))));
|
||||
MOCK_METHOD(void, func5, (), (noexcept(noexcept(DoesntThrow()))));
|
||||
MOCK_METHOD(void, func6, (), (noexcept(noexcept(DoesntThrow())), const));
|
||||
MOCK_METHOD(void, func7, (), (const, noexcept(noexcept(DoesntThrow()))));
|
||||
// Put commas in the noexcept expression
|
||||
MOCK_METHOD(void, func8, (), (noexcept(noexcept(hasTwoParams(1, 2))), const));
|
||||
};
|
||||
|
||||
TEST(MockMethodMockFunctionTest, NoexceptSpecifierPreserved) {
|
||||
EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func1()));
|
||||
EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func2()));
|
||||
EXPECT_FALSE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func3()));
|
||||
EXPECT_FALSE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func4()));
|
||||
EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func5()));
|
||||
EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func6()));
|
||||
EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func7()));
|
||||
EXPECT_EQ(noexcept(std::declval<MockMethodNoexceptSpecifier>().func8()),
|
||||
noexcept(hasTwoParams(1, 2)));
|
||||
}
|
||||
|
||||
} // namespace gmock_function_mocker_test
|
||||
} // namespace testing
|
|
@ -1,720 +0,0 @@
|
|||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file tests the internal utilities.
|
||||
|
||||
#include "gmock/internal/gmock-internal-utils.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
#include "gtest/gtest-spi.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
// Indicates that this translation unit is part of Google Test's
|
||||
// implementation. It must come before gtest-internal-inl.h is
|
||||
// included, or there will be a compiler error. This trick is to
|
||||
// prevent a user from accidentally including gtest-internal-inl.h in
|
||||
// their code.
|
||||
#define GTEST_IMPLEMENTATION_ 1
|
||||
#include "src/gtest-internal-inl.h"
|
||||
#undef GTEST_IMPLEMENTATION_
|
||||
|
||||
#if GTEST_OS_CYGWIN
|
||||
# include <sys/types.h> // For ssize_t. NOLINT
|
||||
#endif
|
||||
|
||||
namespace proto2 {
|
||||
class Message;
|
||||
} // namespace proto2
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(JoinAsTupleTest, JoinsEmptyTuple) {
|
||||
EXPECT_EQ("", JoinAsTuple(Strings()));
|
||||
}
|
||||
|
||||
TEST(JoinAsTupleTest, JoinsOneTuple) {
|
||||
const char* fields[] = {"1"};
|
||||
EXPECT_EQ("1", JoinAsTuple(Strings(fields, fields + 1)));
|
||||
}
|
||||
|
||||
TEST(JoinAsTupleTest, JoinsTwoTuple) {
|
||||
const char* fields[] = {"1", "a"};
|
||||
EXPECT_EQ("(1, a)", JoinAsTuple(Strings(fields, fields + 2)));
|
||||
}
|
||||
|
||||
TEST(JoinAsTupleTest, JoinsTenTuple) {
|
||||
const char* fields[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"};
|
||||
EXPECT_EQ("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)",
|
||||
JoinAsTuple(Strings(fields, fields + 10)));
|
||||
}
|
||||
|
||||
TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameContainsNoWord) {
|
||||
EXPECT_EQ("", ConvertIdentifierNameToWords(""));
|
||||
EXPECT_EQ("", ConvertIdentifierNameToWords("_"));
|
||||
EXPECT_EQ("", ConvertIdentifierNameToWords("__"));
|
||||
}
|
||||
|
||||
TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameContainsDigits) {
|
||||
EXPECT_EQ("1", ConvertIdentifierNameToWords("_1"));
|
||||
EXPECT_EQ("2", ConvertIdentifierNameToWords("2_"));
|
||||
EXPECT_EQ("34", ConvertIdentifierNameToWords("_34_"));
|
||||
EXPECT_EQ("34 56", ConvertIdentifierNameToWords("_34_56"));
|
||||
}
|
||||
|
||||
TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameContainsCamelCaseWords) {
|
||||
EXPECT_EQ("a big word", ConvertIdentifierNameToWords("ABigWord"));
|
||||
EXPECT_EQ("foo bar", ConvertIdentifierNameToWords("FooBar"));
|
||||
EXPECT_EQ("foo", ConvertIdentifierNameToWords("Foo_"));
|
||||
EXPECT_EQ("foo bar", ConvertIdentifierNameToWords("_Foo_Bar_"));
|
||||
EXPECT_EQ("foo and bar", ConvertIdentifierNameToWords("_Foo__And_Bar"));
|
||||
}
|
||||
|
||||
TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameContains_SeparatedWords) {
|
||||
EXPECT_EQ("foo bar", ConvertIdentifierNameToWords("foo_bar"));
|
||||
EXPECT_EQ("foo", ConvertIdentifierNameToWords("_foo_"));
|
||||
EXPECT_EQ("foo bar", ConvertIdentifierNameToWords("_foo_bar_"));
|
||||
EXPECT_EQ("foo and bar", ConvertIdentifierNameToWords("_foo__and_bar"));
|
||||
}
|
||||
|
||||
TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameIsMixture) {
|
||||
EXPECT_EQ("foo bar 123", ConvertIdentifierNameToWords("Foo_bar123"));
|
||||
EXPECT_EQ("chapter 11 section 1",
|
||||
ConvertIdentifierNameToWords("_Chapter11Section_1_"));
|
||||
}
|
||||
|
||||
TEST(GetRawPointerTest, WorksForSmartPointers) {
|
||||
const char* const raw_p1 = new const char('a'); // NOLINT
|
||||
const std::unique_ptr<const char> p1(raw_p1);
|
||||
EXPECT_EQ(raw_p1, GetRawPointer(p1));
|
||||
double* const raw_p2 = new double(2.5); // NOLINT
|
||||
const std::shared_ptr<double> p2(raw_p2);
|
||||
EXPECT_EQ(raw_p2, GetRawPointer(p2));
|
||||
}
|
||||
|
||||
TEST(GetRawPointerTest, WorksForRawPointers) {
|
||||
int* p = nullptr;
|
||||
EXPECT_TRUE(nullptr == GetRawPointer(p));
|
||||
int n = 1;
|
||||
EXPECT_EQ(&n, GetRawPointer(&n));
|
||||
}
|
||||
|
||||
// Tests KindOf<T>.
|
||||
|
||||
class Base {};
|
||||
class Derived : public Base {};
|
||||
|
||||
TEST(KindOfTest, Bool) {
|
||||
EXPECT_EQ(kBool, GMOCK_KIND_OF_(bool)); // NOLINT
|
||||
}
|
||||
|
||||
TEST(KindOfTest, Integer) {
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(char)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(signed char)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(unsigned char)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(short)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(unsigned short)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(int)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(unsigned int)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(long)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(unsigned long)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(long long)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(unsigned long long)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(wchar_t)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(size_t)); // NOLINT
|
||||
#if GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN
|
||||
// ssize_t is not defined on Windows and possibly some other OSes.
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(ssize_t)); // NOLINT
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(KindOfTest, FloatingPoint) {
|
||||
EXPECT_EQ(kFloatingPoint, GMOCK_KIND_OF_(float)); // NOLINT
|
||||
EXPECT_EQ(kFloatingPoint, GMOCK_KIND_OF_(double)); // NOLINT
|
||||
EXPECT_EQ(kFloatingPoint, GMOCK_KIND_OF_(long double)); // NOLINT
|
||||
}
|
||||
|
||||
TEST(KindOfTest, Other) {
|
||||
EXPECT_EQ(kOther, GMOCK_KIND_OF_(void*)); // NOLINT
|
||||
EXPECT_EQ(kOther, GMOCK_KIND_OF_(char**)); // NOLINT
|
||||
EXPECT_EQ(kOther, GMOCK_KIND_OF_(Base)); // NOLINT
|
||||
}
|
||||
|
||||
// Tests LosslessArithmeticConvertible<T, U>.
|
||||
|
||||
TEST(LosslessArithmeticConvertibleTest, BoolToBool) {
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<bool, bool>::value));
|
||||
}
|
||||
|
||||
TEST(LosslessArithmeticConvertibleTest, BoolToInteger) {
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<bool, char>::value));
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<bool, int>::value));
|
||||
EXPECT_TRUE(
|
||||
(LosslessArithmeticConvertible<bool, unsigned long>::value)); // NOLINT
|
||||
}
|
||||
|
||||
TEST(LosslessArithmeticConvertibleTest, BoolToFloatingPoint) {
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<bool, float>::value));
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<bool, double>::value));
|
||||
}
|
||||
|
||||
TEST(LosslessArithmeticConvertibleTest, IntegerToBool) {
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<unsigned char, bool>::value));
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<int, bool>::value));
|
||||
}
|
||||
|
||||
TEST(LosslessArithmeticConvertibleTest, IntegerToInteger) {
|
||||
// Unsigned => larger signed is fine.
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<unsigned char, int>::value));
|
||||
|
||||
// Unsigned => larger unsigned is fine.
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<
|
||||
unsigned short, uint64_t>::value)); // NOLINT
|
||||
|
||||
// Signed => unsigned is not fine.
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<
|
||||
short, uint64_t>::value)); // NOLINT
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<
|
||||
signed char, unsigned int>::value)); // NOLINT
|
||||
|
||||
// Same size and same signedness: fine too.
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<
|
||||
unsigned char, unsigned char>::value));
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<int, int>::value));
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<wchar_t, wchar_t>::value));
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<
|
||||
unsigned long, unsigned long>::value)); // NOLINT
|
||||
|
||||
// Same size, different signedness: not fine.
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<
|
||||
unsigned char, signed char>::value));
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<int, unsigned int>::value));
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<uint64_t, int64_t>::value));
|
||||
|
||||
// Larger size => smaller size is not fine.
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<long, char>::value)); // NOLINT
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<int, signed char>::value));
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<int64_t, unsigned int>::value));
|
||||
}
|
||||
|
||||
TEST(LosslessArithmeticConvertibleTest, IntegerToFloatingPoint) {
|
||||
// Integers cannot be losslessly converted to floating-points, as
|
||||
// the format of the latter is implementation-defined.
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<char, float>::value));
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<int, double>::value));
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<
|
||||
short, long double>::value)); // NOLINT
|
||||
}
|
||||
|
||||
TEST(LosslessArithmeticConvertibleTest, FloatingPointToBool) {
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<float, bool>::value));
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<double, bool>::value));
|
||||
}
|
||||
|
||||
TEST(LosslessArithmeticConvertibleTest, FloatingPointToInteger) {
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<float, long>::value)); // NOLINT
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<double, int64_t>::value));
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<long double, int>::value));
|
||||
}
|
||||
|
||||
TEST(LosslessArithmeticConvertibleTest, FloatingPointToFloatingPoint) {
|
||||
// Smaller size => larger size is fine.
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<float, double>::value));
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<float, long double>::value));
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<double, long double>::value));
|
||||
|
||||
// Same size: fine.
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<float, float>::value));
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<double, double>::value));
|
||||
|
||||
// Larger size => smaller size is not fine.
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<double, float>::value));
|
||||
GTEST_INTENTIONAL_CONST_COND_PUSH_()
|
||||
if (sizeof(double) == sizeof(long double)) { // NOLINT
|
||||
GTEST_INTENTIONAL_CONST_COND_POP_()
|
||||
// In some implementations (e.g. MSVC), double and long double
|
||||
// have the same size.
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<long double, double>::value));
|
||||
} else {
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<long double, double>::value));
|
||||
}
|
||||
}
|
||||
|
||||
// Tests the TupleMatches() template function.
|
||||
|
||||
TEST(TupleMatchesTest, WorksForSize0) {
|
||||
std::tuple<> matchers;
|
||||
std::tuple<> values;
|
||||
|
||||
EXPECT_TRUE(TupleMatches(matchers, values));
|
||||
}
|
||||
|
||||
TEST(TupleMatchesTest, WorksForSize1) {
|
||||
std::tuple<Matcher<int> > matchers(Eq(1));
|
||||
std::tuple<int> values1(1), values2(2);
|
||||
|
||||
EXPECT_TRUE(TupleMatches(matchers, values1));
|
||||
EXPECT_FALSE(TupleMatches(matchers, values2));
|
||||
}
|
||||
|
||||
TEST(TupleMatchesTest, WorksForSize2) {
|
||||
std::tuple<Matcher<int>, Matcher<char> > matchers(Eq(1), Eq('a'));
|
||||
std::tuple<int, char> values1(1, 'a'), values2(1, 'b'), values3(2, 'a'),
|
||||
values4(2, 'b');
|
||||
|
||||
EXPECT_TRUE(TupleMatches(matchers, values1));
|
||||
EXPECT_FALSE(TupleMatches(matchers, values2));
|
||||
EXPECT_FALSE(TupleMatches(matchers, values3));
|
||||
EXPECT_FALSE(TupleMatches(matchers, values4));
|
||||
}
|
||||
|
||||
TEST(TupleMatchesTest, WorksForSize5) {
|
||||
std::tuple<Matcher<int>, Matcher<char>, Matcher<bool>,
|
||||
Matcher<long>, // NOLINT
|
||||
Matcher<std::string> >
|
||||
matchers(Eq(1), Eq('a'), Eq(true), Eq(2L), Eq("hi"));
|
||||
std::tuple<int, char, bool, long, std::string> // NOLINT
|
||||
values1(1, 'a', true, 2L, "hi"), values2(1, 'a', true, 2L, "hello"),
|
||||
values3(2, 'a', true, 2L, "hi");
|
||||
|
||||
EXPECT_TRUE(TupleMatches(matchers, values1));
|
||||
EXPECT_FALSE(TupleMatches(matchers, values2));
|
||||
EXPECT_FALSE(TupleMatches(matchers, values3));
|
||||
}
|
||||
|
||||
// Tests that Assert(true, ...) succeeds.
|
||||
TEST(AssertTest, SucceedsOnTrue) {
|
||||
Assert(true, __FILE__, __LINE__, "This should succeed.");
|
||||
Assert(true, __FILE__, __LINE__); // This should succeed too.
|
||||
}
|
||||
|
||||
// Tests that Assert(false, ...) generates a fatal failure.
|
||||
TEST(AssertTest, FailsFatallyOnFalse) {
|
||||
EXPECT_DEATH_IF_SUPPORTED({
|
||||
Assert(false, __FILE__, __LINE__, "This should fail.");
|
||||
}, "");
|
||||
|
||||
EXPECT_DEATH_IF_SUPPORTED({
|
||||
Assert(false, __FILE__, __LINE__);
|
||||
}, "");
|
||||
}
|
||||
|
||||
// Tests that Expect(true, ...) succeeds.
|
||||
TEST(ExpectTest, SucceedsOnTrue) {
|
||||
Expect(true, __FILE__, __LINE__, "This should succeed.");
|
||||
Expect(true, __FILE__, __LINE__); // This should succeed too.
|
||||
}
|
||||
|
||||
// Tests that Expect(false, ...) generates a non-fatal failure.
|
||||
TEST(ExpectTest, FailsNonfatallyOnFalse) {
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
Expect(false, __FILE__, __LINE__, "This should fail.");
|
||||
}, "This should fail");
|
||||
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
Expect(false, __FILE__, __LINE__);
|
||||
}, "Expectation failed");
|
||||
}
|
||||
|
||||
// Tests LogIsVisible().
|
||||
|
||||
class LogIsVisibleTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override { original_verbose_ = GMOCK_FLAG(verbose); }
|
||||
|
||||
void TearDown() override { GMOCK_FLAG(verbose) = original_verbose_; }
|
||||
|
||||
std::string original_verbose_;
|
||||
};
|
||||
|
||||
TEST_F(LogIsVisibleTest, AlwaysReturnsTrueIfVerbosityIsInfo) {
|
||||
GMOCK_FLAG(verbose) = kInfoVerbosity;
|
||||
EXPECT_TRUE(LogIsVisible(kInfo));
|
||||
EXPECT_TRUE(LogIsVisible(kWarning));
|
||||
}
|
||||
|
||||
TEST_F(LogIsVisibleTest, AlwaysReturnsFalseIfVerbosityIsError) {
|
||||
GMOCK_FLAG(verbose) = kErrorVerbosity;
|
||||
EXPECT_FALSE(LogIsVisible(kInfo));
|
||||
EXPECT_FALSE(LogIsVisible(kWarning));
|
||||
}
|
||||
|
||||
TEST_F(LogIsVisibleTest, WorksWhenVerbosityIsWarning) {
|
||||
GMOCK_FLAG(verbose) = kWarningVerbosity;
|
||||
EXPECT_FALSE(LogIsVisible(kInfo));
|
||||
EXPECT_TRUE(LogIsVisible(kWarning));
|
||||
}
|
||||
|
||||
#if GTEST_HAS_STREAM_REDIRECTION
|
||||
|
||||
// Tests the Log() function.
|
||||
|
||||
// Verifies that Log() behaves correctly for the given verbosity level
|
||||
// and log severity.
|
||||
void TestLogWithSeverity(const std::string& verbosity, LogSeverity severity,
|
||||
bool should_print) {
|
||||
const std::string old_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = verbosity;
|
||||
CaptureStdout();
|
||||
Log(severity, "Test log.\n", 0);
|
||||
if (should_print) {
|
||||
EXPECT_THAT(GetCapturedStdout().c_str(),
|
||||
ContainsRegex(
|
||||
severity == kWarning ?
|
||||
"^\nGMOCK WARNING:\nTest log\\.\nStack trace:\n" :
|
||||
"^\nTest log\\.\nStack trace:\n"));
|
||||
} else {
|
||||
EXPECT_STREQ("", GetCapturedStdout().c_str());
|
||||
}
|
||||
GMOCK_FLAG(verbose) = old_flag;
|
||||
}
|
||||
|
||||
// Tests that when the stack_frames_to_skip parameter is negative,
|
||||
// Log() doesn't include the stack trace in the output.
|
||||
TEST(LogTest, NoStackTraceWhenStackFramesToSkipIsNegative) {
|
||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = kInfoVerbosity;
|
||||
CaptureStdout();
|
||||
Log(kInfo, "Test log.\n", -1);
|
||||
EXPECT_STREQ("\nTest log.\n", GetCapturedStdout().c_str());
|
||||
GMOCK_FLAG(verbose) = saved_flag;
|
||||
}
|
||||
|
||||
struct MockStackTraceGetter : testing::internal::OsStackTraceGetterInterface {
|
||||
std::string CurrentStackTrace(int max_depth, int skip_count) override {
|
||||
return (testing::Message() << max_depth << "::" << skip_count << "\n")
|
||||
.GetString();
|
||||
}
|
||||
void UponLeavingGTest() override {}
|
||||
};
|
||||
|
||||
// Tests that in opt mode, a positive stack_frames_to_skip argument is
|
||||
// treated as 0.
|
||||
TEST(LogTest, NoSkippingStackFrameInOptMode) {
|
||||
MockStackTraceGetter* mock_os_stack_trace_getter = new MockStackTraceGetter;
|
||||
GetUnitTestImpl()->set_os_stack_trace_getter(mock_os_stack_trace_getter);
|
||||
|
||||
CaptureStdout();
|
||||
Log(kWarning, "Test log.\n", 100);
|
||||
const std::string log = GetCapturedStdout();
|
||||
|
||||
std::string expected_trace =
|
||||
(testing::Message() << GTEST_FLAG(stack_trace_depth) << "::").GetString();
|
||||
std::string expected_message =
|
||||
"\nGMOCK WARNING:\n"
|
||||
"Test log.\n"
|
||||
"Stack trace:\n" +
|
||||
expected_trace;
|
||||
EXPECT_THAT(log, HasSubstr(expected_message));
|
||||
int skip_count = atoi(log.substr(expected_message.size()).c_str());
|
||||
|
||||
# if defined(NDEBUG)
|
||||
// In opt mode, no stack frame should be skipped.
|
||||
const int expected_skip_count = 0;
|
||||
# else
|
||||
// In dbg mode, the stack frames should be skipped.
|
||||
const int expected_skip_count = 100;
|
||||
# endif
|
||||
|
||||
// Note that each inner implementation layer will +1 the number to remove
|
||||
// itself from the trace. This means that the value is a little higher than
|
||||
// expected, but close enough.
|
||||
EXPECT_THAT(skip_count,
|
||||
AllOf(Ge(expected_skip_count), Le(expected_skip_count + 10)));
|
||||
|
||||
// Restores the default OS stack trace getter.
|
||||
GetUnitTestImpl()->set_os_stack_trace_getter(nullptr);
|
||||
}
|
||||
|
||||
// Tests that all logs are printed when the value of the
|
||||
// --gmock_verbose flag is "info".
|
||||
TEST(LogTest, AllLogsArePrintedWhenVerbosityIsInfo) {
|
||||
TestLogWithSeverity(kInfoVerbosity, kInfo, true);
|
||||
TestLogWithSeverity(kInfoVerbosity, kWarning, true);
|
||||
}
|
||||
|
||||
// Tests that only warnings are printed when the value of the
|
||||
// --gmock_verbose flag is "warning".
|
||||
TEST(LogTest, OnlyWarningsArePrintedWhenVerbosityIsWarning) {
|
||||
TestLogWithSeverity(kWarningVerbosity, kInfo, false);
|
||||
TestLogWithSeverity(kWarningVerbosity, kWarning, true);
|
||||
}
|
||||
|
||||
// Tests that no logs are printed when the value of the
|
||||
// --gmock_verbose flag is "error".
|
||||
TEST(LogTest, NoLogsArePrintedWhenVerbosityIsError) {
|
||||
TestLogWithSeverity(kErrorVerbosity, kInfo, false);
|
||||
TestLogWithSeverity(kErrorVerbosity, kWarning, false);
|
||||
}
|
||||
|
||||
// Tests that only warnings are printed when the value of the
|
||||
// --gmock_verbose flag is invalid.
|
||||
TEST(LogTest, OnlyWarningsArePrintedWhenVerbosityIsInvalid) {
|
||||
TestLogWithSeverity("invalid", kInfo, false);
|
||||
TestLogWithSeverity("invalid", kWarning, true);
|
||||
}
|
||||
|
||||
// Verifies that Log() behaves correctly for the given verbosity level
|
||||
// and log severity.
|
||||
std::string GrabOutput(void(*logger)(), const char* verbosity) {
|
||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = verbosity;
|
||||
CaptureStdout();
|
||||
logger();
|
||||
GMOCK_FLAG(verbose) = saved_flag;
|
||||
return GetCapturedStdout();
|
||||
}
|
||||
|
||||
class DummyMock {
|
||||
public:
|
||||
MOCK_METHOD0(TestMethod, void());
|
||||
MOCK_METHOD1(TestMethodArg, void(int dummy));
|
||||
};
|
||||
|
||||
void ExpectCallLogger() {
|
||||
DummyMock mock;
|
||||
EXPECT_CALL(mock, TestMethod());
|
||||
mock.TestMethod();
|
||||
}
|
||||
|
||||
// Verifies that EXPECT_CALL logs if the --gmock_verbose flag is set to "info".
|
||||
TEST(ExpectCallTest, LogsWhenVerbosityIsInfo) {
|
||||
EXPECT_THAT(std::string(GrabOutput(ExpectCallLogger, kInfoVerbosity)),
|
||||
HasSubstr("EXPECT_CALL(mock, TestMethod())"));
|
||||
}
|
||||
|
||||
// Verifies that EXPECT_CALL doesn't log
|
||||
// if the --gmock_verbose flag is set to "warning".
|
||||
TEST(ExpectCallTest, DoesNotLogWhenVerbosityIsWarning) {
|
||||
EXPECT_STREQ("", GrabOutput(ExpectCallLogger, kWarningVerbosity).c_str());
|
||||
}
|
||||
|
||||
// Verifies that EXPECT_CALL doesn't log
|
||||
// if the --gmock_verbose flag is set to "error".
|
||||
TEST(ExpectCallTest, DoesNotLogWhenVerbosityIsError) {
|
||||
EXPECT_STREQ("", GrabOutput(ExpectCallLogger, kErrorVerbosity).c_str());
|
||||
}
|
||||
|
||||
void OnCallLogger() {
|
||||
DummyMock mock;
|
||||
ON_CALL(mock, TestMethod());
|
||||
}
|
||||
|
||||
// Verifies that ON_CALL logs if the --gmock_verbose flag is set to "info".
|
||||
TEST(OnCallTest, LogsWhenVerbosityIsInfo) {
|
||||
EXPECT_THAT(std::string(GrabOutput(OnCallLogger, kInfoVerbosity)),
|
||||
HasSubstr("ON_CALL(mock, TestMethod())"));
|
||||
}
|
||||
|
||||
// Verifies that ON_CALL doesn't log
|
||||
// if the --gmock_verbose flag is set to "warning".
|
||||
TEST(OnCallTest, DoesNotLogWhenVerbosityIsWarning) {
|
||||
EXPECT_STREQ("", GrabOutput(OnCallLogger, kWarningVerbosity).c_str());
|
||||
}
|
||||
|
||||
// Verifies that ON_CALL doesn't log if
|
||||
// the --gmock_verbose flag is set to "error".
|
||||
TEST(OnCallTest, DoesNotLogWhenVerbosityIsError) {
|
||||
EXPECT_STREQ("", GrabOutput(OnCallLogger, kErrorVerbosity).c_str());
|
||||
}
|
||||
|
||||
void OnCallAnyArgumentLogger() {
|
||||
DummyMock mock;
|
||||
ON_CALL(mock, TestMethodArg(_));
|
||||
}
|
||||
|
||||
// Verifies that ON_CALL prints provided _ argument.
|
||||
TEST(OnCallTest, LogsAnythingArgument) {
|
||||
EXPECT_THAT(std::string(GrabOutput(OnCallAnyArgumentLogger, kInfoVerbosity)),
|
||||
HasSubstr("ON_CALL(mock, TestMethodArg(_)"));
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_STREAM_REDIRECTION
|
||||
|
||||
// Tests StlContainerView.
|
||||
|
||||
TEST(StlContainerViewTest, WorksForStlContainer) {
|
||||
StaticAssertTypeEq<std::vector<int>,
|
||||
StlContainerView<std::vector<int> >::type>();
|
||||
StaticAssertTypeEq<const std::vector<double>&,
|
||||
StlContainerView<std::vector<double> >::const_reference>();
|
||||
|
||||
typedef std::vector<char> Chars;
|
||||
Chars v1;
|
||||
const Chars& v2(StlContainerView<Chars>::ConstReference(v1));
|
||||
EXPECT_EQ(&v1, &v2);
|
||||
|
||||
v1.push_back('a');
|
||||
Chars v3 = StlContainerView<Chars>::Copy(v1);
|
||||
EXPECT_THAT(v3, Eq(v3));
|
||||
}
|
||||
|
||||
TEST(StlContainerViewTest, WorksForStaticNativeArray) {
|
||||
StaticAssertTypeEq<NativeArray<int>,
|
||||
StlContainerView<int[3]>::type>();
|
||||
StaticAssertTypeEq<NativeArray<double>,
|
||||
StlContainerView<const double[4]>::type>();
|
||||
StaticAssertTypeEq<NativeArray<char[3]>,
|
||||
StlContainerView<const char[2][3]>::type>();
|
||||
|
||||
StaticAssertTypeEq<const NativeArray<int>,
|
||||
StlContainerView<int[2]>::const_reference>();
|
||||
|
||||
int a1[3] = { 0, 1, 2 };
|
||||
NativeArray<int> a2 = StlContainerView<int[3]>::ConstReference(a1);
|
||||
EXPECT_EQ(3U, a2.size());
|
||||
EXPECT_EQ(a1, a2.begin());
|
||||
|
||||
const NativeArray<int> a3 = StlContainerView<int[3]>::Copy(a1);
|
||||
ASSERT_EQ(3U, a3.size());
|
||||
EXPECT_EQ(0, a3.begin()[0]);
|
||||
EXPECT_EQ(1, a3.begin()[1]);
|
||||
EXPECT_EQ(2, a3.begin()[2]);
|
||||
|
||||
// Makes sure a1 and a3 aren't aliases.
|
||||
a1[0] = 3;
|
||||
EXPECT_EQ(0, a3.begin()[0]);
|
||||
}
|
||||
|
||||
TEST(StlContainerViewTest, WorksForDynamicNativeArray) {
|
||||
StaticAssertTypeEq<NativeArray<int>,
|
||||
StlContainerView<std::tuple<const int*, size_t> >::type>();
|
||||
StaticAssertTypeEq<
|
||||
NativeArray<double>,
|
||||
StlContainerView<std::tuple<std::shared_ptr<double>, int> >::type>();
|
||||
|
||||
StaticAssertTypeEq<
|
||||
const NativeArray<int>,
|
||||
StlContainerView<std::tuple<const int*, int> >::const_reference>();
|
||||
|
||||
int a1[3] = { 0, 1, 2 };
|
||||
const int* const p1 = a1;
|
||||
NativeArray<int> a2 =
|
||||
StlContainerView<std::tuple<const int*, int> >::ConstReference(
|
||||
std::make_tuple(p1, 3));
|
||||
EXPECT_EQ(3U, a2.size());
|
||||
EXPECT_EQ(a1, a2.begin());
|
||||
|
||||
const NativeArray<int> a3 = StlContainerView<std::tuple<int*, size_t> >::Copy(
|
||||
std::make_tuple(static_cast<int*>(a1), 3));
|
||||
ASSERT_EQ(3U, a3.size());
|
||||
EXPECT_EQ(0, a3.begin()[0]);
|
||||
EXPECT_EQ(1, a3.begin()[1]);
|
||||
EXPECT_EQ(2, a3.begin()[2]);
|
||||
|
||||
// Makes sure a1 and a3 aren't aliases.
|
||||
a1[0] = 3;
|
||||
EXPECT_EQ(0, a3.begin()[0]);
|
||||
}
|
||||
|
||||
// Tests the Function template struct.
|
||||
|
||||
TEST(FunctionTest, Nullary) {
|
||||
typedef Function<int()> F; // NOLINT
|
||||
EXPECT_EQ(0u, F::ArgumentCount);
|
||||
EXPECT_TRUE((std::is_same<int, F::Result>::value));
|
||||
EXPECT_TRUE((std::is_same<std::tuple<>, F::ArgumentTuple>::value));
|
||||
EXPECT_TRUE((std::is_same<std::tuple<>, F::ArgumentMatcherTuple>::value));
|
||||
EXPECT_TRUE((std::is_same<void(), F::MakeResultVoid>::value));
|
||||
EXPECT_TRUE((std::is_same<IgnoredValue(), F::MakeResultIgnoredValue>::value));
|
||||
}
|
||||
|
||||
TEST(FunctionTest, Unary) {
|
||||
typedef Function<int(bool)> F; // NOLINT
|
||||
EXPECT_EQ(1u, F::ArgumentCount);
|
||||
EXPECT_TRUE((std::is_same<int, F::Result>::value));
|
||||
EXPECT_TRUE((std::is_same<bool, F::Arg<0>::type>::value));
|
||||
EXPECT_TRUE((std::is_same<std::tuple<bool>, F::ArgumentTuple>::value));
|
||||
EXPECT_TRUE((
|
||||
std::is_same<std::tuple<Matcher<bool>>, F::ArgumentMatcherTuple>::value));
|
||||
EXPECT_TRUE((std::is_same<void(bool), F::MakeResultVoid>::value)); // NOLINT
|
||||
EXPECT_TRUE((std::is_same<IgnoredValue(bool), // NOLINT
|
||||
F::MakeResultIgnoredValue>::value));
|
||||
}
|
||||
|
||||
TEST(FunctionTest, Binary) {
|
||||
typedef Function<int(bool, const long&)> F; // NOLINT
|
||||
EXPECT_EQ(2u, F::ArgumentCount);
|
||||
EXPECT_TRUE((std::is_same<int, F::Result>::value));
|
||||
EXPECT_TRUE((std::is_same<bool, F::Arg<0>::type>::value));
|
||||
EXPECT_TRUE((std::is_same<const long&, F::Arg<1>::type>::value)); // NOLINT
|
||||
EXPECT_TRUE((std::is_same<std::tuple<bool, const long&>, // NOLINT
|
||||
F::ArgumentTuple>::value));
|
||||
EXPECT_TRUE(
|
||||
(std::is_same<std::tuple<Matcher<bool>, Matcher<const long&>>, // NOLINT
|
||||
F::ArgumentMatcherTuple>::value));
|
||||
EXPECT_TRUE((std::is_same<void(bool, const long&), // NOLINT
|
||||
F::MakeResultVoid>::value));
|
||||
EXPECT_TRUE((std::is_same<IgnoredValue(bool, const long&), // NOLINT
|
||||
F::MakeResultIgnoredValue>::value));
|
||||
}
|
||||
|
||||
TEST(FunctionTest, LongArgumentList) {
|
||||
typedef Function<char(bool, int, char*, int&, const long&)> F; // NOLINT
|
||||
EXPECT_EQ(5u, F::ArgumentCount);
|
||||
EXPECT_TRUE((std::is_same<char, F::Result>::value));
|
||||
EXPECT_TRUE((std::is_same<bool, F::Arg<0>::type>::value));
|
||||
EXPECT_TRUE((std::is_same<int, F::Arg<1>::type>::value));
|
||||
EXPECT_TRUE((std::is_same<char*, F::Arg<2>::type>::value));
|
||||
EXPECT_TRUE((std::is_same<int&, F::Arg<3>::type>::value));
|
||||
EXPECT_TRUE((std::is_same<const long&, F::Arg<4>::type>::value)); // NOLINT
|
||||
EXPECT_TRUE(
|
||||
(std::is_same<std::tuple<bool, int, char*, int&, const long&>, // NOLINT
|
||||
F::ArgumentTuple>::value));
|
||||
EXPECT_TRUE(
|
||||
(std::is_same<
|
||||
std::tuple<Matcher<bool>, Matcher<int>, Matcher<char*>, Matcher<int&>,
|
||||
Matcher<const long&>>, // NOLINT
|
||||
F::ArgumentMatcherTuple>::value));
|
||||
EXPECT_TRUE(
|
||||
(std::is_same<void(bool, int, char*, int&, const long&), // NOLINT
|
||||
F::MakeResultVoid>::value));
|
||||
EXPECT_TRUE((
|
||||
std::is_same<IgnoredValue(bool, int, char*, int&, const long&), // NOLINT
|
||||
F::MakeResultIgnoredValue>::value));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace internal
|
||||
} // namespace testing
|