Compare commits

..

1 Commits

Author SHA1 Message Date
Jesse Beder
54e63e3f8c Revert "Hide most of non-public symbols by default (#984)"
This reverts commit da1c8d360e.
2021-09-28 08:40:58 -05:00
337 changed files with 24132 additions and 20476 deletions

View File

@@ -1,72 +0,0 @@
name: Github PR
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_dispatch:
permissions: read-all
jobs:
cmake-build:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
build: [static, shared]
generator: ["Default Generator", "MinGW Makefiles"]
exclude:
- os: macos-latest
build: shared
- os: macos-latest
generator: "MinGW Makefiles"
- os: ubuntu-latest
generator: "MinGW Makefiles"
env:
YAML_BUILD_SHARED_LIBS: ${{ matrix.build == 'shared' && 'ON' || 'OFF' }}
YAML_CPP_BUILD_TESTS: 'ON'
CMAKE_GENERATOR: >-
${{format(matrix.generator != 'Default Generator' && '-G "{0}"' || '', matrix.generator)}}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- name: Get number of CPU cores
uses: SimenB/github-actions-cpu-cores@v1
- name: Build
shell: bash
run: |
cmake ${{ env.CMAKE_GENERATOR }} -S "${{ github.workspace }}" -B build -DYAML_BUILD_SHARED_LIBS=${{ env.YAML_BUILD_SHARED_LIBS }}
cd build && cmake --build . --parallel ${{ steps.cpu-cores.outputs.count }}
- name: Build Tests
shell: bash
run: |
cmake ${{ env.CMAKE_GENERATOR }} -S "${{ github.workspace }}" -B build -DYAML_BUILD_SHARED_LIBS=${{ env.YAML_BUILD_SHARED_LIBS }} -DYAML_CPP_BUILD_TESTS=${{ env.YAML_CPP_BUILD_TESTS }}
cd build && cmake --build . --parallel ${{ steps.cpu-cores.outputs.count }}
- name: Run Tests
shell: bash
run: |
cd build && ctest -C Debug --output-on-failure --verbose
bazel-build:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- name: Build
shell: bash
run: |
cd "${{ github.workspace }}"
bazel build :all
- name: Test
shell: bash
run: |
cd "${{ github.workspace }}"
bazel test test

37
.travis.yml Normal file
View File

@@ -0,0 +1,37 @@
language: c++
matrix:
include:
- os: linux
compiler: gcc
- os: osx
compiler: clang
- os: osx
compiler: gcc
env:
- CTEST_OUTPUT_ON_FAILURE=1
before_script:
- mkdir build
- cd build
- cmake ..
- cd ..
script:
- cmake --build build
- cmake --build build --target test
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.9
packages:
- g++-4.9
- clang-3.9
update: true
homebrew:
packages:
- ccache
- gcc@4.9
- llvm@4
update: true

View File

@@ -1,9 +1,3 @@
yaml_cpp_defines = select({
# On Windows, ensure static linking is used.
"@platforms//os:windows": ["YAML_CPP_STATIC_DEFINE", "YAML_CPP_NO_CONTRIB"],
"//conditions:default": [],
})
cc_library(
name = "yaml-cpp_internal",
visibility = ["//:__subpackages__"],
@@ -17,5 +11,4 @@ cc_library(
includes = ["include"],
hdrs = glob(["include/**/*.h"]),
srcs = glob(["src/**/*.cpp", "src/**/*.h"]),
defines = yaml_cpp_defines,
)

View File

@@ -7,12 +7,7 @@ if(POLICY CMP0091)
cmake_policy(SET CMP0091 NEW)
endif()
project(YAML_CPP VERSION 0.8.0 LANGUAGES CXX)
set(YAML_CPP_MAIN_PROJECT OFF)
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
set(YAML_CPP_MAIN_PROJECT ON)
endif()
project(YAML_CPP VERSION 0.7.0 LANGUAGES CXX)
include(CMakePackageConfigHelpers)
include(CMakeDependentOption)
@@ -20,28 +15,27 @@ include(CheckCXXCompilerFlag)
include(GNUInstallDirs)
include(CTest)
find_program(YAML_CPP_CLANG_FORMAT_EXE NAMES clang-format)
option(YAML_CPP_BUILD_CONTRIB "Enable yaml-cpp contrib in library" ON)
option(YAML_CPP_BUILD_TOOLS "Enable parse tools" ON)
option(YAML_BUILD_SHARED_LIBS "Build yaml-cpp shared library" ${BUILD_SHARED_LIBS})
option(YAML_CPP_INSTALL "Enable generation of yaml-cpp install targets" ${YAML_CPP_MAIN_PROJECT})
option(YAML_CPP_FORMAT_SOURCE "Format source" ON)
cmake_dependent_option(YAML_CPP_BUILD_TESTS
"Enable yaml-cpp tests" OFF
"BUILD_TESTING;YAML_CPP_MAIN_PROJECT" OFF)
"Enable yaml-cpp tests" ON
"BUILD_TESTING;CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
cmake_dependent_option(YAML_CPP_INSTALL
"Enable generation of yaml-cpp install targets" ON
"CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
cmake_dependent_option(YAML_MSVC_SHARED_RT
"MSVC: Build yaml-cpp with shared runtime libs (/MD)" ON
"CMAKE_SYSTEM_NAME MATCHES Windows" OFF)
if (YAML_CPP_FORMAT_SOURCE)
find_program(YAML_CPP_CLANG_FORMAT_EXE NAMES clang-format)
endif()
"MSVC" OFF)
set(yaml-cpp-type STATIC)
set(yaml-cpp-label-postfix "static")
if (YAML_BUILD_SHARED_LIBS)
set(yaml-cpp-type SHARED)
set(yaml-cpp-label-postfix "shared")
else()
set(yaml-cpp-type STATIC)
set(yaml-cpp-label-postfix "static")
endif()
set(build-shared $<BOOL:${YAML_BUILD_SHARED_LIBS}>)
@@ -84,10 +78,6 @@ set_property(TARGET yaml-cpp
PROPERTY
CXX_STANDARD_REQUIRED ON)
if (NOT YAML_BUILD_SHARED_LIBS)
set_property(TARGET yaml-cpp PROPERTY POSITION_INDEPENDENT_CODE ON)
endif()
target_include_directories(yaml-cpp
PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
@@ -101,15 +91,11 @@ if (NOT DEFINED CMAKE_CXX_STANDARD)
CXX_STANDARD 11)
endif()
if(YAML_CPP_MAIN_PROJECT)
target_compile_options(yaml-cpp
PRIVATE
$<${not-msvc}:-Wall -Wextra -Wshadow -Weffc++ -Wno-long-long>
$<${not-msvc}:-pedantic -pedantic-errors>)
endif()
target_compile_options(yaml-cpp
PRIVATE
$<${not-msvc}:-Wall -Wextra -Wshadow -Weffc++ -Wno-long-long>
$<${not-msvc}:-pedantic -pedantic-errors>
$<$<AND:${backport-msvc-runtime},${msvc-rt-mtd-static}>:-MTd>
$<$<AND:${backport-msvc-runtime},${msvc-rt-mt-static}>:-MT>
$<$<AND:${backport-msvc-runtime},${msvc-rt-mtd-dll}>:-MDd>
@@ -122,8 +108,6 @@ target_compile_options(yaml-cpp
$<$<CXX_COMPILER_ID:MSVC>:/W3 /wd4127 /wd4355>)
target_compile_definitions(yaml-cpp
PUBLIC
$<$<NOT:$<BOOL:${YAML_BUILD_SHARED_LIBS}>>:YAML_CPP_STATIC_DEFINE>
PRIVATE
$<${build-windows-dll}:${PROJECT_NAME}_DLL>
$<$<NOT:$<BOOL:${YAML_CPP_BUILD_CONTRIB}>>:YAML_CPP_NO_CONTRIB>)
@@ -143,14 +127,10 @@ set_target_properties(yaml-cpp PROPERTIES
PROJECT_LABEL "yaml-cpp ${yaml-cpp-label-postfix}"
DEBUG_POSTFIX "${CMAKE_DEBUG_POSTFIX}")
set(CONFIG_EXPORT_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/yaml-cpp")
set(EXPORT_TARGETS yaml-cpp)
configure_package_config_file(
"${PROJECT_SOURCE_DIR}/yaml-cpp-config.cmake.in"
"${PROJECT_BINARY_DIR}/yaml-cpp-config.cmake"
INSTALL_DESTINATION "${CONFIG_EXPORT_DIR}"
PATH_VARS CMAKE_INSTALL_INCLUDEDIR CMAKE_INSTALL_LIBDIR CONFIG_EXPORT_DIR YAML_BUILD_SHARED_LIBS)
unset(EXPORT_TARGETS)
INSTALL_DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/yaml-cpp")
write_basic_package_version_file(
"${PROJECT_BINARY_DIR}/yaml-cpp-config-version.cmake"
@@ -159,49 +139,36 @@ write_basic_package_version_file(
configure_file(yaml-cpp.pc.in yaml-cpp.pc @ONLY)
if (YAML_CPP_INSTALL)
install(TARGETS yaml-cpp
install(TARGETS yaml-cpp
EXPORT yaml-cpp-targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING PATTERN "*.h")
FILES_MATCHING PATTERN "*.h")
install(EXPORT yaml-cpp-targets
NAMESPACE yaml-cpp::
DESTINATION "${CONFIG_EXPORT_DIR}")
install(FILES
"${PROJECT_BINARY_DIR}/yaml-cpp-config.cmake"
"${PROJECT_BINARY_DIR}/yaml-cpp-config-version.cmake"
DESTINATION "${CONFIG_EXPORT_DIR}")
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/yaml-cpp")
install(FILES
"${PROJECT_BINARY_DIR}/yaml-cpp-config.cmake"
"${PROJECT_BINARY_DIR}/yaml-cpp-config-version.cmake"
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/yaml-cpp")
install(FILES "${PROJECT_BINARY_DIR}/yaml-cpp.pc"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
DESTINATION ${CMAKE_INSTALL_DATADIR}/pkgconfig)
endif()
unset(CONFIG_EXPORT_DIR)
if(YAML_CPP_BUILD_TESTS)
add_subdirectory(test)
add_subdirectory(test)
endif()
if(YAML_CPP_BUILD_TOOLS)
add_subdirectory(util)
add_subdirectory(util)
endif()
if (YAML_CPP_FORMAT_SOURCE AND YAML_CPP_CLANG_FORMAT_EXE)
if (YAML_CPP_CLANG_FORMAT_EXE)
add_custom_target(format
COMMAND clang-format --style=file -i $<TARGET_PROPERTY:yaml-cpp,SOURCES>
COMMAND_EXPAND_LISTS
COMMENT "Running clang-format"
VERBATIM)
endif()
# uninstall target
if(NOT TARGET uninstall)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
endif()

View File

@@ -17,7 +17,7 @@ Commit messages should be in the imperative mood, as described in the [Git contr
# Tests
Please verify the tests pass by running the target `test/yaml-cpp-tests`.
Please verify the tests pass by running the target `tests/run_tests`.
If you are adding functionality, add tests accordingly.

View File

@@ -1,46 +1,50 @@
# yaml-cpp ![Build Status](https://github.com/jbeder/yaml-cpp/actions/workflows/build.yml/badge.svg) [![Documentation](https://codedocs.xyz/jbeder/yaml-cpp.svg)](https://codedocs.xyz/jbeder/yaml-cpp/)
# yaml-cpp [![Build Status](https://travis-ci.org/jbeder/yaml-cpp.svg?branch=master)](https://travis-ci.org/jbeder/yaml-cpp) [![Documentation](https://codedocs.xyz/jbeder/yaml-cpp.svg)](https://codedocs.xyz/jbeder/yaml-cpp/)
`yaml-cpp` is a [YAML](http://www.yaml.org/) parser and emitter in C++ matching the [YAML 1.2 spec](http://www.yaml.org/spec/1.2/spec.html).
yaml-cpp is a [YAML](http://www.yaml.org/) parser and emitter in C++ matching the [YAML 1.2 spec](http://www.yaml.org/spec/1.2/spec.html).
## Usage
To get a feel for how it can be used, see the [Tutorial](https://github.com/jbeder/yaml-cpp/wiki/Tutorial) or [How to Emit YAML](https://github.com/jbeder/yaml-cpp/wiki/How-To-Emit-YAML). For the old API (version < 0.5.0), see [How To Parse A Document](https://github.com/jbeder/yaml-cpp/wiki/How-To-Parse-A-Document-(Old-API)).
See [Tutorial](https://github.com/jbeder/yaml-cpp/wiki/Tutorial) and [How to Emit YAML](https://github.com/jbeder/yaml-cpp/wiki/How-To-Emit-YAML) for reference. For the old API (until 0.5.0), see [How To Parse A Document](https://github.com/jbeder/yaml-cpp/wiki/How-To-Parse-A-Document-(Old-API)).
## Any Problems?
# Problems? #
If you find a bug, post an [issue](https://github.com/jbeder/yaml-cpp/issues)! If you have questions about how to use yaml-cpp, please post it on http://stackoverflow.com and tag it [`yaml-cpp`](http://stackoverflow.com/questions/tagged/yaml-cpp).
## How to Build
# How to Build #
`yaml-cpp` uses [CMake](http://www.cmake.org) to support cross-platform building. Install [CMake](http://www.cmake.org) _(Resources -> Download)_ before proceeding. The basic steps to build are:
yaml-cpp uses [CMake](http://www.cmake.org) to support cross-platform building. The basic steps to build are:
**Note:** If you don't use the provided installer for your platform, make sure that you add `CMake`'s bin folder to your path.
1. Download and install [CMake](http://www.cmake.org) (Resources -> Download).
#### 1. Navigate into the source directory, create build folder and run `CMake`:
**Note:** If you don't use the provided installer for your platform, make sure that you add CMake's bin folder to your path.
```sh
2. Navigate into the source directory, and type:
```
mkdir build
cd build
cmake [-G generator] [-DYAML_BUILD_SHARED_LIBS=on|OFF] ..
```
* The `generator` option is the build system you'd like to use. Run `cmake` without arguments to see a full list of available generators.
* On Windows, you might use "Visual Studio 12 2013" (VS 2013 32-bits), or "Visual Studio 14 2015 Win64" (VS 2015 64-bits).
* On OS X, you might use "Xcode".
* On a UNIX-like system, omit the option (for a Makefile).
3. Run CMake. The basic syntax is:
* `yaml-cpp` builds a static library by default, you may want to build a shared library by specifying `-DYAML_BUILD_SHARED_LIBS=ON`.
```
cmake [-G generator] [-DYAML_BUILD_SHARED_LIBS=ON|OFF] ..
```
* The `generator` is whatever type of build system you'd like to use. To see a full list of generators on your platform, just run `cmake` (with no arguments). For example:
* On Windows, you might use "Visual Studio 12 2013" to generate a Visual Studio 2013 solution or "Visual Studio 14 2015 Win64" to generate a 64-bit Visual Studio 2015 solution.
* On OS X, you might use "Xcode" to generate an Xcode project
* On a UNIX-y system, simply omit the option to generate a makefile
* yaml-cpp defaults to building a static library, but you may build a shared library by specifying `-DYAML_BUILD_SHARED_LIBS=ON`.
* For more options on customizing the build, see the [CMakeLists.txt](https://github.com/jbeder/yaml-cpp/blob/master/CMakeLists.txt) file.
#### 2. Build it!
* The command you'll need to run depends on the generator you chose earlier.
4. Build it!
**Note:** To clean up, just remove the `build` directory.
5. To clean up, just remove the `build` directory.
## Recent Releases
# Recent Release #
[yaml-cpp 0.6.0](https://github.com/jbeder/yaml-cpp/releases/tag/yaml-cpp-0.6.0) released! This release requires C++11, and no longer depends on Boost.
[yaml-cpp 0.6.0](https://github.com/jbeder/yaml-cpp/releases/tag/yaml-cpp-0.6.0) has been released! This release requires C++11, and no longer depends on Boost.
[yaml-cpp 0.3.0](https://github.com/jbeder/yaml-cpp/releases/tag/release-0.3.0) is still available if you want the old API.

View File

@@ -1,13 +0,0 @@
# Security Policy
## Supported Versions
Security updates are applied only to the latest release.
## Reporting a Vulnerability
If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released.
Please disclose it at [security advisory](https://github.com/jbeder/yaml-cpp/security/advisories/new).
This project is maintained by a team of volunteers on a reasonable-effort basis. As such, vulnerabilities will be disclosed in a best effort base.

28
appveyor.yml Normal file
View File

@@ -0,0 +1,28 @@
version: 1.0.{build}
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
CMAKE_GENERATOR: Visual Studio 14 2015
CMAKE_PLATFORM: win32
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
CMAKE_GENERATOR: Visual Studio 14 2015
CMAKE_PLATFORM: x64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
CMAKE_GENERATOR: Visual Studio 15 2017
CMAKE_PLATFORM: win32
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
CMAKE_GENERATOR: Visual Studio 15 2017
CMAKE_PLATFORM: x64
before_build:
- cmd: mkdir build
- cmd: cd build
- cmd: cmake .. -G "%CMAKE_GENERATOR%" -DCMAKE_GENERATOR_PLATFORM=%CMAKE_PLATFORM%
- cmd: cd ..
build_script:
- cmake --build build
test_script:
- cmd: cd build
- ctest

View File

@@ -1,21 +0,0 @@
if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
endif()
file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
foreach(file ${files})
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
exec_program(
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval
)
if(NOT "${rm_retval}" STREQUAL 0)
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
endif()
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
endif()
endforeach()

View File

@@ -1,61 +1,33 @@
#ifndef DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
// Definition YAML_CPP_STATIC_DEFINE using to building YAML-CPP as static
// library (definition created by CMake or defined manually)
// Definition yaml_cpp_EXPORTS using to building YAML-CPP as dll/so library
// (definition created by CMake or defined manually)
#ifdef YAML_CPP_STATIC_DEFINE
# define YAML_CPP_API
# define YAML_CPP_NO_EXPORT
#else
# if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)
# ifndef YAML_CPP_API
# ifdef yaml_cpp_EXPORTS
/* We are building this library */
# pragma message( "Defining YAML_CPP_API for DLL export" )
# define YAML_CPP_API __declspec(dllexport)
# else
/* We are using this library */
# pragma message( "Defining YAML_CPP_API for DLL import" )
# define YAML_CPP_API __declspec(dllimport)
# endif
# endif
# ifndef YAML_CPP_NO_EXPORT
# define YAML_CPP_NO_EXPORT
# endif
# else /* No _MSC_VER */
# ifndef YAML_CPP_API
# ifdef yaml_cpp_EXPORTS
/* We are building this library */
# define YAML_CPP_API __attribute__((visibility("default")))
# else
/* We are using this library */
# define YAML_CPP_API __attribute__((visibility("default")))
# endif
# endif
# ifndef YAML_CPP_NO_EXPORT
# define YAML_CPP_NO_EXPORT __attribute__((visibility("hidden")))
# endif
# endif /* _MSC_VER */
#endif /* YAML_CPP_STATIC_DEFINE */
#ifndef YAML_CPP_DEPRECATED
# ifdef _MSC_VER
# define YAML_CPP_DEPRECATED __declspec(deprecated)
# else
# define YAML_CPP_DEPRECATED __attribute__ ((__deprecated__))
# endif
#if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once
#endif
#ifndef YAML_CPP_DEPRECATED_EXPORT
# define YAML_CPP_DEPRECATED_EXPORT YAML_CPP_API YAML_CPP_DEPRECATED
#endif
// The following ifdef block is the standard way of creating macros which make
// exporting from a DLL simpler. All files within this DLL are compiled with the
// yaml_cpp_EXPORTS symbol defined on the command line. This symbol should not
// be defined on any project that uses this DLL. This way any other project
// whose source files include this file see YAML_CPP_API functions as being
// imported from a DLL, whereas this DLL sees symbols defined with this macro as
// being exported.
#undef YAML_CPP_API
#ifndef YAML_CPP_DEPRECATED_NO_EXPORT
# define YAML_CPP_DEPRECATED_NO_EXPORT YAML_CPP_NO_EXPORT YAML_CPP_DEPRECATED
#endif
#ifdef YAML_CPP_DLL // Using or Building YAML-CPP DLL (definition defined
// manually)
#ifdef yaml_cpp_EXPORTS // Building YAML-CPP DLL (definition created by CMake
// or defined manually)
// #pragma message( "Defining YAML_CPP_API for DLL export" )
#define YAML_CPP_API __declspec(dllexport)
#else // yaml_cpp_EXPORTS
// #pragma message( "Defining YAML_CPP_API for DLL import" )
#define YAML_CPP_API __declspec(dllimport)
#endif // yaml_cpp_EXPORTS
#else // YAML_CPP_DLL
#define YAML_CPP_API
#endif // YAML_CPP_DLL
#endif /* DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 */
#endif // DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -12,16 +12,10 @@
#include <limits>
#include <list>
#include <map>
#include <unordered_map>
#include <sstream>
#include <type_traits>
#include <valarray>
#include <vector>
#if __cplusplus >= 201703L
#include <string_view>
#endif
#include "yaml-cpp/binary.h"
#include "yaml-cpp/node/impl.h"
#include "yaml-cpp/node/iterator.h"
@@ -93,20 +87,6 @@ struct convert<char[N]> {
static Node encode(const char* rhs) { return Node(rhs); }
};
#if __cplusplus >= 201703L
template <>
struct convert<std::string_view> {
static Node encode(std::string_view rhs) { return Node(std::string(rhs)); }
static bool decode(const Node& node, std::string_view& rhs) {
if (!node.IsScalar())
return false;
rhs = node.Scalar();
return true;
}
};
#endif
template <>
struct convert<_Null> {
static Node encode(const _Null& /* rhs */) { return Node(); }
@@ -147,7 +127,7 @@ ConvertStreamTo(std::stringstream& stream, T& rhs) {
if ((stream >> std::noskipws >> num) && (stream >> std::ws).eof()) {
if (num >= (std::numeric_limits<T>::min)() &&
num <= (std::numeric_limits<T>::max)()) {
rhs = static_cast<T>(num);
rhs = (T)num;
return true;
}
}
@@ -271,32 +251,6 @@ struct convert<std::map<K, V, C, A>> {
}
};
// std::unordered_map
template <typename K, typename V, typename H, typename P, typename A>
struct convert<std::unordered_map<K, V, H, P, A>> {
static Node encode(const std::unordered_map<K, V, H, P, A>& rhs) {
Node node(NodeType::Map);
for (const auto& element : rhs)
node.force_insert(element.first, element.second);
return node;
}
static bool decode(const Node& node, std::unordered_map<K, V, H, P, A>& rhs) {
if (!node.IsMap())
return false;
rhs.clear();
for (const auto& element : node)
#if defined(__GNUC__) && __GNUC__ < 4
// workaround for GCC 3:
rhs[element.first.template as<K>()] = element.second.template as<V>();
#else
rhs[element.first.as<K>()] = element.second.as<V>();
#endif
return true;
}
};
// std::vector
template <typename T, typename A>
struct convert<std::vector<T, A>> {
@@ -382,37 +336,6 @@ struct convert<std::array<T, N>> {
}
};
// std::valarray
template <typename T>
struct convert<std::valarray<T>> {
static Node encode(const std::valarray<T>& rhs) {
Node node(NodeType::Sequence);
for (const auto& element : rhs) {
node.push_back(element);
}
return node;
}
static bool decode(const Node& node, std::valarray<T>& rhs) {
if (!node.IsSequence()) {
return false;
}
rhs.resize(node.size());
for (auto i = 0u; i < node.size(); ++i) {
#if defined(__GNUC__) && __GNUC__ < 4
// workaround for GCC 3:
rhs[i] = node[i].template as<T>();
#else
rhs[i] = node[i].as<T>();
#endif
}
return true;
}
};
// std::pair
template <typename T, typename U>
struct convert<std::pair<T, U>> {

View File

@@ -169,7 +169,7 @@ class node {
using nodes = std::set<node*, less>;
nodes m_dependencies;
size_t m_index;
static YAML_CPP_API std::atomic<size_t> m_amount;
static std::atomic<size_t> m_amount;
};
} // namespace detail
} // namespace YAML

View File

@@ -7,6 +7,7 @@
#pragma once
#endif
#include "yaml-cpp/dll.h"
#include <memory>
namespace YAML {

View File

@@ -107,9 +107,9 @@ struct disable_if : public disable_if_c<Cond::value, T> {};
template <typename S, typename T>
struct is_streamable {
template <typename StreamT, typename ValueT>
template <typename SS, typename TT>
static auto test(int)
-> decltype(std::declval<StreamT&>() << std::declval<ValueT>(), std::true_type());
-> decltype(std::declval<SS&>() << std::declval<TT>(), std::true_type());
template <typename, typename>
static auto test(...) -> std::false_type;

View File

@@ -75,11 +75,11 @@ std::vector<unsigned char> DecodeBase64(const std::string &input) {
unsigned value = 0;
for (std::size_t i = 0, cnt = 0; i < input.size(); i++) {
if (std::isspace(static_cast<unsigned char>(input[i]))) {
if (std::isspace(input[i])) {
// skip newlines
continue;
}
unsigned char d = decoding[static_cast<unsigned char>(input[i])];
unsigned char d = decoding[static_cast<unsigned>(input[i])];
if (d == 255)
return ret_type();

View File

@@ -13,6 +13,7 @@
#include "yaml-cpp/anchor.h"
#include "yaml-cpp/contrib/anchordict.h"
#include "yaml-cpp/contrib/graphbuilder.h"
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/eventhandler.h"

View File

@@ -3,7 +3,7 @@
namespace YAML {
Directives::Directives() : version{true, 1, 2}, tags{} {}
std::string Directives::TranslateTagHandle(
const std::string Directives::TranslateTagHandle(
const std::string& handle) const {
auto it = tags.find(handle);
if (it == tags.end()) {

View File

@@ -19,7 +19,7 @@ struct Version {
struct Directives {
Directives();
std::string TranslateTagHandle(const std::string& handle) const;
const std::string TranslateTagHandle(const std::string& handle) const;
Version version;
std::map<std::string, std::string> tags;

View File

@@ -533,8 +533,7 @@ void Emitter::BlockMapPrepareNode(EmitterNodeType::value child) {
if (m_pState->GetMapKeyFormat() == LongKey)
m_pState->SetLongKey();
if (child == EmitterNodeType::BlockSeq ||
child == EmitterNodeType::BlockMap ||
child == EmitterNodeType::Property)
child == EmitterNodeType::BlockMap)
m_pState->SetLongKey();
if (m_pState->CurGroupLongKey())

View File

@@ -176,11 +176,11 @@ bool IsValidPlainScalar(const std::string& str, FlowType::value flowType,
static const RegEx& disallowed_flow =
Exp::EndScalarInFlow() | (Exp::BlankOrBreak() + Exp::Comment()) |
Exp::NotPrintable() | Exp::Utf8_ByteOrderMark() | Exp::Break() |
Exp::Tab() | Exp::Ampersand();
Exp::Tab();
static const RegEx& disallowed_block =
Exp::EndScalar() | (Exp::BlankOrBreak() + Exp::Comment()) |
Exp::NotPrintable() | Exp::Utf8_ByteOrderMark() | Exp::Break() |
Exp::Tab() | Exp::Ampersand();
Exp::Tab();
const RegEx& disallowed =
flowType == FlowType::Flow ? disallowed_flow : disallowed_block;

View File

@@ -37,7 +37,7 @@ inline const RegEx& Blank() {
return e;
}
inline const RegEx& Break() {
static const RegEx e = RegEx('\n') | RegEx("\r\n") | RegEx('\r');
static const RegEx e = RegEx('\n') | RegEx("\r\n");
return e;
}
inline const RegEx& BlankOrBreak() {
@@ -117,10 +117,6 @@ inline const RegEx& ValueInJSONFlow() {
static const RegEx e = RegEx(':');
return e;
}
inline const RegEx& Ampersand() {
static const RegEx e = RegEx('&');
return e;
}
inline const RegEx Comment() {
static const RegEx e = RegEx('#');
return e;

View File

@@ -13,7 +13,7 @@
namespace YAML {
namespace detail {
YAML_CPP_API std::atomic<size_t> node::m_amount{0};
std::atomic<size_t> node::m_amount{0};
const std::string& node_data::empty_scalar() {
static const std::string svalue;

View File

@@ -9,7 +9,9 @@
#include <cstddef>
#include <ios>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>

View File

@@ -29,7 +29,7 @@ Tag::Tag(const Token& token)
}
}
std::string Tag::Translate(const Directives& directives) {
const std::string Tag::Translate(const Directives& directives) {
switch (type) {
case VERBATIM:
return value;

View File

@@ -23,7 +23,7 @@ struct Tag {
};
Tag(const Token& token);
std::string Translate(const Directives& directives);
const std::string Translate(const Directives& directives);
TYPE type;
std::string handle, value;

View File

@@ -5,10 +5,10 @@ set(BUILD_MOCK ON CACHE BOOL "" FORCE)
set(CMAKE_POLICY_DEFAULT_CMP0048 NEW)
add_subdirectory(
"${CMAKE_CURRENT_SOURCE_DIR}/gtest-1.11.0"
"${CMAKE_CURRENT_SOURCE_DIR}/gtest-1.10.0"
"${CMAKE_CURRENT_BINARY_DIR}/prefix")
include_directories(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/gtest-1.11.0/googletest/include")
include_directories(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/gtest-1.10.0/googletest/include")
set(test-new-api-pattern "new-api/*.cpp")
set(test-source-pattern "*.cpp" "integration/*.cpp" "node/*.cpp")
@@ -46,11 +46,4 @@ if (NOT DEFINED CMAKE_CXX_STANDARD)
endif()
add_test(NAME yaml-cpp::test COMMAND yaml-cpp-tests)
if (build-windows-dll)
add_custom_command(
TARGET yaml-cpp-tests
POST_BUILD COMMAND ${CMAKE_COMMAND} -E
copy_if_different "$<TARGET_FILE:yaml-cpp>" "$<TARGET_FILE_DIR:yaml-cpp-tests>")
endif()
add_test(yaml-cpp::test yaml-cpp-tests)

View File

@@ -1,14 +0,0 @@
#include "gtest/gtest.h"
#include <yaml-cpp/binary.h>
TEST(BinaryTest, DecodingSimple) {
std::string input{90, 71, 86, 104, 90, 71, 74, 108, 90, 87, 89, 61};
const std::vector<unsigned char> &result = YAML::DecodeBase64(input);
EXPECT_EQ(std::string(result.begin(), result.end()), "deadbeef");
}
TEST(BinaryTest, DecodingNoCrashOnNegative) {
std::string input{-58, -1, -99, 109};
const std::vector<unsigned char> &result = YAML::DecodeBase64(input);
EXPECT_TRUE(result.empty());
}

View File

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

View File

@@ -36,19 +36,9 @@ 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__"],
constraint_values = ["@bazel_tools//platforms:windows"],
)
config_setting(
@@ -113,7 +103,6 @@ cc_library(
"@com_google_absl//absl/debugging:stacktrace",
"@com_google_absl//absl/debugging:symbolize",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/types:any",
"@com_google_absl//absl/types:optional",
"@com_google_absl//absl/types:variant",
],

View File

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

View File

@@ -28,7 +28,7 @@ PR is acceptable as an alternative.
## Contributing A Patch
1. Submit an issue describing your proposed change to the
[issue tracker](https://github.com/google/googletest/issues).
[issue tracker](https://github.com/google/googletest).
2. Please don't mix more than one logical change per submittal, because it
makes the history hard to follow. If you want to make a change that doesn't
have a corresponding issue in the issue tracker, please create one.
@@ -80,7 +80,7 @@ fairly rigid coding style, as defined by the
will be expected to conform to the style outlined
[here](https://google.github.io/styleguide/cppguide.html). Use
[.clang-format](https://github.com/google/googletest/blob/master/.clang-format)
to check your formatting.
to check your formatting
## Requirements for Contributors
@@ -89,7 +89,7 @@ and their own tests from a git checkout, which has further requirements:
* [Python](https://www.python.org/) v2.3 or newer (for running some of the
tests and re-generating certain source files from templates)
* [CMake](https://cmake.org/) v2.8.12 or newer
* [CMake](https://cmake.org/) v2.6.4 or newer
## Developing Google Test and Google Mock
@@ -128,3 +128,15 @@ To run the tests, do
make test
All tests should pass.
### Regenerating Source Files
Some of Google Test's source files are generated from templates (not in the C++
sense) using a script. For example, the file
include/gtest/internal/gtest-type-util.h.pump is used to generate
gtest-type-util.h in the same directory.
You don't need to worry about regenerating the source files unless you need to
modify them. You would then modify the corresponding `.pump` files and run the
'[pump.py](googletest/scripts/pump.py)' generator script. See the
[Pump Manual](googletest/docs/pump_manual.md).

134
test/gtest-1.10.0/README.md Normal file
View File

@@ -0,0 +1,134 @@
# Google Test
#### OSS Builds Status:
[![Build Status](https://api.travis-ci.org/google/googletest.svg?branch=master)](https://travis-ci.org/google/googletest)
[![Build status](https://ci.appveyor.com/api/projects/status/4o38plt0xbo1ubc8/branch/master?svg=true)](https://ci.appveyor.com/project/GoogleTestAppVeyor/googletest/branch/master)
### Future Plans
#### 1.8.x Release:
[the 1.8.x](https://github.com/google/googletest/releases/tag/release-1.8.1) is
the last release that works with pre-C++11 compilers. The 1.8.x will not accept
any requests for any new features and any bugfix requests will only be accepted
if proven "critical"
#### Post 1.8.x:
On-going work to improve/cleanup/pay technical debt. When this work is completed
there will be a 1.9.x tagged release
#### Post 1.9.x
Post 1.9.x googletest will follow
[Abseil Live at Head philosophy](https://abseil.io/about/philosophy)
## Welcome to **Google Test**, Google's C++ test framework!
This repository is a merger of the formerly separate GoogleTest and GoogleMock
projects. These were so closely related that it makes sense to maintain and
release them together.
Please subscribe to the mailing list at googletestframework@googlegroups.com for
questions, discussions, and development.
### Getting started:
The information for **Google Test** is available in the
[Google Test Primer](googletest/docs/primer.md) documentation.
**Google Mock** is an extension to Google Test for writing and using C++ mock
classes. See the separate [Google Mock documentation](googlemock/README.md).
More detailed documentation for googletest is in its interior
[googletest/README.md](googletest/README.md) file.
## Features
* 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.
## Platforms
Google test has been used on a variety of platforms:
* Linux
* Mac OS X
* Windows
* Cygwin
* MinGW
* Windows Mobile
* Symbian
* PlatformIO
## Who Is Using Google Test?
In addition to many internal projects at Google, Google Test is also used by the
following notable projects:
* The [Chromium projects](http://www.chromium.org/) (behind the Chrome browser
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.
* [tiny-dnn](https://github.com/tiny-dnn/tiny-dnn): header only,
dependency-free deep learning framework in C++11.
## 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.
[Google Test UI](https://github.com/ospector/gtest-gbar) is test runner that
runs your test binary, allows you to track its progress via a progress bar, and
displays a list of test failures. Clicking on one shows failure text. Google
Test UI is written in C#.
[GTest TAP Listener](https://github.com/kinow/gtest-tap-listener) is an event
listener for Google Test that implements the
[TAP protocol](https://en.wikipedia.org/wiki/Test_Anything_Protocol) for test
result output. If your test runner understands TAP, you may find it useful.
[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 Google Tests in a tree view, and
run/debug your tests.
## Requirements
Google Test is designed to have fairly minimal requirements to build and use
with your projects, but there are some. If you notice any problems on your
platform, please notify
[googletestframework@googlegroups.com](https://groups.google.com/forum/#!forum/googletestframework).
Patches for fixing them are welcome!
### Build Requirements
These are the base requirements to build and use Google Test from a source
package:
* [Bazel](https://bazel.build/) or [CMake](https://cmake.org/). NOTE: Bazel is
the build system that googletest is using internally and tests against.
CMake is community-supported.
* a C++11-standard-compliant compiler
## Contributing change
Please read the [`CONTRIBUTING.md`](CONTRIBUTING.md) for details on how to
contribute to this project.
Happy testing!

View File

@@ -0,0 +1,23 @@
workspace(name = "com_google_googletest")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# Abseil
http_archive(
name = "com_google_absl",
urls = ["https://github.com/abseil/abseil-cpp/archive/master.zip"],
strip_prefix = "abseil-cpp-master",
)
http_archive(
name = "rules_cc",
strip_prefix = "rules_cc-master",
urls = ["https://github.com/bazelbuild/rules_cc/archive/master.zip"],
)
http_archive(
name = "rules_python",
strip_prefix = "rules_python-master",
urls = ["https://github.com/bazelbuild/rules_python/archive/master.zip"],
)

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,41 @@
#!/usr/bin/env bash
# Copyright 2017 Google Inc.
# All Rights Reserved.
#
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# This file should be sourced, and not executed as a standalone script.
#
# TODO() - we can check if this is being sourced using $BASH_VERSION and $BASH_SOURCE[0] != ${0}.
if [ "${TRAVIS_OS_NAME}" = "linux" ]; then
if [ "$CXX" = "g++" ]; then export CXX="g++-4.9" CC="gcc-4.9"; fi
if [ "$CXX" = "clang++" ]; then export CXX="clang++-3.9" CC="clang-3.9"; fi
fi

View File

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

View File

@@ -1,7 +1,7 @@
#!/bin/bash
#!/usr/bin/env bash
# Copyright 2017 Google Inc.
# All Rights Reserved.
#
# Copyright 2020, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
@@ -29,45 +29,20 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -euox pipefail
if [[ -z ${GTEST_ROOT:-} ]]; then
GTEST_ROOT="$(realpath $(dirname ${0})/..)"
fi
# Test the CMake build
for cmake_off_on in OFF ON; do
BUILD_DIR=$(mktemp -d build_dir.XXXXXXXX)
cd ${BUILD_DIR}
time cmake ${GTEST_ROOT} \
-DCMAKE_CXX_STANDARD=11 \
-Dgtest_build_samples=ON \
-Dgtest_build_tests=ON \
-Dgmock_build_tests=ON \
-Dcxx_no_exception=${cmake_off_on} \
-Dcxx_no_rtti=${cmake_off_on}
time make
time ctest -j$(nproc) --output-on-failure
done
# Test the Bazel build
# If we are running on Kokoro, check for a versioned Bazel binary.
KOKORO_GFILE_BAZEL_BIN="bazel-3.7.0-darwin-x86_64"
if [[ ${KOKORO_GFILE_DIR:-} ]] && [[ -f ${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN} ]]; then
BAZEL_BIN="${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN}"
chmod +x ${BAZEL_BIN}
# This file is typically sourced by another script.
# if possible, ask for the precise number of processors,
# otherwise take 2 processors as reasonable default; see
# https://docs.travis-ci.com/user/speeding-up-the-build/#Makefile-optimization
if [ -x /usr/bin/getconf ]; then
NPROCESSORS=$(/usr/bin/getconf _NPROCESSORS_ONLN)
else
BAZEL_BIN="bazel"
NPROCESSORS=2
fi
cd ${GTEST_ROOT}
for absl in 0 1; do
${BAZEL_BIN} test ... \
--copt="-Wall" \
--copt="-Werror" \
--define="absl=${absl}" \
--keep_going \
--show_timestamps \
--test_output=errors
done
# as of 2017-09-04 Travis CI reports 32 processors, but GCC build
# crashes if parallelized too much (maybe memory consumption problem),
# so limit to 4 processors for the time being.
if [ $NPROCESSORS -gt 4 ] ; then
echo "$0:Note: Limiting processors to use by make from $NPROCESSORS to 4."
NPROCESSORS=4
fi

View File

@@ -0,0 +1,49 @@
#!/usr/bin/env bash
# Copyright 2017 Google Inc.
# All Rights Reserved.
#
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -eu
if [ "${TRAVIS_OS_NAME}" != linux ]; then
echo "Not a Linux build; skipping installation"
exit 0
fi
if [ "${TRAVIS_SUDO}" = "true" ]; then
echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" | \
sudo tee /etc/apt/sources.list.d/bazel.list
curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -
sudo apt-get update && sudo apt-get install -y bazel gcc-4.9 g++-4.9 clang-3.9
elif [ "${CXX}" = "clang++" ]; then
# Use ccache, assuming $HOME/bin is in the path, which is true in the Travis build environment.
ln -sf /usr/bin/ccache $HOME/bin/${CXX};
ln -sf /usr/bin/ccache $HOME/bin/${CC};
fi

View File

@@ -0,0 +1,40 @@
#!/usr/bin/env bash
# Copyright 2017 Google Inc.
# All Rights Reserved.
#
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -eu
if [ "${TRAVIS_OS_NAME}" != "osx" ]; then
echo "Not a macOS build; skipping installation"
exit 0
fi
brew update
brew install ccache gcc@4.9

View File

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

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env bash
# Copyright 2017 Google Inc.
# All Rights Reserved.
#
# Copyright 2019, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
@@ -29,26 +29,23 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Verifies that SetUpTestSuite and TearDownTestSuite errors are noticed."""
set -e
import gtest_test_utils
# ccache on OS X needs installation first
# reset ccache statistics
ccache --zero-stats
COMMAND = gtest_test_utils.GetTestExecutablePath(
'googletest-setuptestsuite-test_')
echo PATH=${PATH}
echo "Compiler configuration:"
echo CXX=${CXX}
echo CC=${CC}
echo CXXFLAGS=${CXXFLAGS}
class GTestSetUpTestSuiteTest(gtest_test_utils.TestCase):
echo "C++ compiler version:"
${CXX} --version || echo "${CXX} does not seem to support the --version flag"
${CXX} -v || echo "${CXX} does not seem to support the -v flag"
def testSetupErrorAndTearDownError(self):
p = gtest_test_utils.Subprocess(COMMAND)
self.assertNotEqual(p.exit_code, 0, msg=p.output)
self.assertIn(
'[ FAILED ] SetupFailTest: SetUpTestSuite or TearDownTestSuite\n'
'[ FAILED ] TearDownFailTest: SetUpTestSuite or TearDownTestSuite\n'
'\n'
' 2 FAILED TEST SUITES\n',
p.output)
if __name__ == '__main__':
gtest_test_utils.Main()
echo "C compiler version:"
${CC} --version || echo "${CXX} does not seem to support the --version flag"
${CC} -v || echo "${CXX} does not seem to support the -v flag"

View File

@@ -0,0 +1,44 @@
#!/usr/bin/env sh
set -evx
. ci/get-nprocessors.sh
# if possible, ask for the precise number of processors,
# otherwise take 2 processors as reasonable default; see
# https://docs.travis-ci.com/user/speeding-up-the-build/#Makefile-optimization
if [ -x /usr/bin/getconf ]; then
NPROCESSORS=$(/usr/bin/getconf _NPROCESSORS_ONLN)
else
NPROCESSORS=2
fi
# as of 2017-09-04 Travis CI reports 32 processors, but GCC build
# crashes if parallelized too much (maybe memory consumption problem),
# so limit to 4 processors for the time being.
if [ $NPROCESSORS -gt 4 ] ; then
echo "$0:Note: Limiting processors to use by make from $NPROCESSORS to 4."
NPROCESSORS=4
fi
# Tell make to use the processors. No preceding '-' required.
MAKEFLAGS="j${NPROCESSORS}"
export MAKEFLAGS
env | sort
# Set default values to OFF for these variables if not specified.
: "${NO_EXCEPTION:=OFF}"
: "${NO_RTTI:=OFF}"
: "${COMPILER_IS_GNUCXX:=OFF}"
mkdir build || true
cd build
cmake -Dgtest_build_samples=ON \
-Dgtest_build_tests=ON \
-Dgmock_build_tests=ON \
-Dcxx_no_exception=$NO_EXCEPTION \
-Dcxx_no_rtti=$NO_RTTI \
-DCMAKE_COMPILER_IS_GNUCXX=$COMPILER_IS_GNUCXX \
-DCMAKE_CXX_FLAGS=$CXX_FLAGS \
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
..
make
CTEST_OUTPUT_ON_FAILURE=1 make test

View File

@@ -42,7 +42,7 @@ else()
cmake_policy(SET CMP0048 NEW)
project(gmock VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)
endif()
cmake_minimum_required(VERSION 2.8.12)
cmake_minimum_required(VERSION 2.9)
if (COMMAND set_up_hermetic_build)
set_up_hermetic_build()
@@ -100,10 +100,8 @@ if (MSVC)
else()
cxx_library(gmock "${cxx_strict}" src/gmock-all.cc)
target_link_libraries(gmock PUBLIC gtest)
set_target_properties(gmock PROPERTIES VERSION ${GOOGLETEST_VERSION})
cxx_library(gmock_main "${cxx_strict}" src/gmock_main.cc)
target_link_libraries(gmock_main PUBLIC gmock)
set_target_properties(gmock_main PROPERTIES VERSION ${GOOGLETEST_VERSION})
endif()
# If the CMake version supports it, attach header directory information
# to the targets for when we are part of a parent build (ie being pulled
@@ -138,6 +136,20 @@ if (gmock_build_tests)
# 'make test' or ctest.
enable_testing()
if (WIN32)
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/RunTest.ps1"
CONTENT
"$project_bin = \"${CMAKE_BINARY_DIR}/bin/$<CONFIG>\"
$env:Path = \"$project_bin;$env:Path\"
& $args")
elseif (MINGW OR CYGWIN)
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/RunTest.ps1"
CONTENT
"$project_bin = (cygpath --windows ${CMAKE_BINARY_DIR}/bin)
$env:Path = \"$project_bin;$env:Path\"
& $args")
endif()
if (MINGW OR CYGWIN)
if (CMAKE_VERSION VERSION_LESS "2.8.12")
add_compile_options("-Wa,-mbig-obj")
@@ -153,6 +165,9 @@ if (gmock_build_tests)
cxx_test(gmock-cardinalities_test gmock_main)
cxx_test(gmock_ex_test gmock_main)
cxx_test(gmock-function-mocker_test gmock_main)
cxx_test(gmock-generated-actions_test gmock_main)
cxx_test(gmock-generated-function-mockers_test gmock_main)
cxx_test(gmock-generated-matchers_test gmock_main)
cxx_test(gmock-internal-utils_test gmock_main)
cxx_test(gmock-matchers_test gmock_main)
cxx_test(gmock-more-actions_test gmock_main)

View File

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

View File

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

View File

@@ -0,0 +1,44 @@
# Googletest Mocking (gMock) Framework
### Overview
Google's framework for writing and using C++ mock classes. It can help you
derive better designs of your system and write better tests.
It is inspired by:
* [jMock](http://www.jmock.org/),
* [EasyMock](http://www.easymock.org/), and
* [Hamcrest](http://code.google.com/p/hamcrest/),
and designed with C++'s specifics in mind.
gMock:
- provides a declarative syntax for defining mocks,
- can define partial (hybrid) mocks, which are a cross of real and mock
objects,
- handles functions of arbitrary types and overloaded functions,
- comes with a rich set of matchers for validating function arguments,
- uses an intuitive syntax for controlling the behavior of a mock,
- does automatic verification of expectations (no record-and-replay needed),
- allows arbitrary (partial) ordering constraints on function calls to be
expressed,
- lets a user extend it by defining new matchers and actions.
- does not use exceptions, and
- is easy to learn and use.
Details and examples can be found here:
* [gMock for Dummies](docs/for_dummies.md)
* [Legacy gMock FAQ](docs/gmock_faq.md)
* [gMock Cookbook](docs/cook_book.md)
* [gMock Cheat Sheet](docs/cheat_sheet.md)
Please note that code under scripts/generator/ is from the [cppclean
project](http://code.google.com/p/cppclean/) and under the Apache
License, which is different from Google Mock's license.
Google Mock is a part of
[Google Test C++ testing framework](http://github.com/google/googletest/) and a
subject to the same requirements.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -36,8 +36,8 @@
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
#include <limits.h>
#include <memory>
@@ -154,4 +154,4 @@ inline Cardinality MakeCardinality(const CardinalityInterface* c) {
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_

View File

@@ -0,0 +1,253 @@
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements MOCK_METHOD.
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
#define THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
#include "gmock/gmock-generated-function-mockers.h" // NOLINT
#include "gmock/internal/gmock-pp.h"
#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_HAS_NOEXCEPT(_Spec), GMOCK_INTERNAL_GET_CALLTYPE(_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 unproctected commas.")
#define GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT, ~, _Spec)
#define GMOCK_INTERNAL_MOCK_METHOD_IMPL(_N, _MethodName, _Constness, \
_Override, _Final, _Noexcept, \
_CallType, _Signature) \
typename ::testing::internal::Function<GMOCK_PP_REMOVE_PARENS( \
_Signature)>::Result \
GMOCK_INTERNAL_EXPAND(_CallType) \
_MethodName(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N)) \
GMOCK_PP_IF(_Constness, const, ) GMOCK_PP_IF(_Noexcept, noexcept, ) \
GMOCK_PP_IF(_Override, override, ) \
GMOCK_PP_IF(_Final, final, ) { \
GMOCK_MOCKER_(_N, _Constness, _MethodName) \
.SetOwnerAndName(this, #_MethodName); \
return GMOCK_MOCKER_(_N, _Constness, _MethodName) \
.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, ) { \
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 GMOCK_PP_IF(_Noexcept, noexcept, ) { \
return GMOCK_PP_CAT(::testing::internal::AdjustConstness_, \
GMOCK_PP_IF(_Constness, const, ))(this) \
->gmock_##_MethodName(GMOCK_PP_REPEAT( \
GMOCK_INTERNAL_A_MATCHER_ARGUMENT, _Signature, _N)); \
} \
mutable ::testing::FunctionMocker<GMOCK_PP_REMOVE_PARENS(_Signature)> \
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_HAS_NOEXCEPT(_Tuple) \
GMOCK_PP_HAS_COMMA( \
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_NOEXCEPT, ~, _Tuple))
#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_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 ,
// TODO(iserna): Maybe noexcept should accept an argument here as well.
#define GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem) \
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_NOEXCEPT_I_, _elem)
#define GMOCK_INTERNAL_DETECT_NOEXCEPT_I_noexcept ,
#define GMOCK_INTERNAL_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_CAT(GMOCK_PP_IDENTITY, _arg)
#define GMOCK_INTERNAL_IS_CALLTYPE_HELPER_Calltype
#define GMOCK_INTERNAL_SIGNATURE(_Ret, _Args) \
GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_Ret), GMOCK_PP_REMOVE_PARENS, \
GMOCK_PP_IDENTITY) \
(_Ret)(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_TYPE, _, _Args))
#define GMOCK_INTERNAL_GET_TYPE(_i, _, _elem) \
GMOCK_PP_COMMA_IF(_i) \
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(typename, GMOCK_PP_INC(_i), \
GMOCK_PP_REMOVE_PARENS(_Signature)) \
gmock_a##_i
#define GMOCK_INTERNAL_FORWARD_ARG(_i, _Signature, _) \
GMOCK_PP_COMMA_IF(_i) \
::std::forward<GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \
GMOCK_PP_REMOVE_PARENS(_Signature))>( \
gmock_a##_i)
#define GMOCK_INTERNAL_MATCHER_PARAMETER(_i, _Signature, _) \
GMOCK_PP_COMMA_IF(_i) \
GMOCK_INTERNAL_MATCHER_O(typename, GMOCK_PP_INC(_i), \
GMOCK_PP_REMOVE_PARENS(_Signature)) \
gmock_a##_i
#define GMOCK_INTERNAL_MATCHER_ARGUMENT(_i, _1, _2) \
GMOCK_PP_COMMA_IF(_i) \
gmock_a##_i
#define GMOCK_INTERNAL_A_MATCHER_ARGUMENT(_i, _Signature, _) \
GMOCK_PP_COMMA_IF(_i) \
::testing::A<GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \
GMOCK_PP_REMOVE_PARENS(_Signature))>()
#define GMOCK_INTERNAL_ARG_O(_tn, _i, ...) GMOCK_ARG_(_tn, _i, __VA_ARGS__)
#define GMOCK_INTERNAL_MATCHER_O(_tn, _i, ...) \
GMOCK_MATCHER_(_tn, _i, __VA_ARGS__)
#endif // THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,627 @@
$$ -*- mode: c++; -*-
$$ This is a Pump source file. Please use Pump to convert it to
$$ gmock-generated-actions.h.
$$
$var n = 10 $$ The maximum arity we support.
$$}} This meta comment fixes auto-indentation in editors.
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements some commonly used variadic actions.
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
#include <memory>
#include <utility>
#include "gmock/gmock-actions.h"
#include "gmock/internal/gmock-port.h"
namespace testing {
namespace internal {
// A macro from the ACTION* family (defined later in this file)
// defines an action that can be used in a mock function. Typically,
// these actions only care about a subset of the arguments of the mock
// function. For example, if such an action only uses the second
// argument, it can be used in any mock function that takes >= 2
// arguments where the type of the second argument is compatible.
//
// Therefore, the action implementation must be prepared to take more
// arguments than it needs. The ExcessiveArg type is used to
// represent those excessive arguments. In order to keep the compiler
// error messages tractable, we define it in the testing namespace
// instead of testing::internal. However, this is an INTERNAL TYPE
// and subject to change without notice, so a user MUST NOT USE THIS
// TYPE DIRECTLY.
struct ExcessiveArg {};
// A helper class needed for implementing the ACTION* macros.
template <typename Result, class Impl>
class ActionHelper {
public:
$range i 0..n
$for i
[[
$var template = [[$if i==0 [[]] $else [[
$range j 0..i-1
template <$for j, [[typename A$j]]>
]]]]
$range j 0..i-1
$var As = [[$for j, [[A$j]]]]
$var as = [[$for j, [[std::get<$j>(args)]]]]
$range k 1..n-i
$var eas = [[$for k, [[ExcessiveArg()]]]]
$var arg_list = [[$if (i==0) | (i==n) [[$as$eas]] $else [[$as, $eas]]]]
$template
static Result Perform(Impl* impl, const ::std::tuple<$As>& args) {
return impl->template gmock_PerformImpl<$As>(args, $arg_list);
}
]]
};
} // namespace internal
} // namespace testing
// The ACTION* family of macros can be used in a namespace scope to
// define custom actions easily. The syntax:
//
// ACTION(name) { statements; }
//
// will define an action with the given name that executes the
// statements. The value returned by the statements will be used as
// the return value of the action. Inside the statements, you can
// refer to the K-th (0-based) argument of the mock function by
// 'argK', and refer to its type by 'argK_type'. For example:
//
// ACTION(IncrementArg1) {
// arg1_type temp = arg1;
// return ++(*temp);
// }
//
// allows you to write
//
// ...WillOnce(IncrementArg1());
//
// You can also refer to the entire argument tuple and its type by
// 'args' and 'args_type', and refer to the mock function type and its
// return type by 'function_type' and 'return_type'.
//
// Note that you don't need to specify the types of the mock function
// arguments. However rest assured that your code is still type-safe:
// you'll get a compiler error if *arg1 doesn't support the ++
// operator, or if the type of ++(*arg1) isn't compatible with the
// mock function's return type, for example.
//
// Sometimes you'll want to parameterize the action. For that you can use
// another macro:
//
// ACTION_P(name, param_name) { statements; }
//
// For example:
//
// ACTION_P(Add, n) { return arg0 + n; }
//
// will allow you to write:
//
// ...WillOnce(Add(5));
//
// Note that you don't need to provide the type of the parameter
// either. If you need to reference the type of a parameter named
// 'foo', you can write 'foo_type'. For example, in the body of
// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type
// of 'n'.
//
// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P$n to support
// multi-parameter actions.
//
// For the purpose of typing, you can view
//
// ACTION_Pk(Foo, p1, ..., pk) { ... }
//
// as shorthand for
//
// template <typename p1_type, ..., typename pk_type>
// FooActionPk<p1_type, ..., pk_type> Foo(p1_type p1, ..., pk_type pk) { ... }
//
// In particular, you can provide the template type arguments
// explicitly when invoking Foo(), as in Foo<long, bool>(5, false);
// although usually you can rely on the compiler to infer the types
// for you automatically. You can assign the result of expression
// Foo(p1, ..., pk) to a variable of type FooActionPk<p1_type, ...,
// pk_type>. This can be useful when composing actions.
//
// You can also overload actions with different numbers of parameters:
//
// ACTION_P(Plus, a) { ... }
// ACTION_P2(Plus, a, b) { ... }
//
// While it's tempting to always use the ACTION* macros when defining
// a new action, you should also consider implementing ActionInterface
// or using MakePolymorphicAction() instead, especially if you need to
// use the action a lot. While these approaches require more work,
// they give you more control on the types of the mock function
// arguments and the action parameters, which in general leads to
// better compiler error messages that pay off in the long run. They
// also allow overloading actions based on parameter types (as opposed
// to just based on the number of parameters).
//
// CAVEAT:
//
// ACTION*() can only be used in a namespace scope as templates cannot be
// declared inside of a local class.
// Users can, however, define any local functors (e.g. a lambda) that
// can be used as actions.
//
// MORE INFORMATION:
//
// To learn more about using these macros, please search for 'ACTION' on
// https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md
$range i 0..n
$range k 0..n-1
// An internal macro needed for implementing ACTION*().
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\
const args_type& args GTEST_ATTRIBUTE_UNUSED_
$for k [[, \
const arg$k[[]]_type& arg$k GTEST_ATTRIBUTE_UNUSED_]]
// Sometimes you want to give an action explicit template parameters
// that cannot be inferred from its value parameters. ACTION() and
// ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that
// and can be viewed as an extension to ACTION() and ACTION_P*().
//
// The syntax:
//
// ACTION_TEMPLATE(ActionName,
// HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m),
// AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; }
//
// defines an action template that takes m explicit template
// parameters and n value parameters. name_i is the name of the i-th
// template parameter, and kind_i specifies whether it's a typename,
// an integral constant, or a template. p_i is the name of the i-th
// value parameter.
//
// Example:
//
// // DuplicateArg<k, T>(output) converts the k-th argument of the mock
// // function to type T and copies it to *output.
// ACTION_TEMPLATE(DuplicateArg,
// HAS_2_TEMPLATE_PARAMS(int, k, typename, T),
// AND_1_VALUE_PARAMS(output)) {
// *output = T(::std::get<k>(args));
// }
// ...
// int n;
// EXPECT_CALL(mock, Foo(_, _))
// .WillOnce(DuplicateArg<1, unsigned char>(&n));
//
// To create an instance of an action template, write:
//
// ActionName<t1, ..., t_m>(v1, ..., v_n)
//
// where the ts are the template arguments and the vs are the value
// arguments. The value argument types are inferred by the compiler.
// If you want to explicitly specify the value argument types, you can
// provide additional template arguments:
//
// ActionName<t1, ..., t_m, u1, ..., u_k>(v1, ..., v_n)
//
// where u_i is the desired type of v_i.
//
// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the
// number of value parameters, but not on the number of template
// parameters. Without the restriction, the meaning of the following
// is unclear:
//
// OverloadedAction<int, bool>(x);
//
// Are we using a single-template-parameter action where 'bool' refers
// to the type of x, or are we using a two-template-parameter action
// where the compiler is asked to infer the type of x?
//
// Implementation notes:
//
// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and
// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for
// implementing ACTION_TEMPLATE. The main trick we use is to create
// new macro invocations when expanding a macro. For example, we have
//
// #define ACTION_TEMPLATE(name, template_params, value_params)
// ... GMOCK_INTERNAL_DECL_##template_params ...
//
// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...)
// to expand to
//
// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ...
//
// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the
// preprocessor will continue to expand it to
//
// ... typename T ...
//
// This technique conforms to the C++ standard and is portable. It
// allows us to implement action templates using O(N) code, where N is
// the maximum number of template/value parameters supported. Without
// using it, we'd have to devote O(N^2) amount of code to implement all
// combinations of m and n.
// Declares the template parameters.
$range j 1..n
$for j [[
$range m 0..j-1
#define GMOCK_INTERNAL_DECL_HAS_$j[[]]
_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[kind$m name$m]]
]]
// Lists the template parameters.
$for j [[
$range m 0..j-1
#define GMOCK_INTERNAL_LIST_HAS_$j[[]]
_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[name$m]]
]]
// Declares the types of value parameters.
$for i [[
$range j 0..i-1
#define GMOCK_INTERNAL_DECL_TYPE_AND_$i[[]]
_VALUE_PARAMS($for j, [[p$j]]) $for j [[, typename p$j##_type]]
]]
// Initializes the value parameters.
$for i [[
$range j 0..i-1
#define GMOCK_INTERNAL_INIT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])\
($for j, [[p$j##_type gmock_p$j]])$if i>0 [[ : ]]$for j, [[p$j(::std::move(gmock_p$j))]]
]]
// Declares the fields for storing the value parameters.
$for i [[
$range j 0..i-1
#define GMOCK_INTERNAL_DEFN_AND_$i[[]]
_VALUE_PARAMS($for j, [[p$j]]) $for j [[p$j##_type p$j; ]]
]]
// Lists the value parameters.
$for i [[
$range j 0..i-1
#define GMOCK_INTERNAL_LIST_AND_$i[[]]
_VALUE_PARAMS($for j, [[p$j]]) $for j, [[p$j]]
]]
// Lists the value parameter types.
$for i [[
$range j 0..i-1
#define GMOCK_INTERNAL_LIST_TYPE_AND_$i[[]]
_VALUE_PARAMS($for j, [[p$j]]) $for j [[, p$j##_type]]
]]
// Declares the value parameters.
$for i [[
$range j 0..i-1
#define GMOCK_INTERNAL_DECL_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]]
$for j, [[p$j##_type p$j]]
]]
// The suffix of the class template implementing the action template.
$for i [[
$range j 0..i-1
#define GMOCK_INTERNAL_COUNT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]]
$if i==1 [[P]] $elif i>=2 [[P$i]]
]]
// The name of the class template implementing the action template.
#define GMOCK_ACTION_CLASS_(name, value_params)\
GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params)
$range k 0..n-1
#define ACTION_TEMPLATE(name, template_params, value_params)\
template <GMOCK_INTERNAL_DECL_##template_params\
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
class GMOCK_ACTION_CLASS_(name, value_params) {\
public:\
explicit GMOCK_ACTION_CLASS_(name, value_params)\
GMOCK_INTERNAL_INIT_##value_params {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
typedef F function_type;\
typedef typename ::testing::internal::Function<F>::Result return_type;\
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
args_type;\
explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
template <$for k, [[typename arg$k[[]]_type]]>\
return_type gmock_PerformImpl(const args_type& args[[]]
$for k [[, const arg$k[[]]_type& arg$k]]) const;\
GMOCK_INTERNAL_DEFN_##value_params\
private:\
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename F> operator ::testing::Action<F>() const {\
return ::testing::Action<F>(\
new gmock_Impl<F>(GMOCK_INTERNAL_LIST_##value_params));\
}\
GMOCK_INTERNAL_DEFN_##value_params\
private:\
GTEST_DISALLOW_ASSIGN_(GMOCK_ACTION_CLASS_(name, value_params));\
};\
template <GMOCK_INTERNAL_DECL_##template_params\
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
inline GMOCK_ACTION_CLASS_(name, value_params)<\
GMOCK_INTERNAL_LIST_##template_params\
GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\
GMOCK_INTERNAL_DECL_##value_params) {\
return GMOCK_ACTION_CLASS_(name, value_params)<\
GMOCK_INTERNAL_LIST_##template_params\
GMOCK_INTERNAL_LIST_TYPE_##value_params>(\
GMOCK_INTERNAL_LIST_##value_params);\
}\
template <GMOCK_INTERNAL_DECL_##template_params\
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
template <typename F>\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
typename ::testing::internal::Function<F>::Result\
GMOCK_ACTION_CLASS_(name, value_params)<\
GMOCK_INTERNAL_LIST_##template_params\
GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl<F>::\
gmock_PerformImpl(\
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
$for i
[[
$var template = [[$if i==0 [[]] $else [[
$range j 0..i-1
template <$for j, [[typename p$j##_type]]>\
]]]]
$var class_name = [[name##Action[[$if i==0 [[]] $elif i==1 [[P]]
$else [[P$i]]]]]]
$range j 0..i-1
$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]]
$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::std::forward<p$j##_type>(gmock_p$j))]]]]]]
$var param_field_decls = [[$for j
[[
p$j##_type p$j;\
]]]]
$var param_field_decls2 = [[$for j
[[
p$j##_type p$j;\
]]]]
$var params = [[$for j, [[p$j]]]]
$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]]
$var typename_arg_types = [[$for k, [[typename arg$k[[]]_type]]]]
$var arg_types_and_names = [[$for k, [[const arg$k[[]]_type& arg$k]]]]
$var macro_name = [[$if i==0 [[ACTION]] $elif i==1 [[ACTION_P]]
$else [[ACTION_P$i]]]]
#define $macro_name(name$for j [[, p$j]])\$template
class $class_name {\
public:\
[[$if i==1 [[explicit ]]]]$class_name($ctor_param_list)$inits {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
typedef F function_type;\
typedef typename ::testing::internal::Function<F>::Result return_type;\
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
args_type;\
[[$if i==1 [[explicit ]]]]gmock_Impl($ctor_param_list)$inits {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
template <$typename_arg_types>\
return_type gmock_PerformImpl(const args_type& args, [[]]
$arg_types_and_names) const;\$param_field_decls
private:\
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename F> operator ::testing::Action<F>() const {\
return ::testing::Action<F>(new gmock_Impl<F>($params));\
}\$param_field_decls2
private:\
GTEST_DISALLOW_ASSIGN_($class_name);\
};\$template
inline $class_name$param_types name($param_types_and_names) {\
return $class_name$param_types($params);\
}\$template
template <typename F>\
template <$typename_arg_types>\
typename ::testing::internal::Function<F>::Result\
$class_name$param_types::gmock_Impl<F>::gmock_PerformImpl(\
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
]]
$$ } // This meta comment fixes auto-indentation in Emacs. It won't
$$ // show up in the generated code.
namespace testing {
// The ACTION*() macros trigger warning C4100 (unreferenced formal
// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
// the macro definition, as the warnings are generated when the macro
// is expanded and macro expansion cannot contain #pragma. Therefore
// we suppress them here.
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable:4100)
#endif
// Various overloads for InvokeArgument<N>().
//
// The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th
// (0-based) argument, which must be a k-ary callable, of the mock
// function, with arguments a1, a2, ..., a_k.
//
// Notes:
//
// 1. The arguments are passed by value by default. If you need to
// pass an argument by reference, wrap it inside ByRef(). For
// example,
//
// InvokeArgument<1>(5, string("Hello"), ByRef(foo))
//
// passes 5 and string("Hello") by value, and passes foo by
// reference.
//
// 2. If the callable takes an argument by reference but ByRef() is
// not used, it will receive the reference to a copy of the value,
// instead of the original value. For example, when the 0-th
// argument of the mock function takes a const string&, the action
//
// InvokeArgument<0>(string("Hello"))
//
// makes a copy of the temporary string("Hello") object and passes a
// reference of the copy, instead of the original temporary object,
// to the callable. This makes it easy for a user to define an
// InvokeArgument action from temporary values and have it performed
// later.
namespace internal {
namespace invoke_argument {
// Appears in InvokeArgumentAdl's argument list to help avoid
// accidental calls to user functions of the same name.
struct AdlTag {};
// InvokeArgumentAdl - a helper for InvokeArgument.
// The basic overloads are provided here for generic functors.
// Overloads for other custom-callables are provided in the
// internal/custom/callback-actions.h header.
$range i 0..n
$for i
[[
$range j 1..i
template <typename R, typename F[[$for j [[, typename A$j]]]]>
R InvokeArgumentAdl(AdlTag, F f[[$for j [[, A$j a$j]]]]) {
return f([[$for j, [[a$j]]]]);
}
]]
} // namespace invoke_argument
} // namespace internal
$range i 0..n
$for i [[
$range j 0..i-1
ACTION_TEMPLATE(InvokeArgument,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])) {
using internal::invoke_argument::InvokeArgumentAdl;
return InvokeArgumentAdl<return_type>(
internal::invoke_argument::AdlTag(),
::std::get<k>(args)$for j [[, p$j]]);
}
]]
// Various overloads for ReturnNew<T>().
//
// The ReturnNew<T>(a1, a2, ..., a_k) action returns a pointer to a new
// instance of type T, constructed on the heap with constructor arguments
// a1, a2, ..., and a_k. The caller assumes ownership of the returned value.
$range i 0..n
$for i [[
$range j 0..i-1
$var ps = [[$for j, [[p$j]]]]
ACTION_TEMPLATE(ReturnNew,
HAS_1_TEMPLATE_PARAMS(typename, T),
AND_$i[[]]_VALUE_PARAMS($ps)) {
return new T($ps);
}
]]
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // namespace testing
// Include any custom callback actions added by the local installation.
// We must include this header at the end to make sure it can use the
// declarations from this file.
#include "gmock/internal/custom/gmock-generated-actions.h"
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_

View File

@@ -0,0 +1,752 @@
// This file was GENERATED by command:
// pump.py gmock-generated-function-mockers.h.pump
// DO NOT EDIT BY HAND!!!
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements function mockers of various arities.
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
#include <functional>
#include <utility>
#include "gmock/gmock-spec-builders.h"
#include "gmock/internal/gmock-internal-utils.h"
namespace testing {
namespace internal {
// Removes the given pointer; this is a helper for the expectation setter method
// for parameterless matchers.
//
// We want to make sure that the user cannot set a parameterless expectation on
// overloaded methods, including methods which are overloaded on const. Example:
//
// class MockClass {
// MOCK_METHOD0(GetName, string&());
// MOCK_CONST_METHOD0(GetName, const string&());
// };
//
// TEST() {
// // This should be an error, as it's not clear which overload is expected.
// EXPECT_CALL(mock, GetName).WillOnce(ReturnRef(value));
// }
//
// Here are the generated expectation-setter methods:
//
// class MockClass {
// // Overload 1
// MockSpec<string&()> gmock_GetName() { ... }
// // Overload 2. Declared const so that the compiler will generate an
// // error when trying to resolve between this and overload 4 in
// // 'gmock_GetName(WithoutMatchers(), nullptr)'.
// MockSpec<string&()> gmock_GetName(
// const WithoutMatchers&, const Function<string&()>*) const {
// // Removes const from this, calls overload 1
// return AdjustConstness_(this)->gmock_GetName();
// }
//
// // Overload 3
// const string& gmock_GetName() const { ... }
// // Overload 4
// MockSpec<const string&()> gmock_GetName(
// const WithoutMatchers&, const Function<const string&()>*) const {
// // Does not remove const, calls overload 3
// return AdjustConstness_const(this)->gmock_GetName();
// }
// }
//
template <typename MockType>
const MockType* AdjustConstness_const(const MockType* mock) {
return mock;
}
// Removes const from and returns the given pointer; this is a helper for the
// expectation setter method for parameterless matchers.
template <typename MockType>
MockType* AdjustConstness_(const MockType* mock) {
return const_cast<MockType*>(mock);
}
} // namespace internal
// The style guide prohibits "using" statements in a namespace scope
// inside a header file. However, the FunctionMocker class template
// is meant to be defined in the ::testing namespace. The following
// line is just a trick for working around a bug in MSVC 8.0, which
// cannot handle it if we define FunctionMocker in ::testing.
using internal::FunctionMocker;
// GMOCK_RESULT_(tn, F) expands to the result type of function type F.
// We define this as a variadic macro in case F contains unprotected
// commas (the same reason that we use variadic macros in other places
// in this file).
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_RESULT_(tn, ...) \
tn ::testing::internal::Function<__VA_ARGS__>::Result
// The type of argument N of the given function type.
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_ARG_(tn, N, ...) \
tn ::testing::internal::Function<__VA_ARGS__>::template Arg<N-1>::type
// The matcher type for argument N of the given function type.
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_MATCHER_(tn, N, ...) \
const ::testing::Matcher<GMOCK_ARG_(tn, N, __VA_ARGS__)>&
// The variable for mocking the given method.
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_MOCKER_(arity, constness, Method) \
GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD0_(tn, constness, ct, Method, ...) \
static_assert(0 == \
::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
"MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
) constness { \
GMOCK_MOCKER_(0, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(0, constness, Method).Invoke(); \
} \
::testing::MockSpec<__VA_ARGS__> \
gmock_##Method() constness { \
GMOCK_MOCKER_(0, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(0, constness, Method).With(); \
} \
::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
const ::testing::internal::WithoutMatchers&, \
constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
return ::testing::internal::AdjustConstness_##constness(this)-> \
gmock_##Method(); \
} \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(0, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD1_(tn, constness, ct, Method, ...) \
static_assert(1 == \
::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
"MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1) constness { \
GMOCK_MOCKER_(1, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(1, constness, \
Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
__VA_ARGS__)>(gmock_a1)); \
} \
::testing::MockSpec<__VA_ARGS__> \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1) constness { \
GMOCK_MOCKER_(1, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(1, constness, Method).With(gmock_a1); \
} \
::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
const ::testing::internal::WithoutMatchers&, \
constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
return ::testing::internal::AdjustConstness_##constness(this)-> \
gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>()); \
} \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(1, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD2_(tn, constness, ct, Method, ...) \
static_assert(2 == \
::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
"MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
__VA_ARGS__) gmock_a2) constness { \
GMOCK_MOCKER_(2, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(2, constness, \
Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
__VA_ARGS__)>(gmock_a1), \
::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2)); \
} \
::testing::MockSpec<__VA_ARGS__> \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2) constness { \
GMOCK_MOCKER_(2, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(2, constness, Method).With(gmock_a1, gmock_a2); \
} \
::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
const ::testing::internal::WithoutMatchers&, \
constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
return ::testing::internal::AdjustConstness_##constness(this)-> \
gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>()); \
} \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(2, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD3_(tn, constness, ct, Method, ...) \
static_assert(3 == \
::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
"MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
__VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, \
__VA_ARGS__) gmock_a3) constness { \
GMOCK_MOCKER_(3, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(3, constness, \
Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
__VA_ARGS__)>(gmock_a1), \
::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3)); \
} \
::testing::MockSpec<__VA_ARGS__> \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3) constness { \
GMOCK_MOCKER_(3, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(3, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3); \
} \
::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
const ::testing::internal::WithoutMatchers&, \
constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
return ::testing::internal::AdjustConstness_##constness(this)-> \
gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>()); \
} \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(3, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD4_(tn, constness, ct, Method, ...) \
static_assert(4 == \
::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
"MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
__VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4) constness { \
GMOCK_MOCKER_(4, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(4, constness, \
Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
__VA_ARGS__)>(gmock_a1), \
::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4)); \
} \
::testing::MockSpec<__VA_ARGS__> \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4) constness { \
GMOCK_MOCKER_(4, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(4, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4); \
} \
::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
const ::testing::internal::WithoutMatchers&, \
constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
return ::testing::internal::AdjustConstness_##constness(this)-> \
gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>()); \
} \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(4, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD5_(tn, constness, ct, Method, ...) \
static_assert(5 == \
::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
"MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
__VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \
__VA_ARGS__) gmock_a5) constness { \
GMOCK_MOCKER_(5, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(5, constness, \
Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
__VA_ARGS__)>(gmock_a1), \
::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \
::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5)); \
} \
::testing::MockSpec<__VA_ARGS__> \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5) constness { \
GMOCK_MOCKER_(5, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(5, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5); \
} \
::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
const ::testing::internal::WithoutMatchers&, \
constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
return ::testing::internal::AdjustConstness_##constness(this)-> \
gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>()); \
} \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(5, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD6_(tn, constness, ct, Method, ...) \
static_assert(6 == \
::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
"MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
__VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \
__VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, \
__VA_ARGS__) gmock_a6) constness { \
GMOCK_MOCKER_(6, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(6, constness, \
Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
__VA_ARGS__)>(gmock_a1), \
::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \
::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5), \
::std::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(gmock_a6)); \
} \
::testing::MockSpec<__VA_ARGS__> \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6) constness { \
GMOCK_MOCKER_(6, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(6, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6); \
} \
::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
const ::testing::internal::WithoutMatchers&, \
constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
return ::testing::internal::AdjustConstness_##constness(this)-> \
gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>()); \
} \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(6, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD7_(tn, constness, ct, Method, ...) \
static_assert(7 == \
::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
"MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
__VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \
__VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7) constness { \
GMOCK_MOCKER_(7, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(7, constness, \
Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
__VA_ARGS__)>(gmock_a1), \
::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \
::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5), \
::std::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(gmock_a6), \
::std::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(gmock_a7)); \
} \
::testing::MockSpec<__VA_ARGS__> \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7) constness { \
GMOCK_MOCKER_(7, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(7, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \
} \
::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
const ::testing::internal::WithoutMatchers&, \
constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
return ::testing::internal::AdjustConstness_##constness(this)-> \
gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 7, __VA_ARGS__)>()); \
} \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(7, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD8_(tn, constness, ct, Method, ...) \
static_assert(8 == \
::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
"MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
__VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \
__VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, GMOCK_ARG_(tn, 8, \
__VA_ARGS__) gmock_a8) constness { \
GMOCK_MOCKER_(8, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(8, constness, \
Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
__VA_ARGS__)>(gmock_a1), \
::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \
::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5), \
::std::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(gmock_a6), \
::std::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(gmock_a7), \
::std::forward<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(gmock_a8)); \
} \
::testing::MockSpec<__VA_ARGS__> \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \
GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8) constness { \
GMOCK_MOCKER_(8, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(8, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \
} \
::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
const ::testing::internal::WithoutMatchers&, \
constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
return ::testing::internal::AdjustConstness_##constness(this)-> \
gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 8, __VA_ARGS__)>()); \
} \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(8, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD9_(tn, constness, ct, Method, ...) \
static_assert(9 == \
::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
"MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
__VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \
__VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, GMOCK_ARG_(tn, 8, \
__VA_ARGS__) gmock_a8, GMOCK_ARG_(tn, 9, \
__VA_ARGS__) gmock_a9) constness { \
GMOCK_MOCKER_(9, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(9, constness, \
Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
__VA_ARGS__)>(gmock_a1), \
::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \
::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5), \
::std::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(gmock_a6), \
::std::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(gmock_a7), \
::std::forward<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(gmock_a8), \
::std::forward<GMOCK_ARG_(tn, 9, __VA_ARGS__)>(gmock_a9)); \
} \
::testing::MockSpec<__VA_ARGS__> \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \
GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \
GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9) constness { \
GMOCK_MOCKER_(9, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(9, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \
gmock_a9); \
} \
::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
const ::testing::internal::WithoutMatchers&, \
constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
return ::testing::internal::AdjustConstness_##constness(this)-> \
gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 9, __VA_ARGS__)>()); \
} \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(9, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD10_(tn, constness, ct, Method, ...) \
static_assert(10 == \
::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
"MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
__VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \
__VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, GMOCK_ARG_(tn, 8, \
__VA_ARGS__) gmock_a8, GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9, \
GMOCK_ARG_(tn, 10, __VA_ARGS__) gmock_a10) constness { \
GMOCK_MOCKER_(10, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(10, constness, \
Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
__VA_ARGS__)>(gmock_a1), \
::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \
::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5), \
::std::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(gmock_a6), \
::std::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(gmock_a7), \
::std::forward<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(gmock_a8), \
::std::forward<GMOCK_ARG_(tn, 9, __VA_ARGS__)>(gmock_a9), \
::std::forward<GMOCK_ARG_(tn, 10, __VA_ARGS__)>(gmock_a10)); \
} \
::testing::MockSpec<__VA_ARGS__> \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \
GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \
GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9, \
GMOCK_MATCHER_(tn, 10, \
__VA_ARGS__) gmock_a10) constness { \
GMOCK_MOCKER_(10, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(10, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \
gmock_a10); \
} \
::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
const ::testing::internal::WithoutMatchers&, \
constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
return ::testing::internal::AdjustConstness_##constness(this)-> \
gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 9, __VA_ARGS__)>(), \
::testing::A<GMOCK_ARG_(tn, 10, __VA_ARGS__)>()); \
} \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(10, constness, \
Method)
#define MOCK_METHOD0(m, ...) GMOCK_METHOD0_(, , , m, __VA_ARGS__)
#define MOCK_METHOD1(m, ...) GMOCK_METHOD1_(, , , m, __VA_ARGS__)
#define MOCK_METHOD2(m, ...) GMOCK_METHOD2_(, , , m, __VA_ARGS__)
#define MOCK_METHOD3(m, ...) GMOCK_METHOD3_(, , , m, __VA_ARGS__)
#define MOCK_METHOD4(m, ...) GMOCK_METHOD4_(, , , m, __VA_ARGS__)
#define MOCK_METHOD5(m, ...) GMOCK_METHOD5_(, , , m, __VA_ARGS__)
#define MOCK_METHOD6(m, ...) GMOCK_METHOD6_(, , , m, __VA_ARGS__)
#define MOCK_METHOD7(m, ...) GMOCK_METHOD7_(, , , m, __VA_ARGS__)
#define MOCK_METHOD8(m, ...) GMOCK_METHOD8_(, , , m, __VA_ARGS__)
#define MOCK_METHOD9(m, ...) GMOCK_METHOD9_(, , , m, __VA_ARGS__)
#define MOCK_METHOD10(m, ...) GMOCK_METHOD10_(, , , m, __VA_ARGS__)
#define MOCK_CONST_METHOD0(m, ...) GMOCK_METHOD0_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD1(m, ...) GMOCK_METHOD1_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD2(m, ...) GMOCK_METHOD2_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD3(m, ...) GMOCK_METHOD3_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD4(m, ...) GMOCK_METHOD4_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD5(m, ...) GMOCK_METHOD5_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD6(m, ...) GMOCK_METHOD6_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD7(m, ...) GMOCK_METHOD7_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD8(m, ...) GMOCK_METHOD8_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD9(m, ...) GMOCK_METHOD9_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD10(m, ...) GMOCK_METHOD10_(, const, , m, __VA_ARGS__)
#define MOCK_METHOD0_T(m, ...) GMOCK_METHOD0_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD1_T(m, ...) GMOCK_METHOD1_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD2_T(m, ...) GMOCK_METHOD2_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD3_T(m, ...) GMOCK_METHOD3_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD4_T(m, ...) GMOCK_METHOD4_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD5_T(m, ...) GMOCK_METHOD5_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD6_T(m, ...) GMOCK_METHOD6_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD7_T(m, ...) GMOCK_METHOD7_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD8_T(m, ...) GMOCK_METHOD8_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD9_T(m, ...) GMOCK_METHOD9_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD10_T(m, ...) GMOCK_METHOD10_(typename, , , m, __VA_ARGS__)
#define MOCK_CONST_METHOD0_T(m, ...) \
GMOCK_METHOD0_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD1_T(m, ...) \
GMOCK_METHOD1_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD2_T(m, ...) \
GMOCK_METHOD2_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD3_T(m, ...) \
GMOCK_METHOD3_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD4_T(m, ...) \
GMOCK_METHOD4_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD5_T(m, ...) \
GMOCK_METHOD5_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD6_T(m, ...) \
GMOCK_METHOD6_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD7_T(m, ...) \
GMOCK_METHOD7_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD8_T(m, ...) \
GMOCK_METHOD8_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD9_T(m, ...) \
GMOCK_METHOD9_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD10_T(m, ...) \
GMOCK_METHOD10_(typename, const, , m, __VA_ARGS__)
#define MOCK_METHOD0_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD0_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD1_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD1_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD2_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD2_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD3_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD3_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD4_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD4_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD5_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD5_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD6_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD6_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD7_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD7_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD8_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD8_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD9_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD9_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD10_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD10_(, , ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD0_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD1_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD2_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD3_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD4_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD5_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD6_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD7_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD8_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD9_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD10_(, const, ct, m, __VA_ARGS__)
#define MOCK_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD0_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD1_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD2_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD3_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD4_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD5_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD6_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD7_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD8_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD9_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD10_(typename, , ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD0_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD1_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD2_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD3_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD4_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD5_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD6_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD7_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD8_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD9_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD10_(typename, const, ct, m, __VA_ARGS__)
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_

View File

@@ -0,0 +1,227 @@
$$ -*- mode: c++; -*-
$$ This is a Pump source file. Please use Pump to convert
$$ it to gmock-generated-function-mockers.h.
$$
$var n = 10 $$ The maximum arity we support.
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements function mockers of various arities.
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
#include <functional>
#include <utility>
#include "gmock/gmock-spec-builders.h"
#include "gmock/internal/gmock-internal-utils.h"
namespace testing {
namespace internal {
$range i 0..n
// Removes the given pointer; this is a helper for the expectation setter method
// for parameterless matchers.
//
// We want to make sure that the user cannot set a parameterless expectation on
// overloaded methods, including methods which are overloaded on const. Example:
//
// class MockClass {
// MOCK_METHOD0(GetName, string&());
// MOCK_CONST_METHOD0(GetName, const string&());
// };
//
// TEST() {
// // This should be an error, as it's not clear which overload is expected.
// EXPECT_CALL(mock, GetName).WillOnce(ReturnRef(value));
// }
//
// Here are the generated expectation-setter methods:
//
// class MockClass {
// // Overload 1
// MockSpec<string&()> gmock_GetName() { ... }
// // Overload 2. Declared const so that the compiler will generate an
// // error when trying to resolve between this and overload 4 in
// // 'gmock_GetName(WithoutMatchers(), nullptr)'.
// MockSpec<string&()> gmock_GetName(
// const WithoutMatchers&, const Function<string&()>*) const {
// // Removes const from this, calls overload 1
// return AdjustConstness_(this)->gmock_GetName();
// }
//
// // Overload 3
// const string& gmock_GetName() const { ... }
// // Overload 4
// MockSpec<const string&()> gmock_GetName(
// const WithoutMatchers&, const Function<const string&()>*) const {
// // Does not remove const, calls overload 3
// return AdjustConstness_const(this)->gmock_GetName();
// }
// }
//
template <typename MockType>
const MockType* AdjustConstness_const(const MockType* mock) {
return mock;
}
// Removes const from and returns the given pointer; this is a helper for the
// expectation setter method for parameterless matchers.
template <typename MockType>
MockType* AdjustConstness_(const MockType* mock) {
return const_cast<MockType*>(mock);
}
} // namespace internal
// The style guide prohibits "using" statements in a namespace scope
// inside a header file. However, the FunctionMocker class template
// is meant to be defined in the ::testing namespace. The following
// line is just a trick for working around a bug in MSVC 8.0, which
// cannot handle it if we define FunctionMocker in ::testing.
using internal::FunctionMocker;
// GMOCK_RESULT_(tn, F) expands to the result type of function type F.
// We define this as a variadic macro in case F contains unprotected
// commas (the same reason that we use variadic macros in other places
// in this file).
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_RESULT_(tn, ...) \
tn ::testing::internal::Function<__VA_ARGS__>::Result
// The type of argument N of the given function type.
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_ARG_(tn, N, ...) \
tn ::testing::internal::Function<__VA_ARGS__>::template Arg<N-1>::type
// The matcher type for argument N of the given function type.
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_MATCHER_(tn, N, ...) \
const ::testing::Matcher<GMOCK_ARG_(tn, N, __VA_ARGS__)>&
// The variable for mocking the given method.
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_MOCKER_(arity, constness, Method) \
GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)
$for i [[
$range j 1..i
$var arg_as = [[$for j, [[GMOCK_ARG_(tn, $j, __VA_ARGS__) gmock_a$j]]]]
$var as = [[$for j, \
[[::std::forward<GMOCK_ARG_(tn, $j, __VA_ARGS__)>(gmock_a$j)]]]]
$var matcher_arg_as = [[$for j, \
[[GMOCK_MATCHER_(tn, $j, __VA_ARGS__) gmock_a$j]]]]
$var matcher_as = [[$for j, [[gmock_a$j]]]]
$var anything_matchers = [[$for j, \
[[::testing::A<GMOCK_ARG_(tn, $j, __VA_ARGS__)>()]]]]
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD$i[[]]_(tn, constness, ct, Method, ...) \
static_assert($i == ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, "MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
$arg_as) constness { \
GMOCK_MOCKER_($i, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_($i, constness, Method).Invoke($as); \
} \
::testing::MockSpec<__VA_ARGS__> \
gmock_##Method($matcher_arg_as) constness { \
GMOCK_MOCKER_($i, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_($i, constness, Method).With($matcher_as); \
} \
::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
const ::testing::internal::WithoutMatchers&, \
constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
return ::testing::internal::AdjustConstness_##constness(this)-> \
gmock_##Method($anything_matchers); \
} \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_($i, constness, Method)
]]
$for i [[
#define MOCK_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, , , m, __VA_ARGS__)
]]
$for i [[
#define MOCK_CONST_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, const, , m, __VA_ARGS__)
]]
$for i [[
#define MOCK_METHOD$i[[]]_T(m, ...) GMOCK_METHOD$i[[]]_(typename, , , m, __VA_ARGS__)
]]
$for i [[
#define MOCK_CONST_METHOD$i[[]]_T(m, ...) \
GMOCK_METHOD$i[[]]_(typename, const, , m, __VA_ARGS__)
]]
$for i [[
#define MOCK_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD$i[[]]_(, , ct, m, __VA_ARGS__)
]]
$for i [[
#define MOCK_CONST_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD$i[[]]_(, const, ct, m, __VA_ARGS__)
]]
$for i [[
#define MOCK_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD$i[[]]_(typename, , ct, m, __VA_ARGS__)
]]
$for i [[
#define MOCK_CONST_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD$i[[]]_(typename, const, ct, m, __VA_ARGS__)
]]
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,346 @@
$$ -*- mode: c++; -*-
$$ This is a Pump source file. Please use Pump to convert
$$ it to gmock-generated-matchers.h.
$$
$var n = 10 $$ The maximum arity we support.
$$ }} This line fixes auto-indentation of the following code in Emacs.
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements some commonly used variadic matchers.
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
#include <iterator>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#include "gmock/gmock-matchers.h"
// The MATCHER* family of macros can be used in a namespace scope to
// define custom matchers easily.
//
// Basic Usage
// ===========
//
// The syntax
//
// MATCHER(name, description_string) { statements; }
//
// defines a matcher with the given name that executes the statements,
// which must return a bool to indicate if the match succeeds. Inside
// the statements, you can refer to the value being matched by 'arg',
// and refer to its type by 'arg_type'.
//
// The description string documents what the matcher does, and is used
// to generate the failure message when the match fails. Since a
// MATCHER() is usually defined in a header file shared by multiple
// C++ source files, we require the description to be a C-string
// literal to avoid possible side effects. It can be empty, in which
// case we'll use the sequence of words in the matcher name as the
// description.
//
// For example:
//
// MATCHER(IsEven, "") { return (arg % 2) == 0; }
//
// allows you to write
//
// // Expects mock_foo.Bar(n) to be called where n is even.
// EXPECT_CALL(mock_foo, Bar(IsEven()));
//
// or,
//
// // Verifies that the value of some_expression is even.
// EXPECT_THAT(some_expression, IsEven());
//
// If the above assertion fails, it will print something like:
//
// Value of: some_expression
// Expected: is even
// Actual: 7
//
// where the description "is even" is automatically calculated from the
// matcher name IsEven.
//
// Argument Type
// =============
//
// Note that the type of the value being matched (arg_type) is
// determined by the context in which you use the matcher and is
// supplied to you by the compiler, so you don't need to worry about
// declaring it (nor can you). This allows the matcher to be
// polymorphic. For example, IsEven() can be used to match any type
// where the value of "(arg % 2) == 0" can be implicitly converted to
// a bool. In the "Bar(IsEven())" example above, if method Bar()
// takes an int, 'arg_type' will be int; if it takes an unsigned long,
// 'arg_type' will be unsigned long; and so on.
//
// Parameterizing Matchers
// =======================
//
// Sometimes you'll want to parameterize the matcher. For that you
// can use another macro:
//
// MATCHER_P(name, param_name, description_string) { statements; }
//
// For example:
//
// MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; }
//
// will allow you to write:
//
// EXPECT_THAT(Blah("a"), HasAbsoluteValue(n));
//
// which may lead to this message (assuming n is 10):
//
// Value of: Blah("a")
// Expected: has absolute value 10
// Actual: -9
//
// Note that both the matcher description and its parameter are
// printed, making the message human-friendly.
//
// In the matcher definition body, you can write 'foo_type' to
// reference the type of a parameter named 'foo'. For example, in the
// body of MATCHER_P(HasAbsoluteValue, value) above, you can write
// 'value_type' to refer to the type of 'value'.
//
// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P$n to
// support multi-parameter matchers.
//
// Describing Parameterized Matchers
// =================================
//
// The last argument to MATCHER*() is a string-typed expression. The
// expression can reference all of the matcher's parameters and a
// special bool-typed variable named 'negation'. When 'negation' is
// false, the expression should evaluate to the matcher's description;
// otherwise it should evaluate to the description of the negation of
// the matcher. For example,
//
// using testing::PrintToString;
//
// MATCHER_P2(InClosedRange, low, hi,
// std::string(negation ? "is not" : "is") + " in range [" +
// PrintToString(low) + ", " + PrintToString(hi) + "]") {
// return low <= arg && arg <= hi;
// }
// ...
// EXPECT_THAT(3, InClosedRange(4, 6));
// EXPECT_THAT(3, Not(InClosedRange(2, 4)));
//
// would generate two failures that contain the text:
//
// Expected: is in range [4, 6]
// ...
// Expected: is not in range [2, 4]
//
// If you specify "" as the description, the failure message will
// contain the sequence of words in the matcher name followed by the
// parameter values printed as a tuple. For example,
//
// MATCHER_P2(InClosedRange, low, hi, "") { ... }
// ...
// EXPECT_THAT(3, InClosedRange(4, 6));
// EXPECT_THAT(3, Not(InClosedRange(2, 4)));
//
// would generate two failures that contain the text:
//
// Expected: in closed range (4, 6)
// ...
// Expected: not (in closed range (2, 4))
//
// Types of Matcher Parameters
// ===========================
//
// For the purpose of typing, you can view
//
// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... }
//
// as shorthand for
//
// template <typename p1_type, ..., typename pk_type>
// FooMatcherPk<p1_type, ..., pk_type>
// Foo(p1_type p1, ..., pk_type pk) { ... }
//
// When you write Foo(v1, ..., vk), the compiler infers the types of
// the parameters v1, ..., and vk for you. If you are not happy with
// the result of the type inference, you can specify the types by
// explicitly instantiating the template, as in Foo<long, bool>(5,
// false). As said earlier, you don't get to (or need to) specify
// 'arg_type' as that's determined by the context in which the matcher
// is used. You can assign the result of expression Foo(p1, ..., pk)
// to a variable of type FooMatcherPk<p1_type, ..., pk_type>. This
// can be useful when composing matchers.
//
// While you can instantiate a matcher template with reference types,
// passing the parameters by pointer usually makes your code more
// readable. If, however, you still want to pass a parameter by
// reference, be aware that in the failure message generated by the
// matcher you will see the value of the referenced object but not its
// address.
//
// Explaining Match Results
// ========================
//
// Sometimes the matcher description alone isn't enough to explain why
// the match has failed or succeeded. For example, when expecting a
// long string, it can be very helpful to also print the diff between
// the expected string and the actual one. To achieve that, you can
// optionally stream additional information to a special variable
// named result_listener, whose type is a pointer to class
// MatchResultListener:
//
// MATCHER_P(EqualsLongString, str, "") {
// if (arg == str) return true;
//
// *result_listener << "the difference: "
/// << DiffStrings(str, arg);
// return false;
// }
//
// Overloading Matchers
// ====================
//
// You can overload matchers with different numbers of parameters:
//
// MATCHER_P(Blah, a, description_string1) { ... }
// MATCHER_P2(Blah, a, b, description_string2) { ... }
//
// Caveats
// =======
//
// When defining a new matcher, you should also consider implementing
// MatcherInterface or using MakePolymorphicMatcher(). These
// approaches require more work than the MATCHER* macros, but also
// give you more control on the types of the value being matched and
// the matcher parameters, which may leads to better compiler error
// messages when the matcher is used wrong. They also allow
// overloading matchers based on parameter types (as opposed to just
// based on the number of parameters).
//
// MATCHER*() can only be used in a namespace scope as templates cannot be
// declared inside of a local class.
//
// More Information
// ================
//
// To learn more about using these macros, please search for 'MATCHER'
// on
// https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md
$range i 0..n
$for i
[[
$var macro_name = [[$if i==0 [[MATCHER]] $elif i==1 [[MATCHER_P]]
$else [[MATCHER_P$i]]]]
$var class_name = [[name##Matcher[[$if i==0 [[]] $elif i==1 [[P]]
$else [[P$i]]]]]]
$range j 0..i-1
$var template = [[$if i==0 [[]] $else [[
template <$for j, [[typename p$j##_type]]>\
]]]]
$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
$var impl_ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
$var impl_inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::std::move(gmock_p$j))]]]]]]
$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::std::move(gmock_p$j))]]]]]]
$var params = [[$for j, [[p$j]]]]
$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]]
$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]]
$var param_field_decls = [[$for j
[[
p$j##_type const p$j;\
]]]]
$var param_field_decls2 = [[$for j
[[
p$j##_type const p$j;\
]]]]
#define $macro_name(name$for j [[, p$j]], description)\$template
class $class_name {\
public:\
template <typename arg_type>\
class gmock_Impl : public ::testing::MatcherInterface<\
GTEST_REFERENCE_TO_CONST_(arg_type)> {\
public:\
[[$if i==1 [[explicit ]]]]gmock_Impl($impl_ctor_param_list)\
$impl_inits {}\
virtual bool MatchAndExplain(\
GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(false);\
}\
virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(true);\
}\$param_field_decls
private:\
::std::string FormatDescription(bool negation) const {\
::std::string gmock_description = (description);\
if (!gmock_description.empty()) {\
return gmock_description;\
}\
return ::testing::internal::FormatMatcherDescription(\
negation, #name, \
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
::std::tuple<$for j, [[p$j##_type]]>($for j, [[p$j]])));\
}\
};\
template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\
return ::testing::Matcher<arg_type>(\
new gmock_Impl<arg_type>($params));\
}\
[[$if i==1 [[explicit ]]]]$class_name($ctor_param_list)$inits {\
}\$param_field_decls2
private:\
};\$template
inline $class_name$param_types name($param_types_and_names) {\
return $class_name$param_types($params);\
}\$template
template <typename arg_type>\
bool $class_name$param_types::gmock_Impl<arg_type>::MatchAndExplain(\
GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
const
]]
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_

View File

@@ -0,0 +1,162 @@
// 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 actions that depend on gmock-generated-actions.h.
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
#include <algorithm>
#include <type_traits>
#include "gmock/gmock-generated-actions.h"
namespace testing {
namespace internal {
// An internal replacement for std::copy which mimics its behavior. This is
// necessary because Visual Studio deprecates ::std::copy, issuing warning 4996.
// However Visual Studio 2010 and later do not honor #pragmas which disable that
// warning.
template<typename InputIterator, typename OutputIterator>
inline OutputIterator CopyElements(InputIterator first,
InputIterator last,
OutputIterator output) {
for (; first != last; ++first, ++output) {
*output = *first;
}
return output;
}
} // namespace internal
// Various overloads for Invoke().
// The ACTION*() macros trigger warning C4100 (unreferenced formal
// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
// the macro definition, as the warnings are generated when the macro
// is expanded and macro expansion cannot contain #pragma. Therefore
// we suppress them here.
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable:4100)
#endif
// Action ReturnArg<k>() returns the k-th argument of the mock function.
ACTION_TEMPLATE(ReturnArg,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_0_VALUE_PARAMS()) {
return ::std::get<k>(args);
}
// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
// mock function to *pointer.
ACTION_TEMPLATE(SaveArg,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_1_VALUE_PARAMS(pointer)) {
*pointer = ::std::get<k>(args);
}
// Action SaveArgPointee<k>(pointer) saves the value pointed to
// by the k-th (0-based) argument of the mock function to *pointer.
ACTION_TEMPLATE(SaveArgPointee,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_1_VALUE_PARAMS(pointer)) {
*pointer = *::std::get<k>(args);
}
// Action SetArgReferee<k>(value) assigns 'value' to the variable
// referenced by the k-th (0-based) argument of the mock function.
ACTION_TEMPLATE(SetArgReferee,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_1_VALUE_PARAMS(value)) {
typedef typename ::std::tuple_element<k, args_type>::type argk_type;
// Ensures that argument #k is a reference. If you get a compiler
// error on the next line, you are using SetArgReferee<k>(value) in
// a mock function whose k-th (0-based) argument is not a reference.
GTEST_COMPILE_ASSERT_(std::is_reference<argk_type>::value,
SetArgReferee_must_be_used_with_a_reference_argument);
::std::get<k>(args) = value;
}
// Action SetArrayArgument<k>(first, last) copies the elements in
// source range [first, last) to the array pointed to by the k-th
// (0-based) argument, which can be either a pointer or an
// iterator. The action does not take ownership of the elements in the
// source range.
ACTION_TEMPLATE(SetArrayArgument,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_2_VALUE_PARAMS(first, last)) {
// Visual Studio deprecates ::std::copy, so we use our own copy in that case.
#ifdef _MSC_VER
internal::CopyElements(first, last, ::std::get<k>(args));
#else
::std::copy(first, last, ::std::get<k>(args));
#endif
}
// Action DeleteArg<k>() deletes the k-th (0-based) argument of the mock
// function.
ACTION_TEMPLATE(DeleteArg,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_0_VALUE_PARAMS()) {
delete ::std::get<k>(args);
}
// This action returns the value pointed to by 'pointer'.
ACTION_P(ReturnPointee, pointer) { return *pointer; }
// Action Throw(exception) can be used in a mock function of any type
// to throw the given exception. Any copyable value can be thrown.
#if GTEST_HAS_EXCEPTIONS
// Suppresses the 'unreachable code' warning that VC generates in opt modes.
# ifdef _MSC_VER
# pragma warning(push) // Saves the current warning state.
# pragma warning(disable:4702) // Temporarily disables warning 4702.
# endif
ACTION_P(Throw, exception) { throw exception; }
# ifdef _MSC_VER
# pragma warning(pop) // Restores the warning state.
# endif
#endif // GTEST_HAS_EXCEPTIONS
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_

View File

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

View File

@@ -60,91 +60,20 @@
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
#include <type_traits>
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
#include "gmock/gmock-spec-builders.h"
#include "gmock/internal/gmock-port.h"
namespace testing {
template <class MockClass>
class NiceMock;
template <class MockClass>
class NaggyMock;
template <class MockClass>
class StrictMock;
namespace internal {
template <typename T>
std::true_type StrictnessModifierProbe(const NiceMock<T>&);
template <typename T>
std::true_type StrictnessModifierProbe(const NaggyMock<T>&);
template <typename T>
std::true_type StrictnessModifierProbe(const StrictMock<T>&);
std::false_type StrictnessModifierProbe(...);
template <typename T>
constexpr bool HasStrictnessModifier() {
return decltype(StrictnessModifierProbe(std::declval<const T&>()))::value;
}
// Base classes that register and deregister with testing::Mock to alter the
// default behavior around uninteresting calls. Inheriting from one of these
// classes first and then MockClass ensures the MockClass constructor is run
// after registration, and that the MockClass destructor runs before
// deregistration. This guarantees that MockClass's constructor and destructor
// run with the same level of strictness as its instance methods.
#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW && \
(defined(_MSC_VER) || defined(__clang__))
// We need to mark these classes with this declspec to ensure that
// the empty base class optimization is performed.
#define GTEST_INTERNAL_EMPTY_BASE_CLASS __declspec(empty_bases)
#else
#define GTEST_INTERNAL_EMPTY_BASE_CLASS
#endif
template <typename Base>
class NiceMockImpl {
public:
NiceMockImpl() { ::testing::Mock::AllowUninterestingCalls(this); }
~NiceMockImpl() { ::testing::Mock::UnregisterCallReaction(this); }
};
template <typename Base>
class NaggyMockImpl {
public:
NaggyMockImpl() { ::testing::Mock::WarnUninterestingCalls(this); }
~NaggyMockImpl() { ::testing::Mock::UnregisterCallReaction(this); }
};
template <typename Base>
class StrictMockImpl {
public:
StrictMockImpl() { ::testing::Mock::FailUninterestingCalls(this); }
~StrictMockImpl() { ::testing::Mock::UnregisterCallReaction(this); }
};
} // namespace internal
template <class MockClass>
class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
: private internal::NiceMockImpl<MockClass>,
public MockClass {
class NiceMock : public MockClass {
public:
static_assert(!internal::HasStrictnessModifier<MockClass>(),
"Can't apply NiceMock to a class hierarchy that already has a "
"strictness modifier. See "
"https://google.github.io/googletest/"
"gmock_cook_book.html#NiceStrictNaggy");
NiceMock() : MockClass() {
static_assert(sizeof(*this) == sizeof(MockClass),
"The impl subclass shouldn't introduce any padding");
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
// Ideally, we would inherit base class's constructors through a using
@@ -156,16 +85,21 @@ class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
// made explicit.
template <typename A>
explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) {
static_assert(sizeof(*this) == sizeof(MockClass),
"The impl subclass shouldn't introduce any padding");
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename TArg1, typename TArg2, typename... An>
NiceMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
: MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
template <typename A1, typename A2, typename... An>
NiceMock(A1&& arg1, A2&& arg2, An&&... args)
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
std::forward<An>(args)...) {
static_assert(sizeof(*this) == sizeof(MockClass),
"The impl subclass shouldn't introduce any padding");
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
~NiceMock() { // NOLINT
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this));
}
private:
@@ -173,19 +107,11 @@ class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
};
template <class MockClass>
class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
: private internal::NaggyMockImpl<MockClass>,
public MockClass {
static_assert(!internal::HasStrictnessModifier<MockClass>(),
"Can't apply NaggyMock to a class hierarchy that already has a "
"strictness modifier. See "
"https://google.github.io/googletest/"
"gmock_cook_book.html#NiceStrictNaggy");
class NaggyMock : public MockClass {
public:
NaggyMock() : MockClass() {
static_assert(sizeof(*this) == sizeof(MockClass),
"The impl subclass shouldn't introduce any padding");
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
// Ideally, we would inherit base class's constructors through a using
@@ -197,16 +123,21 @@ class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
// made explicit.
template <typename A>
explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) {
static_assert(sizeof(*this) == sizeof(MockClass),
"The impl subclass shouldn't introduce any padding");
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename TArg1, typename TArg2, typename... An>
NaggyMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
: MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
template <typename A1, typename A2, typename... An>
NaggyMock(A1&& arg1, A2&& arg2, An&&... args)
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
std::forward<An>(args)...) {
static_assert(sizeof(*this) == sizeof(MockClass),
"The impl subclass shouldn't introduce any padding");
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
~NaggyMock() { // NOLINT
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this));
}
private:
@@ -214,19 +145,11 @@ class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
};
template <class MockClass>
class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock
: private internal::StrictMockImpl<MockClass>,
public MockClass {
class StrictMock : public MockClass {
public:
static_assert(
!internal::HasStrictnessModifier<MockClass>(),
"Can't apply StrictMock to a class hierarchy that already has a "
"strictness modifier. See "
"https://google.github.io/googletest/"
"gmock_cook_book.html#NiceStrictNaggy");
StrictMock() : MockClass() {
static_assert(sizeof(*this) == sizeof(MockClass),
"The impl subclass shouldn't introduce any padding");
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
// Ideally, we would inherit base class's constructors through a using
@@ -238,24 +161,55 @@ class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock
// made explicit.
template <typename A>
explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) {
static_assert(sizeof(*this) == sizeof(MockClass),
"The impl subclass shouldn't introduce any padding");
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename TArg1, typename TArg2, typename... An>
StrictMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
: MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
template <typename A1, typename A2, typename... An>
StrictMock(A1&& arg1, A2&& arg2, An&&... args)
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
std::forward<An>(args)...) {
static_assert(sizeof(*this) == sizeof(MockClass),
"The impl subclass shouldn't introduce any padding");
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
~StrictMock() { // NOLINT
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this));
}
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock);
};
#undef GTEST_INTERNAL_EMPTY_BASE_CLASS
// The following specializations catch some (relatively more common)
// user errors of nesting nice and strict mocks. They do NOT catch
// all possible errors.
// These specializations are declared but not defined, as NiceMock,
// NaggyMock, and StrictMock cannot be nested.
template <typename MockClass>
class NiceMock<NiceMock<MockClass> >;
template <typename MockClass>
class NiceMock<NaggyMock<MockClass> >;
template <typename MockClass>
class NiceMock<StrictMock<MockClass> >;
template <typename MockClass>
class NaggyMock<NiceMock<MockClass> >;
template <typename MockClass>
class NaggyMock<NaggyMock<MockClass> >;
template <typename MockClass>
class NaggyMock<StrictMock<MockClass> >;
template <typename MockClass>
class StrictMock<NiceMock<MockClass> >;
template <typename MockClass>
class StrictMock<NaggyMock<MockClass> >;
template <typename MockClass>
class StrictMock<StrictMock<MockClass> >;
} // namespace testing
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_

View File

@@ -58,8 +58,8 @@
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
#include <functional>
#include <map>
@@ -108,14 +108,6 @@ template <typename F> class TypedExpectation;
// Helper class for testing the Expectation class template.
class ExpectationTester;
// Helper classes for implementing NiceMock, StrictMock, and NaggyMock.
template <typename MockClass>
class NiceMockImpl;
template <typename MockClass>
class StrictMockImpl;
template <typename MockClass>
class NaggyMockImpl;
// Protects the mock object registry (in class Mock), all function
// mockers, and all expectations.
//
@@ -421,12 +413,14 @@ class GTEST_API_ Mock {
template <typename F>
friend class internal::FunctionMocker;
template <typename MockClass>
friend class internal::NiceMockImpl;
template <typename MockClass>
friend class internal::NaggyMockImpl;
template <typename MockClass>
friend class internal::StrictMockImpl;
template <typename M>
friend class NiceMock;
template <typename M>
friend class NaggyMock;
template <typename M>
friend class StrictMock;
// Tells Google Mock to allow uninteresting calls on the given mock
// object.
@@ -505,10 +499,7 @@ class GTEST_API_ Expectation {
public:
// Constructs a null object that doesn't reference any expectation.
Expectation();
Expectation(Expectation&&) = default;
Expectation(const Expectation&) = default;
Expectation& operator=(Expectation&&) = default;
Expectation& operator=(const Expectation&) = default;
~Expectation();
// This single-argument ctor must not be explicit, in order to support the
@@ -888,6 +879,8 @@ class GTEST_API_ ExpectationBase {
Clause last_clause_;
mutable bool action_count_checked_; // Under mutex_.
mutable Mutex mutex_; // Protects action_count_checked_.
GTEST_DISALLOW_ASSIGN_(ExpectationBase);
}; // class ExpectationBase
// Impements an expectation for the given function type.
@@ -1302,6 +1295,8 @@ class MockSpec {
internal::FunctionMocker<F>* const function_mocker_;
// The argument matchers specified in the spec.
ArgumentMatcherTuple matchers_;
GTEST_DISALLOW_ASSIGN_(MockSpec);
}; // class MockSpec
// Wrapper type for generically holding an ordinary value or lvalue reference.
@@ -1355,6 +1350,12 @@ class ReferenceOrValueWrapper<T&> {
T* value_ptr_;
};
// MSVC warns about using 'this' in base member initializer list, so
// we need to temporarily disable the warning. We have to do it for
// the entire class to suppress the warning, even though it's about
// the constructor only.
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4355)
// C++ treats the void type specially. For example, you cannot define
// a void-typed variable or pass a void value to a function.
// ActionResultHolder<T> holds a value of type T, where T must be a
@@ -1785,87 +1786,18 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
}
}; // class FunctionMocker
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4355
// Reports an uninteresting call (whose description is in msg) in the
// manner specified by 'reaction'.
void ReportUninterestingCall(CallReaction reaction, const std::string& msg);
} // namespace internal
namespace internal {
template <typename F>
class MockFunction;
template <typename R, typename... Args>
class MockFunction<R(Args...)> {
public:
MockFunction(const MockFunction&) = delete;
MockFunction& operator=(const MockFunction&) = delete;
std::function<R(Args...)> AsStdFunction() {
return [this](Args... args) -> R {
return this->Call(std::forward<Args>(args)...);
};
}
// Implementation detail: the expansion of the MOCK_METHOD macro.
R Call(Args... args) {
mock_.SetOwnerAndName(this, "Call");
return mock_.Invoke(std::forward<Args>(args)...);
}
MockSpec<R(Args...)> gmock_Call(Matcher<Args>... m) {
mock_.RegisterOwner(this);
return mock_.With(std::move(m)...);
}
MockSpec<R(Args...)> gmock_Call(const WithoutMatchers&, R (*)(Args...)) {
return this->gmock_Call(::testing::A<Args>()...);
}
protected:
MockFunction() = default;
~MockFunction() = default;
private:
FunctionMocker<R(Args...)> mock_;
};
/*
The SignatureOf<F> struct is a meta-function returning function signature
corresponding to the provided F argument.
It makes use of MockFunction easier by allowing it to accept more F arguments
than just function signatures.
Specializations provided here cover a signature type itself and any template
that can be parameterized with a signature, including std::function and
boost::function.
*/
template <typename F, typename = void>
struct SignatureOf;
template <typename R, typename... Args>
struct SignatureOf<R(Args...)> {
using type = R(Args...);
};
template <template <typename> class C, typename F>
struct SignatureOf<C<F>,
typename std::enable_if<std::is_function<F>::value>::type>
: SignatureOf<F> {};
template <typename F>
using SignatureOfT = typename SignatureOf<F>::type;
} // namespace internal
// A MockFunction<F> type has one mock method whose type is
// internal::SignatureOfT<F>. It is useful when you just want your
// test code to emit some messages and have Google Mock verify the
// right messages are sent (and perhaps at the right times). For
// example, if you are exercising code:
// A MockFunction<F> class has one mock method whose type is F. It is
// useful when you just want your test code to emit some messages and
// have Google Mock verify the right messages are sent (and perhaps at
// the right times). For example, if you are exercising code:
//
// Foo(1);
// Foo(2);
@@ -1899,34 +1831,49 @@ using SignatureOfT = typename SignatureOf<F>::type;
// Bar("a") is called by which call to Foo().
//
// MockFunction<F> can also be used to exercise code that accepts
// std::function<internal::SignatureOfT<F>> callbacks. To do so, use
// AsStdFunction() method to create std::function proxy forwarding to
// original object's Call. Example:
// std::function<F> callbacks. To do so, use AsStdFunction() method
// to create std::function proxy forwarding to original object's Call.
// Example:
//
// TEST(FooTest, RunsCallbackWithBarArgument) {
// MockFunction<int(string)> callback;
// EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1));
// Foo(callback.AsStdFunction());
// }
//
// The internal::SignatureOfT<F> indirection allows to use other types
// than just function signature type. This is typically useful when
// providing a mock for a predefined std::function type. Example:
//
// using FilterPredicate = std::function<bool(string)>;
// void MyFilterAlgorithm(FilterPredicate predicate);
//
// TEST(FooTest, FilterPredicateAlwaysAccepts) {
// MockFunction<FilterPredicate> predicateMock;
// EXPECT_CALL(predicateMock, Call(_)).WillRepeatedly(Return(true));
// MyFilterAlgorithm(predicateMock.AsStdFunction());
// }
template <typename F>
class MockFunction : public internal::MockFunction<internal::SignatureOfT<F>> {
using Base = internal::MockFunction<internal::SignatureOfT<F>>;
class MockFunction;
template <typename R, typename... Args>
class MockFunction<R(Args...)> {
public:
using Base::Base;
MockFunction() {}
MockFunction(const MockFunction&) = delete;
MockFunction& operator=(const MockFunction&) = delete;
std::function<R(Args...)> AsStdFunction() {
return [this](Args... args) -> R {
return this->Call(std::forward<Args>(args)...);
};
}
// Implementation detail: the expansion of the MOCK_METHOD macro.
R Call(Args... args) {
mock_.SetOwnerAndName(this, "Call");
return mock_.Invoke(std::forward<Args>(args)...);
}
internal::MockSpec<R(Args...)> gmock_Call(Matcher<Args>... m) {
mock_.RegisterOwner(this);
return mock_.With(std::move(m)...);
}
internal::MockSpec<R(Args...)> gmock_Call(const internal::WithoutMatchers&,
R (*)(Args...)) {
return this->gmock_Call(::testing::A<Args>()...);
}
private:
internal::FunctionMocker<R(Args...)> mock_;
};
// The style guide prohibits "using" statements in a namespace scope
@@ -2035,4 +1982,4 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#define EXPECT_CALL(obj, call) \
GMOCK_ON_CALL_IMPL_(obj, InternalExpectedAt, call)
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_

View File

@@ -34,8 +34,8 @@
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_H_
// This file implements the following syntax:
//
@@ -59,6 +59,9 @@
#include "gmock/gmock-actions.h"
#include "gmock/gmock-cardinalities.h"
#include "gmock/gmock-function-mocker.h"
#include "gmock/gmock-generated-actions.h"
#include "gmock/gmock-generated-function-mockers.h"
#include "gmock/gmock-generated-matchers.h"
#include "gmock/gmock-matchers.h"
#include "gmock/gmock-more-actions.h"
#include "gmock/gmock-more-matchers.h"
@@ -95,4 +98,4 @@ GTEST_API_ void InitGoogleMock();
} // namespace testing
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_H_

View File

@@ -0,0 +1,10 @@
// This file was GENERATED by command:
// pump.py gmock-generated-actions.h.pump
// DO NOT EDIT BY HAND!!!
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_

View File

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

View File

@@ -31,6 +31,6 @@
//
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_

View File

@@ -33,7 +33,7 @@
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_

View File

@@ -36,8 +36,8 @@
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
#include <stdio.h>
#include <ostream> // NOLINT
@@ -71,6 +71,20 @@ GTEST_API_ std::string JoinAsTuple(const Strings& fields);
// "foo_bar_123" are converted to "foo bar 123".
GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name);
// PointeeOf<Pointer>::type is the type of a value pointed to by a
// Pointer, which can be either a smart pointer or a raw pointer. The
// following default implementation is for the case where Pointer is a
// smart pointer.
template <typename Pointer>
struct PointeeOf {
// Smart pointer classes define type element_type as the type of
// their pointees.
typedef typename Pointer::element_type type;
};
// This specialization is for the raw pointer case.
template <typename T>
struct PointeeOf<T*> { typedef T type; }; // NOLINT
// GetRawPointer(p) returns the raw pointer underlying p when p is a
// smart pointer, or returns p itself when p is already a raw pointer.
// The following default implementation is for the smart pointer case.
@@ -122,13 +136,15 @@ GMOCK_DECLARE_KIND_(int, kInteger);
GMOCK_DECLARE_KIND_(unsigned int, kInteger);
GMOCK_DECLARE_KIND_(long, kInteger); // NOLINT
GMOCK_DECLARE_KIND_(unsigned long, kInteger); // NOLINT
GMOCK_DECLARE_KIND_(long long, kInteger); // NOLINT
GMOCK_DECLARE_KIND_(unsigned long long, kInteger); // NOLINT
#if GMOCK_WCHAR_T_IS_NATIVE_
GMOCK_DECLARE_KIND_(wchar_t, kInteger);
#endif
// Non-standard integer types.
GMOCK_DECLARE_KIND_(Int64, kInteger);
GMOCK_DECLARE_KIND_(UInt64, kInteger);
// All standard floating-point types.
GMOCK_DECLARE_KIND_(float, kFloatingPoint);
GMOCK_DECLARE_KIND_(double, kFloatingPoint);
@@ -141,6 +157,9 @@ GMOCK_DECLARE_KIND_(long double, kFloatingPoint);
static_cast< ::testing::internal::TypeKind>( \
::testing::internal::KindOf<type>::value)
// Evaluates to true if and only if integer type T is signed.
#define GMOCK_IS_SIGNED_(T) (static_cast<T>(-1) < 0)
// LosslessArithmeticConvertibleImpl<kFromKind, From, kToKind, To>::value
// is true if and only if arithmetic type From can be losslessly converted to
// arithmetic type To.
@@ -151,30 +170,65 @@ GMOCK_DECLARE_KIND_(long double, kFloatingPoint);
// From, and kToKind is the kind of To; the value is
// implementation-defined when the above pre-condition is violated.
template <TypeKind kFromKind, typename From, TypeKind kToKind, typename To>
using LosslessArithmeticConvertibleImpl = std::integral_constant<
bool,
// clang-format off
// Converting from bool is always lossless
(kFromKind == kBool) ? true
// Converting between any other type kinds will be lossy if the type
// kinds are not the same.
: (kFromKind != kToKind) ? false
: (kFromKind == kInteger &&
// Converting between integers of different widths is allowed so long
// as the conversion does not go from signed to unsigned.
(((sizeof(From) < sizeof(To)) &&
!(std::is_signed<From>::value && !std::is_signed<To>::value)) ||
// Converting between integers of the same width only requires the
// two types to have the same signedness.
((sizeof(From) == sizeof(To)) &&
(std::is_signed<From>::value == std::is_signed<To>::value)))
) ? true
// Floating point conversions are lossless if and only if `To` is at least
// as wide as `From`.
: (kFromKind == kFloatingPoint && (sizeof(From) <= sizeof(To))) ? true
: false
// clang-format on
>;
struct LosslessArithmeticConvertibleImpl : public std::false_type {};
// Converting bool to bool is lossless.
template <>
struct LosslessArithmeticConvertibleImpl<kBool, bool, kBool, bool>
: public std::true_type {};
// Converting bool to any integer type is lossless.
template <typename To>
struct LosslessArithmeticConvertibleImpl<kBool, bool, kInteger, To>
: public std::true_type {};
// Converting bool to any floating-point type is lossless.
template <typename To>
struct LosslessArithmeticConvertibleImpl<kBool, bool, kFloatingPoint, To>
: public std::true_type {};
// Converting an integer to bool is lossy.
template <typename From>
struct LosslessArithmeticConvertibleImpl<kInteger, From, kBool, bool>
: public std::false_type {};
// Converting an integer to another non-bool integer is lossless
// if and only if the target type's range encloses the source type's range.
template <typename From, typename To>
struct LosslessArithmeticConvertibleImpl<kInteger, From, kInteger, To>
: public bool_constant<
// When converting from a smaller size to a larger size, we are
// fine as long as we are not converting from signed to unsigned.
((sizeof(From) < sizeof(To)) &&
(!GMOCK_IS_SIGNED_(From) || GMOCK_IS_SIGNED_(To))) ||
// When converting between the same size, the signedness must match.
((sizeof(From) == sizeof(To)) &&
(GMOCK_IS_SIGNED_(From) == GMOCK_IS_SIGNED_(To)))> {}; // NOLINT
#undef GMOCK_IS_SIGNED_
// Converting an integer to a floating-point type may be lossy, since
// the format of a floating-point number is implementation-defined.
template <typename From, typename To>
struct LosslessArithmeticConvertibleImpl<kInteger, From, kFloatingPoint, To>
: public std::false_type {};
// Converting a floating-point to bool is lossy.
template <typename From>
struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kBool, bool>
: public std::false_type {};
// Converting a floating-point to an integer is lossy.
template <typename From, typename To>
struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kInteger, To>
: public std::false_type {};
// Converting a floating-point to another floating-point is lossless
// if and only if the target type is at least as big as the source type.
template <typename From, typename To>
struct LosslessArithmeticConvertibleImpl<
kFloatingPoint, From, kFloatingPoint, To>
: public bool_constant<sizeof(From) <= sizeof(To)> {}; // NOLINT
// LosslessArithmeticConvertible<From, To>::value is true if and only if
// arithmetic type From can be losslessly converted to arithmetic type To.
@@ -184,9 +238,9 @@ using LosslessArithmeticConvertibleImpl = std::integral_constant<
// reference) built-in arithmetic types; the value is
// implementation-defined when the above pre-condition is violated.
template <typename From, typename To>
using LosslessArithmeticConvertible =
LosslessArithmeticConvertibleImpl<GMOCK_KIND_OF_(From), From,
GMOCK_KIND_OF_(To), To>;
struct LosslessArithmeticConvertible
: public LosslessArithmeticConvertibleImpl<
GMOCK_KIND_OF_(From), From, GMOCK_KIND_OF_(To), To> {}; // NOLINT
// This interface knows how to report a Google Mock failure (either
// non-fatal or fatal).
@@ -280,6 +334,8 @@ class WithoutMatchers {
// Internal use only: access the singleton instance of WithoutMatchers.
GTEST_API_ WithoutMatchers GetWithoutMatchers();
// Type traits.
// Disable MSVC warnings for infinite recursion, since in this case the
// the recursion is unreachable.
#ifdef _MSC_VER
@@ -364,8 +420,7 @@ template <typename ElementPointer, typename Size>
class StlContainerView< ::std::tuple<ElementPointer, Size> > {
public:
typedef typename std::remove_const<
typename std::pointer_traits<ElementPointer>::element_type>::type
RawElement;
typename internal::PointeeOf<ElementPointer>::type>::type RawElement;
typedef internal::NativeArray<RawElement> type;
typedef const type const_reference;
@@ -409,13 +464,11 @@ auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>) -> decltype(
// Apply the function to a tuple of arguments.
template <typename F, typename Tuple>
auto Apply(F&& f, Tuple&& args) -> decltype(
ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
MakeIndexSequence<std::tuple_size<
typename std::remove_reference<Tuple>::type>::value>())) {
auto Apply(F&& f, Tuple&& args)
-> decltype(ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
MakeIndexSequence<std::tuple_size<Tuple>::value>())) {
return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
MakeIndexSequence<std::tuple_size<
typename std::remove_reference<Tuple>::type>::value>());
MakeIndexSequence<std::tuple_size<Tuple>::value>());
}
// Template struct Function<F>, where F must be a function type, contains
@@ -439,7 +492,8 @@ struct Function<R(Args...)> {
using Result = R;
static constexpr size_t ArgumentCount = sizeof...(Args);
template <size_t I>
using Arg = ElemFromList<I, Args...>;
using Arg = ElemFromList<I, typename MakeIndexSequence<sizeof...(Args)>::type,
Args...>;
using ArgumentTuple = std::tuple<Args...>;
using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;
using MakeResultVoid = void(Args...);
@@ -456,4 +510,4 @@ constexpr size_t Function<R(Args...)>::ArgumentCount;
} // namespace internal
} // namespace testing
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_

View File

@@ -37,12 +37,11 @@
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
#include <assert.h>
#include <stdlib.h>
#include <cstdint>
#include <iostream>
// Most of the utilities needed for porting Google Mock are also
@@ -70,7 +69,8 @@
// 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_int32_(name) \
extern GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name)
# define GMOCK_DECLARE_string_(name) \
extern GTEST_API_ ::std::string GMOCK_FLAG(name)
@@ -78,10 +78,10 @@
# 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)
GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) = (default_val)
# define GMOCK_DEFINE_string_(name, default_val, doc) \
GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val)
#endif // !defined(GMOCK_DECLARE_bool_)
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_

View File

@@ -1,5 +1,18 @@
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_
#ifndef THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_PP_H_
#define THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_PP_H_
#undef GMOCK_PP_INTERNAL_USE_MSVC
#if defined(__clang__)
#define GMOCK_PP_INTERNAL_USE_MSVC 0
#elif defined(_MSC_VER)
// TODO(iserna): Also verify tradional versus comformant preprocessor.
static_assert(
_MSC_VER >= 1900,
"MSVC version not supported. There is support for MSVC 14.0 and above.");
#define GMOCK_PP_INTERNAL_USE_MSVC 1
#else
#define GMOCK_PP_INTERNAL_USE_MSVC 0
#endif
// Expands and concatenates the arguments. Constructed macros reevaluate.
#define GMOCK_PP_CAT(_1, _2) GMOCK_PP_INTERNAL_CAT(_1, _2)
@@ -16,6 +29,10 @@
// Returns the only argument.
#define GMOCK_PP_IDENTITY(_1) _1
// MSVC preprocessor collapses __VA_ARGS__ in a single argument, we use a
// CAT-like directive to force correct evaluation. Each macro has its own.
#if GMOCK_PP_INTERNAL_USE_MSVC
// Evaluates to the number of arguments after expansion.
//
// #define PAIR x, y
@@ -26,27 +43,45 @@
// GMOCK_PP_NARG(PAIR) => 2
//
// Requires: the number of arguments after expansion is at most 15.
#define GMOCK_PP_NARG(...) \
GMOCK_PP_INTERNAL_16TH( \
(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
#define GMOCK_PP_NARG(...) \
GMOCK_PP_INTERNAL_NARG_CAT( \
GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, \
8, 7, 6, 5, 4, 3, 2, 1), )
// Returns 1 if the expansion of arguments has an unprotected comma. Otherwise
// returns 0. Requires no more than 15 unprotected commas.
#define GMOCK_PP_HAS_COMMA(...) \
GMOCK_PP_INTERNAL_16TH( \
(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0))
#define GMOCK_PP_HAS_COMMA(...) \
GMOCK_PP_INTERNAL_HAS_COMMA_CAT( \
GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 0), )
// Returns the first argument.
#define GMOCK_PP_HEAD(...) GMOCK_PP_INTERNAL_HEAD((__VA_ARGS__, unusedArg))
#define GMOCK_PP_HEAD(...) \
GMOCK_PP_INTERNAL_HEAD_CAT(GMOCK_PP_INTERNAL_HEAD(__VA_ARGS__), )
// Returns the tail. A variadic list of all arguments minus the first. Requires
// at least one argument.
#define GMOCK_PP_TAIL(...) GMOCK_PP_INTERNAL_TAIL((__VA_ARGS__))
#define GMOCK_PP_TAIL(...) \
GMOCK_PP_INTERNAL_TAIL_CAT(GMOCK_PP_INTERNAL_TAIL(__VA_ARGS__), )
// Calls CAT(_Macro, NARG(__VA_ARGS__))(__VA_ARGS__)
#define GMOCK_PP_VARIADIC_CALL(_Macro, ...) \
GMOCK_PP_IDENTITY( \
GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__))
GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT( \
GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__), )
#else // GMOCK_PP_INTERNAL_USE_MSVC
#define GMOCK_PP_NARG(...) \
GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, \
7, 6, 5, 4, 3, 2, 1)
#define GMOCK_PP_HAS_COMMA(...) \
GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 0)
#define GMOCK_PP_HEAD(...) GMOCK_PP_INTERNAL_HEAD(__VA_ARGS__)
#define GMOCK_PP_TAIL(...) GMOCK_PP_INTERNAL_TAIL(__VA_ARGS__)
#define GMOCK_PP_VARIADIC_CALL(_Macro, ...) \
GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__)
#endif // GMOCK_PP_INTERNAL_USE_MSVC
// If the arguments after expansion have no tokens, evaluates to `1`. Otherwise
// evaluates to `0`.
@@ -86,14 +121,6 @@
#define GMOCK_PP_IF(_Cond, _Then, _Else) \
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IF_, _Cond)(_Then, _Else)
// Similar to GMOCK_PP_IF but takes _Then and _Else in parentheses.
//
// GMOCK_PP_GENERIC_IF(1, (a, b, c), (d, e, f)) => a, b, c
// GMOCK_PP_GENERIC_IF(0, (a, b, c), (d, e, f)) => d, e, f
//
#define GMOCK_PP_GENERIC_IF(_Cond, _Then, _Else) \
GMOCK_PP_REMOVE_PARENS(GMOCK_PP_IF(_Cond, _Then, _Else))
// Evaluates to the number of arguments after expansion. Identifies 'empty' as
// 0.
//
@@ -112,9 +139,10 @@
// Expands to 1 if the first argument starts with something in parentheses,
// otherwise to 0.
#define GMOCK_PP_IS_BEGIN_PARENS(...) \
GMOCK_PP_HEAD(GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_, \
GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C __VA_ARGS__))
#define GMOCK_PP_IS_BEGIN_PARENS(...) \
GMOCK_PP_INTERNAL_ALTERNATE_HEAD( \
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_, \
GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C __VA_ARGS__))
// Expands to 1 is there is only one argument and it is enclosed in parentheses.
#define GMOCK_PP_IS_ENCLOSED_PARENS(...) \
@@ -151,6 +179,10 @@
#define GMOCK_PP_INTENRAL_EMPTY_TUPLE (, , , , , , , , , , , , , , , )
#define GMOCK_PP_INTERNAL_CAT(_1, _2) _1##_2
#define GMOCK_PP_INTERNAL_STRINGIZE(...) #__VA_ARGS__
#define GMOCK_PP_INTERNAL_INTERNAL_16TH(_1, _2, _3, _4, _5, _6, _7, _8, _9, \
_10, _11, _12, _13, _14, _15, _16, \
...) \
_16
#define GMOCK_PP_INTERNAL_CAT_5(_1, _2, _3, _4, _5) _1##_2##_3##_4##_5
#define GMOCK_PP_INTERNAL_IS_EMPTY(_1, _2, _3, _4) \
GMOCK_PP_HAS_COMMA(GMOCK_PP_INTERNAL_CAT_5(GMOCK_PP_INTERNAL_IS_EMPTY_CASE_, \
@@ -158,24 +190,30 @@
#define GMOCK_PP_INTERNAL_IS_EMPTY_CASE_0001 ,
#define GMOCK_PP_INTERNAL_IF_1(_Then, _Else) _Then
#define GMOCK_PP_INTERNAL_IF_0(_Then, _Else) _Else
#define GMOCK_PP_INTERNAL_HEAD(_1, ...) _1
#define GMOCK_PP_INTERNAL_TAIL(_1, ...) __VA_ARGS__
// Because of MSVC treating a token with a comma in it as a single token when
// passed to another macro, we need to force it to evaluate it as multiple
// tokens. We do that by using a "IDENTITY(MACRO PARENTHESIZED_ARGS)" macro. We
// define one per possible macro that relies on this behavior. Note "_Args" must
// be parenthesized.
#define GMOCK_PP_INTERNAL_INTERNAL_16TH(_1, _2, _3, _4, _5, _6, _7, _8, _9, \
_10, _11, _12, _13, _14, _15, _16, \
...) \
_16
#define GMOCK_PP_INTERNAL_16TH(_Args) \
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_16TH _Args)
#define GMOCK_PP_INTERNAL_INTERNAL_HEAD(_1, ...) _1
#define GMOCK_PP_INTERNAL_HEAD(_Args) \
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_HEAD _Args)
#define GMOCK_PP_INTERNAL_INTERNAL_TAIL(_1, ...) __VA_ARGS__
#define GMOCK_PP_INTERNAL_TAIL(_Args) \
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_TAIL _Args)
#if GMOCK_PP_INTERNAL_USE_MSVC
#define GMOCK_PP_INTERNAL_NARG_CAT(_1, _2) GMOCK_PP_INTERNAL_NARG_CAT_I(_1, _2)
#define GMOCK_PP_INTERNAL_HEAD_CAT(_1, _2) GMOCK_PP_INTERNAL_HEAD_CAT_I(_1, _2)
#define GMOCK_PP_INTERNAL_HAS_COMMA_CAT(_1, _2) \
GMOCK_PP_INTERNAL_HAS_COMMA_CAT_I(_1, _2)
#define GMOCK_PP_INTERNAL_TAIL_CAT(_1, _2) GMOCK_PP_INTERNAL_TAIL_CAT_I(_1, _2)
#define GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT(_1, _2) \
GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT_I(_1, _2)
#define GMOCK_PP_INTERNAL_NARG_CAT_I(_1, _2) _1##_2
#define GMOCK_PP_INTERNAL_HEAD_CAT_I(_1, _2) _1##_2
#define GMOCK_PP_INTERNAL_HAS_COMMA_CAT_I(_1, _2) _1##_2
#define GMOCK_PP_INTERNAL_TAIL_CAT_I(_1, _2) _1##_2
#define GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT_I(_1, _2) _1##_2
#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD(...) \
GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT(GMOCK_PP_HEAD(__VA_ARGS__), )
#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT(_1, _2) \
GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT_I(_1, _2)
#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT_I(_1, _2) _1##_2
#else // GMOCK_PP_INTERNAL_USE_MSVC
#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD(...) GMOCK_PP_HEAD(__VA_ARGS__)
#endif // GMOCK_PP_INTERNAL_USE_MSVC
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C(...) 1 _
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_1 1,
@@ -276,4 +314,4 @@
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_
#endif // THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_

View File

@@ -28,8 +28,8 @@
# 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.
"""fuse_gmock_files.py v0.1.0
Fuses Google Mock and Google Test source code into two .h files and a .cc file.
SYNOPSIS
@@ -55,29 +55,27 @@ EXAMPLES
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
https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md for more
information.
"""
from __future__ import print_function
__author__ = 'wan@google.com (Zhanyong Wan)'
import os
import re
import sets
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
import fuse_gtest_files
gtest = fuse_gtest_files
# Regex for matching
# '#include "gmock/..."'.
# Regex for matching '#include "gmock/..."'.
INCLUDE_GMOCK_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(gmock/.+)"')
# Where to find the source seed files.
@@ -100,9 +98,6 @@ 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))
@@ -114,9 +109,6 @@ 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)
@@ -127,8 +119,8 @@ def ValidateOutputDir(output_dir):
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.
output_file = file(os.path.join(output_dir, GMOCK_H_OUTPUT), 'w')
processed_files = sets.Set() # Holds all gmock headers we've processed.
def ProcessFile(gmock_header_path):
"""Processes the given gmock header file."""
@@ -140,28 +132,25 @@ def FuseGMockH(gmock_root, output_dir):
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)
for line in file(os.path.join(gmock_root, gmock_header_path), 'r'):
m = INCLUDE_GMOCK_FILE_REGEX.match(line)
if m:
# It's '#include "gmock/..."' - let's process it recursively.
ProcessFile('include/' + m.group(1))
else:
m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line)
if m:
# '#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.
# It's '#include "gtest/foo.h"'. We translate it to
# "gtest/gtest.h", regardless of what foo is, since all
# gtest headers are fused into gtest/gtest.h.
# There is no need to #include gtest.h twice.
if 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)
# There is no need to #include gtest.h twice.
if not gtest.GTEST_H_SEED in processed_files:
processed_files.add(gtest.GTEST_H_SEED)
output_file.write('#include "%s"\n' % (gtest.GTEST_H_OUTPUT,))
else:
# Otherwise we copy the line unchanged to the output file.
output_file.write(line)
ProcessFile(GMOCK_H_SEED)
output_file.close()
@@ -170,7 +159,7 @@ def FuseGMockH(gmock_root, output_dir):
def FuseGMockAllCcToFile(gmock_root, output_file):
"""Scans folder gmock_root to fuse gmock-all.cc into output_file."""
processed_files = set()
processed_files = sets.Set()
def ProcessFile(gmock_source_file):
"""Processes the given gmock source file."""
@@ -182,37 +171,32 @@ def FuseGMockAllCcToFile(gmock_root, output_file):
processed_files.add(gmock_source_file)
# Reads each line in the given gmock source file.
for line in file(os.path.join(gmock_root, gmock_source_file), 'r'):
m = INCLUDE_GMOCK_FILE_REGEX.match(line)
if m:
# It's '#include "gmock/foo.h"'. We treat it as '#include
# "gmock/gmock.h"', as all other gmock headers are being fused
# into gmock.h and cannot be #included directly.
with open(os.path.join(gmock_root, gmock_source_file), 'r') as fh:
for line in fh:
m = INCLUDE_GMOCK_FILE_REGEX.match(line)
# There is no need to #include "gmock/gmock.h" more than once.
if not GMOCK_H_SEED in processed_files:
processed_files.add(GMOCK_H_SEED)
output_file.write('#include "%s"\n' % (GMOCK_H_OUTPUT,))
else:
m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line)
if m:
# '#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,))
# It's '#include "gtest/..."'.
# There is no need to #include gtest.h as it has been
# #included by gtest-all.cc.
pass
else:
m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line)
m = gtest.INCLUDE_SRC_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
# It's '#include "src/foo"' - let's process it recursively.
ProcessFile(m.group(1))
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)
# Otherwise we copy the line unchanged to the output file.
output_file.write(line)
ProcessFile(GMOCK_ALL_CC_SEED)
@@ -220,12 +204,12 @@ def FuseGMockAllCcToFile(gmock_root, output_file):
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)
output_file = file(os.path.join(output_dir, GMOCK_GTEST_ALL_CC_OUTPUT), 'w')
# First, fuse gtest-all.cc into gmock-gtest-all.cc.
gtest.FuseGTestAllCcToFile(GetGTestRootDir(gmock_root), output_file)
# Next, append fused gmock-all.cc to gmock-gtest-all.cc.
FuseGMockAllCcToFile(gmock_root, output_file)
output_file.close()
def FuseGMock(gmock_root, output_dir):
@@ -248,7 +232,7 @@ def main():
# fuse_gmock_files.py GMOCK_ROOT_DIR OUTPUT_DIR
FuseGMock(sys.argv[1], sys.argv[2])
else:
print(__doc__)
print __doc__
sys.exit(1)

File diff suppressed because it is too large Load Diff

View File

@@ -26,6 +26,9 @@ Usage:
Output is sent to stdout.
"""
__author__ = 'nnorwitz@google.com (Neal Norwitz)'
import os
import re
import sys
@@ -38,7 +41,6 @@ try:
_dummy = set
except NameError:
import sets
set = sets.Set
_VERSION = (1, 0, 1) # The version of this script.
@@ -46,100 +48,79 @@ _VERSION = (1, 0, 1) # The version of this script.
_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)
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
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'
const = ''
if node.modifiers & ast.FUNCTION_CONST:
modifiers = 'const, ' + modifiers
const = 'CONST_'
return_type = 'void'
if node.return_type:
return_type = _EscapeForMacro(_RenderType(node.return_type))
# Add modifiers like 'const'.
modifiers = ''
if node.return_type.modifiers:
modifiers = ' '.join(node.return_type.modifiers) + ' '
return_type = modifiers + node.return_type.name
template_args = [arg.name for arg in node.return_type.templated_types]
if template_args:
return_type += '<' + ', '.join(template_args) + '>'
if len(template_args) > 1:
for line in [
'// The following line won\'t really compile, as the return',
'// type has multiple template arguments. To fix it, use a',
'// typedef for the return type.']:
output_lines.append(indent + line)
if node.return_type.pointer:
return_type += '*'
if node.return_type.reference:
return_type += '&'
num_parameters = len(node.parameters)
if len(node.parameters) == 1:
first_param = node.parameters[0]
if source[first_param.start:first_param.end].strip() == 'void':
# We must treat T(void) as a function with no parameters.
num_parameters = 0
tmpl = ''
if class_node.templated_types:
tmpl = '_T'
mock_method_macro = 'MOCK_%sMETHOD%d%s' % (const, num_parameters, tmpl)
args = []
for p in node.parameters:
arg = _GenerateArg(source[p.start:p.end])
if arg != 'void':
args.append(_EscapeForMacro(arg))
args = ''
if node.parameters:
# Due to the parser limitations, it is impossible to keep comments
# while stripping the default parameters. When defaults are
# present, we choose to strip them and comments (and produce
# compilable code).
# TODO(nnorwitz@google.com): Investigate whether it is possible to
# preserve parameter name when reconstructing parameter text from
# the AST.
if len([param for param in node.parameters if param.default]) > 0:
args = ', '.join(param.type.name for param in node.parameters)
else:
# Get the full text of the parameters from the start
# of the first parameter to the end of the last parameter.
start = node.parameters[0].start
end = node.parameters[-1].end
# Remove // comments.
args_strings = re.sub(r'//.*', '', source[start:end])
# Condense multiple spaces and eliminate newlines putting the
# parameters together on a single line. Ensure there is a
# space in an argument which is split by a newline without
# intervening whitespace, e.g.: int\nBar
args = re.sub(' +', ' ', args_strings.replace('\n', ' '))
# Create the mock method definition.
output_lines.extend([
'%sMOCK_METHOD(%s, %s, (%s), (%s));' %
(indent, return_type, node.name, ', '.join(args), modifiers)
])
output_lines.extend(['%s%s(%s,' % (indent, mock_method_macro, node.name),
'%s%s(%s));' % (indent*3, return_type, args)])
def _GenerateMocks(filename, source, ast_list, desired_class_names):
@@ -160,13 +141,12 @@ def _GenerateMocks(filename, source, ast_list, desired_class_names):
# Add template args for templated classes.
if class_node.templated_types:
# TODO(paulchang): The AST doesn't preserve template argument order,
# so we have to make up names here.
# TODO(paulchang): Handle non-type template arguments (e.g.
# template<typename T, int N>).
# 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_arg_count = len(class_node.templated_types.keys())
template_args = ['T%d' % n for n in range(template_arg_count)]
template_decls = ['typename ' + arg for arg in template_args]
lines.append('template <' + ', '.join(template_decls) + '>')
parent_name += '<' + ', '.join(template_args) + '>'
@@ -191,7 +171,7 @@ def _GenerateMocks(filename, source, ast_list, desired_class_names):
# Close the namespace.
if class_node.namespace:
for i in range(len(class_node.namespace) - 1, -1, -1):
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.

View File

@@ -17,6 +17,9 @@
"""Tests for gmock.scripts.generator.cpp.gmock_class."""
__author__ = 'nnorwitz@google.com (Neal Norwitz)'
import os
import sys
import unittest
@@ -31,8 +34,7 @@ from cpp import gmock_class
class TestCase(unittest.TestCase):
"""Helper class that adds assert methods."""
@staticmethod
def StripLeadingWhitespace(lines):
def StripLeadingWhitespace(self, lines):
"""Strip leading whitespace in each line in 'lines'."""
return '\n'.join([s.lstrip() for s in lines.split('\n')])
@@ -43,8 +45,7 @@ class TestCase(unittest.TestCase):
class GenerateMethodsTest(TestCase):
@staticmethod
def GenerateMethodSource(cpp_source):
def GenerateMethodSource(self, cpp_source):
"""Convert C++ source to Google Mock output source lines."""
method_source_lines = []
# <test> is a pseudo-filename, it is not read or written.
@@ -61,7 +62,7 @@ class Foo {
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(int, Bar, (), (override));',
'MOCK_METHOD0(Bar,\nint());',
self.GenerateMethodSource(source))
def testSimpleConstructorsAndDestructor(self):
@@ -78,7 +79,7 @@ class Foo {
"""
# The constructors and destructor should be ignored.
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(int, Bar, (), (override));',
'MOCK_METHOD0(Bar,\nint());',
self.GenerateMethodSource(source))
def testVirtualDestructor(self):
@@ -91,7 +92,7 @@ class Foo {
"""
# The destructor should be ignored.
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(int, Bar, (), (override));',
'MOCK_METHOD0(Bar,\nint());',
self.GenerateMethodSource(source))
def testExplicitlyDefaultedConstructorsAndDestructor(self):
@@ -107,7 +108,7 @@ class Foo {
"""
# The constructors and destructor should be ignored.
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(int, Bar, (), (override));',
'MOCK_METHOD0(Bar,\nint());',
self.GenerateMethodSource(source))
def testExplicitlyDeletedConstructorsAndDestructor(self):
@@ -123,7 +124,7 @@ class Foo {
"""
# The constructors and destructor should be ignored.
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(int, Bar, (), (override));',
'MOCK_METHOD0(Bar,\nint());',
self.GenerateMethodSource(source))
def testSimpleOverrideMethod(self):
@@ -134,7 +135,7 @@ class Foo {
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(int, Bar, (), (override));',
'MOCK_METHOD0(Bar,\nint());',
self.GenerateMethodSource(source))
def testSimpleConstMethod(self):
@@ -145,7 +146,7 @@ class Foo {
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(void, Bar, (bool flag), (const, override));',
'MOCK_CONST_METHOD1(Bar,\nvoid(bool flag));',
self.GenerateMethodSource(source))
def testExplicitVoid(self):
@@ -156,7 +157,7 @@ class Foo {
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(int, Bar, (), (override));',
'MOCK_METHOD0(Bar,\nint(void));',
self.GenerateMethodSource(source))
def testStrangeNewlineInParameter(self):
@@ -168,7 +169,7 @@ a) = 0;
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(void, Bar, (int a), (override));',
'MOCK_METHOD1(Bar,\nvoid(int a));',
self.GenerateMethodSource(source))
def testDefaultParameters(self):
@@ -179,58 +180,18 @@ class Foo {
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(void, Bar, (int a, char c), (override));',
'MOCK_METHOD2(Bar,\nvoid(int, char));',
self.GenerateMethodSource(source))
def testMultipleDefaultParameters(self):
source = """
class Foo {
public:
virtual void Bar(
int a = 42,
char c = 'x',
const int* const p = nullptr,
const std::string& s = "42",
char tab[] = {'4','2'},
int const *& rp = aDefaultPointer) = 0;
virtual void Bar(int a = 42, char c = 'x') = 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));',
'MOCK_METHOD2(Bar,\nvoid(int, char));',
self.GenerateMethodSource(source))
def testRemovesCommentsWhenDefaultsArePresent(self):
@@ -242,7 +203,7 @@ class Foo {
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(void, Bar, (int a, char c), (override));',
'MOCK_METHOD2(Bar,\nvoid(int, char));',
self.GenerateMethodSource(source))
def testDoubleSlashCommentsInParameterListAreRemoved(self):
@@ -255,7 +216,7 @@ class Foo {
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(void, Bar, (int a, int b), (const, override));',
'MOCK_CONST_METHOD2(Bar,\nvoid(int a, int b));',
self.GenerateMethodSource(source))
def testCStyleCommentsInParameterListAreNotRemoved(self):
@@ -269,7 +230,7 @@ class Foo {
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(const string&, Bar, (int, int b), (override));',
'MOCK_METHOD2(Bar,\nconst string&(int /* keeper */, int b));',
self.GenerateMethodSource(source))
def testArgsOfTemplateTypes(self):
@@ -279,7 +240,8 @@ class Foo {
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));',
'MOCK_METHOD2(Bar,\n'
'int(const vector<int>& v, map<int, string>* output));',
self.GenerateMethodSource(source))
def testReturnTypeWithOneTemplateArg(self):
@@ -289,7 +251,7 @@ class Foo {
virtual vector<int>* Bar(int n);
};"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(vector<int>*, Bar, (int n), (override));',
'MOCK_METHOD1(Bar,\nvector<int>*(int n));',
self.GenerateMethodSource(source))
def testReturnTypeWithManyTemplateArgs(self):
@@ -298,8 +260,13 @@ class Foo {
public:
virtual map<int, string> Bar();
};"""
# Comparing the comment text is brittle - we'll think of something
# better in case this gets annoying, but for now let's keep it simple.
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD((map<int, string>), Bar, (), (override));',
'// The following line won\'t really compile, as the return\n'
'// type has multiple template arguments. To fix it, use a\n'
'// typedef for the return type.\n'
'MOCK_METHOD0(Bar,\nmap<int, string>());',
self.GenerateMethodSource(source))
def testSimpleMethodInTemplatedClass(self):
@@ -311,7 +278,7 @@ class Foo {
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(int, Bar, (), (override));',
'MOCK_METHOD0_T(Bar,\nint());',
self.GenerateMethodSource(source))
def testPointerArgWithoutNames(self):
@@ -321,7 +288,7 @@ class Foo {
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(int, Bar, (C*), (override));',
'MOCK_METHOD1(Bar,\nint(C*));',
self.GenerateMethodSource(source))
def testReferenceArgWithoutNames(self):
@@ -331,7 +298,7 @@ class Foo {
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(int, Bar, (C&), (override));',
'MOCK_METHOD1(Bar,\nint(C&));',
self.GenerateMethodSource(source))
def testArrayArgWithoutNames(self):
@@ -341,14 +308,13 @@ class Foo {
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD(int, Bar, (C[]), (override));',
'MOCK_METHOD1(Bar,\nint(C[]));',
self.GenerateMethodSource(source))
class GenerateMocksTest(TestCase):
@staticmethod
def GenerateMocks(cpp_source):
def GenerateMocks(self, cpp_source):
"""Convert C++ source to complete Google Mock output source."""
# <test> is a pseudo-filename, it is not read or written.
filename = '<test>'
@@ -361,30 +327,31 @@ class GenerateMocksTest(TestCase):
source = """
namespace Foo {
namespace Bar { class Forward; }
namespace Baz::Qux {
namespace Baz {
class Test {
public:
virtual void Foo();
};
} // namespace Baz::Qux
} // namespace Baz
} // namespace Foo
"""
expected = """\
namespace Foo {
namespace Baz::Qux {
namespace Baz {
class MockTest : public Test {
public:
MOCK_METHOD(void, Foo, (), (override));
MOCK_METHOD0(Foo,
void());
};
} // namespace Baz::Qux
} // namespace Baz
} // namespace Foo
"""
self.assertEqualIgnoreLeadingWhitespace(expected,
self.GenerateMocks(source))
self.assertEqualIgnoreLeadingWhitespace(
expected, self.GenerateMocks(source))
def testClassWithStorageSpecifierMacro(self):
source = """
@@ -396,11 +363,12 @@ class STORAGE_SPECIFIER Test {
expected = """\
class MockTest : public Test {
public:
MOCK_METHOD(void, Foo, (), (override));
MOCK_METHOD0(Foo,
void());
};
"""
self.assertEqualIgnoreLeadingWhitespace(expected,
self.GenerateMocks(source))
self.assertEqualIgnoreLeadingWhitespace(
expected, self.GenerateMocks(source))
def testTemplatedForwardDeclaration(self):
source = """
@@ -413,11 +381,12 @@ class Test {
expected = """\
class MockTest : public Test {
public:
MOCK_METHOD(void, Foo, (), (override));
MOCK_METHOD0(Foo,
void());
};
"""
self.assertEqualIgnoreLeadingWhitespace(expected,
self.GenerateMocks(source))
self.assertEqualIgnoreLeadingWhitespace(
expected, self.GenerateMocks(source))
def testTemplatedClass(self):
source = """
@@ -428,14 +397,15 @@ class Test {
};
"""
expected = """\
template <typename S, typename T>
class MockTest : public Test<S, T> {
template <typename T0, typename T1>
class MockTest : public Test<T0, T1> {
public:
MOCK_METHOD(void, Foo, (), (override));
MOCK_METHOD0_T(Foo,
void());
};
"""
self.assertEqualIgnoreLeadingWhitespace(expected,
self.GenerateMocks(source))
self.assertEqualIgnoreLeadingWhitespace(
expected, self.GenerateMocks(source))
def testTemplateInATemplateTypedef(self):
source = """
@@ -448,29 +418,12 @@ class Test {
expected = """\
class MockTest : public Test {
public:
MOCK_METHOD(void, Bar, (const FooType& test_arg), (override));
MOCK_METHOD1(Bar,
void(const FooType& test_arg));
};
"""
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))
self.assertEqualIgnoreLeadingWhitespace(
expected, self.GenerateMocks(source))
def testTemplateInATemplateTypedefWithComma(self):
source = """
@@ -484,87 +437,30 @@ class Test {
expected = """\
class MockTest : public Test {
public:
MOCK_METHOD(void, Bar, (const FooType& test_arg), (override));
MOCK_METHOD1(Bar,
void(const FooType& test_arg));
};
"""
self.assertEqualIgnoreLeadingWhitespace(expected,
self.GenerateMocks(source))
self.assertEqualIgnoreLeadingWhitespace(
expected, self.GenerateMocks(source))
def testParenthesizedCommaInArg(self):
def testEnumClass(self):
source = """
class Test {
public:
virtual void Bar(std::function<void(int, int)> f);
enum class Baz { BAZINGA };
virtual void Bar(const FooType& test_arg);
};
"""
expected = """\
class MockTest : public Test {
public:
MOCK_METHOD(void, Bar, (std::function<void(int, int)> f), (override));
MOCK_METHOD1(Bar,
void(const FooType& test_arg));
};
"""
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))
self.assertEqualIgnoreLeadingWhitespace(
expected, self.GenerateMocks(source))
if __name__ == '__main__':
unittest.main()

View File

@@ -17,6 +17,9 @@
"""C++ keywords and helper utilities for determining keywords."""
__author__ = 'nnorwitz@google.com (Neal Norwitz)'
try:
# Python 3.x
import builtins

View File

@@ -17,6 +17,9 @@
"""Tokenize C++ source code."""
__author__ = 'nnorwitz@google.com (Neal Norwitz)'
try:
# Python 3.x
import builtins

View File

@@ -17,8 +17,12 @@
"""Generic utilities for C++ parsing."""
__author__ = 'nnorwitz@google.com (Neal Norwitz)'
import sys
# Set to True to see the start/end token indices.
DEBUG = True

View File

@@ -16,6 +16,7 @@
"""Driver for starting up Google Mock class generator."""
__author__ = 'nnorwitz@google.com (Neal Norwitz)'
import os
import sys

View File

@@ -0,0 +1,303 @@
#!/bin/sh
# These variables are automatically filled in by the configure script.
name="@PACKAGE_TARNAME@"
version="@PACKAGE_VERSION@"
show_usage()
{
echo "Usage: gmock-config [OPTIONS...]"
}
show_help()
{
show_usage
cat <<\EOF
The `gmock-config' script provides access to the necessary compile and linking
flags to connect with Google C++ Mocking Framework, both in a build prior to
installation, and on the system proper after installation. The installation
overrides may be issued in combination with any other queries, but will only
affect installation queries if called on a built but not installed gmock. The
installation queries may not be issued with any other types of queries, and
only one installation query may be made at a time. The version queries and
compiler flag queries may be combined as desired but not mixed. Different
version queries are always combined with logical "and" semantics, and only the
last of any particular query is used while all previous ones ignored. All
versions must be specified as a sequence of numbers separated by periods.
Compiler flag queries output the union of the sets of flags when combined.
Examples:
gmock-config --min-version=1.0 || echo "Insufficient Google Mock version."
g++ $(gmock-config --cppflags --cxxflags) -o foo.o -c foo.cpp
g++ $(gmock-config --ldflags --libs) -o foo foo.o
# When using a built but not installed Google Mock:
g++ $(../../my_gmock_build/scripts/gmock-config ...) ...
# When using an installed Google Mock, but with installation overrides:
export GMOCK_PREFIX="/opt"
g++ $(gmock-config --libdir="/opt/lib64" ...) ...
Help:
--usage brief usage information
--help display this help message
Installation Overrides:
--prefix=<dir> overrides the installation prefix
--exec-prefix=<dir> overrides the executable installation prefix
--libdir=<dir> overrides the library installation prefix
--includedir=<dir> overrides the header file installation prefix
Installation Queries:
--prefix installation prefix
--exec-prefix executable installation prefix
--libdir library installation directory
--includedir header file installation directory
--version the version of the Google Mock installation
Version Queries:
--min-version=VERSION return 0 if the version is at least VERSION
--exact-version=VERSION return 0 if the version is exactly VERSION
--max-version=VERSION return 0 if the version is at most VERSION
Compilation Flag Queries:
--cppflags compile flags specific to the C-like preprocessors
--cxxflags compile flags appropriate for C++ programs
--ldflags linker flags
--libs libraries for linking
EOF
}
# This function bounds our version with a min and a max. It uses some clever
# POSIX-compliant variable expansion to portably do all the work in the shell
# and avoid any dependency on a particular "sed" or "awk" implementation.
# Notable is that it will only ever compare the first 3 components of versions.
# Further components will be cleanly stripped off. All versions must be
# unadorned, so "v1.0" will *not* work. The minimum version must be in $1, and
# the max in $2. TODO(chandlerc@google.com): If this ever breaks, we should
# investigate expanding this via autom4te from AS_VERSION_COMPARE rather than
# continuing to maintain our own shell version.
check_versions()
{
major_version=${version%%.*}
minor_version="0"
point_version="0"
if test "${version#*.}" != "${version}"; then
minor_version=${version#*.}
minor_version=${minor_version%%.*}
fi
if test "${version#*.*.}" != "${version}"; then
point_version=${version#*.*.}
point_version=${point_version%%.*}
fi
min_version="$1"
min_major_version=${min_version%%.*}
min_minor_version="0"
min_point_version="0"
if test "${min_version#*.}" != "${min_version}"; then
min_minor_version=${min_version#*.}
min_minor_version=${min_minor_version%%.*}
fi
if test "${min_version#*.*.}" != "${min_version}"; then
min_point_version=${min_version#*.*.}
min_point_version=${min_point_version%%.*}
fi
max_version="$2"
max_major_version=${max_version%%.*}
max_minor_version="0"
max_point_version="0"
if test "${max_version#*.}" != "${max_version}"; then
max_minor_version=${max_version#*.}
max_minor_version=${max_minor_version%%.*}
fi
if test "${max_version#*.*.}" != "${max_version}"; then
max_point_version=${max_version#*.*.}
max_point_version=${max_point_version%%.*}
fi
test $(($major_version)) -lt $(($min_major_version)) && exit 1
if test $(($major_version)) -eq $(($min_major_version)); then
test $(($minor_version)) -lt $(($min_minor_version)) && exit 1
if test $(($minor_version)) -eq $(($min_minor_version)); then
test $(($point_version)) -lt $(($min_point_version)) && exit 1
fi
fi
test $(($major_version)) -gt $(($max_major_version)) && exit 1
if test $(($major_version)) -eq $(($max_major_version)); then
test $(($minor_version)) -gt $(($max_minor_version)) && exit 1
if test $(($minor_version)) -eq $(($max_minor_version)); then
test $(($point_version)) -gt $(($max_point_version)) && exit 1
fi
fi
exit 0
}
# Show the usage line when no arguments are specified.
if test $# -eq 0; then
show_usage
exit 1
fi
while test $# -gt 0; do
case $1 in
--usage) show_usage; exit 0;;
--help) show_help; exit 0;;
# Installation overrides
--prefix=*) GMOCK_PREFIX=${1#--prefix=};;
--exec-prefix=*) GMOCK_EXEC_PREFIX=${1#--exec-prefix=};;
--libdir=*) GMOCK_LIBDIR=${1#--libdir=};;
--includedir=*) GMOCK_INCLUDEDIR=${1#--includedir=};;
# Installation queries
--prefix|--exec-prefix|--libdir|--includedir|--version)
if test -n "${do_query}"; then
show_usage
exit 1
fi
do_query=${1#--}
;;
# Version checking
--min-version=*)
do_check_versions=yes
min_version=${1#--min-version=}
;;
--max-version=*)
do_check_versions=yes
max_version=${1#--max-version=}
;;
--exact-version=*)
do_check_versions=yes
exact_version=${1#--exact-version=}
;;
# Compiler flag output
--cppflags) echo_cppflags=yes;;
--cxxflags) echo_cxxflags=yes;;
--ldflags) echo_ldflags=yes;;
--libs) echo_libs=yes;;
# Everything else is an error
*) show_usage; exit 1;;
esac
shift
done
# These have defaults filled in by the configure script but can also be
# overridden by environment variables or command line parameters.
prefix="${GMOCK_PREFIX:-@prefix@}"
exec_prefix="${GMOCK_EXEC_PREFIX:-@exec_prefix@}"
libdir="${GMOCK_LIBDIR:-@libdir@}"
includedir="${GMOCK_INCLUDEDIR:-@includedir@}"
# We try and detect if our binary is not located at its installed location. If
# it's not, we provide variables pointing to the source and build tree rather
# than to the install tree. We also locate Google Test using the configured
# gtest-config script rather than searching the PATH and our bindir for one.
# This allows building against a just-built gmock rather than an installed
# gmock.
bindir="@bindir@"
this_relative_bindir=`dirname $0`
this_bindir=`cd ${this_relative_bindir}; pwd -P`
if test "${this_bindir}" = "${this_bindir%${bindir}}"; then
# The path to the script doesn't end in the bindir sequence from Autoconf,
# assume that we are in a build tree.
build_dir=`dirname ${this_bindir}`
src_dir=`cd ${this_bindir}/@top_srcdir@; pwd -P`
# TODO(chandlerc@google.com): This is a dangerous dependency on libtool, we
# should work to remove it, and/or remove libtool altogether, replacing it
# with direct references to the library and a link path.
gmock_libs="${build_dir}/lib/libgmock.la"
gmock_ldflags=""
# We provide hooks to include from either the source or build dir, where the
# build dir is always preferred. This will potentially allow us to write
# build rules for generated headers and have them automatically be preferred
# over provided versions.
gmock_cppflags="-I${build_dir}/include -I${src_dir}/include"
gmock_cxxflags=""
# Directly invoke the gtest-config script used during the build process.
gtest_config="@GTEST_CONFIG@"
else
# We're using an installed gmock, although it may be staged under some
# prefix. Assume (as our own libraries do) that we can resolve the prefix,
# and are present in the dynamic link paths.
gmock_ldflags="-L${libdir}"
gmock_libs="-l${name}"
gmock_cppflags="-I${includedir}"
gmock_cxxflags=""
# We also prefer any gtest-config script installed in our prefix. Lacking
# one, we look in the PATH for one.
gtest_config="${bindir}/gtest-config"
if test ! -x "${gtest_config}"; then
gtest_config=`which gtest-config`
fi
fi
# Ensure that we have located a Google Test to link against.
if ! test -x "${gtest_config}"; then
echo "Unable to locate Google Test, check your Google Mock configuration" \
"and installation" >&2
exit 1
elif ! "${gtest_config}" "--exact-version=@GTEST_VERSION@"; then
echo "The Google Test found is not the same version as Google Mock was " \
"built against" >&2
exit 1
fi
# Add the necessary Google Test bits into the various flag variables
gmock_cppflags="${gmock_cppflags} `${gtest_config} --cppflags`"
gmock_cxxflags="${gmock_cxxflags} `${gtest_config} --cxxflags`"
gmock_ldflags="${gmock_ldflags} `${gtest_config} --ldflags`"
gmock_libs="${gmock_libs} `${gtest_config} --libs`"
# Do an installation query if requested.
if test -n "$do_query"; then
case $do_query in
prefix) echo $prefix; exit 0;;
exec-prefix) echo $exec_prefix; exit 0;;
libdir) echo $libdir; exit 0;;
includedir) echo $includedir; exit 0;;
version) echo $version; exit 0;;
*) show_usage; exit 1;;
esac
fi
# Do a version check if requested.
if test "$do_check_versions" = "yes"; then
# Make sure we didn't receive a bad combination of parameters.
test "$echo_cppflags" = "yes" && show_usage && exit 1
test "$echo_cxxflags" = "yes" && show_usage && exit 1
test "$echo_ldflags" = "yes" && show_usage && exit 1
test "$echo_libs" = "yes" && show_usage && exit 1
if test "$exact_version" != ""; then
check_versions $exact_version $exact_version
# unreachable
else
check_versions ${min_version:-0.0.0} ${max_version:-9999.9999.9999}
# unreachable
fi
fi
# Do the output in the correct order so that these can be used in-line of
# a compiler invocation.
output=""
test "$echo_cppflags" = "yes" && output="$output $gmock_cppflags"
test "$echo_cxxflags" = "yes" && output="$output $gmock_cxxflags"
test "$echo_ldflags" = "yes" && output="$output $gmock_ldflags"
test "$echo_libs" = "yes" && output="$output $gmock_libs"
echo $output
exit 0

View File

@@ -0,0 +1,640 @@
#!/usr/bin/env python
#
# Copyright 2008, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Converts compiler's errors in code using Google Mock to plain English."""
__author__ = 'wan@google.com (Zhanyong Wan)'
import re
import sys
_VERSION = '1.0.3'
_EMAIL = 'googlemock@googlegroups.com'
_COMMON_GMOCK_SYMBOLS = [
# Matchers
'_',
'A',
'AddressSatisfies',
'AllOf',
'An',
'AnyOf',
'ContainerEq',
'Contains',
'ContainsRegex',
'DoubleEq',
'ElementsAre',
'ElementsAreArray',
'EndsWith',
'Eq',
'Field',
'FloatEq',
'Ge',
'Gt',
'HasSubstr',
'IsInitializedProto',
'Le',
'Lt',
'MatcherCast',
'Matches',
'MatchesRegex',
'NanSensitiveDoubleEq',
'NanSensitiveFloatEq',
'Ne',
'Not',
'NotNull',
'Pointee',
'Property',
'Ref',
'ResultOf',
'SafeMatcherCast',
'StartsWith',
'StrCaseEq',
'StrCaseNe',
'StrEq',
'StrNe',
'Truly',
'TypedEq',
'Value',
# Actions
'Assign',
'ByRef',
'DeleteArg',
'DoAll',
'DoDefault',
'IgnoreResult',
'Invoke',
'InvokeArgument',
'InvokeWithoutArgs',
'Return',
'ReturnNew',
'ReturnNull',
'ReturnRef',
'SaveArg',
'SetArgReferee',
'SetArgPointee',
'SetArgumentPointee',
'SetArrayArgument',
'SetErrnoAndReturn',
'Throw',
'WithArg',
'WithArgs',
'WithoutArgs',
# Cardinalities
'AnyNumber',
'AtLeast',
'AtMost',
'Between',
'Exactly',
# Sequences
'InSequence',
'Sequence',
# Misc
'DefaultValue',
'Mock',
]
# Regex for matching source file path and line number in the compiler's errors.
_GCC_FILE_LINE_RE = r'(?P<file>.*):(?P<line>\d+):(\d+:)?\s+'
_CLANG_FILE_LINE_RE = r'(?P<file>.*):(?P<line>\d+):(?P<column>\d+):\s+'
_CLANG_NON_GMOCK_FILE_LINE_RE = (
r'(?P<file>.*[/\\^](?!gmock-)[^/\\]+):(?P<line>\d+):(?P<column>\d+):\s+')
def _FindAllMatches(regex, s):
"""Generates all matches of regex in string s."""
r = re.compile(regex)
return r.finditer(s)
def _GenericDiagnoser(short_name, long_name, diagnoses, msg):
"""Diagnoses the given disease by pattern matching.
Can provide different diagnoses for different patterns.
Args:
short_name: Short name of the disease.
long_name: Long name of the disease.
diagnoses: A list of pairs (regex, pattern for formatting the diagnosis
for matching regex).
msg: Compiler's error messages.
Yields:
Tuples of the form
(short name of disease, long name of disease, diagnosis).
"""
for regex, diagnosis in diagnoses:
if re.search(regex, msg):
diagnosis = '%(file)s:%(line)s:' + diagnosis
for m in _FindAllMatches(regex, msg):
yield (short_name, long_name, diagnosis % m.groupdict())
def _NeedToReturnReferenceDiagnoser(msg):
"""Diagnoses the NRR disease, given the error messages by the compiler."""
gcc_regex = (r'In member function \'testing::internal::ReturnAction<R>.*\n'
+ _GCC_FILE_LINE_RE + r'instantiated from here\n'
r'.*gmock-actions\.h.*error: creating array with negative size')
clang_regex = (r'error:.*array.*negative.*\r?\n'
r'(.*\n)*?' +
_CLANG_NON_GMOCK_FILE_LINE_RE +
r'note: in instantiation of function template specialization '
r'\'testing::internal::ReturnAction<(?P<type>.*)>'
r'::operator Action<.*>\' requested here')
clang11_re = (r'use_ReturnRef_instead_of_Return_to_return_a_reference.*'
r'(.*\n)*?' + _CLANG_NON_GMOCK_FILE_LINE_RE)
diagnosis = """
You are using a Return() action in a function that returns a reference to
%(type)s. Please use ReturnRef() instead."""
return _GenericDiagnoser('NRR', 'Need to Return Reference',
[(clang_regex, diagnosis),
(clang11_re, diagnosis % {'type': 'a type'}),
(gcc_regex, diagnosis % {'type': 'a type'})],
msg)
def _NeedToReturnSomethingDiagnoser(msg):
"""Diagnoses the NRS disease, given the error messages by the compiler."""
gcc_regex = (_GCC_FILE_LINE_RE + r'(instantiated from here\n.'
r'*gmock.*actions\.h.*error: void value not ignored)'
r'|(error: control reaches end of non-void function)')
clang_regex1 = (_CLANG_FILE_LINE_RE +
r'error: cannot initialize return object '
r'of type \'Result\' \(aka \'(?P<return_type>.*)\'\) '
r'with an rvalue of type \'void\'')
clang_regex2 = (_CLANG_FILE_LINE_RE +
r'error: cannot initialize return object '
r'of type \'(?P<return_type>.*)\' '
r'with an rvalue of type \'void\'')
diagnosis = """
You are using an action that returns void, but it needs to return
%(return_type)s. Please tell it *what* to return. Perhaps you can use
the pattern DoAll(some_action, Return(some_value))?"""
return _GenericDiagnoser(
'NRS',
'Need to Return Something',
[(gcc_regex, diagnosis % {'return_type': '*something*'}),
(clang_regex1, diagnosis),
(clang_regex2, diagnosis)],
msg)
def _NeedToReturnNothingDiagnoser(msg):
"""Diagnoses the NRN disease, given the error messages by the compiler."""
gcc_regex = (_GCC_FILE_LINE_RE + r'instantiated from here\n'
r'.*gmock-actions\.h.*error: instantiation of '
r'\'testing::internal::ReturnAction<R>::Impl<F>::value_\' '
r'as type \'void\'')
clang_regex1 = (r'error: field has incomplete type '
r'\'Result\' \(aka \'void\'\)(\r)?\n'
r'(.*\n)*?' +
_CLANG_NON_GMOCK_FILE_LINE_RE + r'note: in instantiation '
r'of function template specialization '
r'\'testing::internal::ReturnAction<(?P<return_type>.*)>'
r'::operator Action<void \(.*\)>\' requested here')
clang_regex2 = (r'error: field has incomplete type '
r'\'Result\' \(aka \'void\'\)(\r)?\n'
r'(.*\n)*?' +
_CLANG_NON_GMOCK_FILE_LINE_RE + r'note: in instantiation '
r'of function template specialization '
r'\'testing::internal::DoBothAction<.*>'
r'::operator Action<(?P<return_type>.*) \(.*\)>\' '
r'requested here')
diagnosis = """
You are using an action that returns %(return_type)s, but it needs to return
void. Please use a void-returning action instead.
All actions but the last in DoAll(...) must return void. Perhaps you need
to re-arrange the order of actions in a DoAll(), if you are using one?"""
return _GenericDiagnoser(
'NRN',
'Need to Return Nothing',
[(gcc_regex, diagnosis % {'return_type': '*something*'}),
(clang_regex1, diagnosis),
(clang_regex2, diagnosis)],
msg)
def _IncompleteByReferenceArgumentDiagnoser(msg):
"""Diagnoses the IBRA disease, given the error messages by the compiler."""
gcc_regex = (_GCC_FILE_LINE_RE + r'instantiated from here\n'
r'.*gtest-printers\.h.*error: invalid application of '
r'\'sizeof\' to incomplete type \'(?P<type>.*)\'')
clang_regex = (r'.*gtest-printers\.h.*error: invalid application of '
r'\'sizeof\' to an incomplete type '
r'\'(?P<type>.*)( const)?\'\r?\n'
r'(.*\n)*?' +
_CLANG_NON_GMOCK_FILE_LINE_RE +
r'note: in instantiation of member function '
r'\'testing::internal2::TypeWithoutFormatter<.*>::'
r'PrintValue\' requested here')
diagnosis = """
In order to mock this function, Google Mock needs to see the definition
of type "%(type)s" - declaration alone is not enough. Either #include
the header that defines it, or change the argument to be passed
by pointer."""
return _GenericDiagnoser('IBRA', 'Incomplete By-Reference Argument Type',
[(gcc_regex, diagnosis),
(clang_regex, diagnosis)],
msg)
def _OverloadedFunctionMatcherDiagnoser(msg):
"""Diagnoses the OFM disease, given the error messages by the compiler."""
gcc_regex = (_GCC_FILE_LINE_RE + r'error: no matching function for '
r'call to \'Truly\(<unresolved overloaded function type>\)')
clang_regex = (_CLANG_FILE_LINE_RE + r'error: no matching function for '
r'call to \'Truly')
diagnosis = """
The argument you gave to Truly() is an overloaded function. Please tell
your compiler which overloaded version you want to use.
For example, if you want to use the version whose signature is
bool Foo(int n);
you should write
Truly(static_cast<bool (*)(int n)>(Foo))"""
return _GenericDiagnoser('OFM', 'Overloaded Function Matcher',
[(gcc_regex, diagnosis),
(clang_regex, diagnosis)],
msg)
def _OverloadedFunctionActionDiagnoser(msg):
"""Diagnoses the OFA disease, given the error messages by the compiler."""
gcc_regex = (_GCC_FILE_LINE_RE + r'error: no matching function for call to '
r'\'Invoke\(<unresolved overloaded function type>')
clang_regex = (_CLANG_FILE_LINE_RE + r'error: no matching '
r'function for call to \'Invoke\'\r?\n'
r'(.*\n)*?'
r'.*\bgmock-generated-actions\.h:\d+:\d+:\s+'
r'note: candidate template ignored:\s+'
r'couldn\'t infer template argument \'FunctionImpl\'')
diagnosis = """
Function you are passing to Invoke is overloaded. Please tell your compiler
which overloaded version you want to use.
For example, if you want to use the version whose signature is
bool MyFunction(int n, double x);
you should write something like
Invoke(static_cast<bool (*)(int n, double x)>(MyFunction))"""
return _GenericDiagnoser('OFA', 'Overloaded Function Action',
[(gcc_regex, diagnosis),
(clang_regex, diagnosis)],
msg)
def _OverloadedMethodActionDiagnoser(msg):
"""Diagnoses the OMA disease, given the error messages by the compiler."""
gcc_regex = (_GCC_FILE_LINE_RE + r'error: no matching function for '
r'call to \'Invoke\(.+, <unresolved overloaded function '
r'type>\)')
clang_regex = (_CLANG_FILE_LINE_RE + r'error: no matching function '
r'for call to \'Invoke\'\r?\n'
r'(.*\n)*?'
r'.*\bgmock-generated-actions\.h:\d+:\d+: '
r'note: candidate function template not viable: '
r'requires .*, but 2 (arguments )?were provided')
diagnosis = """
The second argument you gave to Invoke() is an overloaded method. Please
tell your compiler which overloaded version you want to use.
For example, if you want to use the version whose signature is
class Foo {
...
bool Bar(int n, double x);
};
you should write something like
Invoke(foo, static_cast<bool (Foo::*)(int n, double x)>(&Foo::Bar))"""
return _GenericDiagnoser('OMA', 'Overloaded Method Action',
[(gcc_regex, diagnosis),
(clang_regex, diagnosis)],
msg)
def _MockObjectPointerDiagnoser(msg):
"""Diagnoses the MOP disease, given the error messages by the compiler."""
gcc_regex = (_GCC_FILE_LINE_RE + r'error: request for member '
r'\'gmock_(?P<method>.+)\' in \'(?P<mock_object>.+)\', '
r'which is of non-class type \'(.*::)*(?P<class_name>.+)\*\'')
clang_regex = (_CLANG_FILE_LINE_RE + r'error: member reference type '
r'\'(?P<class_name>.*?) *\' is a pointer; '
r'(did you mean|maybe you meant) to use \'->\'\?')
diagnosis = """
The first argument to ON_CALL() and EXPECT_CALL() must be a mock *object*,
not a *pointer* to it. Please write '*(%(mock_object)s)' instead of
'%(mock_object)s' as your first argument.
For example, given the mock class:
class %(class_name)s : public ... {
...
MOCK_METHOD0(%(method)s, ...);
};
and the following mock instance:
%(class_name)s* mock_ptr = ...
you should use the EXPECT_CALL like this:
EXPECT_CALL(*mock_ptr, %(method)s(...));"""
return _GenericDiagnoser(
'MOP',
'Mock Object Pointer',
[(gcc_regex, diagnosis),
(clang_regex, diagnosis % {'mock_object': 'mock_object',
'method': 'method',
'class_name': '%(class_name)s'})],
msg)
def _NeedToUseSymbolDiagnoser(msg):
"""Diagnoses the NUS disease, given the error messages by the compiler."""
gcc_regex = (_GCC_FILE_LINE_RE + r'error: \'(?P<symbol>.+)\' '
r'(was not declared in this scope|has not been declared)')
clang_regex = (_CLANG_FILE_LINE_RE +
r'error: (use of undeclared identifier|unknown type name|'
r'no template named) \'(?P<symbol>[^\']+)\'')
diagnosis = """
'%(symbol)s' is defined by Google Mock in the testing namespace.
Did you forget to write
using testing::%(symbol)s;
?"""
for m in (list(_FindAllMatches(gcc_regex, msg)) +
list(_FindAllMatches(clang_regex, msg))):
symbol = m.groupdict()['symbol']
if symbol in _COMMON_GMOCK_SYMBOLS:
yield ('NUS', 'Need to Use Symbol', diagnosis % m.groupdict())
def _NeedToUseReturnNullDiagnoser(msg):
"""Diagnoses the NRNULL disease, given the error messages by the compiler."""
gcc_regex = ('instantiated from \'testing::internal::ReturnAction<R>'
'::operator testing::Action<Func>\(\) const.*\n' +
_GCC_FILE_LINE_RE + r'instantiated from here\n'
r'.*error: no matching function for call to \'ImplicitCast_\('
r'(:?long )?int&\)')
clang_regex = (r'\bgmock-actions.h:.* error: no matching function for '
r'call to \'ImplicitCast_\'\r?\n'
r'(.*\n)*?' +
_CLANG_NON_GMOCK_FILE_LINE_RE + r'note: in instantiation '
r'of function template specialization '
r'\'testing::internal::ReturnAction<(int|long)>::operator '
r'Action<(?P<type>.*)\(\)>\' requested here')
diagnosis = """
You are probably calling Return(NULL) and the compiler isn't sure how to turn
NULL into %(type)s. Use ReturnNull() instead.
Note: the line number may be off; please fix all instances of Return(NULL)."""
return _GenericDiagnoser(
'NRNULL', 'Need to use ReturnNull',
[(clang_regex, diagnosis),
(gcc_regex, diagnosis % {'type': 'the right type'})],
msg)
def _TypeInTemplatedBaseDiagnoser(msg):
"""Diagnoses the TTB disease, given the error messages by the compiler."""
# This version works when the type is used as the mock function's return
# type.
gcc_4_3_1_regex_type_in_retval = (
r'In member function \'int .*\n' + _GCC_FILE_LINE_RE +
r'error: a function call cannot appear in a constant-expression')
gcc_4_4_0_regex_type_in_retval = (
r'error: a function call cannot appear in a constant-expression'
+ _GCC_FILE_LINE_RE + r'error: template argument 1 is invalid\n')
# This version works when the type is used as the mock function's sole
# parameter type.
gcc_regex_type_of_sole_param = (
_GCC_FILE_LINE_RE +
r'error: \'(?P<type>.+)\' was not declared in this scope\n'
r'.*error: template argument 1 is invalid\n')
# This version works when the type is used as a parameter of a mock
# function that has multiple parameters.
gcc_regex_type_of_a_param = (
r'error: expected `;\' before \'::\' token\n'
+ _GCC_FILE_LINE_RE +
r'error: \'(?P<type>.+)\' was not declared in this scope\n'
r'.*error: template argument 1 is invalid\n'
r'.*error: \'.+\' was not declared in this scope')
clang_regex_type_of_retval_or_sole_param = (
_CLANG_FILE_LINE_RE +
r'error: use of undeclared identifier \'(?P<type>.*)\'\n'
r'(.*\n)*?'
r'(?P=file):(?P=line):\d+: error: '
r'non-friend class member \'Result\' cannot have a qualified name'
)
clang_regex_type_of_a_param = (
_CLANG_FILE_LINE_RE +
r'error: C\+\+ requires a type specifier for all declarations\n'
r'(.*\n)*?'
r'(?P=file):(?P=line):(?P=column): error: '
r'C\+\+ requires a type specifier for all declarations'
)
clang_regex_unknown_type = (
_CLANG_FILE_LINE_RE +
r'error: unknown type name \'(?P<type>[^\']+)\''
)
diagnosis = """
In a mock class template, types or typedefs defined in the base class
template are *not* automatically visible. This is how C++ works. Before
you can use a type or typedef named %(type)s defined in base class Base<T>, you
need to make it visible. One way to do it is:
typedef typename Base<T>::%(type)s %(type)s;"""
for diag in _GenericDiagnoser(
'TTB', 'Type in Template Base',
[(gcc_4_3_1_regex_type_in_retval, diagnosis % {'type': 'Foo'}),
(gcc_4_4_0_regex_type_in_retval, diagnosis % {'type': 'Foo'}),
(gcc_regex_type_of_sole_param, diagnosis),
(gcc_regex_type_of_a_param, diagnosis),
(clang_regex_type_of_retval_or_sole_param, diagnosis),
(clang_regex_type_of_a_param, diagnosis % {'type': 'Foo'})],
msg):
yield diag
# Avoid overlap with the NUS pattern.
for m in _FindAllMatches(clang_regex_unknown_type, msg):
type_ = m.groupdict()['type']
if type_ not in _COMMON_GMOCK_SYMBOLS:
yield ('TTB', 'Type in Template Base', diagnosis % m.groupdict())
def _WrongMockMethodMacroDiagnoser(msg):
"""Diagnoses the WMM disease, given the error messages by the compiler."""
gcc_regex = (_GCC_FILE_LINE_RE +
r'.*this_method_does_not_take_(?P<wrong_args>\d+)_argument.*\n'
r'.*\n'
r'.*candidates are.*FunctionMocker<[^>]+A(?P<args>\d+)\)>')
clang_regex = (_CLANG_NON_GMOCK_FILE_LINE_RE +
r'error:.*array.*negative.*r?\n'
r'(.*\n)*?'
r'(?P=file):(?P=line):(?P=column): error: too few arguments '
r'to function call, expected (?P<args>\d+), '
r'have (?P<wrong_args>\d+)')
clang11_re = (_CLANG_NON_GMOCK_FILE_LINE_RE +
r'.*this_method_does_not_take_'
r'(?P<wrong_args>\d+)_argument.*')
diagnosis = """
You are using MOCK_METHOD%(wrong_args)s to define a mock method that has
%(args)s arguments. Use MOCK_METHOD%(args)s (or MOCK_CONST_METHOD%(args)s,
MOCK_METHOD%(args)s_T, MOCK_CONST_METHOD%(args)s_T as appropriate) instead."""
return _GenericDiagnoser('WMM', 'Wrong MOCK_METHODn Macro',
[(gcc_regex, diagnosis),
(clang11_re, diagnosis % {'wrong_args': 'm',
'args': 'n'}),
(clang_regex, diagnosis)],
msg)
def _WrongParenPositionDiagnoser(msg):
"""Diagnoses the WPP disease, given the error messages by the compiler."""
gcc_regex = (_GCC_FILE_LINE_RE +
r'error:.*testing::internal::MockSpec<.* has no member named \''
r'(?P<method>\w+)\'')
clang_regex = (_CLANG_NON_GMOCK_FILE_LINE_RE +
r'error: no member named \'(?P<method>\w+)\' in '
r'\'testing::internal::MockSpec<.*>\'')
diagnosis = """
The closing parenthesis of ON_CALL or EXPECT_CALL should be *before*
".%(method)s". For example, you should write:
EXPECT_CALL(my_mock, Foo(_)).%(method)s(...);
instead of:
EXPECT_CALL(my_mock, Foo(_).%(method)s(...));"""
return _GenericDiagnoser('WPP', 'Wrong Parenthesis Position',
[(gcc_regex, diagnosis),
(clang_regex, diagnosis)],
msg)
_DIAGNOSERS = [
_IncompleteByReferenceArgumentDiagnoser,
_MockObjectPointerDiagnoser,
_NeedToReturnNothingDiagnoser,
_NeedToReturnReferenceDiagnoser,
_NeedToReturnSomethingDiagnoser,
_NeedToUseReturnNullDiagnoser,
_NeedToUseSymbolDiagnoser,
_OverloadedFunctionActionDiagnoser,
_OverloadedFunctionMatcherDiagnoser,
_OverloadedMethodActionDiagnoser,
_TypeInTemplatedBaseDiagnoser,
_WrongMockMethodMacroDiagnoser,
_WrongParenPositionDiagnoser,
]
def Diagnose(msg):
"""Generates all possible diagnoses given the compiler error message."""
msg = re.sub(r'\x1b\[[^m]*m', '', msg) # Strips all color formatting.
# Assuming the string is using the UTF-8 encoding, replaces the left and
# the right single quote characters with apostrophes.
msg = re.sub(r'(\xe2\x80\x98|\xe2\x80\x99)', "'", msg)
diagnoses = []
for diagnoser in _DIAGNOSERS:
for diag in diagnoser(msg):
diagnosis = '[%s - %s]\n%s' % diag
if not diagnosis in diagnoses:
diagnoses.append(diagnosis)
return diagnoses
def main():
print ('Google Mock Doctor v%s - '
'diagnoses problems in code using Google Mock.' % _VERSION)
if sys.stdin.isatty():
print ('Please copy and paste the compiler errors here. Press c-D when '
'you are done:')
else:
print ('Waiting for compiler errors on stdin . . .')
msg = sys.stdin.read().strip()
diagnoses = Diagnose(msg)
count = len(diagnoses)
if not count:
print ("""
Your compiler complained:
8<------------------------------------------------------------
%s
------------------------------------------------------------>8
Uh-oh, I'm not smart enough to figure out what the problem is. :-(
However...
If you send your source code and the compiler's error messages to
%s, you can be helped and I can get smarter --
win-win for us!""" % (msg, _EMAIL))
else:
print ('------------------------------------------------------------')
print ('Your code appears to have the following',)
if count > 1:
print ('%s diseases:' % (count,))
else:
print ('disease:')
i = 0
for d in diagnoses:
i += 1
if count > 1:
print ('\n#%s:' % (i,))
print (d)
print ("""
How did I do? If you think I'm wrong or unhelpful, please send your
source code and the compiler's error messages to %s.
Then you can be helped and I can get smarter -- I promise I won't be upset!""" %
_EMAIL)
if __name__ == '__main__':
main()

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,7 @@
# Copyright 2021 Google Inc. All Rights Reserved.
#!/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
@@ -25,48 +28,51 @@
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Unit test for Google Test's global test environment behavior.
A user can specify a global test environment via
testing::AddGlobalTestEnvironment. Failures in the global environment should
result in all unit tests being skipped.
"""upload_gmock.py v0.1.0 -- uploads a Google Mock patch for review.
This script tests such functionality by invoking
googletest-global-environment-unittest_ (a program written with Google Test).
This simple wrapper passes all command line flags and
--cc=googlemock@googlegroups.com to upload.py.
USAGE: upload_gmock.py [options for upload.py]
"""
import gtest_test_utils
__author__ = 'wan@google.com (Zhanyong Wan)'
import os
import sys
CC_FLAG = '--cc='
GMOCK_GROUP = 'googlemock@googlegroups.com'
def RunAndReturnOutput():
"""Runs the test program and returns its output."""
def main():
# Finds the path to upload.py, assuming it is in the same directory
# as this file.
my_dir = os.path.dirname(os.path.abspath(__file__))
upload_py_path = os.path.join(my_dir, 'upload.py')
return gtest_test_utils.Subprocess([
gtest_test_utils.GetTestExecutablePath(
'googletest-global-environment-unittest_')
]).output
# Adds Google Mock discussion group to the cc line if it's not there
# already.
upload_py_argv = [upload_py_path]
found_cc_flag = False
for arg in sys.argv[1:]:
if arg.startswith(CC_FLAG):
found_cc_flag = True
cc_line = arg[len(CC_FLAG):]
cc_list = [addr for addr in cc_line.split(',') if addr]
if GMOCK_GROUP not in cc_list:
cc_list.append(GMOCK_GROUP)
upload_py_argv.append(CC_FLAG + ','.join(cc_list))
else:
upload_py_argv.append(arg)
if not found_cc_flag:
upload_py_argv.append(CC_FLAG + GMOCK_GROUP)
class GTestGlobalEnvironmentUnitTest(gtest_test_utils.TestCase):
"""Tests global test environment failures."""
def testEnvironmentSetUpFails(self):
"""Tests the behavior of not specifying the fail_fast."""
# Run the test.
txt = RunAndReturnOutput()
# We should see the text of the global environment setup error.
self.assertIn('Canned environment setup error', txt)
# Our test should have been skipped due to the error, and not treated as a
# pass.
self.assertIn('[ SKIPPED ] 1 test', txt)
self.assertIn('[ PASSED ] 0 tests', txt)
# The test case shouldn't have been run.
self.assertNotIn('Unexpected call', txt)
# Invokes upload.py with the modified command line flags.
os.execv(upload_py_path, upload_py_argv)
if __name__ == '__main__':
gtest_test_utils.Main()
main()

View File

@@ -34,6 +34,7 @@
// utilities for defining matchers.
#include "gmock/gmock-matchers.h"
#include "gmock/gmock-generated-matchers.h"
#include <string.h>
#include <iostream>
@@ -218,6 +219,8 @@ class MaxBipartiteMatchState {
// right_[left_[i]] = i.
::std::vector<size_t> left_;
::std::vector<size_t> right_;
GTEST_DISALLOW_ASSIGN_(MaxBipartiteMatchState);
};
const size_t MaxBipartiteMatchState::kUnused;

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