mirror of
https://github.com/google/googletest.git
synced 2024-12-26 01:30:49 +08:00
Merge branch 'main' into default-enable-thread-support-for-Solaris-AIX-zOS
This commit is contained in:
commit
fbc93e61c4
43
.github/ISSUE_TEMPLATE/00-bug_report.md
vendored
43
.github/ISSUE_TEMPLATE/00-bug_report.md
vendored
@ -1,43 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: 'bug'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
|
||||
Include a clear and concise description of what the problem is, including what
|
||||
you expected to happen, and what actually happened.
|
||||
|
||||
**Steps to reproduce the bug**
|
||||
|
||||
It's important that we are able to reproduce the problem that you are
|
||||
experiencing. Please provide all code and relevant steps to reproduce the
|
||||
problem, including your `BUILD`/`CMakeLists.txt` file and build commands. Links
|
||||
to a GitHub branch or [godbolt.org](https://godbolt.org/) that demonstrate the
|
||||
problem are also helpful.
|
||||
|
||||
**Does the bug persist in the most recent commit?**
|
||||
|
||||
We recommend using the latest commit in the master branch in your projects.
|
||||
|
||||
**What operating system and version are you using?**
|
||||
|
||||
If you are using a Linux distribution please include the name and version of the
|
||||
distribution as well.
|
||||
|
||||
**What compiler and version are you using?**
|
||||
|
||||
Please include the output of `gcc -v` or `clang -v`, or the equivalent for your
|
||||
compiler.
|
||||
|
||||
**What build system are you using?**
|
||||
|
||||
Please include the output of `bazel --version` or `cmake --version`, or the
|
||||
equivalent for your build system.
|
||||
|
||||
**Additional context**
|
||||
|
||||
Add any other context about the problem here.
|
53
.github/ISSUE_TEMPLATE/00-bug_report.yml
vendored
Normal file
53
.github/ISSUE_TEMPLATE/00-bug_report.yml
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
name: Bug Report
|
||||
description: Let us know that something does not work as expected.
|
||||
title: "[Bug]: Please title this bug report"
|
||||
body:
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
label: Describe the issue
|
||||
description: What happened, and what did you expect to happen?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: steps
|
||||
attributes:
|
||||
label: Steps to reproduce the problem
|
||||
description: It is important that we are able to reproduce the problem that you are experiencing. Please provide all code and relevant steps to reproduce the problem, including your `BUILD`/`CMakeLists.txt` file and build commands. Links to a GitHub branch or [godbolt.org](https://godbolt.org/) that demonstrate the problem are also helpful.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: version
|
||||
attributes:
|
||||
label: What version of GoogleTest are you using?
|
||||
description: Please include the output of `git rev-parse HEAD` or the GoogleTest release version number that you are using.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: os
|
||||
attributes:
|
||||
label: What operating system and version are you using?
|
||||
description: If you are using a Linux distribution please include the name and version of the distribution as well.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: compiler
|
||||
attributes:
|
||||
label: What compiler and version are you using?
|
||||
description: Please include the output of `gcc -v` or `clang -v`, or the equivalent for your compiler.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: buildsystem
|
||||
attributes:
|
||||
label: What build system are you using?
|
||||
description: Please include the output of `bazel --version` or `cmake --version`, or the equivalent for your build system.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: additional
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any other context about the problem here.
|
||||
validations:
|
||||
required: false
|
24
.github/ISSUE_TEMPLATE/10-feature_request.md
vendored
24
.github/ISSUE_TEMPLATE/10-feature_request.md
vendored
@ -1,24 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Propose a new feature
|
||||
title: ''
|
||||
labels: 'enhancement'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
**Does the feature exist in the most recent commit?**
|
||||
|
||||
We recommend using the latest commit from GitHub in your projects.
|
||||
|
||||
**Why do we need this feature?**
|
||||
|
||||
Ideally, explain why a combination of existing features cannot be used instead.
|
||||
|
||||
**Describe the proposal**
|
||||
|
||||
Include a detailed description of the feature, with usage examples.
|
||||
|
||||
**Is the feature specific to an operating system, compiler, or build system version?**
|
||||
|
||||
If it is, please specify which versions.
|
||||
|
33
.github/ISSUE_TEMPLATE/10-feature_request.yml
vendored
Normal file
33
.github/ISSUE_TEMPLATE/10-feature_request.yml
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
name: Feature request
|
||||
description: Propose a new feature.
|
||||
title: "[FR]: Please title this feature request"
|
||||
labels: "enhancement"
|
||||
body:
|
||||
- type: textarea
|
||||
id: version
|
||||
attributes:
|
||||
label: Does the feature exist in the most recent commit?
|
||||
description: We recommend using the latest commit from GitHub in your projects.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: why
|
||||
attributes:
|
||||
label: Why do we need this feature?
|
||||
description: Ideally, explain why a combination of existing features cannot be used instead.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: proposal
|
||||
attributes:
|
||||
label: Describe the proposal.
|
||||
description: Include a detailed description of the feature, with usage examples.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: platform
|
||||
attributes:
|
||||
label: Is the feature specific to an operating system, compiler, or build system version?
|
||||
description: If it is, please specify which versions.
|
||||
validations:
|
||||
required: true
|
4
.github/ISSUE_TEMPLATE/config.yml
vendored
4
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -1 +1,5 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Get Help
|
||||
url: https://github.com/google/googletest/discussions
|
||||
about: Please ask and answer questions here.
|
||||
|
43
.github/workflows/gtest-ci.yml
vendored
43
.github/workflows/gtest-ci.yml
vendored
@ -1,43 +0,0 @@
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
BAZEL_CXXOPTS: -std=c++14
|
||||
|
||||
jobs:
|
||||
Linux:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Tests
|
||||
run: bazel test --cxxopt=-std=c++14 --features=external_include_paths --test_output=errors ...
|
||||
|
||||
MacOs:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Tests
|
||||
run: bazel test --cxxopt=-std=c++14 --features=external_include_paths --test_output=errors ...
|
||||
|
||||
|
||||
Windows:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Tests
|
||||
run: bazel test --cxxopt=-std=c++14 --features=external_include_paths --test_output=errors ...
|
5
.gitignore
vendored
5
.gitignore
vendored
@ -8,6 +8,7 @@ bazel-genfiles
|
||||
bazel-googletest
|
||||
bazel-out
|
||||
bazel-testlogs
|
||||
MODULE.bazel.lock
|
||||
# python
|
||||
*.pyc
|
||||
|
||||
@ -24,6 +25,10 @@ Win32-Release/
|
||||
x64-Debug/
|
||||
x64-Release/
|
||||
|
||||
# VSCode files
|
||||
.cache/
|
||||
cmake-variants.yaml
|
||||
|
||||
# Ignore autoconf / automake files
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
|
18
BUILD.bazel
18
BUILD.bazel
@ -56,6 +56,12 @@ config_setting(
|
||||
constraint_values = ["@platforms//os:openbsd"],
|
||||
)
|
||||
|
||||
# NOTE: Fuchsia is not an officially supported platform.
|
||||
config_setting(
|
||||
name = "fuchsia",
|
||||
constraint_values = ["@platforms//os:fuchsia"],
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name = "msvc_compiler",
|
||||
flag_values = {
|
||||
@ -132,6 +138,7 @@ cc_library(
|
||||
}),
|
||||
deps = select({
|
||||
":has_absl": [
|
||||
"@com_google_absl//absl/container:flat_hash_set",
|
||||
"@com_google_absl//absl/debugging:failure_signal_handler",
|
||||
"@com_google_absl//absl/debugging:stacktrace",
|
||||
"@com_google_absl//absl/debugging:symbolize",
|
||||
@ -146,6 +153,17 @@ cc_library(
|
||||
"@com_googlesource_code_re2//:re2",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}) + select({
|
||||
# `gtest-death-test.cc` has `EXPECT_DEATH` that spawns a process,
|
||||
# expects it to crash and inspects its logs with the given matcher,
|
||||
# so that's why these libraries are needed.
|
||||
# Otherwise, builds targeting Fuchsia would fail to compile.
|
||||
":fuchsia": [
|
||||
"@fuchsia_sdk//pkg/fdio",
|
||||
"@fuchsia_sdk//pkg/syslog",
|
||||
"@fuchsia_sdk//pkg/zx",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
)
|
||||
|
||||
|
@ -1,22 +1,10 @@
|
||||
# Note: CMake support is community-based. The maintainers do not use CMake
|
||||
# internally.
|
||||
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
if (POLICY CMP0048)
|
||||
cmake_policy(SET CMP0048 NEW)
|
||||
endif (POLICY CMP0048)
|
||||
|
||||
if (POLICY CMP0069)
|
||||
cmake_policy(SET CMP0069 NEW)
|
||||
endif (POLICY CMP0069)
|
||||
|
||||
if (POLICY CMP0077)
|
||||
cmake_policy(SET CMP0077 NEW)
|
||||
endif (POLICY CMP0077)
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
project(googletest-distribution)
|
||||
set(GOOGLETEST_VERSION 1.12.1)
|
||||
set(GOOGLETEST_VERSION 1.14.0)
|
||||
|
||||
if(NOT CYGWIN AND NOT MSYS AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL QNX)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
@ -27,9 +15,19 @@ enable_testing()
|
||||
include(CMakeDependentOption)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
#Note that googlemock target already builds googletest
|
||||
# Note that googlemock target already builds googletest.
|
||||
option(BUILD_GMOCK "Builds the googlemock subproject" ON)
|
||||
option(INSTALL_GTEST "Enable installation of googletest. (Projects embedding googletest may want to turn this OFF.)" ON)
|
||||
option(GTEST_HAS_ABSL "Use Abseil and RE2. Requires Abseil and RE2 to be separately added to the build." OFF)
|
||||
|
||||
if(GTEST_HAS_ABSL)
|
||||
if(NOT TARGET absl::base)
|
||||
find_package(absl REQUIRED)
|
||||
endif()
|
||||
if(NOT TARGET re2::re2)
|
||||
find_package(re2 REQUIRED)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(BUILD_GMOCK)
|
||||
add_subdirectory( googlemock )
|
||||
|
@ -47,11 +47,11 @@ PR is acceptable as an alternative.
|
||||
## The Google Test and Google Mock Communities
|
||||
|
||||
The Google Test community exists primarily through the
|
||||
[discussion group](http://groups.google.com/group/googletestframework) and the
|
||||
[discussion group](https://groups.google.com/group/googletestframework) and the
|
||||
GitHub repository. Likewise, the Google Mock community exists primarily through
|
||||
their own [discussion group](http://groups.google.com/group/googlemock). You are
|
||||
definitely encouraged to contribute to the discussion and you can also help us
|
||||
to keep the effectiveness of the group high by following and promoting the
|
||||
their own [discussion group](https://groups.google.com/group/googlemock). You
|
||||
are definitely encouraged to contribute to the discussion and you can also help
|
||||
us to keep the effectiveness of the group high by following and promoting the
|
||||
guidelines listed here.
|
||||
|
||||
### Please Be Friendly
|
||||
@ -88,7 +88,7 @@ check your formatting.
|
||||
If you plan to contribute a patch, you need to build Google Test, Google Mock,
|
||||
and their own tests from a git checkout, which has further requirements:
|
||||
|
||||
* [Python](https://www.python.org/) v2.3 or newer (for running some of the
|
||||
* [Python](https://www.python.org/) v3.6 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
|
||||
|
||||
@ -102,30 +102,40 @@ To make sure your changes work as intended and don't break existing
|
||||
functionality, you'll want to compile and run Google Test and GoogleMock's own
|
||||
tests. For that you can use CMake:
|
||||
|
||||
mkdir mybuild
|
||||
cd mybuild
|
||||
cmake -Dgtest_build_tests=ON -Dgmock_build_tests=ON ${GTEST_REPO_DIR}
|
||||
```
|
||||
mkdir mybuild
|
||||
cd mybuild
|
||||
cmake -Dgtest_build_tests=ON -Dgmock_build_tests=ON ${GTEST_REPO_DIR}
|
||||
```
|
||||
|
||||
To choose between building only Google Test or Google Mock, you may modify your
|
||||
cmake command to be one of each
|
||||
|
||||
cmake -Dgtest_build_tests=ON ${GTEST_DIR} # sets up Google Test tests
|
||||
cmake -Dgmock_build_tests=ON ${GMOCK_DIR} # sets up Google Mock tests
|
||||
```
|
||||
cmake -Dgtest_build_tests=ON ${GTEST_DIR} # sets up Google Test tests
|
||||
cmake -Dgmock_build_tests=ON ${GMOCK_DIR} # sets up Google Mock tests
|
||||
```
|
||||
|
||||
Make sure you have Python installed, as some of Google Test's tests are written
|
||||
in Python. If the cmake command complains about not being able to find Python
|
||||
(`Could NOT find PythonInterp (missing: PYTHON_EXECUTABLE)`), try telling it
|
||||
explicitly where your Python executable can be found:
|
||||
|
||||
cmake -DPYTHON_EXECUTABLE=path/to/python ...
|
||||
```
|
||||
cmake -DPYTHON_EXECUTABLE=path/to/python ...
|
||||
```
|
||||
|
||||
Next, you can build Google Test and / or Google Mock and all desired tests. On
|
||||
\*nix, this is usually done by
|
||||
|
||||
make
|
||||
```
|
||||
make
|
||||
```
|
||||
|
||||
To run the tests, do
|
||||
|
||||
make test
|
||||
```
|
||||
make test
|
||||
```
|
||||
|
||||
All tests should pass.
|
||||
|
@ -55,6 +55,7 @@ Russ Cox <rsc@google.com>
|
||||
Russ Rufer <russ@pentad.com>
|
||||
Sean Mcafee <eefacm@gmail.com>
|
||||
Sigurður Ásgeirsson <siggi@google.com>
|
||||
Soyeon Kim <sxshx818@naver.com>
|
||||
Sverre Sundsdal <sundsdal@gmail.com>
|
||||
Szymon Sobik <sobik.szymon@gmail.com>
|
||||
Takeshi Yoshino <tyoshino@google.com>
|
||||
|
61
MODULE.bazel
Normal file
61
MODULE.bazel
Normal file
@ -0,0 +1,61 @@
|
||||
# Copyright 2024 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.
|
||||
|
||||
# https://bazel.build/external/overview#bzlmod
|
||||
|
||||
module(
|
||||
name = "googletest",
|
||||
version = "head",
|
||||
compatibility_level = 1,
|
||||
)
|
||||
|
||||
# Only direct dependencies need to be listed below.
|
||||
# Please keep the versions in sync with the versions in the WORKSPACE file.
|
||||
|
||||
bazel_dep(name = "abseil-cpp",
|
||||
version = "20240116.0",
|
||||
repo_name = "com_google_absl")
|
||||
|
||||
bazel_dep(name = "platforms",
|
||||
version = "0.0.8")
|
||||
|
||||
bazel_dep(name = "re2",
|
||||
repo_name = "com_googlesource_code_re2",
|
||||
version = "2023-11-01")
|
||||
|
||||
bazel_dep(name = "rules_python",
|
||||
version = "0.29.0")
|
||||
|
||||
|
||||
fake_fuchsia_sdk = use_repo_rule("//:fake_fuchsia_sdk.bzl", "fake_fuchsia_sdk")
|
||||
fake_fuchsia_sdk(name = "fuchsia_sdk")
|
||||
|
||||
# https://github.com/bazelbuild/rules_python/blob/main/BZLMOD_SUPPORT.md#default-toolchain-is-not-the-local-system-python
|
||||
register_toolchains("@bazel_tools//tools/python:autodetecting_toolchain")
|
69
README.md
69
README.md
@ -8,6 +8,8 @@ GoogleTest now follows the
|
||||
[Abseil Live at Head philosophy](https://abseil.io/about/philosophy#upgrade-support).
|
||||
We recommend
|
||||
[updating to the latest commit in the `main` branch as often as possible](https://github.com/abseil/abseil-cpp/blob/master/FAQ.md#what-is-live-at-head-and-how-do-i-do-it).
|
||||
We do publish occasional semantic versions, tagged with
|
||||
`v${major}.${minor}.${patch}` (e.g. `v1.14.0`).
|
||||
|
||||
#### Documentation Updates
|
||||
|
||||
@ -15,13 +17,19 @@ Our documentation is now live on GitHub Pages at
|
||||
https://google.github.io/googletest/. We recommend browsing the documentation on
|
||||
GitHub Pages rather than directly in the repository.
|
||||
|
||||
#### Release 1.12.1
|
||||
#### Release 1.14.0
|
||||
|
||||
[Release 1.12.1](https://github.com/google/googletest/releases/tag/release-1.12.1)
|
||||
is now available.
|
||||
[Release 1.14.0](https://github.com/google/googletest/releases/tag/v1.14.0) is
|
||||
now available.
|
||||
|
||||
The 1.12.x branch will be the last to support C++11. Future releases will
|
||||
require at least C++14.
|
||||
The 1.14.x branch requires at least C++14.
|
||||
|
||||
#### Continuous Integration
|
||||
|
||||
We use Google's internal systems for continuous integration. \
|
||||
GitHub Actions were added for the convenience of open-source contributors. They
|
||||
are exclusively maintained by the open-source community and not used by the
|
||||
GoogleTest team.
|
||||
|
||||
#### Coming Soon
|
||||
|
||||
@ -46,16 +54,37 @@ More information about building GoogleTest can be found at
|
||||
|
||||
## 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.
|
||||
* xUnit test framework: \
|
||||
Googletest is based on the [xUnit](https://en.wikipedia.org/wiki/XUnit)
|
||||
testing framework, a popular architecture for unit testing
|
||||
* Test discovery: \
|
||||
Googletest automatically discovers and runs your tests, eliminating the need
|
||||
to manually register your tests
|
||||
* Rich set of assertions: \
|
||||
Googletest provides a variety of assertions, such as equality, inequality,
|
||||
exceptions, and more, making it easy to test your code
|
||||
* User-defined assertions: \
|
||||
You can define your own assertions with Googletest, making it simple to
|
||||
write tests that are specific to your code
|
||||
* Death tests: \
|
||||
Googletest supports death tests, which verify that your code exits in a
|
||||
certain way, making it useful for testing error-handling code
|
||||
* Fatal and non-fatal failures: \
|
||||
You can specify whether a test failure should be treated as fatal or
|
||||
non-fatal with Googletest, allowing tests to continue running even if a
|
||||
failure occurs
|
||||
* Value-parameterized tests: \
|
||||
Googletest supports value-parameterized tests, which run multiple times with
|
||||
different input values, making it useful for testing functions that take
|
||||
different inputs
|
||||
* Type-parameterized tests: \
|
||||
Googletest also supports type-parameterized tests, which run with different
|
||||
data types, making it useful for testing functions that work with different
|
||||
data types
|
||||
* Various options for running tests: \
|
||||
Googletest provides many options for running tests including running
|
||||
individual tests, running tests in a specific order and running tests in
|
||||
parallel
|
||||
|
||||
## Supported Platforms
|
||||
|
||||
@ -63,7 +92,7 @@ GoogleTest follows Google's
|
||||
[Foundational C++ Support Policy](https://opensource.google/documentation/policies/cplusplus-support).
|
||||
See
|
||||
[this table](https://github.com/google/oss-policies-info/blob/main/foundational-cxx-support-matrix.md)
|
||||
for a list of currently supported versions compilers, platforms, and build
|
||||
for a list of currently supported versions of compilers, platforms, and build
|
||||
tools.
|
||||
|
||||
## Who Is Using GoogleTest?
|
||||
@ -71,12 +100,12 @@ tools.
|
||||
In addition to many internal projects at Google, GoogleTest is also used by the
|
||||
following notable projects:
|
||||
|
||||
* The [Chromium projects](http://www.chromium.org/) (behind the Chrome browser
|
||||
and Chrome OS).
|
||||
* The [LLVM](http://llvm.org/) compiler.
|
||||
* The [Chromium projects](https://www.chromium.org/) (behind the Chrome
|
||||
browser and Chrome OS).
|
||||
* The [LLVM](https://llvm.org/) compiler.
|
||||
* [Protocol Buffers](https://github.com/google/protobuf), Google's data
|
||||
interchange format.
|
||||
* The [OpenCV](http://opencv.org/) computer vision library.
|
||||
* The [OpenCV](https://opencv.org/) computer vision library.
|
||||
|
||||
## Related Open Source Projects
|
||||
|
||||
|
40
WORKSPACE
40
WORKSPACE
@ -1,39 +1,29 @@
|
||||
workspace(name = "com_google_googletest")
|
||||
|
||||
load("//:googletest_deps.bzl", "googletest_deps")
|
||||
googletest_deps()
|
||||
|
||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
|
||||
http_archive(
|
||||
name = "com_google_absl",
|
||||
sha256 = "1a1745b5ee81392f5ea4371a4ca41e55d446eeaee122903b2eaffbd8a3b67a2b",
|
||||
strip_prefix = "abseil-cpp-01cc6567cff77738e416a7ddc17de2d435a780ce",
|
||||
urls = ["https://github.com/abseil/abseil-cpp/archive/01cc6567cff77738e416a7ddc17de2d435a780ce.zip"], # 2022-06-21T19:28:27Z
|
||||
name = "rules_python",
|
||||
sha256 = "d71d2c67e0bce986e1c5a7731b4693226867c45bfe0b7c5e0067228a536fc580",
|
||||
strip_prefix = "rules_python-0.29.0",
|
||||
urls = ["https://github.com/bazelbuild/rules_python/releases/download/0.29.0/rules_python-0.29.0.tar.gz"],
|
||||
)
|
||||
|
||||
# Note this must use a commit from the `abseil` branch of the RE2 project.
|
||||
# https://github.com/google/re2/tree/abseil
|
||||
http_archive(
|
||||
name = "com_googlesource_code_re2",
|
||||
sha256 = "0a890c2aa0bb05b2ce906a15efb520d0f5ad4c7d37b8db959c43772802991887",
|
||||
strip_prefix = "re2-a427f10b9fb4622dd6d8643032600aa1b50fbd12",
|
||||
urls = ["https://github.com/google/re2/archive/a427f10b9fb4622dd6d8643032600aa1b50fbd12.zip"], # 2022-06-09
|
||||
)
|
||||
# https://github.com/bazelbuild/rules_python/releases/tag/0.29.0
|
||||
load("@rules_python//python:repositories.bzl", "py_repositories")
|
||||
py_repositories()
|
||||
|
||||
http_archive(
|
||||
name = "rules_python",
|
||||
sha256 = "0b460f17771258341528753b1679335b629d1d25e3af28eda47d009c103a6e15",
|
||||
strip_prefix = "rules_python-aef17ad72919d184e5edb7abf61509eb78e57eda",
|
||||
urls = ["https://github.com/bazelbuild/rules_python/archive/aef17ad72919d184e5edb7abf61509eb78e57eda.zip"], # 2022-06-21T23:44:47Z
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "bazel_skylib",
|
||||
urls = ["https://github.com/bazelbuild/bazel-skylib/releases/download/1.2.1/bazel-skylib-1.2.1.tar.gz"],
|
||||
sha256 = "f7be3474d42aae265405a592bb7da8e171919d74c16f082a5457840f06054728",
|
||||
name = "bazel_skylib",
|
||||
sha256 = "cd55a062e763b9349921f0f5db8c3933288dc8ba4f76dd9416aac68acee3cb94",
|
||||
urls = ["https://github.com/bazelbuild/bazel-skylib/releases/download/1.5.0/bazel-skylib-1.5.0.tar.gz"],
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "platforms",
|
||||
sha256 = "a879ea428c6d56ab0ec18224f976515948822451473a80d06c2e50af0bbe5121",
|
||||
strip_prefix = "platforms-da5541f26b7de1dc8e04c075c99df5351742a4a2",
|
||||
urls = ["https://github.com/bazelbuild/platforms/archive/da5541f26b7de1dc8e04c075c99df5351742a4a2.zip"], # 2022-05-27
|
||||
sha256 = "8150406605389ececb6da07cbcb509d5637a3ab9a24bc69b1101531367d89d74",
|
||||
urls = ["https://github.com/bazelbuild/platforms/releases/download/0.0.8/platforms-0.0.8.tar.gz"],
|
||||
)
|
||||
|
35
WORKSPACE.bzlmod
Normal file
35
WORKSPACE.bzlmod
Normal file
@ -0,0 +1,35 @@
|
||||
# Copyright 2024 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.
|
||||
|
||||
# https://bazel.build/external/migration#workspace.bzlmod
|
||||
#
|
||||
# This file is intentionally empty. When bzlmod is enabled and this
|
||||
# file exists, the content of WORKSPACE is ignored. This prevents
|
||||
# bzlmod builds from unintentionally depending on the WORKSPACE file.
|
@ -31,8 +31,8 @@
|
||||
|
||||
set -euox pipefail
|
||||
|
||||
readonly LINUX_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20220217"
|
||||
readonly LINUX_GCC_FLOOR_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-floor:20220621"
|
||||
readonly LINUX_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20231218"
|
||||
readonly LINUX_GCC_FLOOR_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-floor:20230120"
|
||||
|
||||
if [[ -z ${GTEST_ROOT:-} ]]; then
|
||||
GTEST_ROOT="$(realpath $(dirname ${0})/..)"
|
||||
@ -51,7 +51,7 @@ for cc in /usr/local/bin/gcc /opt/llvm/clang/bin/clang; do
|
||||
--workdir="/build" \
|
||||
--rm \
|
||||
--env="CC=${cc}" \
|
||||
--env="CXX_FLAGS=\"-Werror -Wdeprecated\"" \
|
||||
--env=CXXFLAGS="-Werror -Wdeprecated" \
|
||||
${LINUX_LATEST_CONTAINER} \
|
||||
/bin/bash -c "
|
||||
cmake /src \
|
||||
@ -67,6 +67,9 @@ for cc in /usr/local/bin/gcc /opt/llvm/clang/bin/clang; do
|
||||
done
|
||||
|
||||
# Do one test with an older version of GCC
|
||||
# TODO(googletest-team): This currently uses Bazel 5. When upgrading to a
|
||||
# version of Bazel that supports Bzlmod, add --enable_bzlmod=false to keep test
|
||||
# coverage for the old WORKSPACE dependency management.
|
||||
time docker run \
|
||||
--volume="${GTEST_ROOT}:/src:ro" \
|
||||
--workdir="/src" \
|
||||
@ -78,8 +81,8 @@ time docker run \
|
||||
--copt="-Wall" \
|
||||
--copt="-Werror" \
|
||||
--copt="-Wuninitialized" \
|
||||
--copt="-Wundef" \
|
||||
--copt="-Wno-error=pragmas" \
|
||||
--distdir="/bazel-distdir" \
|
||||
--features=external_include_paths \
|
||||
--keep_going \
|
||||
--show_timestamps \
|
||||
@ -99,8 +102,9 @@ for std in ${STD}; do
|
||||
--copt="-Wall" \
|
||||
--copt="-Werror" \
|
||||
--copt="-Wuninitialized" \
|
||||
--copt="-Wundef" \
|
||||
--define="absl=${absl}" \
|
||||
--distdir="/bazel-distdir" \
|
||||
--enable_bzlmod=true \
|
||||
--features=external_include_paths \
|
||||
--keep_going \
|
||||
--show_timestamps \
|
||||
@ -123,8 +127,9 @@ for std in ${STD}; do
|
||||
--copt="-Wall" \
|
||||
--copt="-Werror" \
|
||||
--copt="-Wuninitialized" \
|
||||
--copt="-Wundef" \
|
||||
--define="absl=${absl}" \
|
||||
--distdir="/bazel-distdir" \
|
||||
--enable_bzlmod=true \
|
||||
--features=external_include_paths \
|
||||
--keep_going \
|
||||
--linkopt="--gcc-toolchain=/usr/local" \
|
||||
|
@ -53,7 +53,7 @@ done
|
||||
# Test the Bazel build
|
||||
|
||||
# If we are running on Kokoro, check for a versioned Bazel binary.
|
||||
KOKORO_GFILE_BAZEL_BIN="bazel-5.1.1-darwin-x86_64"
|
||||
KOKORO_GFILE_BAZEL_BIN="bazel-7.0.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}
|
||||
@ -66,8 +66,10 @@ for absl in 0 1; do
|
||||
${BAZEL_BIN} test ... \
|
||||
--copt="-Wall" \
|
||||
--copt="-Werror" \
|
||||
--copt="-Wundef" \
|
||||
--cxxopt="-std=c++14" \
|
||||
--define="absl=${absl}" \
|
||||
--enable_bzlmod=true \
|
||||
--features=external_include_paths \
|
||||
--keep_going \
|
||||
--show_timestamps \
|
||||
|
58
ci/windows-presubmit.bat
Normal file
58
ci/windows-presubmit.bat
Normal file
@ -0,0 +1,58 @@
|
||||
SETLOCAL ENABLEDELAYEDEXPANSION
|
||||
|
||||
SET BAZEL_EXE=%KOKORO_GFILE_DIR%\bazel-7.0.0-windows-x86_64.exe
|
||||
|
||||
SET PATH=C:\Python34;%PATH%
|
||||
SET BAZEL_PYTHON=C:\python34\python.exe
|
||||
SET BAZEL_SH=C:\tools\msys64\usr\bin\bash.exe
|
||||
SET CMAKE_BIN="cmake.exe"
|
||||
SET CTEST_BIN="ctest.exe"
|
||||
SET CTEST_OUTPUT_ON_FAILURE=1
|
||||
SET CMAKE_BUILD_PARALLEL_LEVEL=16
|
||||
SET CTEST_PARALLEL_LEVEL=16
|
||||
|
||||
IF EXIST git\googletest (
|
||||
CD git\googletest
|
||||
) ELSE IF EXIST github\googletest (
|
||||
CD github\googletest
|
||||
)
|
||||
|
||||
IF %errorlevel% neq 0 EXIT /B 1
|
||||
|
||||
:: ----------------------------------------------------------------------------
|
||||
:: CMake
|
||||
MKDIR cmake_msvc2022
|
||||
CD cmake_msvc2022
|
||||
|
||||
%CMAKE_BIN% .. ^
|
||||
-G "Visual Studio 17 2022" ^
|
||||
-DPYTHON_EXECUTABLE:FILEPATH=c:\python37\python.exe ^
|
||||
-DPYTHON_INCLUDE_DIR:PATH=c:\python37\include ^
|
||||
-DPYTHON_LIBRARY:FILEPATH=c:\python37\lib\site-packages\pip ^
|
||||
-Dgtest_build_samples=ON ^
|
||||
-Dgtest_build_tests=ON ^
|
||||
-Dgmock_build_tests=ON
|
||||
IF %errorlevel% neq 0 EXIT /B 1
|
||||
|
||||
%CMAKE_BIN% --build . --target ALL_BUILD --config Debug -- -maxcpucount
|
||||
IF %errorlevel% neq 0 EXIT /B 1
|
||||
|
||||
%CTEST_BIN% -C Debug --timeout 600
|
||||
IF %errorlevel% neq 0 EXIT /B 1
|
||||
|
||||
CD ..
|
||||
RMDIR /S /Q cmake_msvc2022
|
||||
|
||||
:: ----------------------------------------------------------------------------
|
||||
:: Bazel
|
||||
|
||||
SET BAZEL_VS=C:\Program Files\Microsoft Visual Studio\2022\Community
|
||||
%BAZEL_EXE% test ... ^
|
||||
--compilation_mode=dbg ^
|
||||
--copt=/std:c++14 ^
|
||||
--copt=/WX ^
|
||||
--enable_bzlmod=true ^
|
||||
--keep_going ^
|
||||
--test_output=errors ^
|
||||
--test_tag_filters=-no_test_msvc2017
|
||||
IF %errorlevel% neq 0 EXIT /B 1
|
272
docs/advanced.md
272
docs/advanced.md
@ -1,9 +1,9 @@
|
||||
# Advanced googletest Topics
|
||||
# Advanced GoogleTest Topics
|
||||
|
||||
## Introduction
|
||||
|
||||
Now that you have read the [googletest Primer](primer.md) and learned how to
|
||||
write tests using googletest, it's time to learn some new tricks. This document
|
||||
Now that you have read the [GoogleTest Primer](primer.md) and learned how to
|
||||
write tests using GoogleTest, it's time to learn some new tricks. This document
|
||||
will show you more assertions as well as how to construct complex failure
|
||||
messages, propagate fatal failures, reuse and speed up your test fixtures, and
|
||||
use various flags with your tests.
|
||||
@ -25,7 +25,7 @@ Reference.
|
||||
|
||||
### Predicate Assertions for Better Error Messages
|
||||
|
||||
Even though googletest has a rich set of assertions, they can never be complete,
|
||||
Even though GoogleTest has a rich set of assertions, they can never be complete,
|
||||
as it's impossible (nor a good idea) to anticipate all scenarios a user might
|
||||
run into. Therefore, sometimes a user has to use `EXPECT_TRUE()` to check a
|
||||
complex expression, for lack of a better macro. This has the problem of not
|
||||
@ -35,7 +35,7 @@ failure message by themselves, streaming it into `EXPECT_TRUE()`. However, this
|
||||
is awkward especially when the expression has side-effects or is expensive to
|
||||
evaluate.
|
||||
|
||||
googletest gives you three different options to solve this problem:
|
||||
GoogleTest gives you three different options to solve this problem:
|
||||
|
||||
#### Using an Existing Boolean Function
|
||||
|
||||
@ -304,9 +304,9 @@ TEST_F(SkipFixture, SkipsOneTest) {
|
||||
|
||||
As with assertion macros, you can stream a custom message into `GTEST_SKIP()`.
|
||||
|
||||
## Teaching googletest How to Print Your Values
|
||||
## Teaching GoogleTest How to Print Your Values
|
||||
|
||||
When a test assertion such as `EXPECT_EQ` fails, googletest prints the argument
|
||||
When a test assertion such as `EXPECT_EQ` fails, GoogleTest prints the argument
|
||||
values to help you debug. It does this using a user-extensible value printer.
|
||||
|
||||
This printer knows how to print built-in C++ types, native arrays, STL
|
||||
@ -315,73 +315,96 @@ prints the raw bytes in the value and hopes that you the user can figure it out.
|
||||
|
||||
As mentioned earlier, the printer is *extensible*. That means you can teach it
|
||||
to do a better job at printing your particular type than to dump the bytes. To
|
||||
do that, define `<<` for your type:
|
||||
|
||||
```c++
|
||||
#include <ostream>
|
||||
do that, define an `AbslStringify()` overload as a `friend` function template
|
||||
for your type:
|
||||
|
||||
```cpp
|
||||
namespace foo {
|
||||
|
||||
class Bar { // We want googletest to be able to print instances of this.
|
||||
...
|
||||
// Create a free inline friend function.
|
||||
friend std::ostream& operator<<(std::ostream& os, const Bar& bar) {
|
||||
return os << bar.DebugString(); // whatever needed to print bar to os
|
||||
class Point { // We want GoogleTest to be able to print instances of this.
|
||||
...
|
||||
// Provide a friend overload.
|
||||
template <typename Sink>
|
||||
friend void AbslStringify(Sink& sink, const Point& point) {
|
||||
absl::Format(&sink, "(%d, %d)", point.x, point.y);
|
||||
}
|
||||
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
// If you can't declare the function in the class it's important that the
|
||||
// << operator is defined in the SAME namespace that defines Bar. C++'s look-up
|
||||
// rules rely on that.
|
||||
std::ostream& operator<<(std::ostream& os, const Bar& bar) {
|
||||
return os << bar.DebugString(); // whatever needed to print bar to os
|
||||
// AbslStringify overload is defined in the SAME namespace that defines Point.
|
||||
// C++'s look-up rules rely on that.
|
||||
enum class EnumWithStringify { kMany = 0, kChoices = 1 };
|
||||
|
||||
template <typename Sink>
|
||||
void AbslStringify(Sink& sink, EnumWithStringify e) {
|
||||
absl::Format(&sink, "%s", e == EnumWithStringify::kMany ? "Many" : "Choices");
|
||||
}
|
||||
|
||||
} // namespace foo
|
||||
```
|
||||
|
||||
Sometimes, this might not be an option: your team may consider it bad style to
|
||||
have a `<<` operator for `Bar`, or `Bar` may already have a `<<` operator that
|
||||
doesn't do what you want (and you cannot change it). If so, you can instead
|
||||
define a `PrintTo()` function like this:
|
||||
{: .callout .note}
|
||||
Note: `AbslStringify()` utilizes a generic "sink" buffer to construct its
|
||||
string. For more information about supported operations on `AbslStringify()`'s
|
||||
sink, see go/abslstringify.
|
||||
|
||||
`AbslStringify()` can also use `absl::StrFormat`'s catch-all `%v` type specifier
|
||||
within its own format strings to perform type deduction. `Point` above could be
|
||||
formatted as `"(%v, %v)"` for example, and deduce the `int` values as `%d`.
|
||||
|
||||
Sometimes, `AbslStringify()` might not be an option: your team may wish to print
|
||||
types with extra debugging information for testing purposes only. If so, you can
|
||||
instead define a `PrintTo()` function like this:
|
||||
|
||||
```c++
|
||||
#include <ostream>
|
||||
|
||||
namespace foo {
|
||||
|
||||
class Bar {
|
||||
class Point {
|
||||
...
|
||||
friend void PrintTo(const Bar& bar, std::ostream* os) {
|
||||
*os << bar.DebugString(); // whatever needed to print bar to os
|
||||
friend void PrintTo(const Point& point, std::ostream* os) {
|
||||
*os << "(" << point.x << "," << point.y << ")";
|
||||
}
|
||||
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
// If you can't declare the function in the class it's important that PrintTo()
|
||||
// is defined in the SAME namespace that defines Bar. C++'s look-up rules rely
|
||||
// on that.
|
||||
void PrintTo(const Bar& bar, std::ostream* os) {
|
||||
*os << bar.DebugString(); // whatever needed to print bar to os
|
||||
// is defined in the SAME namespace that defines Point. C++'s look-up rules
|
||||
// rely on that.
|
||||
void PrintTo(const Point& point, std::ostream* os) {
|
||||
*os << "(" << point.x << "," << point.y << ")";
|
||||
}
|
||||
|
||||
} // namespace foo
|
||||
```
|
||||
|
||||
If you have defined both `<<` and `PrintTo()`, the latter will be used when
|
||||
googletest is concerned. This allows you to customize how the value appears in
|
||||
googletest's output without affecting code that relies on the behavior of its
|
||||
`<<` operator.
|
||||
If you have defined both `AbslStringify()` and `PrintTo()`, the latter will be
|
||||
used by GoogleTest. This allows you to customize how the value appears in
|
||||
GoogleTest's output without affecting code that relies on the behavior of
|
||||
`AbslStringify()`.
|
||||
|
||||
If you want to print a value `x` using googletest's value printer yourself, just
|
||||
If you have an existing `<<` operator and would like to define an
|
||||
`AbslStringify()`, the latter will be used for GoogleTest printing.
|
||||
|
||||
If you want to print a value `x` using GoogleTest's value printer yourself, just
|
||||
call `::testing::PrintToString(x)`, which returns an `std::string`:
|
||||
|
||||
```c++
|
||||
vector<pair<Bar, int> > bar_ints = GetBarIntVector();
|
||||
vector<pair<Point, int> > point_ints = GetPointIntVector();
|
||||
|
||||
EXPECT_TRUE(IsCorrectBarIntVector(bar_ints))
|
||||
<< "bar_ints = " << testing::PrintToString(bar_ints);
|
||||
EXPECT_TRUE(IsCorrectPointIntVector(point_ints))
|
||||
<< "point_ints = " << testing::PrintToString(point_ints);
|
||||
```
|
||||
|
||||
For more details regarding `AbslStringify()` and its integration with other
|
||||
libraries, see go/abslstringify.
|
||||
|
||||
## Death Tests
|
||||
|
||||
In many applications, there are assertions that can cause application failure if
|
||||
@ -451,7 +474,7 @@ Note that a death test only cares about three things:
|
||||
3. does the stderr output match `matcher`?
|
||||
|
||||
In particular, if `statement` generates an `ASSERT_*` or `EXPECT_*` failure, it
|
||||
will **not** cause the death test to fail, as googletest assertions don't abort
|
||||
will **not** cause the death test to fail, as GoogleTest assertions don't abort
|
||||
the process.
|
||||
|
||||
### Death Test Naming
|
||||
@ -482,14 +505,14 @@ TEST_F(FooDeathTest, DoesThat) {
|
||||
|
||||
### Regular Expression Syntax
|
||||
|
||||
When built with Bazel and using Abseil, googletest uses the
|
||||
When built with Bazel and using Abseil, GoogleTest uses the
|
||||
[RE2](https://github.com/google/re2/wiki/Syntax) syntax. Otherwise, for POSIX
|
||||
systems (Linux, Cygwin, Mac), googletest uses the
|
||||
[POSIX extended regular expression](http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.html#tag_09_04)
|
||||
systems (Linux, Cygwin, Mac), GoogleTest uses the
|
||||
[POSIX extended regular expression](https://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.html#tag_09_04)
|
||||
syntax. To learn about POSIX syntax, you may want to read this
|
||||
[Wikipedia entry](http://en.wikipedia.org/wiki/Regular_expression#POSIX_Extended_Regular_Expressions).
|
||||
[Wikipedia entry](https://en.wikipedia.org/wiki/Regular_expression#POSIX_extended).
|
||||
|
||||
On Windows, googletest uses its own simple regular expression implementation. It
|
||||
On Windows, GoogleTest uses its own simple regular expression implementation. It
|
||||
lacks many features. For example, we don't support union (`"x|y"`), grouping
|
||||
(`"(xy)"`), brackets (`"[xy]"`), and repetition count (`"x{5,7}"`), among
|
||||
others. Below is what we do support (`A` denotes a literal character, period
|
||||
@ -519,7 +542,7 @@ Expression | Meaning
|
||||
`$` | matches the end of a string (not that of each line)
|
||||
`xy` | matches `x` followed by `y`
|
||||
|
||||
To help you determine which capability is available on your system, googletest
|
||||
To help you determine which capability is available on your system, GoogleTest
|
||||
defines macros to govern which regular expression it is using. The macros are:
|
||||
`GTEST_USES_SIMPLE_RE=1` or `GTEST_USES_POSIX_RE=1`. If you want your death
|
||||
tests to work in all cases, you can either `#if` on these macros or use the more
|
||||
@ -539,7 +562,7 @@ arrange that kind of environment. For example, statically-initialized modules
|
||||
may start threads before main is ever reached. Once threads have been created,
|
||||
it may be difficult or impossible to clean them up.
|
||||
|
||||
googletest has three features intended to raise awareness of threading issues.
|
||||
GoogleTest has three features intended to raise awareness of threading issues.
|
||||
|
||||
1. A warning is emitted if multiple threads are running when a death test is
|
||||
encountered.
|
||||
@ -562,7 +585,7 @@ The automated testing framework does not set the style flag. You can choose a
|
||||
particular style of death tests by setting the flag programmatically:
|
||||
|
||||
```c++
|
||||
GTEST_FLAG_SET(death_test_style, "threadsafe")
|
||||
GTEST_FLAG_SET(death_test_style, "threadsafe");
|
||||
```
|
||||
|
||||
You can do this in `main()` to set the style for all death tests in the binary,
|
||||
@ -592,7 +615,7 @@ TEST(MyDeathTest, TestTwo) {
|
||||
|
||||
The `statement` argument of `ASSERT_EXIT()` can be any valid C++ statement. If
|
||||
it leaves the current function via a `return` statement or by throwing an
|
||||
exception, the death test is considered to have failed. Some googletest macros
|
||||
exception, the death test is considered to have failed. Some GoogleTest macros
|
||||
may return from the current function (e.g. `ASSERT_TRUE()`), so be sure to avoid
|
||||
them in `statement`.
|
||||
|
||||
@ -726,7 +749,7 @@ TEST(FooTest, Bar) {
|
||||
}
|
||||
```
|
||||
|
||||
To alleviate this, googletest provides three different solutions. You could use
|
||||
To alleviate this, GoogleTest provides three different solutions. You could use
|
||||
either exceptions, the `(ASSERT|EXPECT)_NO_FATAL_FAILURE` assertions or the
|
||||
`HasFatalFailure()` function. They are described in the following two
|
||||
subsections.
|
||||
@ -760,7 +783,7 @@ in it, the test will continue after the subroutine returns. This may not be what
|
||||
you want.
|
||||
|
||||
Often people want fatal failures to propagate like exceptions. For that
|
||||
googletest offers the following macros:
|
||||
GoogleTest offers the following macros:
|
||||
|
||||
Fatal assertion | Nonfatal assertion | Verifies
|
||||
------------------------------------- | ------------------------------------- | --------
|
||||
@ -852,7 +875,7 @@ will output XML like this:
|
||||
> needs to be prefixed with `::testing::Test::` if used outside of the
|
||||
> `TEST` body and the test fixture class.
|
||||
> * *`key`* must be a valid XML attribute name, and cannot conflict with the
|
||||
> ones already used by googletest (`name`, `status`, `time`, `classname`,
|
||||
> ones already used by GoogleTest (`name`, `status`, `time`, `classname`,
|
||||
> `type_param`, and `value_param`).
|
||||
> * Calling `RecordProperty()` outside of the lifespan of a test is allowed.
|
||||
> If it's called outside of a test but between a test suite's
|
||||
@ -863,25 +886,25 @@ will output XML like this:
|
||||
|
||||
## Sharing Resources Between Tests in the Same Test Suite
|
||||
|
||||
googletest creates a new test fixture object for each test in order to make
|
||||
GoogleTest creates a new test fixture object for each test in order to make
|
||||
tests independent and easier to debug. However, sometimes tests use resources
|
||||
that are expensive to set up, making the one-copy-per-test model prohibitively
|
||||
expensive.
|
||||
|
||||
If the tests don't change the resource, there's no harm in their sharing a
|
||||
single resource copy. So, in addition to per-test set-up/tear-down, googletest
|
||||
single resource copy. So, in addition to per-test set-up/tear-down, GoogleTest
|
||||
also supports per-test-suite set-up/tear-down. To use it:
|
||||
|
||||
1. In your test fixture class (say `FooTest` ), declare as `static` some member
|
||||
variables to hold the shared resources.
|
||||
2. Outside your test fixture class (typically just below it), define those
|
||||
member variables, optionally giving them initial values.
|
||||
3. In the same test fixture class, define a `static void SetUpTestSuite()`
|
||||
function (remember not to spell it as **`SetupTestSuite`** with a small
|
||||
`u`!) to set up the shared resources and a `static void TearDownTestSuite()`
|
||||
function to tear them down.
|
||||
3. In the same test fixture class, define a public member function `static void
|
||||
SetUpTestSuite()` (remember not to spell it as **`SetupTestSuite`** with a
|
||||
small `u`!) to set up the shared resources and a `static void
|
||||
TearDownTestSuite()` function to tear them down.
|
||||
|
||||
That's it! googletest automatically calls `SetUpTestSuite()` before running the
|
||||
That's it! GoogleTest automatically calls `SetUpTestSuite()` before running the
|
||||
*first test* in the `FooTest` test suite (i.e. before creating the first
|
||||
`FooTest` object), and calls `TearDownTestSuite()` after running the *last test*
|
||||
in it (i.e. after deleting the last `FooTest` object). In between, the tests can
|
||||
@ -896,7 +919,8 @@ Note that `SetUpTestSuite()` may be called multiple times for a test fixture
|
||||
class that has derived classes, so you should not expect code in the function
|
||||
body to be run only once. Also, derived classes still have access to shared
|
||||
resources defined as static members, so careful consideration is needed when
|
||||
managing shared resources to avoid memory leaks.
|
||||
managing shared resources to avoid memory leaks if shared resources are not
|
||||
properly cleaned up in `TearDownTestSuite()`.
|
||||
|
||||
Here's an example of per-test-suite set-up and tear-down:
|
||||
|
||||
@ -907,10 +931,15 @@ class FooTest : public testing::Test {
|
||||
// Called before the first test in this test suite.
|
||||
// Can be omitted if not needed.
|
||||
static void SetUpTestSuite() {
|
||||
// Avoid reallocating static objects if called in subclasses of FooTest.
|
||||
if (shared_resource_ == nullptr) {
|
||||
shared_resource_ = new ...;
|
||||
}
|
||||
shared_resource_ = new ...;
|
||||
|
||||
// If `shared_resource_` is **not deleted** in `TearDownTestSuite()`,
|
||||
// reallocation should be prevented because `SetUpTestSuite()` may be called
|
||||
// in subclasses of FooTest and lead to memory leak.
|
||||
//
|
||||
// if (shared_resource_ == nullptr) {
|
||||
// shared_resource_ = new ...;
|
||||
// }
|
||||
}
|
||||
|
||||
// Per-test-suite tear-down.
|
||||
@ -968,24 +997,34 @@ class Environment : public ::testing::Environment {
|
||||
};
|
||||
```
|
||||
|
||||
Then, you register an instance of your environment class with googletest by
|
||||
Then, you register an instance of your environment class with GoogleTest by
|
||||
calling the `::testing::AddGlobalTestEnvironment()` function:
|
||||
|
||||
```c++
|
||||
Environment* AddGlobalTestEnvironment(Environment* env);
|
||||
```
|
||||
|
||||
Now, when `RUN_ALL_TESTS()` is called, it first calls the `SetUp()` method of
|
||||
each environment object, then runs the tests if none of the environments
|
||||
reported fatal failures and `GTEST_SKIP()` was not called. `RUN_ALL_TESTS()`
|
||||
always calls `TearDown()` with each environment object, regardless of whether or
|
||||
not the tests were run.
|
||||
Now, when `RUN_ALL_TESTS()` is invoked, it first calls the `SetUp()` method. The
|
||||
tests are then executed, provided that none of the environments have reported
|
||||
fatal failures and `GTEST_SKIP()` has not been invoked. Finally, `TearDown()` is
|
||||
called.
|
||||
|
||||
Note that `SetUp()` and `TearDown()` are only invoked if there is at least one
|
||||
test to be performed. Importantly, `TearDown()` is executed even if the test is
|
||||
not run due to a fatal failure or `GTEST_SKIP()`.
|
||||
|
||||
Calling `SetUp()` and `TearDown()` for each iteration depends on the flag
|
||||
`gtest_recreate_environments_when_repeating`. `SetUp()` and `TearDown()` are
|
||||
called for each environment object when the object is recreated for each
|
||||
iteration. However, if test environments are not recreated for each iteration,
|
||||
`SetUp()` is called only on the first iteration, and `TearDown()` is called only
|
||||
on the last iteration.
|
||||
|
||||
It's OK to register multiple environment objects. In this suite, their `SetUp()`
|
||||
will be called in the order they are registered, and their `TearDown()` will be
|
||||
called in the reverse order.
|
||||
|
||||
Note that googletest takes ownership of the registered environment objects.
|
||||
Note that GoogleTest takes ownership of the registered environment objects.
|
||||
Therefore **do not delete them** by yourself.
|
||||
|
||||
You should call `AddGlobalTestEnvironment()` before `RUN_ALL_TESTS()` is called,
|
||||
@ -1037,7 +1076,7 @@ they must be declared **public** rather than **protected** in order to use
|
||||
|
||||
```c++
|
||||
class FooTest :
|
||||
public testing::TestWithParam<const char*> {
|
||||
public testing::TestWithParam<absl::string_view> {
|
||||
// You can implement all the usual fixture class members here.
|
||||
// To access the test parameter, call GetParam() from class
|
||||
// TestWithParam<T>.
|
||||
@ -1048,7 +1087,7 @@ class BaseTest : public testing::Test {
|
||||
...
|
||||
};
|
||||
class BarTest : public BaseTest,
|
||||
public testing::WithParamInterface<const char*> {
|
||||
public testing::WithParamInterface<absl::string_view> {
|
||||
...
|
||||
};
|
||||
```
|
||||
@ -1095,6 +1134,11 @@ instantiation of the test suite. The next argument is the name of the test
|
||||
pattern, and the last is the
|
||||
[parameter generator](reference/testing.md#param-generators).
|
||||
|
||||
The parameter generator expression is not evaluated until GoogleTest is
|
||||
initialized (via `InitGoogleTest()`). Any prior initialization done in the
|
||||
`main` function will be accessible from the parameter generator, for example,
|
||||
the results of flag parsing.
|
||||
|
||||
You can instantiate a test pattern more than once, so to distinguish different
|
||||
instances of the pattern, the instantiation name is added as a prefix to the
|
||||
actual test suite name. Remember to pick unique prefixes for different
|
||||
@ -1114,8 +1158,8 @@ with parameter values `"cat"` and `"dog"` using the
|
||||
[`ValuesIn`](reference/testing.md#param-generators) parameter generator:
|
||||
|
||||
```c++
|
||||
const char* pets[] = {"cat", "dog"};
|
||||
INSTANTIATE_TEST_SUITE_P(Pets, FooTest, testing::ValuesIn(pets));
|
||||
constexpr absl::string_view kPets[] = {"cat", "dog"};
|
||||
INSTANTIATE_TEST_SUITE_P(Pets, FooTest, testing::ValuesIn(kPets));
|
||||
```
|
||||
|
||||
The tests from the instantiation above will have these names:
|
||||
@ -1490,12 +1534,12 @@ To test them, we use the following special techniques:
|
||||
|
||||
## "Catching" Failures
|
||||
|
||||
If you are building a testing utility on top of googletest, you'll want to test
|
||||
your utility. What framework would you use to test it? googletest, of course.
|
||||
If you are building a testing utility on top of GoogleTest, you'll want to test
|
||||
your utility. What framework would you use to test it? GoogleTest, of course.
|
||||
|
||||
The challenge is to verify that your testing utility reports failures correctly.
|
||||
In frameworks that report a failure by throwing an exception, you could catch
|
||||
the exception and assert on it. But googletest doesn't use exceptions, so how do
|
||||
the exception and assert on it. But GoogleTest doesn't use exceptions, so how do
|
||||
we test that a piece of code generates an expected failure?
|
||||
|
||||
`"gtest/gtest-spi.h"` contains some constructs to do this.
|
||||
@ -1638,9 +1682,9 @@ particular, you cannot find the test suite name in `SetUpTestSuite()`,
|
||||
`TearDownTestSuite()` (where you know the test suite name implicitly), or
|
||||
functions called from them.
|
||||
|
||||
## Extending googletest by Handling Test Events
|
||||
## Extending GoogleTest by Handling Test Events
|
||||
|
||||
googletest provides an **event listener API** to let you receive notifications
|
||||
GoogleTest provides an **event listener API** to let you receive notifications
|
||||
about the progress of a test program and test failures. The events you can
|
||||
listen to include the start and end of the test program, a test suite, or a test
|
||||
method, among others. You may use this API to augment or replace the standard
|
||||
@ -1701,7 +1745,7 @@ Here's an example:
|
||||
### Using Event Listeners
|
||||
|
||||
To use the event listener you have defined, add an instance of it to the
|
||||
googletest event listener list (represented by class
|
||||
GoogleTest event listener list (represented by class
|
||||
[`TestEventListeners`](reference/testing.md#TestEventListeners) - note the "s"
|
||||
at the end of the name) in your `main()` function, before calling
|
||||
`RUN_ALL_TESTS()`:
|
||||
@ -1712,7 +1756,7 @@ int main(int argc, char** argv) {
|
||||
// Gets hold of the event listener list.
|
||||
testing::TestEventListeners& listeners =
|
||||
testing::UnitTest::GetInstance()->listeners();
|
||||
// Adds a listener to the end. googletest takes the ownership.
|
||||
// Adds a listener to the end. GoogleTest takes the ownership.
|
||||
listeners.Append(new MinimalistPrinter);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@ -1764,7 +1808,7 @@ See [sample10_unittest.cc] for an example of a failure-raising listener.
|
||||
|
||||
## Running Test Programs: Advanced Options
|
||||
|
||||
googletest test programs are ordinary executables. Once built, you can run them
|
||||
GoogleTest test programs are ordinary executables. Once built, you can run them
|
||||
directly and affect their behavior via the following environment variables
|
||||
and/or command line flags. For the flags to work, your programs must call
|
||||
`::testing::InitGoogleTest()` before calling `RUN_ALL_TESTS()`.
|
||||
@ -1797,10 +1841,10 @@ corresponding environment variable for this flag.
|
||||
|
||||
#### Running a Subset of the Tests
|
||||
|
||||
By default, a googletest program runs all tests the user has defined. Sometimes,
|
||||
By default, a GoogleTest program runs all tests the user has defined. Sometimes,
|
||||
you want to run only a subset of the tests (e.g. for debugging or quickly
|
||||
verifying a change). If you set the `GTEST_FILTER` environment variable or the
|
||||
`--gtest_filter` flag to a filter string, googletest will only run the tests
|
||||
`--gtest_filter` flag to a filter string, GoogleTest will only run the tests
|
||||
whose full names (in the form of `TestSuiteName.TestName`) match the filter.
|
||||
|
||||
The format of a filter is a '`:`'-separated list of wildcard patterns (called
|
||||
@ -1831,7 +1875,7 @@ For example:
|
||||
|
||||
#### Stop test execution upon first failure
|
||||
|
||||
By default, a googletest program runs all tests the user has defined. In some
|
||||
By default, a GoogleTest program runs all tests the user has defined. In some
|
||||
cases (e.g. iterative test development & execution) it may be desirable stop
|
||||
test execution upon first failure (trading improved latency for completeness).
|
||||
If `GTEST_FAIL_FAST` environment variable or `--gtest_fail_fast` flag is set,
|
||||
@ -1848,7 +1892,7 @@ If you need to disable all tests in a test suite, you can either add `DISABLED_`
|
||||
to the front of the name of each test, or alternatively add it to the front of
|
||||
the test suite name.
|
||||
|
||||
For example, the following tests won't be run by googletest, even though they
|
||||
For example, the following tests won't be run by GoogleTest, even though they
|
||||
will still be compiled:
|
||||
|
||||
```c++
|
||||
@ -1863,7 +1907,7 @@ TEST_F(DISABLED_BarTest, DoesXyz) { ... }
|
||||
|
||||
{: .callout .note}
|
||||
NOTE: This feature should only be used for temporary pain-relief. You still have
|
||||
to fix the disabled tests at a later date. As a reminder, googletest will print
|
||||
to fix the disabled tests at a later date. As a reminder, GoogleTest will print
|
||||
a banner warning you if a test program contains any disabled tests.
|
||||
|
||||
{: .callout .tip}
|
||||
@ -1908,8 +1952,12 @@ Repeat the tests whose name matches the filter 1000 times.
|
||||
|
||||
If your test program contains
|
||||
[global set-up/tear-down](#global-set-up-and-tear-down) code, it will be
|
||||
repeated in each iteration as well, as the flakiness may be in it. You can also
|
||||
specify the repeat count by setting the `GTEST_REPEAT` environment variable.
|
||||
repeated in each iteration as well, as the flakiness may be in it. To avoid
|
||||
repeating global set-up/tear-down, specify
|
||||
`--gtest_recreate_environments_when_repeating=false`{.nowrap}.
|
||||
|
||||
You can also specify the repeat count by setting the `GTEST_REPEAT` environment
|
||||
variable.
|
||||
|
||||
### Shuffling the Tests
|
||||
|
||||
@ -1917,16 +1965,16 @@ You can specify the `--gtest_shuffle` flag (or set the `GTEST_SHUFFLE`
|
||||
environment variable to `1`) to run the tests in a program in a random order.
|
||||
This helps to reveal bad dependencies between tests.
|
||||
|
||||
By default, googletest uses a random seed calculated from the current time.
|
||||
By default, GoogleTest uses a random seed calculated from the current time.
|
||||
Therefore you'll get a different order every time. The console output includes
|
||||
the random seed value, such that you can reproduce an order-related test failure
|
||||
later. To specify the random seed explicitly, use the `--gtest_random_seed=SEED`
|
||||
flag (or set the `GTEST_RANDOM_SEED` environment variable), where `SEED` is an
|
||||
integer in the range [0, 99999]. The seed value 0 is special: it tells
|
||||
googletest to do the default behavior of calculating the seed from the current
|
||||
GoogleTest to do the default behavior of calculating the seed from the current
|
||||
time.
|
||||
|
||||
If you combine this with `--gtest_repeat=N`, googletest will pick a different
|
||||
If you combine this with `--gtest_repeat=N`, GoogleTest will pick a different
|
||||
random seed and re-shuffle the tests in each iteration.
|
||||
|
||||
### Distributing Test Functions to Multiple Machines
|
||||
@ -1985,7 +2033,7 @@ shards, but here's one possible scenario:
|
||||
|
||||
#### Colored Terminal Output
|
||||
|
||||
googletest can use colors in its terminal output to make it easier to spot the
|
||||
GoogleTest can use colors in its terminal output to make it easier to spot the
|
||||
important information:
|
||||
|
||||
<pre>...
|
||||
@ -2010,25 +2058,25 @@ important information:
|
||||
|
||||
You can set the `GTEST_COLOR` environment variable or the `--gtest_color`
|
||||
command line flag to `yes`, `no`, or `auto` (the default) to enable colors,
|
||||
disable colors, or let googletest decide. When the value is `auto`, googletest
|
||||
disable colors, or let GoogleTest decide. When the value is `auto`, GoogleTest
|
||||
will use colors if and only if the output goes to a terminal and (on non-Windows
|
||||
platforms) the `TERM` environment variable is set to `xterm` or `xterm-color`.
|
||||
|
||||
#### Suppressing test passes
|
||||
|
||||
By default, googletest prints 1 line of output for each test, indicating if it
|
||||
By default, GoogleTest prints 1 line of output for each test, indicating if it
|
||||
passed or failed. To show only test failures, run the test program with
|
||||
`--gtest_brief=1`, or set the GTEST_BRIEF environment variable to `1`.
|
||||
|
||||
#### Suppressing the Elapsed Time
|
||||
|
||||
By default, googletest prints the time it takes to run each test. To disable
|
||||
By default, GoogleTest prints the time it takes to run each test. To disable
|
||||
that, run the test program with the `--gtest_print_time=0` command line flag, or
|
||||
set the GTEST_PRINT_TIME environment variable to `0`.
|
||||
|
||||
#### Suppressing UTF-8 Text Output
|
||||
|
||||
In case of assertion failures, googletest prints expected and actual values of
|
||||
In case of assertion failures, GoogleTest prints expected and actual values of
|
||||
type `string` both as hex-encoded strings as well as in readable UTF-8 text if
|
||||
they contain valid non-ASCII UTF-8 characters. If you want to suppress the UTF-8
|
||||
text because, for example, you don't have an UTF-8 compatible output medium, run
|
||||
@ -2037,7 +2085,7 @@ environment variable to `0`.
|
||||
|
||||
#### Generating an XML Report
|
||||
|
||||
googletest can emit a detailed XML report to a file in addition to its normal
|
||||
GoogleTest can emit a detailed XML report to a file in addition to its normal
|
||||
textual output. The report contains the duration of each test, and thus can help
|
||||
you identify slow tests.
|
||||
|
||||
@ -2048,15 +2096,15 @@ in which case the output can be found in the `test_detail.xml` file in the
|
||||
current directory.
|
||||
|
||||
If you specify a directory (for example, `"xml:output/directory/"` on Linux or
|
||||
`"xml:output\directory\"` on Windows), googletest will create the XML file in
|
||||
`"xml:output\directory\"` on Windows), GoogleTest will create the XML file in
|
||||
that directory, named after the test executable (e.g. `foo_test.xml` for test
|
||||
program `foo_test` or `foo_test.exe`). If the file already exists (perhaps left
|
||||
over from a previous run), googletest will pick a different name (e.g.
|
||||
over from a previous run), GoogleTest will pick a different name (e.g.
|
||||
`foo_test_1.xml`) to avoid overwriting it.
|
||||
|
||||
The report is based on the `junitreport` Ant task. Since that format was
|
||||
originally intended for Java, a little interpretation is required to make it
|
||||
apply to googletest tests, as shown here:
|
||||
apply to GoogleTest tests, as shown here:
|
||||
|
||||
```xml
|
||||
<testsuites name="AllTests" ...>
|
||||
@ -2071,8 +2119,8 @@ apply to googletest tests, as shown here:
|
||||
```
|
||||
|
||||
* The root `<testsuites>` element corresponds to the entire test program.
|
||||
* `<testsuite>` elements correspond to googletest test suites.
|
||||
* `<testcase>` elements correspond to googletest test functions.
|
||||
* `<testsuite>` elements correspond to GoogleTest test suites.
|
||||
* `<testcase>` elements correspond to GoogleTest test functions.
|
||||
|
||||
For instance, the following program
|
||||
|
||||
@ -2105,7 +2153,7 @@ could generate this report:
|
||||
Things to note:
|
||||
|
||||
* The `tests` attribute of a `<testsuites>` or `<testsuite>` element tells how
|
||||
many test functions the googletest program or test suite contains, while the
|
||||
many test functions the GoogleTest program or test suite contains, while the
|
||||
`failures` attribute tells how many of them failed.
|
||||
|
||||
* The `time` attribute expresses the duration of the test, test suite, or
|
||||
@ -2117,12 +2165,12 @@ Things to note:
|
||||
* The `file` and `line` attributes record the source file location, where the
|
||||
test was defined.
|
||||
|
||||
* Each `<failure>` element corresponds to a single failed googletest
|
||||
* Each `<failure>` element corresponds to a single failed GoogleTest
|
||||
assertion.
|
||||
|
||||
#### Generating a JSON Report
|
||||
|
||||
googletest can also emit a JSON report as an alternative format to XML. To
|
||||
GoogleTest can also emit a JSON report as an alternative format to XML. To
|
||||
generate the JSON report, set the `GTEST_OUTPUT` environment variable or the
|
||||
`--gtest_output` flag to the string `"json:path_to_output_file"`, which will
|
||||
create the file at the given location. You can also just use the string
|
||||
@ -2133,7 +2181,7 @@ The report format conforms to the following JSON Schema:
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "http://json-schema.org/schema#",
|
||||
"$schema": "https://json-schema.org/schema#",
|
||||
"type": "object",
|
||||
"definitions": {
|
||||
"TestCase": {
|
||||
@ -2347,7 +2395,7 @@ variable has been set.
|
||||
|
||||
When running test programs under a debugger, it's very convenient if the
|
||||
debugger can catch an assertion failure and automatically drop into interactive
|
||||
mode. googletest's *break-on-failure* mode supports this behavior.
|
||||
mode. GoogleTest's *break-on-failure* mode supports this behavior.
|
||||
|
||||
To enable it, set the `GTEST_BREAK_ON_FAILURE` environment variable to a value
|
||||
other than `0`. Alternatively, you can use the `--gtest_break_on_failure`
|
||||
@ -2355,9 +2403,9 @@ command line flag.
|
||||
|
||||
#### Disabling Catching Test-Thrown Exceptions
|
||||
|
||||
googletest can be used either with or without exceptions enabled. If a test
|
||||
GoogleTest can be used either with or without exceptions enabled. If a test
|
||||
throws a C++ exception or (on Windows) a structured exception (SEH), by default
|
||||
googletest catches it, reports it as a test failure, and continues with the next
|
||||
GoogleTest catches it, reports it as a test failure, and continues with the next
|
||||
test method. This maximizes the coverage of a test run. Also, on Windows an
|
||||
uncaught exception will cause a pop-up window, so catching the exceptions allows
|
||||
you to run the tests automatically.
|
||||
@ -2395,4 +2443,4 @@ void __tsan_on_report() {
|
||||
```
|
||||
|
||||
After compiling your project with one of the sanitizers enabled, if a particular
|
||||
test triggers a sanitizer error, googletest will report that it failed.
|
||||
test triggers a sanitizer error, GoogleTest will report that it failed.
|
||||
|
57
docs/faq.md
57
docs/faq.md
@ -3,7 +3,7 @@
|
||||
## Why should test suite names and test names not contain underscore?
|
||||
|
||||
{: .callout .note}
|
||||
Note: GoogleTest reserves underscore (`_`) for special purpose keywords, such as
|
||||
Note: GoogleTest reserves underscore (`_`) for special-purpose keywords, such as
|
||||
[the `DISABLED_` prefix](advanced.md#temporarily-disabling-tests), in addition
|
||||
to the following rationale.
|
||||
|
||||
@ -33,9 +33,9 @@ contains `_`?
|
||||
`TestSuiteName_Bar__Test`, which is invalid.
|
||||
|
||||
So clearly `TestSuiteName` and `TestName` cannot start or end with `_`
|
||||
(Actually, `TestSuiteName` can start with `_` -- as long as the `_` isn't
|
||||
followed by an upper-case letter. But that's getting complicated. So for
|
||||
simplicity we just say that it cannot start with `_`.).
|
||||
(Actually, `TestSuiteName` can start with `_`—as long as the `_` isn't followed
|
||||
by an upper-case letter. But that's getting complicated. So for simplicity we
|
||||
just say that it cannot start with `_`.).
|
||||
|
||||
It may seem fine for `TestSuiteName` and `TestName` to contain `_` in the
|
||||
middle. However, consider this:
|
||||
@ -128,30 +128,9 @@ both approaches a try. Practice is a much better way to grasp the subtle
|
||||
differences between the two tools. Once you have some concrete experience, you
|
||||
can much more easily decide which one to use the next time.
|
||||
|
||||
## I got some run-time errors about invalid proto descriptors when using `ProtocolMessageEquals`. Help!
|
||||
|
||||
{: .callout .note}
|
||||
**Note:** `ProtocolMessageEquals` and `ProtocolMessageEquiv` are *deprecated*
|
||||
now. Please use `EqualsProto`, etc instead.
|
||||
|
||||
`ProtocolMessageEquals` and `ProtocolMessageEquiv` were redefined recently and
|
||||
are now less tolerant of invalid protocol buffer definitions. In particular, if
|
||||
you have a `foo.proto` that doesn't fully qualify the type of a protocol message
|
||||
it references (e.g. `message<Bar>` where it should be `message<blah.Bar>`), you
|
||||
will now get run-time errors like:
|
||||
|
||||
```
|
||||
... descriptor.cc:...] Invalid proto descriptor for file "path/to/foo.proto":
|
||||
... descriptor.cc:...] blah.MyMessage.my_field: ".Bar" is not defined.
|
||||
```
|
||||
|
||||
If you see this, your `.proto` file is broken and needs to be fixed by making
|
||||
the types fully qualified. The new definition of `ProtocolMessageEquals` and
|
||||
`ProtocolMessageEquiv` just happen to reveal your bug.
|
||||
|
||||
## My death test modifies some state, but the change seems lost after the death test finishes. Why?
|
||||
|
||||
Death tests (`EXPECT_DEATH`, etc) are executed in a sub-process s.t. the
|
||||
Death tests (`EXPECT_DEATH`, etc.) are executed in a sub-process s.t. the
|
||||
expected crash won't kill the test program (i.e. the parent process). As a
|
||||
result, any in-memory side effects they incur are observable in their respective
|
||||
sub-processes, but not in the parent process. You can think of them as running
|
||||
@ -192,16 +171,16 @@ class Foo {
|
||||
};
|
||||
```
|
||||
|
||||
You also need to define it *outside* of the class body in `foo.cc`:
|
||||
you also need to define it *outside* of the class body in `foo.cc`:
|
||||
|
||||
```c++
|
||||
const int Foo::kBar; // No initializer here.
|
||||
```
|
||||
|
||||
Otherwise your code is **invalid C++**, and may break in unexpected ways. In
|
||||
particular, using it in GoogleTest comparison assertions (`EXPECT_EQ`, etc) will
|
||||
generate an "undefined reference" linker error. The fact that "it used to work"
|
||||
doesn't mean it's valid. It just means that you were lucky. :-)
|
||||
particular, using it in GoogleTest comparison assertions (`EXPECT_EQ`, etc.)
|
||||
will generate an "undefined reference" linker error. The fact that "it used to
|
||||
work" doesn't mean it's valid. It just means that you were lucky. :-)
|
||||
|
||||
If the declaration of the static data member is `constexpr` then it is
|
||||
implicitly an `inline` definition, and a separate definition in `foo.cc` is not
|
||||
@ -311,7 +290,7 @@ a **fresh** test fixture object, immediately call `SetUp()`, run the test body,
|
||||
call `TearDown()`, and then delete the test fixture object.
|
||||
|
||||
When you need to write per-test set-up and tear-down logic, you have the choice
|
||||
between using the test fixture constructor/destructor or `SetUp()/TearDown()`.
|
||||
between using the test fixture constructor/destructor or `SetUp()`/`TearDown()`.
|
||||
The former is usually preferred, as it has the following benefits:
|
||||
|
||||
* By initializing a member variable in the constructor, we have the option to
|
||||
@ -352,7 +331,7 @@ You may still want to use `SetUp()/TearDown()` in the following cases:
|
||||
GoogleTest assertions in a destructor if your code could run on such a
|
||||
platform.
|
||||
|
||||
## The compiler complains "no matching function to call" when I use ASSERT_PRED*. How do I fix it?
|
||||
## The compiler complains "no matching function to call" when I use `ASSERT_PRED*`. How do I fix it?
|
||||
|
||||
See details for [`EXPECT_PRED*`](reference/assertions.md#EXPECT_PRED) in the
|
||||
Assertions Reference.
|
||||
@ -410,7 +389,7 @@ C++ is case-sensitive. Did you spell it as `Setup()`?
|
||||
Similarly, sometimes people spell `SetUpTestSuite()` as `SetupTestSuite()` and
|
||||
wonder why it's never called.
|
||||
|
||||
## I have several test suites which share the same test fixture logic, do I have to define a new test fixture class for each of them? This seems pretty tedious.
|
||||
## I have several test suites which share the same test fixture logic; do I have to define a new test fixture class for each of them? This seems pretty tedious.
|
||||
|
||||
You don't have to. Instead of
|
||||
|
||||
@ -545,7 +524,7 @@ The new NPTL thread library doesn't suffer from this problem, as it doesn't
|
||||
create a manager thread. However, if you don't control which machine your test
|
||||
runs on, you shouldn't depend on this.
|
||||
|
||||
## Why does GoogleTest require the entire test suite, instead of individual tests, to be named *DeathTest when it uses ASSERT_DEATH?
|
||||
## Why does GoogleTest require the entire test suite, instead of individual tests, to be named `*DeathTest` when it uses `ASSERT_DEATH`?
|
||||
|
||||
GoogleTest does not interleave tests from different test suites. That is, it
|
||||
runs all tests in one test suite first, and then runs all tests in the next test
|
||||
@ -570,7 +549,7 @@ interleave tests from different test suites, we need to run all tests in the
|
||||
`FooTest` case before running any test in the `BarTest` case. This contradicts
|
||||
with the requirement to run `BarTest.DefDeathTest` before `FooTest.Uvw`.
|
||||
|
||||
## But I don't like calling my entire test suite \*DeathTest when it contains both death tests and non-death tests. What do I do?
|
||||
## But I don't like calling my entire test suite `*DeathTest` when it contains both death tests and non-death tests. What do I do?
|
||||
|
||||
You don't have to, but if you like, you may split up the test suite into
|
||||
`FooTest` and `FooDeathTest`, where the names make it clear that they are
|
||||
@ -607,7 +586,7 @@ defined such that we can print a value of `FooType`.
|
||||
|
||||
In addition, if `FooType` is declared in a name space, the `<<` operator also
|
||||
needs to be defined in the *same* name space. See
|
||||
[Tip of the Week #49](http://abseil.io/tips/49) for details.
|
||||
[Tip of the Week #49](https://abseil.io/tips/49) for details.
|
||||
|
||||
## How do I suppress the memory leak messages on Windows?
|
||||
|
||||
@ -628,10 +607,10 @@ mistake in production. Such cleverness also leads to
|
||||
advise against the practice, and GoogleTest doesn't provide a way to do it.
|
||||
|
||||
In general, the recommended way to cause the code to behave differently under
|
||||
test is [Dependency Injection](http://en.wikipedia.org/wiki/Dependency_injection). You can inject
|
||||
test is [Dependency Injection](https://en.wikipedia.org/wiki/Dependency_injection). You can inject
|
||||
different functionality from the test and from the production code. Since your
|
||||
production code doesn't link in the for-test logic at all (the
|
||||
[`testonly`](http://docs.bazel.build/versions/master/be/common-definitions.html#common.testonly) attribute for BUILD targets helps to ensure
|
||||
[`testonly`](https://docs.bazel.build/versions/master/be/common-definitions.html#common.testonly) attribute for BUILD targets helps to ensure
|
||||
that), there is no danger in accidentally running it.
|
||||
|
||||
However, if you *really*, *really*, *really* have no choice, and if you follow
|
||||
@ -654,7 +633,7 @@ the `--gtest_also_run_disabled_tests` flag.
|
||||
Yes.
|
||||
|
||||
The rule is **all test methods in the same test suite must use the same fixture
|
||||
class.** This means that the following is **allowed** because both tests use the
|
||||
class**. This means that the following is **allowed** because both tests use the
|
||||
same fixture class (`::testing::Test`).
|
||||
|
||||
```c++
|
||||
|
@ -20,7 +20,7 @@ class Foo {
|
||||
(note that `~Foo()` **must** be virtual) we can define its mock as
|
||||
|
||||
```cpp
|
||||
#include "gmock/gmock.h"
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
class MockFoo : public Foo {
|
||||
public:
|
||||
@ -140,7 +140,7 @@ To customize the default action for functions with return type `T`, use
|
||||
// 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); });
|
||||
[] { return std::make_unique<Buzz>(AccessLevel::kInternal); });
|
||||
|
||||
// When this fires, the default action of MakeBuzz() will run, which
|
||||
// will return a new Buzz object.
|
||||
|
@ -285,6 +285,10 @@ If you are concerned about the performance overhead incurred by virtual
|
||||
functions, and profiling confirms your concern, you can combine this with the
|
||||
recipe for [mocking non-virtual methods](#MockingNonVirtualMethods).
|
||||
|
||||
Alternatively, instead of introducing a new interface, you can rewrite your code
|
||||
to accept a std::function instead of the free function, and then use
|
||||
[MockFunction](#MockFunction) to mock the std::function.
|
||||
|
||||
### Old-Style `MOCK_METHODn` Macros
|
||||
|
||||
Before the generic `MOCK_METHOD` macro
|
||||
@ -693,9 +697,9 @@ TEST(AbcTest, Xyz) {
|
||||
EXPECT_CALL(foo, DoThat(_, _));
|
||||
|
||||
int n = 0;
|
||||
EXPECT_EQ('+', foo.DoThis(5)); // FakeFoo::DoThis() is invoked.
|
||||
EXPECT_EQ(foo.DoThis(5), '+'); // FakeFoo::DoThis() is invoked.
|
||||
foo.DoThat("Hi", &n); // FakeFoo::DoThat() is invoked.
|
||||
EXPECT_EQ(2, n);
|
||||
EXPECT_EQ(n, 2);
|
||||
}
|
||||
```
|
||||
|
||||
@ -904,7 +908,7 @@ using ::testing::Contains;
|
||||
using ::testing::Property;
|
||||
|
||||
inline constexpr auto HasFoo = [](const auto& f) {
|
||||
return Property(&MyClass::foo, Contains(f));
|
||||
return Property("foo", &MyClass::foo, Contains(f));
|
||||
};
|
||||
...
|
||||
EXPECT_THAT(x, HasFoo("blah"));
|
||||
@ -1125,11 +1129,11 @@ using STL's `<functional>` header is just painful). For example, here's a
|
||||
predicate that's satisfied by any number that is >= 0, <= 100, and != 50:
|
||||
|
||||
```cpp
|
||||
using testing::AllOf;
|
||||
using testing::Ge;
|
||||
using testing::Le;
|
||||
using testing::Matches;
|
||||
using testing::Ne;
|
||||
using ::testing::AllOf;
|
||||
using ::testing::Ge;
|
||||
using ::testing::Le;
|
||||
using ::testing::Matches;
|
||||
using ::testing::Ne;
|
||||
...
|
||||
Matches(AllOf(Ge(0), Le(100), Ne(50)))
|
||||
```
|
||||
@ -1158,7 +1162,7 @@ int IsEven(int n) { return (n % 2) == 0 ? 1 : 0; }
|
||||
```
|
||||
|
||||
Note that the predicate function / functor doesn't have to return `bool`. It
|
||||
works as long as the return value can be used as the condition in in statement
|
||||
works as long as the return value can be used as the condition in the statement
|
||||
`if (condition) ...`.
|
||||
|
||||
### Matching Arguments that Are Not Copyable
|
||||
@ -1345,7 +1349,7 @@ class BarPlusBazEqMatcher {
|
||||
|
||||
...
|
||||
Foo foo;
|
||||
EXPECT_CALL(foo, BarPlusBazEq(5))...;
|
||||
EXPECT_THAT(foo, BarPlusBazEq(5))...;
|
||||
```
|
||||
|
||||
### Matching Containers
|
||||
@ -1424,11 +1428,12 @@ Use `Pair` when comparing maps or other associative containers.
|
||||
{% raw %}
|
||||
|
||||
```cpp
|
||||
using testing::ElementsAre;
|
||||
using testing::Pair;
|
||||
using ::testing::UnorderedElementsAre;
|
||||
using ::testing::Pair;
|
||||
...
|
||||
std::map<string, int> m = {{"a", 1}, {"b", 2}, {"c", 3}};
|
||||
EXPECT_THAT(m, ElementsAre(Pair("a", 1), Pair("b", 2), Pair("c", 3)));
|
||||
absl::flat_hash_map<string, int> m = {{"a", 1}, {"b", 2}, {"c", 3}};
|
||||
EXPECT_THAT(m, UnorderedElementsAre(
|
||||
Pair("a", 1), Pair("b", 2), Pair("c", 3)));
|
||||
```
|
||||
|
||||
{% endraw %}
|
||||
@ -1445,8 +1450,8 @@ using testing::Pair;
|
||||
* If the container is passed by pointer instead of by reference, just write
|
||||
`Pointee(ElementsAre*(...))`.
|
||||
* The order of elements *matters* for `ElementsAre*()`. If you are using it
|
||||
with containers whose element order are undefined (e.g. `hash_map`) you
|
||||
should use `WhenSorted` around `ElementsAre`.
|
||||
with containers whose element order are undefined (such as a
|
||||
`std::unordered_map`) you should use `UnorderedElementsAre`.
|
||||
|
||||
### Sharing Matchers
|
||||
|
||||
@ -1856,7 +1861,7 @@ error. So, what shall you do?
|
||||
Though you may be tempted, DO NOT use `std::ref()`:
|
||||
|
||||
```cpp
|
||||
using testing::Return;
|
||||
using ::testing::Return;
|
||||
|
||||
class MockFoo : public Foo {
|
||||
public:
|
||||
@ -1868,7 +1873,7 @@ class MockFoo : public Foo {
|
||||
EXPECT_CALL(foo, GetValue())
|
||||
.WillRepeatedly(Return(std::ref(x))); // Wrong!
|
||||
x = 42;
|
||||
EXPECT_EQ(42, foo.GetValue());
|
||||
EXPECT_EQ(foo.GetValue(), 42);
|
||||
```
|
||||
|
||||
Unfortunately, it doesn't work here. The above code will fail with error:
|
||||
@ -1890,20 +1895,20 @@ the expectation is set, and `Return(std::ref(x))` will always return 0.
|
||||
returns the value pointed to by `pointer` at the time the action is *executed*:
|
||||
|
||||
```cpp
|
||||
using testing::ReturnPointee;
|
||||
using ::testing::ReturnPointee;
|
||||
...
|
||||
int x = 0;
|
||||
MockFoo foo;
|
||||
EXPECT_CALL(foo, GetValue())
|
||||
.WillRepeatedly(ReturnPointee(&x)); // Note the & here.
|
||||
x = 42;
|
||||
EXPECT_EQ(42, foo.GetValue()); // This will succeed now.
|
||||
EXPECT_EQ(foo.GetValue(), 42); // This will succeed now.
|
||||
```
|
||||
|
||||
### Combining Actions
|
||||
|
||||
Want to do more than one thing when a function is called? That's fine. `DoAll()`
|
||||
allow you to do sequence of actions every time. Only the return value of the
|
||||
allows you to do a sequence of actions every time. Only the return value of the
|
||||
last action in the sequence will be used.
|
||||
|
||||
```cpp
|
||||
@ -1922,6 +1927,12 @@ class MockFoo : public Foo {
|
||||
action_n));
|
||||
```
|
||||
|
||||
The return value of the last action **must** match the return type of the mocked
|
||||
method. In the example above, `action_n` could be `Return(true)`, or a lambda
|
||||
that returns a `bool`, but not `SaveArg`, which returns `void`. Otherwise the
|
||||
signature of `DoAll` would not match the signature expected by `WillOnce`, which
|
||||
is the signature of the mocked method, and it wouldn't compile.
|
||||
|
||||
### Verifying Complex Arguments {#SaveArgVerify}
|
||||
|
||||
If you want to verify that a method is called with a particular argument but the
|
||||
@ -2259,7 +2270,7 @@ TEST_F(FooTest, Test) {
|
||||
|
||||
EXPECT_CALL(foo, DoThis(2))
|
||||
.WillOnce(Invoke(NewPermanentCallback(SignOfSum, 5)));
|
||||
EXPECT_EQ('+', foo.DoThis(2)); // Invokes SignOfSum(5, 2).
|
||||
EXPECT_EQ(foo.DoThis(2), '+'); // Invokes SignOfSum(5, 2).
|
||||
}
|
||||
```
|
||||
|
||||
@ -2635,8 +2646,8 @@ action will exhibit different behaviors. Example:
|
||||
.WillRepeatedly(IncrementCounter(0));
|
||||
foo.DoThis(); // Returns 1.
|
||||
foo.DoThis(); // Returns 2.
|
||||
foo.DoThat(); // Returns 1 - Blah() uses a different
|
||||
// counter than Bar()'s.
|
||||
foo.DoThat(); // Returns 1 - DoThat() uses a different
|
||||
// counter than DoThis()'s.
|
||||
```
|
||||
|
||||
versus
|
||||
@ -2766,36 +2777,33 @@ returns a null `unique_ptr`, that’s what you’ll get if you don’t specify a
|
||||
action:
|
||||
|
||||
```cpp
|
||||
using ::testing::IsNull;
|
||||
...
|
||||
// Use the default action.
|
||||
EXPECT_CALL(mock_buzzer_, MakeBuzz("hello"));
|
||||
|
||||
// Triggers the previous EXPECT_CALL.
|
||||
EXPECT_EQ(nullptr, mock_buzzer_.MakeBuzz("hello"));
|
||||
EXPECT_THAT(mock_buzzer_.MakeBuzz("hello"), IsNull());
|
||||
```
|
||||
|
||||
If you are not happy with the default action, you can tweak it as usual; see
|
||||
[Setting Default Actions](#OnCall).
|
||||
|
||||
If you just need to return a pre-defined move-only value, you can use the
|
||||
`Return(ByMove(...))` action:
|
||||
If you just need to return a move-only value, you can use it in combination with
|
||||
`WillOnce`. For example:
|
||||
|
||||
```cpp
|
||||
// When this fires, the unique_ptr<> specified by ByMove(...) will
|
||||
// be returned.
|
||||
EXPECT_CALL(mock_buzzer_, MakeBuzz("world"))
|
||||
.WillOnce(Return(ByMove(MakeUnique<Buzz>(AccessLevel::kInternal))));
|
||||
|
||||
EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("world"));
|
||||
EXPECT_CALL(mock_buzzer_, MakeBuzz("hello"))
|
||||
.WillOnce(Return(std::make_unique<Buzz>(AccessLevel::kInternal)));
|
||||
EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("hello"));
|
||||
```
|
||||
|
||||
Note that `ByMove()` is essential here - if you drop it, the code won’t compile.
|
||||
|
||||
Quiz time! What do you think will happen if a `Return(ByMove(...))` action is
|
||||
performed more than once (e.g. you write `...
|
||||
.WillRepeatedly(Return(ByMove(...)));`)? Come think of it, after the first time
|
||||
the action runs, the source value will be consumed (since it’s a move-only
|
||||
value), so the next time around, there’s no value to move from -- you’ll get a
|
||||
run-time error that `Return(ByMove(...))` can only be run once.
|
||||
Quiz time! What do you think will happen if a `Return` action is performed more
|
||||
than once (e.g. you write `... .WillRepeatedly(Return(std::move(...)));`)? Come
|
||||
think of it, after the first time the action runs, the source value will be
|
||||
consumed (since it’s a move-only value), so the next time around, there’s no
|
||||
value to move from -- you’ll get a run-time error that `Return(std::move(...))`
|
||||
can only be run once.
|
||||
|
||||
If you need your mock method to do more than just moving a pre-defined value,
|
||||
remember that you can always use a lambda or a callable object, which can do
|
||||
@ -2804,7 +2812,7 @@ pretty much anything you want:
|
||||
```cpp
|
||||
EXPECT_CALL(mock_buzzer_, MakeBuzz("x"))
|
||||
.WillRepeatedly([](StringPiece text) {
|
||||
return MakeUnique<Buzz>(AccessLevel::kInternal);
|
||||
return std::make_unique<Buzz>(AccessLevel::kInternal);
|
||||
});
|
||||
|
||||
EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("x"));
|
||||
@ -2812,7 +2820,7 @@ pretty much anything you want:
|
||||
```
|
||||
|
||||
Every time this `EXPECT_CALL` fires, a new `unique_ptr<Buzz>` will be created
|
||||
and returned. You cannot do this with `Return(ByMove(...))`.
|
||||
and returned. You cannot do this with `Return(std::make_unique<...>(...))`.
|
||||
|
||||
That covers returning move-only values; but how do we work with methods
|
||||
accepting move-only arguments? The answer is that they work normally, although
|
||||
@ -2823,7 +2831,7 @@ can always use `Return`, or a [lambda or functor](#FunctionsAsActions):
|
||||
using ::testing::Unused;
|
||||
|
||||
EXPECT_CALL(mock_buzzer_, ShareBuzz(NotNull(), _)).WillOnce(Return(true));
|
||||
EXPECT_TRUE(mock_buzzer_.ShareBuzz(MakeUnique<Buzz>(AccessLevel::kInternal)),
|
||||
EXPECT_TRUE(mock_buzzer_.ShareBuzz(std::make_unique<Buzz>(AccessLevel::kInternal)),
|
||||
0);
|
||||
|
||||
EXPECT_CALL(mock_buzzer_, ShareBuzz(_, _)).WillOnce(
|
||||
@ -2867,7 +2875,7 @@ method:
|
||||
// When one calls ShareBuzz() on the MockBuzzer like this, the call is
|
||||
// forwarded to DoShareBuzz(), which is mocked. Therefore this statement
|
||||
// will trigger the above EXPECT_CALL.
|
||||
mock_buzzer_.ShareBuzz(MakeUnique<Buzz>(AccessLevel::kInternal), 0);
|
||||
mock_buzzer_.ShareBuzz(std::make_unique<Buzz>(AccessLevel::kInternal), 0);
|
||||
```
|
||||
|
||||
### Making the Compilation Faster
|
||||
@ -3192,11 +3200,11 @@ You can unlock this power by running your test with the `--gmock_verbose=info`
|
||||
flag. For example, given the test program:
|
||||
|
||||
```cpp
|
||||
#include "gmock/gmock.h"
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
using testing::_;
|
||||
using testing::HasSubstr;
|
||||
using testing::Return;
|
||||
using ::testing::_;
|
||||
using ::testing::HasSubstr;
|
||||
using ::testing::Return;
|
||||
|
||||
class MockFoo {
|
||||
public:
|
||||
@ -3817,15 +3825,15 @@ If the built-in actions don't work for you, you can easily define your own one.
|
||||
All you need is a call operator with a signature compatible with the mocked
|
||||
function. So you can use a lambda:
|
||||
|
||||
```
|
||||
```cpp
|
||||
MockFunction<int(int)> mock;
|
||||
EXPECT_CALL(mock, Call).WillOnce([](const int input) { return input * 7; });
|
||||
EXPECT_EQ(14, mock.AsStdFunction()(2));
|
||||
EXPECT_EQ(mock.AsStdFunction()(2), 14);
|
||||
```
|
||||
|
||||
Or a struct with a call operator (even a templated one):
|
||||
|
||||
```
|
||||
```cpp
|
||||
struct MultiplyBy {
|
||||
template <typename T>
|
||||
T operator()(T arg) { return arg * multiplier; }
|
||||
@ -3840,16 +3848,16 @@ struct MultiplyBy {
|
||||
It's also fine for the callable to take no arguments, ignoring the arguments
|
||||
supplied to the mock function:
|
||||
|
||||
```
|
||||
```cpp
|
||||
MockFunction<int(int)> mock;
|
||||
EXPECT_CALL(mock, Call).WillOnce([] { return 17; });
|
||||
EXPECT_EQ(17, mock.AsStdFunction()(0));
|
||||
EXPECT_EQ(mock.AsStdFunction()(0), 17);
|
||||
```
|
||||
|
||||
When used with `WillOnce`, the callable can assume it will be called at most
|
||||
once and is allowed to be a move-only type:
|
||||
|
||||
```
|
||||
```cpp
|
||||
// An action that contains move-only types and has an &&-qualified operator,
|
||||
// demanding in the type system that it be called at most once. This can be
|
||||
// used with WillOnce, but the compiler will reject it if handed to
|
||||
@ -4293,7 +4301,7 @@ particular type than to dump the bytes.
|
||||
### Mock std::function {#MockFunction}
|
||||
|
||||
`std::function` is a general function type introduced in C++11. It is a
|
||||
preferred way of passing callbacks to new interfaces. Functions are copiable,
|
||||
preferred way of passing callbacks to new interfaces. Functions are copyable,
|
||||
and are not usually passed around by pointer, which makes them tricky to mock.
|
||||
But fear not - `MockFunction` can help you with that.
|
||||
|
||||
|
@ -90,14 +90,14 @@ gMock is bundled with googletest.
|
||||
## A Case for Mock Turtles
|
||||
|
||||
Let's look at an example. Suppose you are developing a graphics program that
|
||||
relies on a [LOGO](http://en.wikipedia.org/wiki/Logo_programming_language)-like
|
||||
relies on a [LOGO](https://en.wikipedia.org/wiki/Logo_programming_language)-like
|
||||
API for drawing. How would you test that it does the right thing? Well, you can
|
||||
run it and compare the screen with a golden screen snapshot, but let's admit it:
|
||||
tests like this are expensive to run and fragile (What if you just upgraded to a
|
||||
shiny new graphics card that has better anti-aliasing? Suddenly you have to
|
||||
update all your golden images.). It would be too painful if all your tests are
|
||||
like this. Fortunately, you learned about
|
||||
[Dependency Injection](http://en.wikipedia.org/wiki/Dependency_injection) and know the right thing
|
||||
[Dependency Injection](https://en.wikipedia.org/wiki/Dependency_injection) and know the right thing
|
||||
to do: instead of having your application talk to the system API directly, wrap
|
||||
the API in an interface (say, `Turtle`) and code to that interface:
|
||||
|
||||
@ -164,7 +164,7 @@ follow:
|
||||
After the process, you should have something like:
|
||||
|
||||
```cpp
|
||||
#include "gmock/gmock.h" // Brings in gMock.
|
||||
#include <gmock/gmock.h> // Brings in gMock.
|
||||
|
||||
class MockTurtle : public Turtle {
|
||||
public:
|
||||
@ -224,8 +224,8 @@ Here's an example:
|
||||
|
||||
```cpp
|
||||
#include "path/to/mock-turtle.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using ::testing::AtLeast; // #1
|
||||
|
||||
@ -261,6 +261,8 @@ happen. Therefore it's a good idea to turn on the heap checker in your tests
|
||||
when you allocate mocks on the heap. You get that automatically if you use the
|
||||
`gtest_main` library already.
|
||||
|
||||
###### Expectation Ordering
|
||||
|
||||
**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
|
||||
|
@ -19,19 +19,15 @@ examples here we assume you want to compile the sample
|
||||
Using `pkg-config` in CMake is fairly easy:
|
||||
|
||||
```cmake
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
cmake_policy(SET CMP0048 NEW)
|
||||
project(my_gtest_pkgconfig VERSION 0.0.1 LANGUAGES CXX)
|
||||
|
||||
find_package(PkgConfig)
|
||||
pkg_search_module(GTEST REQUIRED gtest_main)
|
||||
|
||||
add_executable(testapp samples/sample3_unittest.cc)
|
||||
target_link_libraries(testapp ${GTEST_LDFLAGS})
|
||||
target_compile_options(testapp PUBLIC ${GTEST_CFLAGS})
|
||||
add_executable(testapp)
|
||||
target_sources(testapp PRIVATE samples/sample3_unittest.cc)
|
||||
target_link_libraries(testapp PRIVATE ${GTEST_LDFLAGS})
|
||||
target_compile_options(testapp PRIVATE ${GTEST_CFLAGS})
|
||||
|
||||
include(CTest)
|
||||
enable_testing()
|
||||
add_test(first_and_only_test testapp)
|
||||
```
|
||||
|
||||
|
@ -1,35 +1,8 @@
|
||||
# Supported Platforms
|
||||
|
||||
GoogleTest requires a codebase and compiler compliant with the C++11 standard or
|
||||
newer.
|
||||
|
||||
The GoogleTest code is officially supported on the following platforms.
|
||||
Operating systems or tools not listed below are community-supported. For
|
||||
community-supported platforms, patches that do not complicate the code may be
|
||||
considered.
|
||||
|
||||
If you notice any problems on your platform, please file an issue on the
|
||||
[GoogleTest GitHub Issue Tracker](https://github.com/google/googletest/issues).
|
||||
Pull requests containing fixes are welcome!
|
||||
|
||||
### Operating systems
|
||||
|
||||
* Linux
|
||||
* macOS
|
||||
* Windows
|
||||
|
||||
### Compilers
|
||||
|
||||
* gcc 5.0+
|
||||
* clang 5.0+
|
||||
* MSVC 2015+
|
||||
|
||||
**macOS users:** Xcode 9.3+ provides clang 5.0+.
|
||||
|
||||
### Build systems
|
||||
|
||||
* [Bazel](https://bazel.build/)
|
||||
* [CMake](https://cmake.org/)
|
||||
|
||||
Bazel is the build system used by the team internally and in tests. CMake is
|
||||
supported on a best-effort basis and by the community.
|
||||
GoogleTest follows Google's
|
||||
[Foundational C++ Support Policy](https://opensource.google/documentation/policies/cplusplus-support).
|
||||
See
|
||||
[this table](https://github.com/google/oss-policies-info/blob/main/foundational-cxx-support-matrix.md)
|
||||
for a list of currently supported versions compilers, platforms, and build
|
||||
tools.
|
||||
|
132
docs/primer.md
132
docs/primer.md
@ -1,84 +1,84 @@
|
||||
# Googletest Primer
|
||||
# GoogleTest Primer
|
||||
|
||||
## Introduction: Why googletest?
|
||||
## Introduction: Why GoogleTest?
|
||||
|
||||
*googletest* helps you write better C++ tests.
|
||||
*GoogleTest* helps you write better C++ tests.
|
||||
|
||||
googletest is a testing framework developed by the Testing Technology team with
|
||||
GoogleTest is a testing framework developed by the Testing Technology team with
|
||||
Google's specific requirements and constraints in mind. Whether you work on
|
||||
Linux, Windows, or a Mac, if you write C++ code, googletest can help you. And it
|
||||
Linux, Windows, or a Mac, if you write C++ code, GoogleTest can help you. And it
|
||||
supports *any* kind of tests, not just unit tests.
|
||||
|
||||
So what makes a good test, and how does googletest fit in? We believe:
|
||||
So what makes a good test, and how does GoogleTest fit in? We believe:
|
||||
|
||||
1. Tests should be *independent* and *repeatable*. It's a pain to debug a test
|
||||
that succeeds or fails as a result of other tests. googletest isolates the
|
||||
that succeeds or fails as a result of other tests. GoogleTest isolates the
|
||||
tests by running each of them on a different object. When a test fails,
|
||||
googletest allows you to run it in isolation for quick debugging.
|
||||
GoogleTest allows you to run it in isolation for quick debugging.
|
||||
2. Tests should be well *organized* and reflect the structure of the tested
|
||||
code. googletest groups related tests into test suites that can share data
|
||||
code. GoogleTest groups related tests into test suites that can share data
|
||||
and subroutines. This common pattern is easy to recognize and makes tests
|
||||
easy to maintain. Such consistency is especially helpful when people switch
|
||||
projects and start to work on a new code base.
|
||||
3. Tests should be *portable* and *reusable*. Google has a lot of code that is
|
||||
platform-neutral; its tests should also be platform-neutral. googletest
|
||||
platform-neutral; its tests should also be platform-neutral. GoogleTest
|
||||
works on different OSes, with different compilers, with or without
|
||||
exceptions, so googletest tests can work with a variety of configurations.
|
||||
exceptions, so GoogleTest tests can work with a variety of configurations.
|
||||
4. When tests fail, they should provide as much *information* about the problem
|
||||
as possible. googletest doesn't stop at the first test failure. Instead, it
|
||||
as possible. GoogleTest doesn't stop at the first test failure. Instead, it
|
||||
only stops the current test and continues with the next. You can also set up
|
||||
tests that report non-fatal failures after which the current test continues.
|
||||
Thus, you can detect and fix multiple bugs in a single run-edit-compile
|
||||
cycle.
|
||||
5. The testing framework should liberate test writers from housekeeping chores
|
||||
and let them focus on the test *content*. googletest automatically keeps
|
||||
and let them focus on the test *content*. GoogleTest automatically keeps
|
||||
track of all tests defined, and doesn't require the user to enumerate them
|
||||
in order to run them.
|
||||
6. Tests should be *fast*. With googletest, you can reuse shared resources
|
||||
6. Tests should be *fast*. With GoogleTest, you can reuse shared resources
|
||||
across tests and pay for the set-up/tear-down only once, without making
|
||||
tests depend on each other.
|
||||
|
||||
Since googletest is based on the popular xUnit architecture, you'll feel right
|
||||
Since GoogleTest is based on the popular xUnit architecture, you'll feel right
|
||||
at home if you've used JUnit or PyUnit before. If not, it will take you about 10
|
||||
minutes to learn the basics and get started. So let's go!
|
||||
|
||||
## Beware of the nomenclature
|
||||
## Beware of the Nomenclature
|
||||
|
||||
{: .callout .note}
|
||||
_Note:_ There might be some confusion arising from different definitions of the
|
||||
terms _Test_, _Test Case_ and _Test Suite_, so beware of misunderstanding these.
|
||||
*Note:* There might be some confusion arising from different definitions of the
|
||||
terms *Test*, *Test Case* and *Test Suite*, so beware of misunderstanding these.
|
||||
|
||||
Historically, googletest started to use the term _Test Case_ for grouping
|
||||
Historically, GoogleTest started to use the term *Test Case* for grouping
|
||||
related tests, whereas current publications, including International Software
|
||||
Testing Qualifications Board ([ISTQB](http://www.istqb.org/)) materials and
|
||||
Testing Qualifications Board ([ISTQB](https://www.istqb.org/)) materials and
|
||||
various textbooks on software quality, use the term
|
||||
_[Test Suite][istqb test suite]_ for this.
|
||||
*[Test Suite][istqb test suite]* for this.
|
||||
|
||||
The related term _Test_, as it is used in googletest, corresponds to the term
|
||||
_[Test Case][istqb test case]_ of ISTQB and others.
|
||||
The related term *Test*, as it is used in GoogleTest, corresponds to the term
|
||||
*[Test Case][istqb test case]* of ISTQB and others.
|
||||
|
||||
The term _Test_ is commonly of broad enough sense, including ISTQB's definition
|
||||
of _Test Case_, so it's not much of a problem here. But the term _Test Case_ as
|
||||
The term *Test* is commonly of broad enough sense, including ISTQB's definition
|
||||
of *Test Case*, so it's not much of a problem here. But the term *Test Case* as
|
||||
was used in Google Test is of contradictory sense and thus confusing.
|
||||
|
||||
googletest recently started replacing the term _Test Case_ with _Test Suite_.
|
||||
GoogleTest recently started replacing the term *Test Case* with *Test Suite*.
|
||||
The preferred API is *TestSuite*. The older TestCase API is being slowly
|
||||
deprecated and refactored away.
|
||||
|
||||
So please be aware of the different definitions of the terms:
|
||||
|
||||
|
||||
Meaning | googletest Term | [ISTQB](http://www.istqb.org/) Term
|
||||
Meaning | GoogleTest Term | [ISTQB](https://www.istqb.org/) Term
|
||||
:----------------------------------------------------------------------------------- | :---------------------- | :----------------------------------
|
||||
Exercise a particular program path with specific input values and verify the results | [TEST()](#simple-tests) | [Test Case][istqb test case]
|
||||
|
||||
|
||||
[istqb test case]: http://glossary.istqb.org/en/search/test%20case
|
||||
[istqb test suite]: http://glossary.istqb.org/en/search/test%20suite
|
||||
[istqb test case]: https://glossary.istqb.org/en_US/term/test-case-2
|
||||
[istqb test suite]: https://glossary.istqb.org/en_US/term/test-suite-1-3
|
||||
|
||||
## Basic Concepts
|
||||
|
||||
When using googletest, you start by writing *assertions*, which are statements
|
||||
When using GoogleTest, you start by writing *assertions*, which are statements
|
||||
that check whether a condition is true. An assertion's result can be *success*,
|
||||
*nonfatal failure*, or *fatal failure*. If a fatal failure occurs, it aborts the
|
||||
current function; otherwise the program continues normally.
|
||||
@ -98,11 +98,11 @@ assertion level and building up to tests and test suites.
|
||||
|
||||
## Assertions
|
||||
|
||||
googletest assertions are macros that resemble function calls. You test a class
|
||||
GoogleTest assertions are macros that resemble function calls. You test a class
|
||||
or function by making assertions about its behavior. When an assertion fails,
|
||||
googletest prints the assertion's source file and line number location, along
|
||||
GoogleTest prints the assertion's source file and line number location, along
|
||||
with a failure message. You may also supply a custom failure message which will
|
||||
be appended to googletest's message.
|
||||
be appended to GoogleTest's message.
|
||||
|
||||
The assertions come in pairs that test the same thing but have different effects
|
||||
on the current function. `ASSERT_*` versions generate fatal failures when they
|
||||
@ -149,7 +149,7 @@ To create a test:
|
||||
1. Use the `TEST()` macro to define and name a test function. These are
|
||||
ordinary C++ functions that don't return a value.
|
||||
2. In this function, along with any valid C++ statements you want to include,
|
||||
use the various googletest assertions to check values.
|
||||
use the various GoogleTest assertions to check values.
|
||||
3. The test's result is determined by the assertions; if any assertion in the
|
||||
test fails (either fatally or non-fatally), or if the test crashes, the
|
||||
entire test fails. Otherwise, it succeeds.
|
||||
@ -190,7 +190,7 @@ TEST(FactorialTest, HandlesPositiveInput) {
|
||||
}
|
||||
```
|
||||
|
||||
googletest groups the test results by test suites, so logically related tests
|
||||
GoogleTest groups the test results by test suites, so logically related tests
|
||||
should be in the same test suite; in other words, the first argument to their
|
||||
`TEST()` should be the same. In the above example, we have two tests,
|
||||
`HandlesZeroInput` and `HandlesPositiveInput`, that belong to the same test
|
||||
@ -210,7 +210,7 @@ objects for several different tests.
|
||||
|
||||
To create a fixture:
|
||||
|
||||
1. Derive a class from `::testing::Test` . Start its body with `protected:`, as
|
||||
1. Derive a class from `testing::Test` . Start its body with `protected:`, as
|
||||
we'll want to access fixture members from sub-classes.
|
||||
2. Inside the class, declare any objects you plan to use.
|
||||
3. If necessary, write a default constructor or `SetUp()` function to prepare
|
||||
@ -227,14 +227,14 @@ When using a fixture, use `TEST_F()` instead of `TEST()` as it allows you to
|
||||
access objects and subroutines in the test fixture:
|
||||
|
||||
```c++
|
||||
TEST_F(TestFixtureName, TestName) {
|
||||
TEST_F(TestFixtureClassName, TestName) {
|
||||
... test body ...
|
||||
}
|
||||
```
|
||||
|
||||
Like `TEST()`, the first argument is the test suite name, but for `TEST_F()`
|
||||
this must be the name of the test fixture class. You've probably guessed: `_F`
|
||||
is for fixture.
|
||||
Unlike `TEST()`, in `TEST_F()` the first argument must be the name of the test
|
||||
fixture class. (`_F` stands for "Fixture"). No test suite name is specified for
|
||||
this macro.
|
||||
|
||||
Unfortunately, the C++ macro system does not allow us to create a single macro
|
||||
that can handle both types of tests. Using the wrong macro causes a compiler
|
||||
@ -244,12 +244,12 @@ Also, you must first define a test fixture class before using it in a
|
||||
`TEST_F()`, or you'll get the compiler error "`virtual outside class
|
||||
declaration`".
|
||||
|
||||
For each test defined with `TEST_F()`, googletest will create a *fresh* test
|
||||
For each test defined with `TEST_F()`, GoogleTest will create a *fresh* test
|
||||
fixture at runtime, immediately initialize it via `SetUp()`, run the test, clean
|
||||
up by calling `TearDown()`, and then delete the test fixture. Note that
|
||||
different tests in the same test suite have different test fixture objects, and
|
||||
googletest always deletes a test fixture before it creates the next one.
|
||||
googletest does **not** reuse the same test fixture for multiple tests. Any
|
||||
GoogleTest always deletes a test fixture before it creates the next one.
|
||||
GoogleTest does **not** reuse the same test fixture for multiple tests. Any
|
||||
changes one test makes to the fixture do not affect other tests.
|
||||
|
||||
As an example, let's write tests for a FIFO queue class named `Queue`, which has
|
||||
@ -271,15 +271,16 @@ First, define a fixture class. By convention, you should give it the name
|
||||
`FooTest` where `Foo` is the class being tested.
|
||||
|
||||
```c++
|
||||
class QueueTest : public ::testing::Test {
|
||||
class QueueTest : public testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
QueueTest() {
|
||||
// q0_ remains empty
|
||||
q1_.Enqueue(1);
|
||||
q2_.Enqueue(2);
|
||||
q2_.Enqueue(3);
|
||||
}
|
||||
|
||||
// void TearDown() override {}
|
||||
// ~QueueTest() override = default;
|
||||
|
||||
Queue<int> q0_;
|
||||
Queue<int> q1_;
|
||||
@ -287,8 +288,9 @@ class QueueTest : public ::testing::Test {
|
||||
};
|
||||
```
|
||||
|
||||
In this case, `TearDown()` is not needed since we don't have to clean up after
|
||||
each test, other than what's already done by the destructor.
|
||||
In this case, we don't need to define a destructor or a `TearDown()` method,
|
||||
because the implicit destructor generated by the compiler will perform all of
|
||||
the necessary cleanup.
|
||||
|
||||
Now we'll write tests using `TEST_F()` and this fixture.
|
||||
|
||||
@ -324,19 +326,17 @@ would lead to a segfault when `n` is `NULL`.
|
||||
|
||||
When these tests run, the following happens:
|
||||
|
||||
1. googletest constructs a `QueueTest` object (let's call it `t1`).
|
||||
2. `t1.SetUp()` initializes `t1`.
|
||||
3. The first test (`IsEmptyInitially`) runs on `t1`.
|
||||
4. `t1.TearDown()` cleans up after the test finishes.
|
||||
5. `t1` is destructed.
|
||||
6. The above steps are repeated on another `QueueTest` object, this time
|
||||
1. GoogleTest constructs a `QueueTest` object (let's call it `t1`).
|
||||
2. The first test (`IsEmptyInitially`) runs on `t1`.
|
||||
3. `t1` is destructed.
|
||||
4. The above steps are repeated on another `QueueTest` object, this time
|
||||
running the `DequeueWorks` test.
|
||||
|
||||
**Availability**: Linux, Windows, Mac.
|
||||
|
||||
## Invoking the Tests
|
||||
|
||||
`TEST()` and `TEST_F()` implicitly register their tests with googletest. So,
|
||||
`TEST()` and `TEST_F()` implicitly register their tests with GoogleTest. So,
|
||||
unlike with many other C++ testing frameworks, you don't have to re-list all
|
||||
your defined tests in order to run them.
|
||||
|
||||
@ -347,7 +347,7 @@ test suites, or even different source files.
|
||||
|
||||
When invoked, the `RUN_ALL_TESTS()` macro:
|
||||
|
||||
* Saves the state of all googletest flags.
|
||||
* Saves the state of all GoogleTest flags.
|
||||
|
||||
* Creates a test fixture object for the first test.
|
||||
|
||||
@ -359,7 +359,7 @@ When invoked, the `RUN_ALL_TESTS()` macro:
|
||||
|
||||
* Deletes the fixture.
|
||||
|
||||
* Restores the state of all googletest flags.
|
||||
* Restores the state of all GoogleTest flags.
|
||||
|
||||
* Repeats the above steps for the next test, until all tests have run.
|
||||
|
||||
@ -373,14 +373,14 @@ If a fatal failure happens the subsequent steps will be skipped.
|
||||
> return the value of `RUN_ALL_TESTS()`.
|
||||
>
|
||||
> Also, you should call `RUN_ALL_TESTS()` only **once**. Calling it more than
|
||||
> once conflicts with some advanced googletest features (e.g., thread-safe
|
||||
> once conflicts with some advanced GoogleTest features (e.g., thread-safe
|
||||
> [death tests](advanced.md#death-tests)) and thus is not supported.
|
||||
|
||||
**Availability**: Linux, Windows, Mac.
|
||||
|
||||
## Writing the main() Function
|
||||
|
||||
Most users should _not_ need to write their own `main` function and instead link
|
||||
Most users should *not* need to write their own `main` function and instead link
|
||||
with `gtest_main` (as opposed to with `gtest`), which defines a suitable entry
|
||||
point. See the end of this section for details. The remainder of this section
|
||||
should only apply when you need to do something custom before the tests run that
|
||||
@ -394,14 +394,14 @@ You can start from this boilerplate:
|
||||
```c++
|
||||
#include "this/package/foo.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace my {
|
||||
namespace project {
|
||||
namespace {
|
||||
|
||||
// The fixture for testing class Foo.
|
||||
class FooTest : public ::testing::Test {
|
||||
class FooTest : public testing::Test {
|
||||
protected:
|
||||
// You can remove any or all of the following functions if their bodies would
|
||||
// be empty.
|
||||
@ -449,14 +449,14 @@ TEST_F(FooTest, DoesXyz) {
|
||||
} // namespace my
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
```
|
||||
|
||||
The `::testing::InitGoogleTest()` function parses the command line for
|
||||
googletest flags, and removes all recognized flags. This allows the user to
|
||||
control a test program's behavior via various flags, which we'll cover in the
|
||||
The `testing::InitGoogleTest()` function parses the command line for GoogleTest
|
||||
flags, and removes all recognized flags. This allows the user to control a test
|
||||
program's behavior via various flags, which we'll cover in the
|
||||
[AdvancedGuide](advanced.md). You **must** call this function before calling
|
||||
`RUN_ALL_TESTS()`, or the flags won't be properly initialized.
|
||||
|
||||
@ -475,7 +475,7 @@ NOTE: `ParseGUnitFlags()` is deprecated in favor of `InitGoogleTest()`.
|
||||
|
||||
* Google Test is designed to be thread-safe. The implementation is thread-safe
|
||||
on systems where the `pthreads` library is available. It is currently
|
||||
_unsafe_ to use Google Test assertions from two threads concurrently on
|
||||
*unsafe* to use Google Test assertions from two threads concurrently on
|
||||
other systems (e.g. Windows). In most tests this is not an issue as usually
|
||||
the assertions are done in the main thread. If you want to help, you can
|
||||
volunteer to implement the necessary synchronization primitives in
|
||||
|
@ -17,11 +17,10 @@ See [Supported Platforms](platforms.md) for more information about platforms
|
||||
compatible with GoogleTest.
|
||||
|
||||
If you don't already have Bazel installed, see the
|
||||
[Bazel installation guide](https://docs.bazel.build/versions/main/install.html).
|
||||
[Bazel installation guide](https://bazel.build/install).
|
||||
|
||||
{: .callout .note}
|
||||
Note: The terminal commands in this tutorial show a Unix shell prompt, but the
|
||||
commands work on the Windows command line as well.
|
||||
{: .callout .note} Note: The terminal commands in this tutorial show a Unix
|
||||
shell prompt, but the commands work on the Windows command line as well.
|
||||
|
||||
## Set up a Bazel workspace
|
||||
|
||||
@ -51,16 +50,16 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
|
||||
http_archive(
|
||||
name = "com_google_googletest",
|
||||
urls = ["https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip"],
|
||||
strip_prefix = "googletest-609281088cfefc76f9d0ce82e1ff6c30cc3591e5",
|
||||
urls = ["https://github.com/google/googletest/archive/5ab508a01f9eb089207ee87fd547d290da39d015.zip"],
|
||||
strip_prefix = "googletest-5ab508a01f9eb089207ee87fd547d290da39d015",
|
||||
)
|
||||
```
|
||||
|
||||
The above configuration declares a dependency on GoogleTest which is downloaded
|
||||
as a ZIP archive from GitHub. In the above example,
|
||||
`609281088cfefc76f9d0ce82e1ff6c30cc3591e5` is the Git commit hash of the
|
||||
`5ab508a01f9eb089207ee87fd547d290da39d015` is the Git commit hash of the
|
||||
GoogleTest version to use; we recommend updating the hash often to point to the
|
||||
latest version.
|
||||
latest version. Use a recent hash on the `main` branch.
|
||||
|
||||
Now you're ready to build C++ code that uses GoogleTest.
|
||||
|
||||
@ -106,10 +105,17 @@ file (`@com_google_googletest`). For more information about Bazel `BUILD` files,
|
||||
see the
|
||||
[Bazel C++ Tutorial](https://docs.bazel.build/versions/main/tutorial/cpp.html).
|
||||
|
||||
{: .callout .note}
|
||||
NOTE: In the example below, we assume Clang or GCC and set `--cxxopt=-std=c++14`
|
||||
to ensure that GoogleTest is compiled as C++14 instead of the compiler's default
|
||||
setting (which could be C++11). For MSVC, the equivalent would be
|
||||
`--cxxopt=/std:c++14`. See [Supported Platforms](platforms.md) for more details
|
||||
on supported language versions.
|
||||
|
||||
Now you can build and run your test:
|
||||
|
||||
<pre>
|
||||
<strong>my_workspace$ bazel test --test_output=all //:hello_test</strong>
|
||||
<strong>my_workspace$ bazel test --cxxopt=-std=c++14 --test_output=all //:hello_test</strong>
|
||||
INFO: Analyzed target //:hello_test (26 packages loaded, 362 targets configured).
|
||||
INFO: Found 1 test target...
|
||||
INFO: From Testing //:hello_test:
|
||||
|
@ -54,12 +54,12 @@ project(my_project)
|
||||
|
||||
# GoogleTest requires at least C++14
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
googletest
|
||||
GIT_REPOSITORY https://github.com/google/googletest.git
|
||||
GIT_TAG release-1.12.1
|
||||
URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
|
||||
)
|
||||
# For Windows: Prevent overriding the parent project's compiler/linker settings
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||
@ -67,7 +67,7 @@ FetchContent_MakeAvailable(googletest)
|
||||
```
|
||||
|
||||
The above configuration declares a dependency on GoogleTest which is downloaded
|
||||
from GitHub. In the above example, `609281088cfefc76f9d0ce82e1ff6c30cc3591e5` is
|
||||
from GitHub. In the above example, `03597a01ee50ed33e9dfd640b249b4be3799d395` is
|
||||
the Git commit hash of the GoogleTest version to use; we recommend updating the
|
||||
hash often to point to the latest version.
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Assertions Reference
|
||||
|
||||
This page lists the assertion macros provided by GoogleTest for verifying code
|
||||
behavior. To use them, include the header `gtest/gtest.h`.
|
||||
behavior. To use them, add `#include <gtest/gtest.h>`.
|
||||
|
||||
The majority of the macros listed below come as a pair with an `EXPECT_` variant
|
||||
and an `ASSERT_` variant. Upon failure, `EXPECT_` macros generate nonfatal
|
||||
@ -88,7 +88,7 @@ For example, the following code verifies that the string `value1` starts with
|
||||
10:
|
||||
|
||||
```cpp
|
||||
#include "gmock/gmock.h"
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
using ::testing::AllOf;
|
||||
using ::testing::Gt;
|
||||
@ -515,7 +515,7 @@ Verifies that *`expression`* is a success `HRESULT`.
|
||||
### EXPECT_HRESULT_FAILED {#EXPECT_HRESULT_FAILED}
|
||||
|
||||
`EXPECT_HRESULT_FAILED(`*`expression`*`)` \
|
||||
`EXPECT_HRESULT_FAILED(`*`expression`*`)`
|
||||
`ASSERT_HRESULT_FAILED(`*`expression`*`)`
|
||||
|
||||
Verifies that *`expression`* is a failure `HRESULT`.
|
||||
|
||||
|
@ -102,7 +102,7 @@ The `argument` can be either a C string or a C++ string object:
|
||||
| `StrCaseNe(string)` | `argument` is not equal to `string`, ignoring case. |
|
||||
| `StrEq(string)` | `argument` is equal to `string`. |
|
||||
| `StrNe(string)` | `argument` is not equal to `string`. |
|
||||
| `WhenBase64Unescaped(m)` | `argument` is a base-64 escaped string whose unescaped string matches `m`. |
|
||||
| `WhenBase64Unescaped(m)` | `argument` is a base-64 escaped string whose unescaped string matches `m`. The web-safe format from [RFC 4648](https://www.rfc-editor.org/rfc/rfc4648#section-5) is supported. |
|
||||
|
||||
`ContainsRegex()` and `MatchesRegex()` take ownership of the `RE` object. They
|
||||
use the regular expression syntax defined
|
||||
@ -288,3 +288,15 @@ which must be a permanent callback.
|
||||
return ExplainMatchResult(matcher, arg.nested().property(), result_listener);
|
||||
}
|
||||
```
|
||||
|
||||
5. You can use `DescribeMatcher<>` to describe another matcher. For example:
|
||||
|
||||
```cpp
|
||||
MATCHER_P(XAndYThat, matcher,
|
||||
"X that " + DescribeMatcher<int>(matcher, negation) +
|
||||
(negation ? " or" : " and") + " Y that " +
|
||||
DescribeMatcher<double>(matcher, negation)) {
|
||||
return ExplainMatchResult(matcher, arg.x(), result_listener) &&
|
||||
ExplainMatchResult(matcher, arg.y(), result_listener);
|
||||
}
|
||||
```
|
||||
|
@ -1,8 +1,7 @@
|
||||
# Mocking Reference
|
||||
|
||||
This page lists the facilities provided by GoogleTest for creating and working
|
||||
with mock objects. To use them, include the header
|
||||
`gmock/gmock.h`.
|
||||
with mock objects. To use them, add `#include <gmock/gmock.h>`.
|
||||
|
||||
## Macros {#macros}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
<!--* toc_depth: 3 *-->
|
||||
|
||||
This page lists the facilities provided by GoogleTest for writing test programs.
|
||||
To use them, include the header `gtest/gtest.h`.
|
||||
To use them, add `#include <gtest/gtest.h>`.
|
||||
|
||||
## Macros
|
||||
|
||||
@ -94,7 +94,8 @@ Instantiates the value-parameterized test suite *`TestSuiteName`* (defined with
|
||||
The argument *`InstantiationName`* is a unique name for the instantiation of the
|
||||
test suite, to distinguish between multiple instantiations. In test output, the
|
||||
instantiation name is added as a prefix to the test suite name
|
||||
*`TestSuiteName`*.
|
||||
*`TestSuiteName`*. If *`InstantiationName`* is empty
|
||||
(`INSTANTIATE_TEST_SUITE_P(, ...)`), no prefix is added.
|
||||
|
||||
The argument *`param_generator`* is one of the following GoogleTest-provided
|
||||
functions that generate the test parameters, all defined in the `::testing`
|
||||
@ -109,6 +110,7 @@ namespace:
|
||||
| `ValuesIn(container)` or `ValuesIn(begin,end)` | Yields values from a C-style array, an STL-style container, or an iterator range `[begin, end)`. |
|
||||
| `Bool()` | Yields sequence `{false, true}`. |
|
||||
| `Combine(g1, g2, ..., gN)` | Yields as `std::tuple` *n*-tuples all combinations (Cartesian product) of the values generated by the given *n* generators `g1`, `g2`, ..., `gN`. |
|
||||
| `ConvertGenerator<T>(g)` | Yields values generated by generator `g`, `static_cast` to `T`. |
|
||||
|
||||
The optional last argument *`name_generator`* is a function or functor that
|
||||
generates custom test name suffixes based on the test parameters. The function
|
||||
@ -121,8 +123,8 @@ custom function can be used for more control:
|
||||
```cpp
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
MyInstantiation, MyTestSuite,
|
||||
::testing::Values(...),
|
||||
[](const ::testing::TestParamInfo<MyTestSuite::ParamType>& info) {
|
||||
testing::Values(...),
|
||||
[](const testing::TestParamInfo<MyTestSuite::ParamType>& info) {
|
||||
// Can use info.param here to generate the test suffix
|
||||
std::string name = ...
|
||||
return name;
|
||||
@ -147,7 +149,7 @@ type, for example:
|
||||
|
||||
```cpp
|
||||
template <typename T>
|
||||
class MyFixture : public ::testing::Test {
|
||||
class MyFixture : public testing::Test {
|
||||
public:
|
||||
...
|
||||
using List = std::list<T>;
|
||||
@ -276,7 +278,8 @@ must be registered with
|
||||
The argument *`InstantiationName`* is a unique name for the instantiation of the
|
||||
test suite, to distinguish between multiple instantiations. In test output, the
|
||||
instantiation name is added as a prefix to the test suite name
|
||||
*`TestSuiteName`*.
|
||||
*`TestSuiteName`*. If *`InstantiationName`* is empty
|
||||
(`INSTANTIATE_TYPED_TEST_SUITE_P(, ...)`), no prefix is added.
|
||||
|
||||
The argument *`Types`* is a [`Types`](#Types) object representing the list of
|
||||
types to run the tests on, for example:
|
||||
@ -323,7 +326,7 @@ Then the test code should look like:
|
||||
```cpp
|
||||
namespace my_namespace {
|
||||
|
||||
class MyClassTest : public ::testing::Test {
|
||||
class MyClassTest : public testing::Test {
|
||||
...
|
||||
};
|
||||
|
||||
@ -386,7 +389,7 @@ GoogleTest defines the following classes and types to help with writing tests.
|
||||
|
||||
### AssertionResult {#AssertionResult}
|
||||
|
||||
`::testing::AssertionResult`
|
||||
`testing::AssertionResult`
|
||||
|
||||
A class for indicating whether an assertion was successful.
|
||||
|
||||
@ -400,14 +403,14 @@ To create an instance of this class, use one of the factory functions
|
||||
|
||||
### AssertionException {#AssertionException}
|
||||
|
||||
`::testing::AssertionException`
|
||||
`testing::AssertionException`
|
||||
|
||||
Exception which can be thrown from
|
||||
[`TestEventListener::OnTestPartResult`](#TestEventListener::OnTestPartResult).
|
||||
|
||||
### EmptyTestEventListener {#EmptyTestEventListener}
|
||||
|
||||
`::testing::EmptyTestEventListener`
|
||||
`testing::EmptyTestEventListener`
|
||||
|
||||
Provides an empty implementation of all methods in the
|
||||
[`TestEventListener`](#TestEventListener) interface, such that a subclass only
|
||||
@ -415,7 +418,7 @@ needs to override the methods it cares about.
|
||||
|
||||
### Environment {#Environment}
|
||||
|
||||
`::testing::Environment`
|
||||
`testing::Environment`
|
||||
|
||||
Represents a global test environment. See
|
||||
[Global Set-Up and Tear-Down](../advanced.md#global-set-up-and-tear-down).
|
||||
@ -436,7 +439,7 @@ Override this to define how to tear down the environment.
|
||||
|
||||
### ScopedTrace {#ScopedTrace}
|
||||
|
||||
`::testing::ScopedTrace`
|
||||
`testing::ScopedTrace`
|
||||
|
||||
An instance of this class causes a trace to be included in every test failure
|
||||
message generated by code in the scope of the lifetime of the `ScopedTrace`
|
||||
@ -452,7 +455,7 @@ ScopedTrace(const char* file, int line, const T& message)
|
||||
Example usage:
|
||||
|
||||
```cpp
|
||||
::testing::ScopedTrace trace("file.cc", 123, "message");
|
||||
testing::ScopedTrace trace("file.cc", 123, "message");
|
||||
```
|
||||
|
||||
The resulting trace includes the given source file path and line number, and the
|
||||
@ -463,7 +466,7 @@ See also [`SCOPED_TRACE`](#SCOPED_TRACE).
|
||||
|
||||
### Test {#Test}
|
||||
|
||||
`::testing::Test`
|
||||
`testing::Test`
|
||||
|
||||
The abstract class that all tests inherit from. `Test` is not copyable.
|
||||
|
||||
@ -551,7 +554,7 @@ after running each individual test.
|
||||
|
||||
### TestWithParam {#TestWithParam}
|
||||
|
||||
`::testing::TestWithParam<T>`
|
||||
`testing::TestWithParam<T>`
|
||||
|
||||
A convenience class which inherits from both [`Test`](#Test) and
|
||||
[`WithParamInterface<T>`](#WithParamInterface).
|
||||
@ -671,7 +674,7 @@ during execution of `SetUpTestSuite` and `TearDownTestSuite`.
|
||||
|
||||
### TestInfo {#TestInfo}
|
||||
|
||||
`::testing::TestInfo`
|
||||
`testing::TestInfo`
|
||||
|
||||
Stores information about a test.
|
||||
|
||||
@ -750,7 +753,7 @@ Returns the result of the test. See [`TestResult`](#TestResult).
|
||||
|
||||
### TestParamInfo {#TestParamInfo}
|
||||
|
||||
`::testing::TestParamInfo<T>`
|
||||
`testing::TestParamInfo<T>`
|
||||
|
||||
Describes a parameter to a value-parameterized test. The type `T` is the type of
|
||||
the parameter.
|
||||
@ -760,7 +763,7 @@ and its integer index respectively.
|
||||
|
||||
### UnitTest {#UnitTest}
|
||||
|
||||
`::testing::UnitTest`
|
||||
`testing::UnitTest`
|
||||
|
||||
This class contains information about the test program.
|
||||
|
||||
@ -928,7 +931,7 @@ GoogleTest. See [`TestEventListeners`](#TestEventListeners).
|
||||
|
||||
### TestEventListener {#TestEventListener}
|
||||
|
||||
`::testing::TestEventListener`
|
||||
`testing::TestEventListener`
|
||||
|
||||
The interface for tracing execution of tests. The methods below are listed in
|
||||
the order the corresponding events are fired.
|
||||
@ -1026,7 +1029,7 @@ Fired after all test activities have ended.
|
||||
|
||||
### TestEventListeners {#TestEventListeners}
|
||||
|
||||
`::testing::TestEventListeners`
|
||||
`testing::TestEventListeners`
|
||||
|
||||
Lets users add listeners to track events in GoogleTest.
|
||||
|
||||
@ -1071,7 +1074,7 @@ the caller and makes this function return `NULL` the next time.
|
||||
|
||||
### TestPartResult {#TestPartResult}
|
||||
|
||||
`::testing::TestPartResult`
|
||||
`testing::TestPartResult`
|
||||
|
||||
A copyable object representing the result of a test part (i.e. an assertion or
|
||||
an explicit `FAIL()`, `ADD_FAILURE()`, or `SUCCESS()`).
|
||||
@ -1153,7 +1156,7 @@ Returns true if and only if the test part failed.
|
||||
|
||||
### TestProperty {#TestProperty}
|
||||
|
||||
`::testing::TestProperty`
|
||||
`testing::TestProperty`
|
||||
|
||||
A copyable object representing a user-specified test property which can be
|
||||
output as a key/value string pair.
|
||||
@ -1180,7 +1183,7 @@ Sets a new value, overriding the previous one.
|
||||
|
||||
### TestResult {#TestResult}
|
||||
|
||||
`::testing::TestResult`
|
||||
`testing::TestResult`
|
||||
|
||||
Contains information about the result of a single test.
|
||||
|
||||
@ -1261,20 +1264,20 @@ range, aborts the program.
|
||||
|
||||
### TimeInMillis {#TimeInMillis}
|
||||
|
||||
`::testing::TimeInMillis`
|
||||
`testing::TimeInMillis`
|
||||
|
||||
An integer type representing time in milliseconds.
|
||||
|
||||
### Types {#Types}
|
||||
|
||||
`::testing::Types<T...>`
|
||||
`testing::Types<T...>`
|
||||
|
||||
Represents a list of types for use in typed tests and type-parameterized tests.
|
||||
|
||||
The template argument `T...` can be any number of types, for example:
|
||||
|
||||
```
|
||||
::testing::Types<char, int, unsigned int>
|
||||
testing::Types<char, int, unsigned int>
|
||||
```
|
||||
|
||||
See [Typed Tests](../advanced.md#typed-tests) and
|
||||
@ -1283,7 +1286,7 @@ information.
|
||||
|
||||
### WithParamInterface {#WithParamInterface}
|
||||
|
||||
`::testing::WithParamInterface<T>`
|
||||
`testing::WithParamInterface<T>`
|
||||
|
||||
The pure interface class that all value-parameterized tests inherit from.
|
||||
|
||||
@ -1309,14 +1312,16 @@ tests.
|
||||
|
||||
### InitGoogleTest {#InitGoogleTest}
|
||||
|
||||
`void ::testing::InitGoogleTest(int* argc, char** argv)` \
|
||||
`void ::testing::InitGoogleTest(int* argc, wchar_t** argv)` \
|
||||
`void ::testing::InitGoogleTest()`
|
||||
`void testing::InitGoogleTest(int* argc, char** argv)` \
|
||||
`void testing::InitGoogleTest(int* argc, wchar_t** argv)` \
|
||||
`void testing::InitGoogleTest()`
|
||||
|
||||
Initializes GoogleTest. This must be called before calling
|
||||
[`RUN_ALL_TESTS()`](#RUN_ALL_TESTS). In particular, it parses the command line
|
||||
for the flags that GoogleTest recognizes. Whenever a GoogleTest flag is seen, it
|
||||
is removed from `argv`, and `*argc` is decremented.
|
||||
is removed from `argv`, and `*argc` is decremented. Keep in mind that `argv`
|
||||
must terminate with a `NULL` pointer (i.e. `argv[argc]` is `NULL`), which is
|
||||
already the case with the default `argv` passed to `main`.
|
||||
|
||||
No value is returned. Instead, the GoogleTest flag variables are updated.
|
||||
|
||||
@ -1328,7 +1333,7 @@ platforms where there is no `argc`/`argv`.
|
||||
|
||||
### AddGlobalTestEnvironment {#AddGlobalTestEnvironment}
|
||||
|
||||
`Environment* ::testing::AddGlobalTestEnvironment(Environment* env)`
|
||||
`Environment* testing::AddGlobalTestEnvironment(Environment* env)`
|
||||
|
||||
Adds a test environment to the test program. Must be called before
|
||||
[`RUN_ALL_TESTS()`](#RUN_ALL_TESTS) is called. See
|
||||
@ -1341,7 +1346,7 @@ See also [`Environment`](#Environment).
|
||||
|
||||
```cpp
|
||||
template <typename Factory>
|
||||
TestInfo* ::testing::RegisterTest(const char* test_suite_name, const char* test_name,
|
||||
TestInfo* testing::RegisterTest(const char* test_suite_name, const char* test_name,
|
||||
const char* type_param, const char* value_param,
|
||||
const char* file, int line, Factory factory)
|
||||
```
|
||||
@ -1380,27 +1385,27 @@ an all-caps name.
|
||||
|
||||
### AssertionSuccess {#AssertionSuccess}
|
||||
|
||||
`AssertionResult ::testing::AssertionSuccess()`
|
||||
`AssertionResult testing::AssertionSuccess()`
|
||||
|
||||
Creates a successful assertion result. See
|
||||
[`AssertionResult`](#AssertionResult).
|
||||
|
||||
### AssertionFailure {#AssertionFailure}
|
||||
|
||||
`AssertionResult ::testing::AssertionFailure()`
|
||||
`AssertionResult testing::AssertionFailure()`
|
||||
|
||||
Creates a failed assertion result. Use the `<<` operator to store a failure
|
||||
message:
|
||||
|
||||
```cpp
|
||||
::testing::AssertionFailure() << "My failure message";
|
||||
testing::AssertionFailure() << "My failure message";
|
||||
```
|
||||
|
||||
See [`AssertionResult`](#AssertionResult).
|
||||
|
||||
### StaticAssertTypeEq {#StaticAssertTypeEq}
|
||||
|
||||
`::testing::StaticAssertTypeEq<T1, T2>()`
|
||||
`testing::StaticAssertTypeEq<T1, T2>()`
|
||||
|
||||
Compile-time assertion for type equality. Compiles if and only if `T1` and `T2`
|
||||
are the same type. The value it returns is irrelevant.
|
||||
@ -1409,7 +1414,7 @@ See [Type Assertions](../advanced.md#type-assertions) for more information.
|
||||
|
||||
### PrintToString {#PrintToString}
|
||||
|
||||
`std::string ::testing::PrintToString(x)`
|
||||
`std::string testing::PrintToString(x)`
|
||||
|
||||
Prints any value `x` using GoogleTest's value printer.
|
||||
|
||||
@ -1419,7 +1424,7 @@ for more information.
|
||||
|
||||
### PrintToStringParamName {#PrintToStringParamName}
|
||||
|
||||
`std::string ::testing::PrintToStringParamName(TestParamInfo<T>& info)`
|
||||
`std::string testing::PrintToStringParamName(TestParamInfo<T>& info)`
|
||||
|
||||
A built-in parameterized test name generator which returns the result of
|
||||
[`PrintToString`](#PrintToString) called on `info.param`. Does not work when the
|
||||
|
33
fake_fuchsia_sdk.bzl
Normal file
33
fake_fuchsia_sdk.bzl
Normal file
@ -0,0 +1,33 @@
|
||||
"""Provides a fake @fuchsia_sdk implementation that's used when the real one isn't available.
|
||||
|
||||
This is needed since bazel queries on targets that depend on //:gtest (eg:
|
||||
`bazel query "deps(set(//googletest/test:gtest_all_test))"`) will fail if @fuchsia_sdk is not
|
||||
defined when bazel is evaluating the transitive closure of the query target.
|
||||
|
||||
See https://github.com/google/googletest/issues/4472.
|
||||
"""
|
||||
|
||||
def _fake_fuchsia_sdk_impl(repo_ctx):
|
||||
for stub_target in repo_ctx.attr._stub_build_targets:
|
||||
stub_package = stub_target
|
||||
stub_target_name = stub_target.split("/")[-1]
|
||||
repo_ctx.file("%s/BUILD.bazel" % stub_package, """
|
||||
filegroup(
|
||||
name = "%s",
|
||||
)
|
||||
""" % stub_target_name)
|
||||
|
||||
fake_fuchsia_sdk = repository_rule(
|
||||
doc = "Used to create a fake @fuchsia_sdk repository with stub build targets.",
|
||||
implementation = _fake_fuchsia_sdk_impl,
|
||||
attrs = {
|
||||
"_stub_build_targets": attr.string_list(
|
||||
doc = "The stub build targets to initialize.",
|
||||
default = [
|
||||
"pkg/fdio",
|
||||
"pkg/syslog",
|
||||
"pkg/zx",
|
||||
],
|
||||
),
|
||||
},
|
||||
)
|
@ -5,7 +5,7 @@
|
||||
# CMake build script for Google Mock.
|
||||
#
|
||||
# To run the tests for Google Mock itself on Linux, use 'make test' or
|
||||
# ctest. You can select which tests to run using 'ctest -R regex'.
|
||||
# ctest. You can select which tests to run using 'ctest -R regex'.
|
||||
# For more options, run 'ctest --help'.
|
||||
|
||||
option(gmock_build_tests "Build all of Google Mock's own tests." OFF)
|
||||
@ -36,8 +36,7 @@ endif()
|
||||
# as ${gmock_SOURCE_DIR} and to the root binary directory as
|
||||
# ${gmock_BINARY_DIR}.
|
||||
# Language "C" is required for find_package(Threads).
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
cmake_policy(SET CMP0048 NEW)
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(gmock VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)
|
||||
|
||||
if (COMMAND set_up_hermetic_build)
|
||||
@ -45,7 +44,7 @@ if (COMMAND set_up_hermetic_build)
|
||||
endif()
|
||||
|
||||
# Instructs CMake to process Google Test's CMakeLists.txt and add its
|
||||
# targets to the current scope. We are placing Google Test's binary
|
||||
# targets to the current scope. We are placing Google Test's binary
|
||||
# directory in a subdirectory of our own as VC compilation may break
|
||||
# if they are the same (the default).
|
||||
add_subdirectory("${gtest_dir}" "${gmock_BINARY_DIR}/${gtest_dir}")
|
||||
@ -61,25 +60,26 @@ else()
|
||||
endif()
|
||||
|
||||
# Although Google Test's CMakeLists.txt calls this function, the
|
||||
# changes there don't affect the current scope. Therefore we have to
|
||||
# changes there don't affect the current scope. Therefore we have to
|
||||
# call it again here.
|
||||
config_compiler_and_linker() # from ${gtest_dir}/cmake/internal_utils.cmake
|
||||
config_compiler_and_linker() # from ${gtest_dir}/cmake/internal_utils.cmake
|
||||
|
||||
# Adds Google Mock's and Google Test's header directories to the search path.
|
||||
# Get Google Test's include dirs from the target, gtest_SOURCE_DIR is broken
|
||||
# when using fetch-content with the name "GTest".
|
||||
get_target_property(gtest_include_dirs gtest INCLUDE_DIRECTORIES)
|
||||
set(gmock_build_include_dirs
|
||||
"${gmock_SOURCE_DIR}/include"
|
||||
"${gmock_SOURCE_DIR}"
|
||||
"${gtest_SOURCE_DIR}/include"
|
||||
# This directory is needed to build directly from Google Test sources.
|
||||
"${gtest_SOURCE_DIR}")
|
||||
"${gtest_include_dirs}")
|
||||
include_directories(${gmock_build_include_dirs})
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Defines the gmock & gmock_main libraries. User tests should link
|
||||
# Defines the gmock & gmock_main libraries. User tests should link
|
||||
# with one of them.
|
||||
|
||||
# Google Mock libraries. We build them using more strict warnings than what
|
||||
# Google Mock libraries. We build them using more strict warnings than what
|
||||
# are used for other targets, to ensure that Google Mock can be compiled by
|
||||
# a user aggressive about warnings.
|
||||
if (MSVC)
|
||||
@ -101,22 +101,18 @@ else()
|
||||
target_link_libraries(gmock_main PUBLIC gmock)
|
||||
set_target_properties(gmock_main PROPERTIES VERSION ${GOOGLETEST_VERSION})
|
||||
endif()
|
||||
# If the CMake version supports it, attach header directory information
|
||||
# to the targets for when we are part of a parent build (ie being pulled
|
||||
# in via add_subdirectory() rather than being a standalone build).
|
||||
if (DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11")
|
||||
string(REPLACE ";" "$<SEMICOLON>" dirs "${gmock_build_include_dirs}")
|
||||
target_include_directories(gmock SYSTEM INTERFACE
|
||||
"$<BUILD_INTERFACE:${dirs}>"
|
||||
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
|
||||
target_include_directories(gmock_main SYSTEM INTERFACE
|
||||
"$<BUILD_INTERFACE:${dirs}>"
|
||||
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
|
||||
endif()
|
||||
|
||||
string(REPLACE ";" "$<SEMICOLON>" dirs "${gmock_build_include_dirs}")
|
||||
target_include_directories(gmock SYSTEM INTERFACE
|
||||
"$<BUILD_INTERFACE:${dirs}>"
|
||||
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
|
||||
target_include_directories(gmock_main SYSTEM INTERFACE
|
||||
"$<BUILD_INTERFACE:${dirs}>"
|
||||
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Install rules
|
||||
# Install rules.
|
||||
install_project(gmock gmock_main)
|
||||
|
||||
########################################################################
|
||||
@ -126,8 +122,8 @@ install_project(gmock gmock_main)
|
||||
# You can skip this section if you aren't interested in testing
|
||||
# Google Mock itself.
|
||||
#
|
||||
# The tests are not built by default. To build them, set the
|
||||
# gmock_build_tests option to ON. You can do it by running ccmake
|
||||
# The tests are not built by default. To build them, set the
|
||||
# gmock_build_tests option to ON. You can do it by running ccmake
|
||||
# or specifying the -Dgmock_build_tests=ON flag when running cmake.
|
||||
|
||||
if (gmock_build_tests)
|
||||
@ -136,11 +132,7 @@ if (gmock_build_tests)
|
||||
enable_testing()
|
||||
|
||||
if (MINGW OR CYGWIN)
|
||||
if (CMAKE_VERSION VERSION_LESS "2.8.12")
|
||||
add_compile_options("-Wa,-mbig-obj")
|
||||
else()
|
||||
add_definitions("-Wa,-mbig-obj")
|
||||
endif()
|
||||
add_compile_options("-Wa,-mbig-obj")
|
||||
endif()
|
||||
|
||||
############################################################
|
||||
@ -196,7 +188,7 @@ if (gmock_build_tests)
|
||||
cxx_shared_library(shared_gmock_main "${cxx_default}"
|
||||
"${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc)
|
||||
|
||||
# Tests that a binary can be built with Google Mock as a shared library. On
|
||||
# Tests that a binary can be built with Google Mock as a shared library. On
|
||||
# some system configurations, it may not possible to run the binary without
|
||||
# knowing more details about the system configurations. We do not try to run
|
||||
# this binary. To get a more robust shared library coverage, configure with
|
||||
|
@ -8,8 +8,8 @@ derive better designs of your system and write better tests.
|
||||
It is inspired by:
|
||||
|
||||
* [jMock](http://www.jmock.org/)
|
||||
* [EasyMock](http://www.easymock.org/)
|
||||
* [Hamcrest](http://code.google.com/p/hamcrest/)
|
||||
* [EasyMock](https://easymock.org/)
|
||||
* [Hamcrest](https://code.google.com/p/hamcrest/)
|
||||
|
||||
It is designed with C++'s specifics in mind.
|
||||
|
||||
@ -36,5 +36,5 @@ Details and examples can be found here:
|
||||
* [gMock Cheat Sheet](https://google.github.io/googletest/gmock_cheat_sheet.html)
|
||||
|
||||
GoogleMock is a part of
|
||||
[GoogleTest C++ testing framework](http://github.com/google/googletest/) and a
|
||||
[GoogleTest C++ testing framework](https://github.com/google/googletest/) and a
|
||||
subject to the same requirements.
|
||||
|
@ -135,6 +135,7 @@
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <exception>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@ -146,10 +147,7 @@
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
#include "gmock/internal/gmock-pp.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4100)
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)
|
||||
|
||||
namespace testing {
|
||||
|
||||
@ -178,9 +176,15 @@ struct BuiltInDefaultValueGetter<T, false> {
|
||||
static T Get() {
|
||||
Assert(false, __FILE__, __LINE__,
|
||||
"Default action undefined for the function return type.");
|
||||
return internal::Invalid<T>();
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
__builtin_unreachable();
|
||||
#elif defined(_MSC_VER)
|
||||
__assume(0);
|
||||
#else
|
||||
return Invalid<T>();
|
||||
// The above statement will never be reached, but is required in
|
||||
// order for this function to compile.
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
@ -614,7 +618,7 @@ class DefaultValue {
|
||||
private:
|
||||
class ValueProducer {
|
||||
public:
|
||||
virtual ~ValueProducer() {}
|
||||
virtual ~ValueProducer() = default;
|
||||
virtual T Produce() = 0;
|
||||
};
|
||||
|
||||
@ -702,8 +706,8 @@ class ActionInterface {
|
||||
typedef typename internal::Function<F>::Result Result;
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
ActionInterface() {}
|
||||
virtual ~ActionInterface() {}
|
||||
ActionInterface() = default;
|
||||
virtual ~ActionInterface() = default;
|
||||
|
||||
// Performs the action. This method is not const, as in general an
|
||||
// action can have side effects and be stateful. For example, a
|
||||
@ -752,7 +756,7 @@ class Action<R(Args...)> {
|
||||
|
||||
// Constructs a null Action. Needed for storing Action objects in
|
||||
// STL containers.
|
||||
Action() {}
|
||||
Action() = default;
|
||||
|
||||
// Construct an Action from a specified callable.
|
||||
// This cannot take std::function directly, because then Action would not be
|
||||
@ -1276,7 +1280,7 @@ class AssignAction {
|
||||
const T2 value_;
|
||||
};
|
||||
|
||||
#if !GTEST_OS_WINDOWS_MOBILE
|
||||
#ifndef GTEST_OS_WINDOWS_MOBILE
|
||||
|
||||
// Implements the SetErrnoAndReturn action to simulate return from
|
||||
// various system calls and libc functions.
|
||||
@ -1420,17 +1424,19 @@ struct WithArgsAction {
|
||||
// providing a call operator because even with a particular set of arguments
|
||||
// they don't have a fixed return type.
|
||||
|
||||
template <typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
std::is_convertible<
|
||||
InnerAction,
|
||||
// Unfortunately we can't use the InnerSignature alias here;
|
||||
// MSVC complains about the I parameter pack not being
|
||||
// expanded (error C3520) despite it being expanded in the
|
||||
// type alias.
|
||||
OnceAction<R(typename std::tuple_element<
|
||||
I, std::tuple<Args...>>::type...)>>::value,
|
||||
int>::type = 0>
|
||||
template <
|
||||
typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
std::is_convertible<InnerAction,
|
||||
// Unfortunately we can't use the InnerSignature
|
||||
// alias here; MSVC complains about the I
|
||||
// parameter pack not being expanded (error C3520)
|
||||
// despite it being expanded in the type alias.
|
||||
// TupleElement is also an MSVC workaround.
|
||||
// See its definition for details.
|
||||
OnceAction<R(internal::TupleElement<
|
||||
I, std::tuple<Args...>>...)>>::value,
|
||||
int>::type = 0>
|
||||
operator OnceAction<R(Args...)>() && { // NOLINT
|
||||
struct OA {
|
||||
OnceAction<InnerSignature<R, Args...>> inner_action;
|
||||
@ -1445,17 +1451,19 @@ struct WithArgsAction {
|
||||
return OA{std::move(inner_action)};
|
||||
}
|
||||
|
||||
template <typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
std::is_convertible<
|
||||
const InnerAction&,
|
||||
// Unfortunately we can't use the InnerSignature alias here;
|
||||
// MSVC complains about the I parameter pack not being
|
||||
// expanded (error C3520) despite it being expanded in the
|
||||
// type alias.
|
||||
Action<R(typename std::tuple_element<
|
||||
I, std::tuple<Args...>>::type...)>>::value,
|
||||
int>::type = 0>
|
||||
template <
|
||||
typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
std::is_convertible<const InnerAction&,
|
||||
// Unfortunately we can't use the InnerSignature
|
||||
// alias here; MSVC complains about the I
|
||||
// parameter pack not being expanded (error C3520)
|
||||
// despite it being expanded in the type alias.
|
||||
// TupleElement is also an MSVC workaround.
|
||||
// See its definition for details.
|
||||
Action<R(internal::TupleElement<
|
||||
I, std::tuple<Args...>>...)>>::value,
|
||||
int>::type = 0>
|
||||
operator Action<R(Args...)>() const { // NOLINT
|
||||
Action<InnerSignature<R, Args...>> converted(inner_action);
|
||||
|
||||
@ -1739,6 +1747,13 @@ struct ThrowAction {
|
||||
return [copy](Args...) -> R { throw copy; };
|
||||
}
|
||||
};
|
||||
struct RethrowAction {
|
||||
std::exception_ptr exception;
|
||||
template <typename R, typename... Args>
|
||||
operator Action<R(Args...)>() const { // NOLINT
|
||||
return [ex = exception](Args...) -> R { std::rethrow_exception(ex); };
|
||||
}
|
||||
};
|
||||
#endif // GTEST_HAS_EXCEPTIONS
|
||||
|
||||
} // namespace internal
|
||||
@ -1925,7 +1940,7 @@ PolymorphicAction<internal::AssignAction<T1, T2>> Assign(T1* ptr, T2 val) {
|
||||
return MakePolymorphicAction(internal::AssignAction<T1, T2>(ptr, val));
|
||||
}
|
||||
|
||||
#if !GTEST_OS_WINDOWS_MOBILE
|
||||
#ifndef GTEST_OS_WINDOWS_MOBILE
|
||||
|
||||
// Creates an action that sets errno and returns the appropriate error.
|
||||
template <typename T>
|
||||
@ -2055,13 +2070,23 @@ 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
|
||||
// Action Throw(exception) can be used in a mock function of any type
|
||||
// to throw the given exception. Any copyable value can be thrown,
|
||||
// except for std::exception_ptr, which is likely a mistake if
|
||||
// thrown directly.
|
||||
template <typename T>
|
||||
internal::ThrowAction<typename std::decay<T>::type> Throw(T&& exception) {
|
||||
typename std::enable_if<
|
||||
!std::is_base_of<std::exception_ptr, typename std::decay<T>::type>::value,
|
||||
internal::ThrowAction<typename std::decay<T>::type>>::type
|
||||
Throw(T&& exception) {
|
||||
return {std::forward<T>(exception)};
|
||||
}
|
||||
// Action Rethrow(exception_ptr) can be used in a mock function of any type
|
||||
// to rethrow any exception_ptr. Note that the same object is thrown each time.
|
||||
inline internal::RethrowAction Rethrow(std::exception_ptr exception) {
|
||||
return {std::move(exception)};
|
||||
}
|
||||
#endif // GTEST_HAS_EXCEPTIONS
|
||||
|
||||
namespace internal {
|
||||
@ -2110,13 +2135,13 @@ struct ActionImpl<R(Args...), Impl> : ImplBase<Impl>::type {
|
||||
R operator()(Args&&... arg) const {
|
||||
static constexpr size_t kMaxArgs =
|
||||
sizeof...(Args) <= 10 ? sizeof...(Args) : 10;
|
||||
return Apply(MakeIndexSequence<kMaxArgs>{},
|
||||
MakeIndexSequence<10 - kMaxArgs>{},
|
||||
return Apply(std::make_index_sequence<kMaxArgs>{},
|
||||
std::make_index_sequence<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...>,
|
||||
R Apply(std::index_sequence<arg_id...>, std::index_sequence<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
|
||||
@ -2149,9 +2174,9 @@ template <typename F, typename 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( \
|
||||
, GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED const arg##i##_type& arg##i
|
||||
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \
|
||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED const args_type& args GMOCK_PP_REPEAT( \
|
||||
GMOCK_INTERNAL_ARG_UNUSED, , 10)
|
||||
|
||||
#define GMOCK_INTERNAL_ARG(i, data, el) , const arg##i##_type& arg##i
|
||||
@ -2291,8 +2316,6 @@ template <typename F, typename Impl>
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
|
||||
|
@ -65,7 +65,7 @@ namespace testing {
|
||||
// The implementation of a cardinality.
|
||||
class CardinalityInterface {
|
||||
public:
|
||||
virtual ~CardinalityInterface() {}
|
||||
virtual ~CardinalityInterface() = default;
|
||||
|
||||
// Conservative estimate on the lower/upper bound of the number of
|
||||
// calls allowed.
|
||||
@ -92,7 +92,7 @@ class GTEST_API_ Cardinality {
|
||||
public:
|
||||
// Constructs a null cardinality. Needed for storing Cardinality
|
||||
// objects in STL containers.
|
||||
Cardinality() {}
|
||||
Cardinality() = default;
|
||||
|
||||
// Constructs a Cardinality from its implementation.
|
||||
explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {}
|
||||
|
@ -34,9 +34,10 @@
|
||||
// IWYU pragma: private, include "gmock/gmock.h"
|
||||
// IWYU pragma: friend gmock/.*
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits> // IWYU pragma: keep
|
||||
#include <utility> // IWYU pragma: keep
|
||||
|
||||
@ -69,22 +70,22 @@ constexpr bool PrefixOf(const char* a, const char* b) {
|
||||
return *a == 0 || (*a == *b && internal::PrefixOf(a + 1, b + 1));
|
||||
}
|
||||
|
||||
template <int N, int M>
|
||||
template <size_t N, size_t M>
|
||||
constexpr bool StartsWith(const char (&prefix)[N], const char (&str)[M]) {
|
||||
return N <= M && internal::PrefixOf(prefix, str);
|
||||
}
|
||||
|
||||
template <int N, int M>
|
||||
template <size_t N, size_t M>
|
||||
constexpr bool EndsWith(const char (&suffix)[N], const char (&str)[M]) {
|
||||
return N <= M && internal::PrefixOf(suffix, str + M - N);
|
||||
}
|
||||
|
||||
template <int N, int M>
|
||||
template <size_t N, size_t M>
|
||||
constexpr bool Equals(const char (&a)[N], const char (&b)[M]) {
|
||||
return N == M && internal::PrefixOf(a, b);
|
||||
}
|
||||
|
||||
template <int N>
|
||||
template <size_t N>
|
||||
constexpr bool ValidateSpec(const char (&spec)[N]) {
|
||||
return internal::Equals("const", spec) ||
|
||||
internal::Equals("override", spec) ||
|
||||
@ -108,8 +109,11 @@ constexpr bool ValidateSpec(const char (&spec)[N]) {
|
||||
using internal::FunctionMocker;
|
||||
} // namespace testing
|
||||
|
||||
#define MOCK_METHOD(...) \
|
||||
GMOCK_PP_VARIADIC_CALL(GMOCK_INTERNAL_MOCK_METHOD_ARG_, __VA_ARGS__)
|
||||
#define MOCK_METHOD(...) \
|
||||
GMOCK_INTERNAL_WARNING_PUSH() \
|
||||
GMOCK_INTERNAL_WARNING_CLANG(ignored, "-Wunused-member-function") \
|
||||
GMOCK_PP_VARIADIC_CALL(GMOCK_INTERNAL_MOCK_METHOD_ARG_, __VA_ARGS__) \
|
||||
GMOCK_INTERNAL_WARNING_POP()
|
||||
|
||||
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_1(...) \
|
||||
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
|
||||
@ -177,8 +181,9 @@ using internal::FunctionMocker;
|
||||
_Signature)>::Result \
|
||||
GMOCK_INTERNAL_EXPAND(_CallType) \
|
||||
_MethodName(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N)) \
|
||||
GMOCK_PP_IF(_Constness, const, ) _RefSpec _NoexceptSpec \
|
||||
GMOCK_PP_IF(_Override, override, ) GMOCK_PP_IF(_Final, final, ) { \
|
||||
GMOCK_PP_IF(_Constness, const, ) \
|
||||
_RefSpec _NoexceptSpec GMOCK_PP_IF(_Override, override, ) \
|
||||
GMOCK_PP_IF(_Final, final, ) { \
|
||||
GMOCK_MOCKER_(_N, _Constness, _MethodName) \
|
||||
.SetOwnerAndName(this, #_MethodName); \
|
||||
return GMOCK_MOCKER_(_N, _Constness, _MethodName) \
|
||||
@ -511,4 +516,4 @@ using internal::FunctionMocker;
|
||||
#define GMOCK_MOCKER_(arity, constness, Method) \
|
||||
GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_
|
||||
|
@ -257,7 +257,10 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <exception>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <ios>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
@ -487,12 +490,12 @@ class MatcherBaseImpl<Derived<Ts...>> {
|
||||
|
||||
template <typename F>
|
||||
operator ::testing::Matcher<F>() const { // NOLINT(runtime/explicit)
|
||||
return Apply<F>(MakeIndexSequence<sizeof...(Ts)>{});
|
||||
return Apply<F>(std::make_index_sequence<sizeof...(Ts)>{});
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename F, std::size_t... tuple_ids>
|
||||
::testing::Matcher<F> Apply(IndexSequence<tuple_ids...>) const {
|
||||
::testing::Matcher<F> Apply(std::index_sequence<tuple_ids...>) const {
|
||||
return ::testing::Matcher<F>(
|
||||
new typename Derived<Ts...>::template gmock_Impl<F>(
|
||||
std::get<tuple_ids>(params_)...));
|
||||
@ -561,7 +564,7 @@ namespace internal {
|
||||
// If the explanation is not empty, prints it to the ostream.
|
||||
inline void PrintIfNotEmpty(const std::string& explanation,
|
||||
::std::ostream* os) {
|
||||
if (explanation != "" && os != nullptr) {
|
||||
if (!explanation.empty() && os != nullptr) {
|
||||
*os << ", " << explanation;
|
||||
}
|
||||
}
|
||||
@ -1045,7 +1048,7 @@ class StartsWithMatcher {
|
||||
template <typename MatcheeStringType>
|
||||
bool MatchAndExplain(const MatcheeStringType& s,
|
||||
MatchResultListener* /* listener */) const {
|
||||
const StringType& s2(s);
|
||||
const StringType s2(s);
|
||||
return s2.length() >= prefix_.length() &&
|
||||
s2.substr(0, prefix_.length()) == prefix_;
|
||||
}
|
||||
@ -1099,7 +1102,7 @@ class EndsWithMatcher {
|
||||
template <typename MatcheeStringType>
|
||||
bool MatchAndExplain(const MatcheeStringType& s,
|
||||
MatchResultListener* /* listener */) const {
|
||||
const StringType& s2(s);
|
||||
const StringType s2(s);
|
||||
return s2.length() >= suffix_.length() &&
|
||||
s2.substr(s2.length() - suffix_.length()) == suffix_;
|
||||
}
|
||||
@ -1198,27 +1201,27 @@ class PairMatchBase {
|
||||
};
|
||||
};
|
||||
|
||||
class Eq2Matcher : public PairMatchBase<Eq2Matcher, AnyEq> {
|
||||
class Eq2Matcher : public PairMatchBase<Eq2Matcher, std::equal_to<>> {
|
||||
public:
|
||||
static const char* Desc() { return "an equal pair"; }
|
||||
};
|
||||
class Ne2Matcher : public PairMatchBase<Ne2Matcher, AnyNe> {
|
||||
class Ne2Matcher : public PairMatchBase<Ne2Matcher, std::not_equal_to<>> {
|
||||
public:
|
||||
static const char* Desc() { return "an unequal pair"; }
|
||||
};
|
||||
class Lt2Matcher : public PairMatchBase<Lt2Matcher, AnyLt> {
|
||||
class Lt2Matcher : public PairMatchBase<Lt2Matcher, std::less<>> {
|
||||
public:
|
||||
static const char* Desc() { return "a pair where the first < the second"; }
|
||||
};
|
||||
class Gt2Matcher : public PairMatchBase<Gt2Matcher, AnyGt> {
|
||||
class Gt2Matcher : public PairMatchBase<Gt2Matcher, std::greater<>> {
|
||||
public:
|
||||
static const char* Desc() { return "a pair where the first > the second"; }
|
||||
};
|
||||
class Le2Matcher : public PairMatchBase<Le2Matcher, AnyLe> {
|
||||
class Le2Matcher : public PairMatchBase<Le2Matcher, std::less_equal<>> {
|
||||
public:
|
||||
static const char* Desc() { return "a pair where the first <= the second"; }
|
||||
};
|
||||
class Ge2Matcher : public PairMatchBase<Ge2Matcher, AnyGe> {
|
||||
class Ge2Matcher : public PairMatchBase<Ge2Matcher, std::greater_equal<>> {
|
||||
public:
|
||||
static const char* Desc() { return "a pair where the first >= the second"; }
|
||||
};
|
||||
@ -1472,6 +1475,7 @@ class SomeOfArrayMatcher {
|
||||
operator Matcher<U>() const { // NOLINT
|
||||
using RawU = typename std::decay<U>::type;
|
||||
std::vector<Matcher<RawU>> matchers;
|
||||
matchers.reserve(matchers_.size());
|
||||
for (const auto& matcher : matchers_) {
|
||||
matchers.push_back(MatcherCast<RawU>(matcher));
|
||||
}
|
||||
@ -2309,11 +2313,11 @@ class SizeIsMatcher {
|
||||
: size_matcher_(MatcherCast<SizeType>(size_matcher)) {}
|
||||
|
||||
void DescribeTo(::std::ostream* os) const override {
|
||||
*os << "size ";
|
||||
*os << "has a size that ";
|
||||
size_matcher_.DescribeTo(os);
|
||||
}
|
||||
void DescribeNegationTo(::std::ostream* os) const override {
|
||||
*os << "size ";
|
||||
*os << "has a size that ";
|
||||
size_matcher_.DescribeNegationTo(os);
|
||||
}
|
||||
|
||||
@ -2916,26 +2920,27 @@ class EachMatcher {
|
||||
const M inner_matcher_;
|
||||
};
|
||||
|
||||
struct Rank1 {};
|
||||
struct Rank0 : Rank1 {};
|
||||
// Use go/ranked-overloads for dispatching.
|
||||
struct Rank0 {};
|
||||
struct Rank1 : Rank0 {};
|
||||
|
||||
namespace pair_getters {
|
||||
using std::get;
|
||||
template <typename T>
|
||||
auto First(T& x, Rank1) -> decltype(get<0>(x)) { // NOLINT
|
||||
auto First(T& x, Rank0) -> decltype(get<0>(x)) { // NOLINT
|
||||
return get<0>(x);
|
||||
}
|
||||
template <typename T>
|
||||
auto First(T& x, Rank0) -> decltype((x.first)) { // NOLINT
|
||||
auto First(T& x, Rank1) -> decltype((x.first)) { // NOLINT
|
||||
return x.first;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto Second(T& x, Rank1) -> decltype(get<1>(x)) { // NOLINT
|
||||
auto Second(T& x, Rank0) -> decltype(get<1>(x)) { // NOLINT
|
||||
return get<1>(x);
|
||||
}
|
||||
template <typename T>
|
||||
auto Second(T& x, Rank0) -> decltype((x.second)) { // NOLINT
|
||||
auto Second(T& x, Rank1) -> decltype((x.second)) { // NOLINT
|
||||
return x.second;
|
||||
}
|
||||
} // namespace pair_getters
|
||||
@ -2961,9 +2966,9 @@ class KeyMatcherImpl : public MatcherInterface<PairType> {
|
||||
MatchResultListener* listener) const override {
|
||||
StringMatchResultListener inner_listener;
|
||||
const bool match = inner_matcher_.MatchAndExplain(
|
||||
pair_getters::First(key_value, Rank0()), &inner_listener);
|
||||
pair_getters::First(key_value, Rank1()), &inner_listener);
|
||||
const std::string explanation = inner_listener.str();
|
||||
if (explanation != "") {
|
||||
if (!explanation.empty()) {
|
||||
*listener << "whose first field is a value " << explanation;
|
||||
}
|
||||
return match;
|
||||
@ -3083,18 +3088,18 @@ class PairMatcherImpl : public MatcherInterface<PairType> {
|
||||
if (!listener->IsInterested()) {
|
||||
// If the listener is not interested, we don't need to construct the
|
||||
// explanation.
|
||||
return first_matcher_.Matches(pair_getters::First(a_pair, Rank0())) &&
|
||||
second_matcher_.Matches(pair_getters::Second(a_pair, Rank0()));
|
||||
return first_matcher_.Matches(pair_getters::First(a_pair, Rank1())) &&
|
||||
second_matcher_.Matches(pair_getters::Second(a_pair, Rank1()));
|
||||
}
|
||||
StringMatchResultListener first_inner_listener;
|
||||
if (!first_matcher_.MatchAndExplain(pair_getters::First(a_pair, Rank0()),
|
||||
if (!first_matcher_.MatchAndExplain(pair_getters::First(a_pair, Rank1()),
|
||||
&first_inner_listener)) {
|
||||
*listener << "whose first field does not match";
|
||||
PrintIfNotEmpty(first_inner_listener.str(), listener->stream());
|
||||
return false;
|
||||
}
|
||||
StringMatchResultListener second_inner_listener;
|
||||
if (!second_matcher_.MatchAndExplain(pair_getters::Second(a_pair, Rank0()),
|
||||
if (!second_matcher_.MatchAndExplain(pair_getters::Second(a_pair, Rank1()),
|
||||
&second_inner_listener)) {
|
||||
*listener << "whose second field does not match";
|
||||
PrintIfNotEmpty(second_inner_listener.str(), listener->stream());
|
||||
@ -3110,12 +3115,12 @@ class PairMatcherImpl : public MatcherInterface<PairType> {
|
||||
const std::string& second_explanation,
|
||||
MatchResultListener* listener) const {
|
||||
*listener << "whose both fields match";
|
||||
if (first_explanation != "") {
|
||||
if (!first_explanation.empty()) {
|
||||
*listener << ", where the first field is a value " << first_explanation;
|
||||
}
|
||||
if (second_explanation != "") {
|
||||
if (!second_explanation.empty()) {
|
||||
*listener << ", ";
|
||||
if (first_explanation != "") {
|
||||
if (!first_explanation.empty()) {
|
||||
*listener << "and ";
|
||||
} else {
|
||||
*listener << "where ";
|
||||
@ -3147,8 +3152,8 @@ class PairMatcher {
|
||||
};
|
||||
|
||||
template <typename T, size_t... I>
|
||||
auto UnpackStructImpl(const T& t, IndexSequence<I...>, int)
|
||||
-> decltype(std::tie(get<I>(t)...)) {
|
||||
auto UnpackStructImpl(const T& t, std::index_sequence<I...>,
|
||||
int) -> decltype(std::tie(get<I>(t)...)) {
|
||||
static_assert(std::tuple_size<T>::value == sizeof...(I),
|
||||
"Number of arguments doesn't match the number of fields.");
|
||||
return std::tie(get<I>(t)...);
|
||||
@ -3156,97 +3161,97 @@ auto UnpackStructImpl(const T& t, IndexSequence<I...>, int)
|
||||
|
||||
#if defined(__cpp_structured_bindings) && __cpp_structured_bindings >= 201606
|
||||
template <typename T>
|
||||
auto UnpackStructImpl(const T& t, MakeIndexSequence<1>, char) {
|
||||
auto UnpackStructImpl(const T& t, std::make_index_sequence<1>, char) {
|
||||
const auto& [a] = t;
|
||||
return std::tie(a);
|
||||
}
|
||||
template <typename T>
|
||||
auto UnpackStructImpl(const T& t, MakeIndexSequence<2>, char) {
|
||||
auto UnpackStructImpl(const T& t, std::make_index_sequence<2>, char) {
|
||||
const auto& [a, b] = t;
|
||||
return std::tie(a, b);
|
||||
}
|
||||
template <typename T>
|
||||
auto UnpackStructImpl(const T& t, MakeIndexSequence<3>, char) {
|
||||
auto UnpackStructImpl(const T& t, std::make_index_sequence<3>, char) {
|
||||
const auto& [a, b, c] = t;
|
||||
return std::tie(a, b, c);
|
||||
}
|
||||
template <typename T>
|
||||
auto UnpackStructImpl(const T& t, MakeIndexSequence<4>, char) {
|
||||
auto UnpackStructImpl(const T& t, std::make_index_sequence<4>, char) {
|
||||
const auto& [a, b, c, d] = t;
|
||||
return std::tie(a, b, c, d);
|
||||
}
|
||||
template <typename T>
|
||||
auto UnpackStructImpl(const T& t, MakeIndexSequence<5>, char) {
|
||||
auto UnpackStructImpl(const T& t, std::make_index_sequence<5>, char) {
|
||||
const auto& [a, b, c, d, e] = t;
|
||||
return std::tie(a, b, c, d, e);
|
||||
}
|
||||
template <typename T>
|
||||
auto UnpackStructImpl(const T& t, MakeIndexSequence<6>, char) {
|
||||
auto UnpackStructImpl(const T& t, std::make_index_sequence<6>, char) {
|
||||
const auto& [a, b, c, d, e, f] = t;
|
||||
return std::tie(a, b, c, d, e, f);
|
||||
}
|
||||
template <typename T>
|
||||
auto UnpackStructImpl(const T& t, MakeIndexSequence<7>, char) {
|
||||
auto UnpackStructImpl(const T& t, std::make_index_sequence<7>, char) {
|
||||
const auto& [a, b, c, d, e, f, g] = t;
|
||||
return std::tie(a, b, c, d, e, f, g);
|
||||
}
|
||||
template <typename T>
|
||||
auto UnpackStructImpl(const T& t, MakeIndexSequence<8>, char) {
|
||||
auto UnpackStructImpl(const T& t, std::make_index_sequence<8>, char) {
|
||||
const auto& [a, b, c, d, e, f, g, h] = t;
|
||||
return std::tie(a, b, c, d, e, f, g, h);
|
||||
}
|
||||
template <typename T>
|
||||
auto UnpackStructImpl(const T& t, MakeIndexSequence<9>, char) {
|
||||
auto UnpackStructImpl(const T& t, std::make_index_sequence<9>, char) {
|
||||
const auto& [a, b, c, d, e, f, g, h, i] = t;
|
||||
return std::tie(a, b, c, d, e, f, g, h, i);
|
||||
}
|
||||
template <typename T>
|
||||
auto UnpackStructImpl(const T& t, MakeIndexSequence<10>, char) {
|
||||
auto UnpackStructImpl(const T& t, std::make_index_sequence<10>, char) {
|
||||
const auto& [a, b, c, d, e, f, g, h, i, j] = t;
|
||||
return std::tie(a, b, c, d, e, f, g, h, i, j);
|
||||
}
|
||||
template <typename T>
|
||||
auto UnpackStructImpl(const T& t, MakeIndexSequence<11>, char) {
|
||||
auto UnpackStructImpl(const T& t, std::make_index_sequence<11>, char) {
|
||||
const auto& [a, b, c, d, e, f, g, h, i, j, k] = t;
|
||||
return std::tie(a, b, c, d, e, f, g, h, i, j, k);
|
||||
}
|
||||
template <typename T>
|
||||
auto UnpackStructImpl(const T& t, MakeIndexSequence<12>, char) {
|
||||
auto UnpackStructImpl(const T& t, std::make_index_sequence<12>, char) {
|
||||
const auto& [a, b, c, d, e, f, g, h, i, j, k, l] = t;
|
||||
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l);
|
||||
}
|
||||
template <typename T>
|
||||
auto UnpackStructImpl(const T& t, MakeIndexSequence<13>, char) {
|
||||
auto UnpackStructImpl(const T& t, std::make_index_sequence<13>, char) {
|
||||
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m] = t;
|
||||
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m);
|
||||
}
|
||||
template <typename T>
|
||||
auto UnpackStructImpl(const T& t, MakeIndexSequence<14>, char) {
|
||||
auto UnpackStructImpl(const T& t, std::make_index_sequence<14>, char) {
|
||||
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n] = t;
|
||||
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n);
|
||||
}
|
||||
template <typename T>
|
||||
auto UnpackStructImpl(const T& t, MakeIndexSequence<15>, char) {
|
||||
auto UnpackStructImpl(const T& t, std::make_index_sequence<15>, char) {
|
||||
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o] = t;
|
||||
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o);
|
||||
}
|
||||
template <typename T>
|
||||
auto UnpackStructImpl(const T& t, MakeIndexSequence<16>, char) {
|
||||
auto UnpackStructImpl(const T& t, std::make_index_sequence<16>, char) {
|
||||
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] = t;
|
||||
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p);
|
||||
}
|
||||
template <typename T>
|
||||
auto UnpackStructImpl(const T& t, MakeIndexSequence<17>, char) {
|
||||
auto UnpackStructImpl(const T& t, std::make_index_sequence<17>, char) {
|
||||
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q] = t;
|
||||
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q);
|
||||
}
|
||||
template <typename T>
|
||||
auto UnpackStructImpl(const T& t, MakeIndexSequence<18>, char) {
|
||||
auto UnpackStructImpl(const T& t, std::make_index_sequence<18>, char) {
|
||||
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r] = t;
|
||||
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r);
|
||||
}
|
||||
template <typename T>
|
||||
auto UnpackStructImpl(const T& t, MakeIndexSequence<19>, char) {
|
||||
auto UnpackStructImpl(const T& t, std::make_index_sequence<19>, char) {
|
||||
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s] = t;
|
||||
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s);
|
||||
}
|
||||
@ -3254,8 +3259,8 @@ auto UnpackStructImpl(const T& t, MakeIndexSequence<19>, char) {
|
||||
|
||||
template <size_t I, typename T>
|
||||
auto UnpackStruct(const T& t)
|
||||
-> decltype((UnpackStructImpl)(t, MakeIndexSequence<I>{}, 0)) {
|
||||
return (UnpackStructImpl)(t, MakeIndexSequence<I>{}, 0);
|
||||
-> decltype((UnpackStructImpl)(t, std::make_index_sequence<I>{}, 0)) {
|
||||
return (UnpackStructImpl)(t, std::make_index_sequence<I>{}, 0);
|
||||
}
|
||||
|
||||
// Helper function to do comma folding in C++11.
|
||||
@ -3268,7 +3273,7 @@ template <typename Struct, typename StructSize>
|
||||
class FieldsAreMatcherImpl;
|
||||
|
||||
template <typename Struct, size_t... I>
|
||||
class FieldsAreMatcherImpl<Struct, IndexSequence<I...>>
|
||||
class FieldsAreMatcherImpl<Struct, std::index_sequence<I...>>
|
||||
: public MatcherInterface<Struct> {
|
||||
using UnpackedType =
|
||||
decltype(UnpackStruct<sizeof...(I)>(std::declval<const Struct&>()));
|
||||
@ -3316,8 +3321,8 @@ class FieldsAreMatcherImpl<Struct, IndexSequence<I...>>
|
||||
std::vector<StringMatchResultListener> inner_listener(sizeof...(I));
|
||||
|
||||
VariadicExpand(
|
||||
{failed_pos == ~size_t{}&& !std::get<I>(matchers_).MatchAndExplain(
|
||||
std::get<I>(tuple), &inner_listener[I])
|
||||
{failed_pos == ~size_t{} && !std::get<I>(matchers_).MatchAndExplain(
|
||||
std::get<I>(tuple), &inner_listener[I])
|
||||
? failed_pos = I
|
||||
: 0 ...});
|
||||
if (failed_pos != ~size_t{}) {
|
||||
@ -3350,8 +3355,8 @@ class FieldsAreMatcher {
|
||||
template <typename Struct>
|
||||
operator Matcher<Struct>() const { // NOLINT
|
||||
return Matcher<Struct>(
|
||||
new FieldsAreMatcherImpl<const Struct&, IndexSequenceFor<Inner...>>(
|
||||
matchers_));
|
||||
new FieldsAreMatcherImpl<const Struct&,
|
||||
std::index_sequence_for<Inner...>>(matchers_));
|
||||
}
|
||||
|
||||
private:
|
||||
@ -3644,23 +3649,6 @@ class UnorderedElementsAreMatcherImpl
|
||||
AnalyzeElements(stl_container.begin(), stl_container.end(),
|
||||
&element_printouts, listener);
|
||||
|
||||
if (matrix.LhsSize() == 0 && matrix.RhsSize() == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
|
||||
if (matrix.LhsSize() != matrix.RhsSize()) {
|
||||
// The element count doesn't match. If the container is empty,
|
||||
// there's no need to explain anything as Google Mock already
|
||||
// prints the empty container. Otherwise we just need to show
|
||||
// how many elements there actually are.
|
||||
if (matrix.LhsSize() != 0 && listener->IsInterested()) {
|
||||
*listener << "which has " << Elements(matrix.LhsSize());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return VerifyMatchMatrix(element_printouts, matrix, listener) &&
|
||||
FindPairing(matrix, listener);
|
||||
}
|
||||
@ -4115,7 +4103,12 @@ class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
|
||||
const char* sep = "";
|
||||
// Workaround spurious C4189 on MSVC<=15.7 when k is empty.
|
||||
(void)sep;
|
||||
const char* dummy[] = {"", (*os << sep << "#" << k, sep = ", ")...};
|
||||
// The static_cast to void is needed to silence Clang's -Wcomma warning.
|
||||
// This pattern looks suspiciously like we may have mismatched parentheses
|
||||
// and may have been trying to use the first operation of the comma operator
|
||||
// as a member of the array, so Clang warns that we may have made a mistake.
|
||||
const char* dummy[] = {
|
||||
"", (static_cast<void>(*os << sep << "#" << k), sep = ", ")...};
|
||||
(void)dummy;
|
||||
*os << ") ";
|
||||
}
|
||||
@ -5452,42 +5445,47 @@ PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> ThrowsMessage(
|
||||
::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
|
||||
|
||||
// MATCHER* macros itself are listed below.
|
||||
#define MATCHER(name, description) \
|
||||
class name##Matcher \
|
||||
: public ::testing::internal::MatcherBaseImpl<name##Matcher> { \
|
||||
public: \
|
||||
template <typename arg_type> \
|
||||
class gmock_Impl : public ::testing::MatcherInterface<const arg_type&> { \
|
||||
public: \
|
||||
gmock_Impl() {} \
|
||||
bool MatchAndExplain( \
|
||||
const arg_type& arg, \
|
||||
::testing::MatchResultListener* result_listener) const override; \
|
||||
void DescribeTo(::std::ostream* gmock_os) const override { \
|
||||
*gmock_os << FormatDescription(false); \
|
||||
} \
|
||||
void DescribeNegationTo(::std::ostream* gmock_os) const override { \
|
||||
*gmock_os << FormatDescription(true); \
|
||||
} \
|
||||
\
|
||||
private: \
|
||||
::std::string FormatDescription(bool negation) const { \
|
||||
/* NOLINTNEXTLINE readability-redundant-string-init */ \
|
||||
::std::string gmock_description = (description); \
|
||||
if (!gmock_description.empty()) { \
|
||||
return gmock_description; \
|
||||
} \
|
||||
return ::testing::internal::FormatMatcherDescription(negation, #name, \
|
||||
{}, {}); \
|
||||
} \
|
||||
}; \
|
||||
}; \
|
||||
GTEST_ATTRIBUTE_UNUSED_ inline name##Matcher name() { return {}; } \
|
||||
template <typename arg_type> \
|
||||
bool name##Matcher::gmock_Impl<arg_type>::MatchAndExplain( \
|
||||
const arg_type& arg, \
|
||||
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_) \
|
||||
const
|
||||
#define MATCHER(name, description) \
|
||||
class name##Matcher \
|
||||
: public ::testing::internal::MatcherBaseImpl<name##Matcher> { \
|
||||
public: \
|
||||
template <typename arg_type> \
|
||||
class gmock_Impl : public ::testing::MatcherInterface<const arg_type&> { \
|
||||
public: \
|
||||
gmock_Impl() {} \
|
||||
bool MatchAndExplain( \
|
||||
const arg_type& arg, \
|
||||
::testing::MatchResultListener* result_listener) const override; \
|
||||
void DescribeTo(::std::ostream* gmock_os) const override { \
|
||||
*gmock_os << FormatDescription(false); \
|
||||
} \
|
||||
void DescribeNegationTo(::std::ostream* gmock_os) const override { \
|
||||
*gmock_os << FormatDescription(true); \
|
||||
} \
|
||||
\
|
||||
private: \
|
||||
::std::string FormatDescription(bool negation) const { \
|
||||
/* NOLINTNEXTLINE readability-redundant-string-init */ \
|
||||
::std::string gmock_description = (description); \
|
||||
if (!gmock_description.empty()) { \
|
||||
return gmock_description; \
|
||||
} \
|
||||
return ::testing::internal::FormatMatcherDescription(negation, #name, \
|
||||
{}, {}); \
|
||||
} \
|
||||
}; \
|
||||
}; \
|
||||
inline name##Matcher GMOCK_INTERNAL_WARNING_PUSH() \
|
||||
GMOCK_INTERNAL_WARNING_CLANG(ignored, "-Wunused-function") \
|
||||
GMOCK_INTERNAL_WARNING_CLANG(ignored, "-Wunused-member-function") \
|
||||
name GMOCK_INTERNAL_WARNING_POP()() { \
|
||||
return {}; \
|
||||
} \
|
||||
template <typename arg_type> \
|
||||
bool name##Matcher::gmock_Impl<arg_type>::MatchAndExplain( \
|
||||
const arg_type& arg, \
|
||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED ::testing::MatchResultListener* \
|
||||
result_listener) const
|
||||
|
||||
#define MATCHER_P(name, p0, description) \
|
||||
GMOCK_INTERNAL_MATCHER(name, name##MatcherP, description, (#p0), (p0))
|
||||
@ -5548,7 +5546,8 @@ PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> ThrowsMessage(
|
||||
\
|
||||
private: \
|
||||
::std::string FormatDescription(bool negation) const { \
|
||||
::std::string gmock_description = (description); \
|
||||
::std::string gmock_description; \
|
||||
gmock_description = (description); \
|
||||
if (!gmock_description.empty()) { \
|
||||
return gmock_description; \
|
||||
} \
|
||||
@ -5568,11 +5567,11 @@ PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> ThrowsMessage(
|
||||
} \
|
||||
template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)> \
|
||||
template <typename arg_type> \
|
||||
bool full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>::gmock_Impl< \
|
||||
arg_type>::MatchAndExplain(const arg_type& arg, \
|
||||
::testing::MatchResultListener* \
|
||||
result_listener GTEST_ATTRIBUTE_UNUSED_) \
|
||||
const
|
||||
bool full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>:: \
|
||||
gmock_Impl<arg_type>::MatchAndExplain( \
|
||||
const arg_type& arg, \
|
||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED ::testing:: \
|
||||
MatchResultListener* result_listener) const
|
||||
|
||||
#define GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args) \
|
||||
GMOCK_PP_TAIL( \
|
||||
|
@ -526,9 +526,10 @@
|
||||
GMOCK_INTERNAL_LIST_##value_params)){}) \
|
||||
GMOCK_ACTION_CLASS_(name, value_params)(const GMOCK_ACTION_CLASS_( \
|
||||
name, value_params) &) noexcept GMOCK_INTERNAL_DEFN_COPY_ \
|
||||
##value_params GMOCK_ACTION_CLASS_(name, value_params)( \
|
||||
GMOCK_ACTION_CLASS_(name, value_params) &&) noexcept \
|
||||
GMOCK_INTERNAL_DEFN_COPY_##value_params template <typename F> \
|
||||
##value_params \
|
||||
GMOCK_ACTION_CLASS_(name, value_params)(GMOCK_ACTION_CLASS_( \
|
||||
name, value_params) &&) noexcept GMOCK_INTERNAL_DEFN_COPY_ \
|
||||
##value_params template <typename F> \
|
||||
operator ::testing::Action<F>() const { \
|
||||
return GMOCK_PP_IF( \
|
||||
GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
|
||||
@ -582,10 +583,7 @@ namespace testing {
|
||||
// the macro definition, as the warnings are generated when the macro
|
||||
// is expanded and macro expansion cannot contain #pragma. Therefore
|
||||
// we suppress them here.
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4100)
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)
|
||||
|
||||
namespace internal {
|
||||
|
||||
@ -594,21 +592,22 @@ namespace internal {
|
||||
// Overloads for other custom-callables are provided in the
|
||||
// internal/custom/gmock-generated-actions.h header.
|
||||
template <typename F, typename... Args>
|
||||
auto InvokeArgument(F f, Args... args) -> decltype(f(args...)) {
|
||||
return f(args...);
|
||||
auto InvokeArgument(F &&f,
|
||||
Args... args) -> decltype(std::forward<F>(f)(args...)) {
|
||||
return std::forward<F>(f)(args...);
|
||||
}
|
||||
|
||||
template <std::size_t index, typename... Params>
|
||||
struct InvokeArgumentAction {
|
||||
template <typename... Args,
|
||||
typename = typename std::enable_if<(index < sizeof...(Args))>::type>
|
||||
auto operator()(Args&&... args) const -> decltype(internal::InvokeArgument(
|
||||
auto operator()(Args &&...args) const -> decltype(internal::InvokeArgument(
|
||||
std::get<index>(std::forward_as_tuple(std::forward<Args>(args)...)),
|
||||
std::declval<const Params&>()...)) {
|
||||
internal::FlatTuple<Args&&...> args_tuple(FlatTupleConstructTag{},
|
||||
std::forward<Args>(args)...);
|
||||
return params.Apply([&](const Params&... unpacked_params) {
|
||||
auto&& callable = args_tuple.template Get<index>();
|
||||
std::declval<const Params &>()...)) {
|
||||
internal::FlatTuple<Args &&...> args_tuple(FlatTupleConstructTag{},
|
||||
std::forward<Args>(args)...);
|
||||
return params.Apply([&](const Params &...unpacked_params) {
|
||||
auto &&callable = std::move(args_tuple.template Get<index>());
|
||||
return internal::InvokeArgument(
|
||||
std::forward<decltype(callable)>(callable), unpacked_params...);
|
||||
});
|
||||
@ -648,14 +647,12 @@ struct InvokeArgumentAction {
|
||||
// later.
|
||||
template <std::size_t index, typename... Params>
|
||||
internal::InvokeArgumentAction<index, typename std::decay<Params>::type...>
|
||||
InvokeArgument(Params&&... params) {
|
||||
InvokeArgument(Params &&...params) {
|
||||
return {internal::FlatTuple<typename std::decay<Params>::type...>(
|
||||
internal::FlatTupleConstructTag{}, std::forward<Params>(params)...)};
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100
|
||||
|
||||
} // namespace testing
|
||||
|
||||
|
@ -49,14 +49,11 @@ namespace testing {
|
||||
|
||||
// Silence C4100 (unreferenced formal
|
||||
// parameter) for MSVC
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4100)
|
||||
#if (_MSC_VER == 1900)
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)
|
||||
#if defined(_MSC_VER) && (_MSC_VER == 1900)
|
||||
// and silence C4800 (C4800: 'int *const ': forcing value
|
||||
// to bool 'true' or 'false') for MSVC 14
|
||||
#pragma warning(disable : 4800)
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800)
|
||||
#endif
|
||||
|
||||
namespace internal {
|
||||
@ -113,9 +110,10 @@ MATCHER(IsFalse, negation ? "is true" : "is false") {
|
||||
return !static_cast<bool>(arg);
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#if defined(_MSC_VER) && (_MSC_VER == 1900)
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4800
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100
|
||||
|
||||
} // namespace testing
|
||||
|
||||
|
@ -98,7 +98,7 @@ constexpr bool HasStrictnessModifier() {
|
||||
// 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 && \
|
||||
#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MINGW) && \
|
||||
(defined(_MSC_VER) || defined(__clang__))
|
||||
// We need to mark these classes with this declspec to ensure that
|
||||
// the empty base class optimization is performed.
|
||||
|
@ -65,6 +65,7 @@
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
@ -203,6 +204,9 @@ class GTEST_API_ UntypedFunctionMockerBase {
|
||||
|
||||
using UntypedExpectations = std::vector<std::shared_ptr<ExpectationBase>>;
|
||||
|
||||
struct UninterestingCallCleanupHandler;
|
||||
struct FailureCleanupHandler;
|
||||
|
||||
// Returns an Expectation object that references and co-owns exp,
|
||||
// which must be an expectation on this mock function.
|
||||
Expectation GetHandleOf(ExpectationBase* exp);
|
||||
@ -562,7 +566,7 @@ class ExpectationSet {
|
||||
typedef Expectation::Set::value_type value_type;
|
||||
|
||||
// Constructs an empty set.
|
||||
ExpectationSet() {}
|
||||
ExpectationSet() = default;
|
||||
|
||||
// This single-argument ctor must not be explicit, in order to support the
|
||||
// ExpectationSet es = EXPECT_CALL(...);
|
||||
@ -656,7 +660,7 @@ class GTEST_API_ InSequence {
|
||||
|
||||
InSequence(const InSequence&) = delete;
|
||||
InSequence& operator=(const InSequence&) = delete;
|
||||
} GTEST_ATTRIBUTE_UNUSED_;
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
@ -706,6 +710,12 @@ class GTEST_API_ ExpectationBase {
|
||||
// describes it to the ostream.
|
||||
virtual void MaybeDescribeExtraMatcherTo(::std::ostream* os) = 0;
|
||||
|
||||
// Do not rely on this for correctness.
|
||||
// This is only for making human-readable test output easier to understand.
|
||||
void UntypedDescription(std::string description) {
|
||||
description_ = std::move(description);
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class ::testing::Expectation;
|
||||
friend class UntypedFunctionMockerBase;
|
||||
@ -772,6 +782,10 @@ class GTEST_API_ ExpectationBase {
|
||||
retired_ = true;
|
||||
}
|
||||
|
||||
// Returns a human-readable description of this expectation.
|
||||
// Do not rely on this for correctness. It is only for human readability.
|
||||
const std::string& GetDescription() const { return description_; }
|
||||
|
||||
// Returns true if and only if this expectation is satisfied.
|
||||
bool IsSatisfied() const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
g_gmock_mutex.AssertHeld();
|
||||
@ -831,6 +845,7 @@ class GTEST_API_ ExpectationBase {
|
||||
const char* file_; // The file that contains the expectation.
|
||||
int line_; // The line number of the expectation.
|
||||
const std::string source_text_; // The EXPECT_CALL(...) source text.
|
||||
std::string description_; // User-readable name for the expectation.
|
||||
// True if and only if the cardinality is specified explicitly.
|
||||
bool cardinality_specified_;
|
||||
Cardinality cardinality_; // The cardinality of the expectation.
|
||||
@ -909,6 +924,13 @@ class TypedExpectation<R(Args...)> : public ExpectationBase {
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Do not rely on this for correctness.
|
||||
// This is only for making human-readable test output easier to understand.
|
||||
TypedExpectation& Description(std::string name) {
|
||||
ExpectationBase::UntypedDescription(std::move(name));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Implements the .Times() clause.
|
||||
TypedExpectation& Times(const Cardinality& a_cardinality) {
|
||||
ExpectationBase::UntypedTimes(a_cardinality);
|
||||
@ -1199,10 +1221,15 @@ class TypedExpectation<R(Args...)> : public ExpectationBase {
|
||||
::std::ostream* why)
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
g_gmock_mutex.AssertHeld();
|
||||
const ::std::string& expectation_description = GetDescription();
|
||||
if (IsSaturated()) {
|
||||
// We have an excessive call.
|
||||
IncrementCallCount();
|
||||
*what << "Mock function called more times than expected - ";
|
||||
*what << "Mock function ";
|
||||
if (!expectation_description.empty()) {
|
||||
*what << "\"" << expectation_description << "\" ";
|
||||
}
|
||||
*what << "called more times than expected - ";
|
||||
mocker->DescribeDefaultActionTo(args, what);
|
||||
DescribeCallCountTo(why);
|
||||
|
||||
@ -1217,7 +1244,11 @@ class TypedExpectation<R(Args...)> : public ExpectationBase {
|
||||
}
|
||||
|
||||
// Must be done after IncrementCount()!
|
||||
*what << "Mock function call matches " << source_text() << "...\n";
|
||||
*what << "Mock function ";
|
||||
if (!expectation_description.empty()) {
|
||||
*what << "\"" << expectation_description << "\" ";
|
||||
}
|
||||
*what << "call matches " << source_text() << "...\n";
|
||||
return &(GetCurrentAction(mocker, args));
|
||||
}
|
||||
|
||||
@ -1368,6 +1399,41 @@ class Cleanup final {
|
||||
std::function<void()> f_;
|
||||
};
|
||||
|
||||
struct UntypedFunctionMockerBase::UninterestingCallCleanupHandler {
|
||||
CallReaction reaction;
|
||||
std::stringstream& ss;
|
||||
|
||||
~UninterestingCallCleanupHandler() {
|
||||
ReportUninterestingCall(reaction, ss.str());
|
||||
}
|
||||
};
|
||||
|
||||
struct UntypedFunctionMockerBase::FailureCleanupHandler {
|
||||
std::stringstream& ss;
|
||||
std::stringstream& why;
|
||||
std::stringstream& loc;
|
||||
const ExpectationBase* untyped_expectation;
|
||||
bool found;
|
||||
bool is_excessive;
|
||||
|
||||
~FailureCleanupHandler() {
|
||||
ss << "\n" << why.str();
|
||||
|
||||
if (!found) {
|
||||
// No expectation matches this call - reports a failure.
|
||||
Expect(false, nullptr, -1, ss.str());
|
||||
} else if (is_excessive) {
|
||||
// We had an upper-bound violation and the failure message is in ss.
|
||||
Expect(false, untyped_expectation->file(), untyped_expectation->line(),
|
||||
ss.str());
|
||||
} else {
|
||||
// We had an expected call and the matching expectation is
|
||||
// described in ss.
|
||||
Log(kInfo, loc.str() + ss.str(), 2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
class FunctionMocker;
|
||||
|
||||
@ -1380,7 +1446,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
||||
using ArgumentTuple = std::tuple<Args...>;
|
||||
using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;
|
||||
|
||||
FunctionMocker() {}
|
||||
FunctionMocker() = default;
|
||||
|
||||
// There is no generally useful and implementable semantics of
|
||||
// copying a mock object, so copying a mock is usually a user error.
|
||||
@ -1766,8 +1832,15 @@ R FunctionMocker<R(Args...)>::InvokeWith(ArgumentTuple&& args)
|
||||
//
|
||||
// We use RAII to do the latter in case R is void or a non-moveable type. In
|
||||
// either case we can't assign it to a local variable.
|
||||
const Cleanup report_uninteresting_call(
|
||||
[&] { ReportUninterestingCall(reaction, ss.str()); });
|
||||
//
|
||||
// Note that std::bind() is essential here.
|
||||
// We *don't* use any local callback types (like lambdas).
|
||||
// Doing so slows down compilation dramatically because the *constructor* of
|
||||
// std::function<T> is re-instantiated with different template
|
||||
// parameters each time.
|
||||
const UninterestingCallCleanupHandler report_uninteresting_call = {
|
||||
reaction, ss
|
||||
};
|
||||
|
||||
return PerformActionAndPrintResult(nullptr, std::move(args), ss.str(), ss);
|
||||
}
|
||||
@ -1811,22 +1884,14 @@ R FunctionMocker<R(Args...)>::InvokeWith(ArgumentTuple&& args)
|
||||
//
|
||||
// We use RAII to do the latter in case R is void or a non-moveable type. In
|
||||
// either case we can't assign it to a local variable.
|
||||
const Cleanup handle_failures([&] {
|
||||
ss << "\n" << why.str();
|
||||
|
||||
if (!found) {
|
||||
// No expectation matches this call - reports a failure.
|
||||
Expect(false, nullptr, -1, ss.str());
|
||||
} else if (is_excessive) {
|
||||
// We had an upper-bound violation and the failure message is in ss.
|
||||
Expect(false, untyped_expectation->file(), untyped_expectation->line(),
|
||||
ss.str());
|
||||
} else {
|
||||
// We had an expected call and the matching expectation is
|
||||
// described in ss.
|
||||
Log(kInfo, loc.str() + ss.str(), 2);
|
||||
}
|
||||
});
|
||||
//
|
||||
// Note that we *don't* use any local callback types (like lambdas) here.
|
||||
// Doing so slows down compilation dramatically because the *constructor* of
|
||||
// std::function<T> is re-instantiated with different template
|
||||
// parameters each time.
|
||||
const FailureCleanupHandler handle_failures = {
|
||||
ss, why, loc, untyped_expectation, found, is_excessive
|
||||
};
|
||||
|
||||
return PerformActionAndPrintResult(untyped_action, std::move(args), ss.str(),
|
||||
ss);
|
||||
|
@ -53,13 +53,14 @@
|
||||
//
|
||||
// where all clauses are optional and WillOnce() can be repeated.
|
||||
|
||||
#include "gmock/gmock-actions.h"
|
||||
#include "gmock/gmock-cardinalities.h"
|
||||
#include "gmock/gmock-function-mocker.h"
|
||||
#include "gmock/gmock-matchers.h"
|
||||
#include "gmock/gmock-more-actions.h"
|
||||
#include "gmock/gmock-more-matchers.h"
|
||||
#include "gmock/gmock-nice-strict.h"
|
||||
#include "gmock/gmock-actions.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-cardinalities.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-function-mocker.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-matchers.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-more-actions.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-more-matchers.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-nice-strict.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-spec-builders.h" // IWYU pragma: export
|
||||
#include "gmock/internal/gmock-internal-utils.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
@ -58,11 +59,7 @@ namespace internal {
|
||||
|
||||
// Silence MSVC C4100 (unreferenced formal parameter) and
|
||||
// C4805('==': unsafe mix of type 'const int' and type 'const bool')
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4100)
|
||||
#pragma warning(disable : 4805)
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100 4805)
|
||||
|
||||
// Joins a vector of strings as if they are fields of a tuple; returns
|
||||
// the joined string.
|
||||
@ -95,6 +92,24 @@ inline Element* GetRawPointer(Element* p) {
|
||||
return p;
|
||||
}
|
||||
|
||||
// Default definitions for all compilers.
|
||||
// NOTE: If you implement support for other compilers, make sure to avoid
|
||||
// unexpected overlaps.
|
||||
// (e.g., Clang also processes #pragma GCC, and clang-cl also handles _MSC_VER.)
|
||||
#define GMOCK_INTERNAL_WARNING_PUSH()
|
||||
#define GMOCK_INTERNAL_WARNING_CLANG(Level, Name)
|
||||
#define GMOCK_INTERNAL_WARNING_POP()
|
||||
|
||||
#if defined(__clang__)
|
||||
#undef GMOCK_INTERNAL_WARNING_PUSH
|
||||
#define GMOCK_INTERNAL_WARNING_PUSH() _Pragma("clang diagnostic push")
|
||||
#undef GMOCK_INTERNAL_WARNING_CLANG
|
||||
#define GMOCK_INTERNAL_WARNING_CLANG(Level, Warning) \
|
||||
_Pragma(GMOCK_PP_INTERNAL_STRINGIZE(clang diagnostic Level Warning))
|
||||
#undef GMOCK_INTERNAL_WARNING_POP
|
||||
#define GMOCK_INTERNAL_WARNING_POP() _Pragma("clang diagnostic pop")
|
||||
#endif
|
||||
|
||||
// MSVC treats wchar_t as a native type usually, but treats it as the
|
||||
// same as unsigned short when the compiler option /Zc:wchar_t- is
|
||||
// specified. It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t
|
||||
@ -210,7 +225,7 @@ class FailureReporterInterface {
|
||||
// The type of a failure (either non-fatal or fatal).
|
||||
enum FailureType { kNonfatal, kFatal };
|
||||
|
||||
virtual ~FailureReporterInterface() {}
|
||||
virtual ~FailureReporterInterface() = default;
|
||||
|
||||
// Reports a failure that occurred at the given source file location.
|
||||
virtual void ReportFailure(FailureType type, const char* file, int line,
|
||||
@ -290,13 +305,6 @@ class WithoutMatchers {
|
||||
// Internal use only: access the singleton instance of WithoutMatchers.
|
||||
GTEST_API_ WithoutMatchers GetWithoutMatchers();
|
||||
|
||||
// Disable MSVC warnings for infinite recursion, since in this case the
|
||||
// recursion is unreachable.
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4717)
|
||||
#endif
|
||||
|
||||
// Invalid<T>() is usable as an expression of type T, but will terminate
|
||||
// the program with an assertion failure if actually run. This is useful
|
||||
// when a value of type T is needed for compilation, but the statement
|
||||
@ -304,7 +312,8 @@ GTEST_API_ WithoutMatchers GetWithoutMatchers();
|
||||
// crashes).
|
||||
template <typename T>
|
||||
inline T Invalid() {
|
||||
Assert(false, "", -1, "Internal error: attempt to return invalid value");
|
||||
Assert(/*condition=*/false, /*file=*/"", /*line=*/-1,
|
||||
"Internal error: attempt to return invalid value");
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
__builtin_unreachable();
|
||||
#elif defined(_MSC_VER)
|
||||
@ -314,10 +323,6 @@ inline T Invalid() {
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
// Given a raw type (i.e. having no top-level reference or const
|
||||
// modifier) RawContainer that's either an STL-style container or a
|
||||
// native array, class StlContainerView<RawContainer> has the
|
||||
@ -416,7 +421,7 @@ struct RemoveConstFromKey<std::pair<const K, V> > {
|
||||
GTEST_API_ void IllegalDoDefault(const char* file, int line);
|
||||
|
||||
template <typename F, typename Tuple, size_t... Idx>
|
||||
auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>)
|
||||
auto ApplyImpl(F&& f, Tuple&& args, std::index_sequence<Idx...>)
|
||||
-> decltype(std::forward<F>(f)(
|
||||
std::get<Idx>(std::forward<Tuple>(args))...)) {
|
||||
return std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...);
|
||||
@ -424,12 +429,13 @@ auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>)
|
||||
|
||||
// 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),
|
||||
std::make_index_sequence<std::tuple_size<
|
||||
typename std::remove_reference<Tuple>::type>::value>())) {
|
||||
return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
|
||||
MakeIndexSequence<std::tuple_size<
|
||||
std::make_index_sequence<std::tuple_size<
|
||||
typename std::remove_reference<Tuple>::type>::value>());
|
||||
}
|
||||
|
||||
@ -461,14 +467,21 @@ struct Function<R(Args...)> {
|
||||
using MakeResultIgnoredValue = IgnoredValue(Args...);
|
||||
};
|
||||
|
||||
#ifdef GTEST_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
|
||||
template <typename R, typename... Args>
|
||||
constexpr size_t Function<R(Args...)>::ArgumentCount;
|
||||
#endif
|
||||
|
||||
// Workaround for MSVC error C2039: 'type': is not a member of 'std'
|
||||
// when std::tuple_element is used.
|
||||
// See: https://github.com/google/googletest/issues/3931
|
||||
// Can be replaced with std::tuple_element_t in C++14.
|
||||
template <size_t I, typename T>
|
||||
using TupleElement = typename std::tuple_element<I, T>::type;
|
||||
|
||||
bool Base64Unescape(const std::string& encoded, std::string* decoded);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100 4805
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
@ -56,7 +56,7 @@
|
||||
#include "gmock/internal/custom/gmock-port.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
#if GTEST_HAS_ABSL
|
||||
#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
|
||||
#include "absl/flags/declare.h"
|
||||
#include "absl/flags/flag.h"
|
||||
#endif
|
||||
@ -73,7 +73,7 @@
|
||||
#define GMOCK_FLAG(name) FLAGS_gmock_##name
|
||||
|
||||
// Pick a command line flags implementation.
|
||||
#if GTEST_HAS_ABSL
|
||||
#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
|
||||
|
||||
// Macros for defining flags.
|
||||
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||
@ -95,7 +95,7 @@
|
||||
#define GMOCK_FLAG_SET(name, value) \
|
||||
(void)(::absl::SetFlag(&GMOCK_FLAG(name), value))
|
||||
|
||||
#else // GTEST_HAS_ABSL
|
||||
#else // defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
|
||||
|
||||
// Macros for defining flags.
|
||||
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||
@ -134,6 +134,6 @@
|
||||
#define GMOCK_FLAG_GET(name) ::testing::GMOCK_FLAG(name)
|
||||
#define GMOCK_FLAG_SET(name, value) (void)(::testing::GMOCK_FLAG(name) = value)
|
||||
|
||||
#endif // GTEST_HAS_ABSL
|
||||
#endif // defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||
|
@ -41,8 +41,10 @@
|
||||
#include <cctype>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
@ -87,7 +89,7 @@ GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name) {
|
||||
(!IsDigit(prev_char) && IsDigit(*p));
|
||||
|
||||
if (IsAlNum(*p)) {
|
||||
if (starts_new_word && result != "") result += ' ';
|
||||
if (starts_new_word && !result.empty()) result += ' ';
|
||||
result += ToLower(*p);
|
||||
}
|
||||
}
|
||||
@ -198,6 +200,10 @@ GTEST_API_ void IllegalDoDefault(const char* file, int line) {
|
||||
"the variable in various places.");
|
||||
}
|
||||
|
||||
constexpr char UndoWebSafeEncoding(char c) {
|
||||
return c == '-' ? '+' : c == '_' ? '/' : c;
|
||||
}
|
||||
|
||||
constexpr char UnBase64Impl(char c, const char* const base64, char carry) {
|
||||
return *base64 == 0 ? static_cast<char>(65)
|
||||
: *base64 == c
|
||||
@ -206,13 +212,14 @@ constexpr char UnBase64Impl(char c, const char* const base64, char carry) {
|
||||
}
|
||||
|
||||
template <size_t... I>
|
||||
constexpr std::array<char, 256> UnBase64Impl(IndexSequence<I...>,
|
||||
constexpr std::array<char, 256> UnBase64Impl(std::index_sequence<I...>,
|
||||
const char* const base64) {
|
||||
return {{UnBase64Impl(static_cast<char>(I), base64, 0)...}};
|
||||
return {
|
||||
{UnBase64Impl(UndoWebSafeEncoding(static_cast<char>(I)), base64, 0)...}};
|
||||
}
|
||||
|
||||
constexpr std::array<char, 256> UnBase64(const char* const base64) {
|
||||
return UnBase64Impl(MakeIndexSequence<256>{}, base64);
|
||||
return UnBase64Impl(std::make_index_sequence<256>{}, base64);
|
||||
}
|
||||
|
||||
static constexpr char kBase64[] =
|
||||
|
@ -53,7 +53,7 @@ GTEST_API_ std::string FormatMatcherDescription(
|
||||
bool negation, const char* matcher_name,
|
||||
const std::vector<const char*>& param_names, const Strings& param_values) {
|
||||
std::string result = ConvertIdentifierNameToWords(matcher_name);
|
||||
if (param_values.size() >= 1) {
|
||||
if (!param_values.empty()) {
|
||||
result += " " + JoinAsKeyValueTuple(param_names, param_values);
|
||||
}
|
||||
return negation ? "not (" + result + ")" : result;
|
||||
@ -120,7 +120,7 @@ GTEST_API_ std::string FormatMatcherDescription(
|
||||
// [1] Cormen, et al (2001). "Section 26.2: The Ford-Fulkerson method".
|
||||
// "Introduction to Algorithms (Second ed.)", pp. 651-664.
|
||||
// [2] "Ford-Fulkerson algorithm", Wikipedia,
|
||||
// 'http://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm'
|
||||
// 'https://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm'
|
||||
class MaxBipartiteMatchState {
|
||||
public:
|
||||
explicit MaxBipartiteMatchState(const MatchMatrix& graph)
|
||||
@ -370,6 +370,23 @@ void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(
|
||||
bool UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix(
|
||||
const ::std::vector<std::string>& element_printouts,
|
||||
const MatchMatrix& matrix, MatchResultListener* listener) const {
|
||||
if (matrix.LhsSize() == 0 && matrix.RhsSize() == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
|
||||
if (matrix.LhsSize() != matrix.RhsSize()) {
|
||||
// The element count doesn't match. If the container is empty,
|
||||
// there's no need to explain anything as Google Mock already
|
||||
// prints the empty container. Otherwise we just need to show
|
||||
// how many elements there actually are.
|
||||
if (matrix.LhsSize() != 0 && listener->IsInterested()) {
|
||||
*listener << "which has " << Elements(matrix.LhsSize());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool result = true;
|
||||
::std::vector<char> element_matched(matrix.LhsSize(), 0);
|
||||
::std::vector<char> matcher_matched(matrix.RhsSize(), 0);
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
@ -48,17 +49,17 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC
|
||||
#if defined(GTEST_OS_CYGWIN) || defined(GTEST_OS_LINUX) || defined(GTEST_OS_MAC)
|
||||
#include <unistd.h> // NOLINT
|
||||
#endif
|
||||
#ifdef GTEST_OS_QURT
|
||||
#include <qurt_event.h>
|
||||
#endif
|
||||
|
||||
// Silence C4800 (C4800: 'int *const ': forcing value
|
||||
// to bool 'true' or 'false') for MSVC 15
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER == 1900
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4800)
|
||||
#endif
|
||||
#if defined(_MSC_VER) && (_MSC_VER == 1900)
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800)
|
||||
#endif
|
||||
|
||||
namespace testing {
|
||||
@ -95,7 +96,7 @@ ExpectationBase::ExpectationBase(const char* a_file, int a_line,
|
||||
action_count_checked_(false) {}
|
||||
|
||||
// Destructs an ExpectationBase object.
|
||||
ExpectationBase::~ExpectationBase() {}
|
||||
ExpectationBase::~ExpectationBase() = default;
|
||||
|
||||
// Explicitly specifies the cardinality of this expectation. Used by
|
||||
// the subclasses to implement the .Times() clause.
|
||||
@ -297,7 +298,7 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg) {
|
||||
"See "
|
||||
"https://github.com/google/googletest/blob/main/docs/"
|
||||
"gmock_cook_book.md#"
|
||||
"knowing-when-to-expect for details.\n",
|
||||
"knowing-when-to-expect-useoncall for details.\n",
|
||||
stack_frames_to_skip);
|
||||
break;
|
||||
default: // FAIL
|
||||
@ -308,7 +309,7 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg) {
|
||||
UntypedFunctionMockerBase::UntypedFunctionMockerBase()
|
||||
: mock_obj_(nullptr), name_("") {}
|
||||
|
||||
UntypedFunctionMockerBase::~UntypedFunctionMockerBase() {}
|
||||
UntypedFunctionMockerBase::~UntypedFunctionMockerBase() = default;
|
||||
|
||||
// Sets the mock object this mock method belongs to, and registers
|
||||
// this information in the global mock registry. Will be called
|
||||
@ -406,8 +407,15 @@ bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()
|
||||
} else if (!untyped_expectation->IsSatisfied()) {
|
||||
expectations_met = false;
|
||||
::std::stringstream ss;
|
||||
ss << "Actual function call count doesn't match "
|
||||
<< untyped_expectation->source_text() << "...\n";
|
||||
|
||||
const ::std::string& expectation_name =
|
||||
untyped_expectation->GetDescription();
|
||||
ss << "Actual function ";
|
||||
if (!expectation_name.empty()) {
|
||||
ss << "\"" << expectation_name << "\" ";
|
||||
}
|
||||
ss << "call count doesn't match " << untyped_expectation->source_text()
|
||||
<< "...\n";
|
||||
// No need to show the source file location of the expectation
|
||||
// in the description, as the Expect() call that follows already
|
||||
// takes care of it.
|
||||
@ -482,6 +490,7 @@ class MockObjectRegistry {
|
||||
// failure, unless the user explicitly asked us to ignore it.
|
||||
~MockObjectRegistry() {
|
||||
if (!GMOCK_FLAG_GET(catch_leaked_mocks)) return;
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
|
||||
int leaked_count = 0;
|
||||
for (StateMap::const_iterator it = states_.begin(); it != states_.end();
|
||||
@ -496,7 +505,7 @@ class MockObjectRegistry {
|
||||
std::cout << internal::FormatFileLocation(state.first_used_file,
|
||||
state.first_used_line);
|
||||
std::cout << " ERROR: this mock object";
|
||||
if (state.first_used_test != "") {
|
||||
if (!state.first_used_test.empty()) {
|
||||
std::cout << " (used in test " << state.first_used_test_suite << "."
|
||||
<< state.first_used_test << ")";
|
||||
}
|
||||
@ -519,8 +528,12 @@ class MockObjectRegistry {
|
||||
// RUN_ALL_TESTS() has already returned when this destructor is
|
||||
// called. Therefore we cannot use the normal Google Test
|
||||
// failure reporting mechanism.
|
||||
_exit(1); // We cannot call exit() as it is not reentrant and
|
||||
#ifdef GTEST_OS_QURT
|
||||
qurt_exception_raise_fatal();
|
||||
#else
|
||||
_Exit(1); // We cannot call exit() as it is not reentrant and
|
||||
// may already have been called.
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -734,13 +747,13 @@ void Mock::ClearDefaultActionsLocked(void* mock_obj)
|
||||
// needed by VerifyAndClearExpectationsLocked().
|
||||
}
|
||||
|
||||
Expectation::Expectation() {}
|
||||
Expectation::Expectation() = default;
|
||||
|
||||
Expectation::Expectation(
|
||||
const std::shared_ptr<internal::ExpectationBase>& an_expectation_base)
|
||||
: expectation_base_(an_expectation_base) {}
|
||||
|
||||
Expectation::~Expectation() {}
|
||||
Expectation::~Expectation() = default;
|
||||
|
||||
// Adds an expectation to a sequence.
|
||||
void Sequence::AddExpectation(const Expectation& expectation) const {
|
||||
@ -774,8 +787,6 @@ InSequence::~InSequence() {
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER == 1900
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
#if defined(_MSC_VER) && (_MSC_VER == 1900)
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4800
|
||||
#endif
|
||||
|
@ -29,6 +29,8 @@
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
|
||||
GMOCK_DEFINE_bool_(catch_leaked_mocks, true,
|
||||
|
@ -32,8 +32,9 @@
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#if GTEST_OS_ESP8266 || GTEST_OS_ESP32
|
||||
#if GTEST_OS_ESP8266
|
||||
#if defined(GTEST_OS_ESP8266) || defined(GTEST_OS_ESP32) || \
|
||||
(defined(GTEST_OS_NRF52) && defined(ARDUINO))
|
||||
#ifdef GTEST_OS_ESP8266
|
||||
extern "C" {
|
||||
#endif
|
||||
void setup() {
|
||||
@ -43,7 +44,7 @@ void setup() {
|
||||
testing::InitGoogleMock();
|
||||
}
|
||||
void loop() { RUN_ALL_TESTS(); }
|
||||
#if GTEST_OS_ESP8266
|
||||
#ifdef GTEST_OS_ESP8266
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -55,7 +56,7 @@ void loop() { RUN_ALL_TESTS(); }
|
||||
// Windows. See the following link to track the current status of this bug:
|
||||
// https://web.archive.org/web/20170912203238/connect.microsoft.com/VisualStudio/feedback/details/394464/wmain-link-error-in-the-static-library
|
||||
// // NOLINT
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
#ifdef GTEST_OS_WINDOWS_MOBILE
|
||||
#include <tchar.h> // NOLINT
|
||||
|
||||
GTEST_API_ int _tmain(int argc, TCHAR** argv) {
|
||||
|
@ -31,33 +31,33 @@
|
||||
//
|
||||
// This file tests the built-in actions.
|
||||
|
||||
// Silence C4100 (unreferenced formal parameter) and C4503 (decorated name
|
||||
// length exceeded) for MSVC.
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4100)
|
||||
#pragma warning(disable : 4503)
|
||||
#if _MSC_VER == 1900
|
||||
// and silence C4800 (C4800: 'int *const ': forcing value
|
||||
// to bool 'true' or 'false') for MSVC 15
|
||||
#pragma warning(disable : 4800)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "gmock/gmock-actions.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
#include "gtest/gtest-spi.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
// Silence C4100 (unreferenced formal parameter) and C4503 (decorated name
|
||||
// length exceeded) for MSVC.
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100 4503)
|
||||
#if defined(_MSC_VER) && (_MSC_VER == 1900)
|
||||
// and silence C4800 (C4800: 'int *const ': forcing value
|
||||
// to bool 'true' or 'false') for MSVC 15
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800)
|
||||
#endif
|
||||
|
||||
namespace testing {
|
||||
namespace {
|
||||
@ -222,7 +222,8 @@ TEST(TypeTraits, IsInvocableRV) {
|
||||
// In C++17 and above, where it's guaranteed that functions can return
|
||||
// non-moveable objects, everything should work fine for non-moveable rsult
|
||||
// types too.
|
||||
#if defined(__cplusplus) && __cplusplus >= 201703L
|
||||
#if defined(GTEST_INTERNAL_CPLUSPLUS_LANG) && \
|
||||
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L
|
||||
{
|
||||
struct NonMoveable {
|
||||
NonMoveable() = default;
|
||||
@ -448,7 +449,7 @@ TEST(DefaultValueTest, GetWorksForMoveOnlyIfSet) {
|
||||
EXPECT_TRUE(DefaultValue<std::unique_ptr<int>>::Exists());
|
||||
EXPECT_TRUE(DefaultValue<std::unique_ptr<int>>::Get() == nullptr);
|
||||
DefaultValue<std::unique_ptr<int>>::SetFactory(
|
||||
[] { return std::unique_ptr<int>(new int(42)); });
|
||||
[] { return std::make_unique<int>(42); });
|
||||
EXPECT_TRUE(DefaultValue<std::unique_ptr<int>>::Exists());
|
||||
std::unique_ptr<int> i = DefaultValue<std::unique_ptr<int>>::Get();
|
||||
EXPECT_EQ(42, *i);
|
||||
@ -684,7 +685,7 @@ TEST(ReturnTest, SupportsReferenceLikeReturnType) {
|
||||
// A reference wrapper for std::vector<int>, implicitly convertible from it.
|
||||
struct Result {
|
||||
const std::vector<int>* v;
|
||||
Result(const std::vector<int>& v) : v(&v) {} // NOLINT
|
||||
Result(const std::vector<int>& vec) : v(&vec) {} // NOLINT
|
||||
};
|
||||
|
||||
// Set up an action for a mock function that returns the reference wrapper
|
||||
@ -717,7 +718,7 @@ TEST(ReturnTest, PrefersConversionOperator) {
|
||||
struct Out {
|
||||
int x;
|
||||
|
||||
explicit Out(const int x) : x(x) {}
|
||||
explicit Out(const int val) : x(val) {}
|
||||
explicit Out(const In&) : x(0) {}
|
||||
};
|
||||
|
||||
@ -986,7 +987,7 @@ TEST(ReturnRoundRobinTest, WorksForVector) {
|
||||
|
||||
class MockClass {
|
||||
public:
|
||||
MockClass() {}
|
||||
MockClass() = default;
|
||||
|
||||
MOCK_METHOD1(IntFunc, int(bool flag)); // NOLINT
|
||||
MOCK_METHOD0(Foo, MyNonDefaultConstructible());
|
||||
@ -1410,7 +1411,7 @@ TEST(DoAll, ProvidesLvalueReferencesToInitialActions) {
|
||||
void operator()(Obj&&) const { FAIL() << "Unexpected call"; }
|
||||
};
|
||||
|
||||
MockFunction<void(Obj &&)> mock;
|
||||
MockFunction<void(Obj&&)> mock;
|
||||
EXPECT_CALL(mock, Call)
|
||||
.WillOnce(DoAll(InitialAction{}, InitialAction{}, [](Obj&&) {}))
|
||||
.WillRepeatedly(DoAll(InitialAction{}, InitialAction{}, [](Obj&&) {}));
|
||||
@ -1438,7 +1439,7 @@ TEST(DoAll, ProvidesLvalueReferencesToInitialActions) {
|
||||
void operator()(Obj&) && {}
|
||||
};
|
||||
|
||||
MockFunction<void(Obj &&)> mock;
|
||||
MockFunction<void(Obj&&)> mock;
|
||||
EXPECT_CALL(mock, Call)
|
||||
.WillOnce(DoAll(InitialAction{}, InitialAction{}, [](Obj&&) {}));
|
||||
|
||||
@ -1596,7 +1597,7 @@ TEST(WithArgsTest, RefQualifiedInnerAction) {
|
||||
EXPECT_EQ(19, mock.AsStdFunction()(0, 17));
|
||||
}
|
||||
|
||||
#if !GTEST_OS_WINDOWS_MOBILE
|
||||
#ifndef GTEST_OS_WINDOWS_MOBILE
|
||||
|
||||
class SetErrnoAndReturnTest : public testing::Test {
|
||||
protected:
|
||||
@ -1755,9 +1756,7 @@ TEST(ReturnNewTest, ConstructorThatTakes10Arguments) {
|
||||
delete c;
|
||||
}
|
||||
|
||||
std::unique_ptr<int> UniquePtrSource() {
|
||||
return std::unique_ptr<int>(new int(19));
|
||||
}
|
||||
std::unique_ptr<int> UniquePtrSource() { return std::make_unique<int>(19); }
|
||||
|
||||
std::vector<std::unique_ptr<int>> VectorUniquePtrSource() {
|
||||
std::vector<std::unique_ptr<int>> out;
|
||||
@ -1806,7 +1805,7 @@ TEST(MockMethodTest, CanReturnMoveOnlyValue_Invoke) {
|
||||
|
||||
// Check default value
|
||||
DefaultValue<std::unique_ptr<int>>::SetFactory(
|
||||
[] { return std::unique_ptr<int>(new int(42)); });
|
||||
[] { return std::make_unique<int>(42); });
|
||||
EXPECT_EQ(42, *mock.MakeUnique());
|
||||
|
||||
EXPECT_CALL(mock, MakeUnique()).WillRepeatedly(Invoke(UniquePtrSource));
|
||||
@ -1826,7 +1825,7 @@ TEST(MockMethodTest, CanReturnMoveOnlyValue_Invoke) {
|
||||
|
||||
TEST(MockMethodTest, CanTakeMoveOnlyValue) {
|
||||
MockClass mock;
|
||||
auto make = [](int i) { return std::unique_ptr<int>(new int(i)); };
|
||||
auto make = [](int i) { return std::make_unique<int>(i); };
|
||||
|
||||
EXPECT_CALL(mock, TakeUnique(_)).WillRepeatedly([](std::unique_ptr<int> i) {
|
||||
return *i;
|
||||
@ -2057,9 +2056,7 @@ struct Double {
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<int> UniqueInt(int i) {
|
||||
return std::unique_ptr<int>(new int(i));
|
||||
}
|
||||
std::unique_ptr<int> UniqueInt(int i) { return std::make_unique<int>(i); }
|
||||
|
||||
TEST(FunctorActionTest, ActionFromFunction) {
|
||||
Action<int(int, int&, int*)> a = &Add;
|
||||
@ -2165,3 +2162,8 @@ TEST(ActionMacro, LargeArity) {
|
||||
|
||||
} // namespace
|
||||
} // namespace testing
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER == 1900)
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4800
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100 4503
|
||||
|
@ -31,6 +31,8 @@
|
||||
//
|
||||
// This file tests the built-in cardinalities.
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest-spi.h"
|
||||
#include "gtest/gtest.h"
|
||||
@ -50,7 +52,7 @@ using testing::MakeCardinality;
|
||||
|
||||
class MockFoo {
|
||||
public:
|
||||
MockFoo() {}
|
||||
MockFoo() = default;
|
||||
MOCK_METHOD0(Bar, int()); // NOLINT
|
||||
|
||||
private:
|
||||
|
@ -27,18 +27,15 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Silence C4503 (decorated name length exceeded) for MSVC.
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4503)
|
||||
#endif
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file tests the function mocker classes.
|
||||
#include "gmock/gmock-function-mocker.h"
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
// Silence C4503 (decorated name length exceeded) for MSVC.
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4503)
|
||||
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
// MSDN says the header file to be included for STDMETHOD is BaseTyps.h but
|
||||
// we are getting compiler errors if we use basetyps.h, hence including
|
||||
// objbase.h for definition of STDMETHOD.
|
||||
@ -73,7 +70,7 @@ using testing::TypedEq;
|
||||
template <typename T>
|
||||
class TemplatedCopyable {
|
||||
public:
|
||||
TemplatedCopyable() {}
|
||||
TemplatedCopyable() = default;
|
||||
|
||||
template <typename U>
|
||||
TemplatedCopyable(const U& other) {} // NOLINT
|
||||
@ -81,7 +78,7 @@ class TemplatedCopyable {
|
||||
|
||||
class FooInterface {
|
||||
public:
|
||||
virtual ~FooInterface() {}
|
||||
virtual ~FooInterface() = default;
|
||||
|
||||
virtual void VoidReturning(int x) = 0;
|
||||
|
||||
@ -123,7 +120,7 @@ class FooInterface {
|
||||
virtual int RefQualifiedOverloaded() & = 0;
|
||||
virtual int RefQualifiedOverloaded() && = 0;
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
STDMETHOD_(int, CTNullary)() = 0;
|
||||
STDMETHOD_(bool, CTUnary)(int x) = 0;
|
||||
STDMETHOD_(int, CTDecimal)
|
||||
@ -137,13 +134,10 @@ class FooInterface {
|
||||
// significant in determining whether two virtual functions had the same
|
||||
// signature. This was fixed in Visual Studio 2008. However, the compiler
|
||||
// still emits a warning that alerts about this change in behavior.
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4373)
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4373)
|
||||
class MockFoo : public FooInterface {
|
||||
public:
|
||||
MockFoo() {}
|
||||
MockFoo() = default;
|
||||
|
||||
// Makes sure that a mock function parameter can be named.
|
||||
MOCK_METHOD(void, VoidReturning, (int n)); // NOLINT
|
||||
@ -184,7 +178,7 @@ class MockFoo : public FooInterface {
|
||||
MOCK_METHOD(int (*)(bool), ReturnsFunctionPointer1, (int), ());
|
||||
MOCK_METHOD(fn_ptr, ReturnsFunctionPointer2, (int), ());
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
MOCK_METHOD(int, CTNullary, (), (Calltype(STDMETHODCALLTYPE)));
|
||||
MOCK_METHOD(bool, CTUnary, (int), (Calltype(STDMETHODCALLTYPE)));
|
||||
MOCK_METHOD(int, CTDecimal,
|
||||
@ -214,7 +208,7 @@ class MockFoo : public FooInterface {
|
||||
|
||||
class LegacyMockFoo : public FooInterface {
|
||||
public:
|
||||
LegacyMockFoo() {}
|
||||
LegacyMockFoo() = default;
|
||||
|
||||
// Makes sure that a mock function parameter can be named.
|
||||
MOCK_METHOD1(VoidReturning, void(int n)); // NOLINT
|
||||
@ -254,7 +248,7 @@ class LegacyMockFoo : public FooInterface {
|
||||
MOCK_METHOD1(ReturnsFunctionPointer1, int (*(int))(bool));
|
||||
MOCK_METHOD1(ReturnsFunctionPointer2, fn_ptr(int));
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTNullary, int());
|
||||
MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTUnary, bool(int)); // NOLINT
|
||||
MOCK_METHOD10_WITH_CALLTYPE(STDMETHODCALLTYPE, CTDecimal,
|
||||
@ -285,9 +279,7 @@ class LegacyMockFoo : public FooInterface {
|
||||
LegacyMockFoo& operator=(const LegacyMockFoo&) = delete;
|
||||
};
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4373
|
||||
|
||||
template <class T>
|
||||
class FunctionMockerTest : public testing::Test {
|
||||
@ -412,7 +404,7 @@ TYPED_TEST(FunctionMockerTest, MocksTypeWithTemplatedCopyCtor) {
|
||||
EXPECT_TRUE(this->foo_->TypeWithTemplatedCopyCtor(TemplatedCopyable<int>()));
|
||||
}
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
// Tests mocking a nullary function with calltype.
|
||||
TYPED_TEST(FunctionMockerTest, MocksNullaryFunctionWithCallType) {
|
||||
EXPECT_CALL(this->mock_foo_, CTNullary())
|
||||
@ -495,7 +487,7 @@ TEST(FunctionMockerTest, RefQualified) {
|
||||
|
||||
class MockB {
|
||||
public:
|
||||
MockB() {}
|
||||
MockB() = default;
|
||||
|
||||
MOCK_METHOD(void, DoB, ());
|
||||
|
||||
@ -506,7 +498,7 @@ class MockB {
|
||||
|
||||
class LegacyMockB {
|
||||
public:
|
||||
LegacyMockB() {}
|
||||
LegacyMockB() = default;
|
||||
|
||||
MOCK_METHOD0(DoB, void());
|
||||
|
||||
@ -542,7 +534,7 @@ TYPED_TEST(ExpectCallTest, UnmentionedFunctionCanBeCalledAnyNumberOfTimes) {
|
||||
template <typename T>
|
||||
class StackInterface {
|
||||
public:
|
||||
virtual ~StackInterface() {}
|
||||
virtual ~StackInterface() = default;
|
||||
|
||||
// Template parameter appears in function parameter.
|
||||
virtual void Push(const T& value) = 0;
|
||||
@ -555,7 +547,7 @@ class StackInterface {
|
||||
template <typename T>
|
||||
class MockStack : public StackInterface<T> {
|
||||
public:
|
||||
MockStack() {}
|
||||
MockStack() = default;
|
||||
|
||||
MOCK_METHOD(void, Push, (const T& elem), ());
|
||||
MOCK_METHOD(void, Pop, (), (final));
|
||||
@ -574,7 +566,7 @@ class MockStack : public StackInterface<T> {
|
||||
template <typename T>
|
||||
class LegacyMockStack : public StackInterface<T> {
|
||||
public:
|
||||
LegacyMockStack() {}
|
||||
LegacyMockStack() = default;
|
||||
|
||||
MOCK_METHOD1_T(Push, void(const T& elem));
|
||||
MOCK_METHOD0_T(Pop, void());
|
||||
@ -628,7 +620,7 @@ TYPED_TEST(TemplateMockTest, MethodWithCommaInReturnTypeWorks) {
|
||||
EXPECT_EQ(a_map, mock.ReturnTypeWithComma(1));
|
||||
}
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
// Tests mocking template interfaces with calltype.
|
||||
|
||||
template <typename T>
|
||||
@ -719,7 +711,7 @@ TYPED_TEST(TemplateMockTestWithCallType, Works) {
|
||||
|
||||
class MockOverloadedOnArgNumber {
|
||||
public:
|
||||
MockOverloadedOnArgNumber() {}
|
||||
MockOverloadedOnArgNumber() = default;
|
||||
|
||||
MY_MOCK_METHODS1_;
|
||||
|
||||
@ -731,7 +723,7 @@ class MockOverloadedOnArgNumber {
|
||||
|
||||
class LegacyMockOverloadedOnArgNumber {
|
||||
public:
|
||||
LegacyMockOverloadedOnArgNumber() {}
|
||||
LegacyMockOverloadedOnArgNumber() = default;
|
||||
|
||||
LEGACY_MY_MOCK_METHODS1_;
|
||||
|
||||
@ -766,7 +758,7 @@ TYPED_TEST(OverloadedMockMethodTest, CanOverloadOnArgNumberInMacroBody) {
|
||||
|
||||
class MockOverloadedOnConstness {
|
||||
public:
|
||||
MockOverloadedOnConstness() {}
|
||||
MockOverloadedOnConstness() = default;
|
||||
|
||||
MY_MOCK_METHODS2_;
|
||||
|
||||
@ -958,6 +950,21 @@ TEST(MockMethodMockFunctionTest, MockMethodSizeOverhead) {
|
||||
EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(MockMethodSizes0));
|
||||
}
|
||||
|
||||
TEST(MockMethodMockFunctionTest, EnsureNoUnusedMemberFunction) {
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic error "-Wunused-member-function"
|
||||
#endif
|
||||
// https://github.com/google/googletest/issues/4052
|
||||
struct Foo {
|
||||
MOCK_METHOD(void, foo, ());
|
||||
};
|
||||
EXPECT_CALL(Foo(), foo()).Times(0);
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
void hasTwoParams(int, int);
|
||||
void MaybeThrows();
|
||||
void DoesntThrow() noexcept;
|
||||
@ -987,3 +994,5 @@ TEST(MockMethodMockFunctionTest, NoexceptSpecifierPreserved) {
|
||||
|
||||
} // namespace gmock_function_mocker_test
|
||||
} // namespace testing
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4503
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
@ -56,7 +57,7 @@
|
||||
#include "src/gtest-internal-inl.h"
|
||||
#undef GTEST_IMPLEMENTATION_
|
||||
|
||||
#if GTEST_OS_CYGWIN
|
||||
#ifdef GTEST_OS_CYGWIN
|
||||
#include <sys/types.h> // For ssize_t. NOLINT
|
||||
#endif
|
||||
|
||||
@ -167,7 +168,7 @@ TEST(KindOfTest, Integer) {
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(unsigned long long)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(wchar_t)); // NOLINT
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(size_t)); // NOLINT
|
||||
#if GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN
|
||||
#if defined(GTEST_OS_LINUX) || defined(GTEST_OS_MAC) || defined(GTEST_OS_CYGWIN)
|
||||
// ssize_t is not defined on Windows and possibly some other OSes.
|
||||
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(ssize_t)); // NOLINT
|
||||
#endif
|
||||
|
@ -31,16 +31,17 @@
|
||||
//
|
||||
// This file tests some commonly used argument matchers.
|
||||
|
||||
// Silence warning C4244: 'initializing': conversion from 'int' to 'short',
|
||||
// possible loss of data and C4100, unreferenced local parameter
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4244)
|
||||
#pragma warning(disable : 4100)
|
||||
#endif
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "test/gmock-matchers_test.h"
|
||||
|
||||
// Silence warning C4244: 'initializing': conversion from 'int' to 'short',
|
||||
// possible loss of data and C4100, unreferenced local parameter
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4244 4100)
|
||||
|
||||
namespace testing {
|
||||
namespace gmock_matchers_test {
|
||||
namespace {
|
||||
@ -954,7 +955,7 @@ TEST(AllArgsTest, WorksForNonTuple) {
|
||||
|
||||
class AllArgsHelper {
|
||||
public:
|
||||
AllArgsHelper() {}
|
||||
AllArgsHelper() = default;
|
||||
|
||||
MOCK_METHOD2(Helper, int(char x, int y));
|
||||
|
||||
@ -975,7 +976,7 @@ TEST(AllArgsTest, WorksInWithClause) {
|
||||
|
||||
class OptionalMatchersHelper {
|
||||
public:
|
||||
OptionalMatchersHelper() {}
|
||||
OptionalMatchersHelper() = default;
|
||||
|
||||
MOCK_METHOD0(NoArgs, int());
|
||||
|
||||
@ -1037,7 +1038,7 @@ class FloatingPointTest : public testing::Test {
|
||||
Floating::ReinterpretBits(infinity_bits_ - max_ulps_)),
|
||||
further_from_infinity_(
|
||||
Floating::ReinterpretBits(infinity_bits_ - max_ulps_ - 1)),
|
||||
max_(Floating::Max()),
|
||||
max_(std::numeric_limits<RawType>::max()),
|
||||
nan1_(Floating::ReinterpretBits(Floating::kExponentBitMask | 1)),
|
||||
nan2_(Floating::ReinterpretBits(Floating::kExponentBitMask | 200)) {}
|
||||
|
||||
@ -1512,6 +1513,4 @@ TEST(AnyOfTest, WorksOnMoveOnlyType) {
|
||||
} // namespace gmock_matchers_test
|
||||
} // namespace testing
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4244 4100
|
||||
|
@ -31,18 +31,19 @@
|
||||
//
|
||||
// This file tests some commonly used argument matchers.
|
||||
|
||||
// Silence warning C4244: 'initializing': conversion from 'int' to 'short',
|
||||
// possible loss of data and C4100, unreferenced local parameter
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4244)
|
||||
#pragma warning(disable : 4100)
|
||||
#endif
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include "test/gmock-matchers_test.h"
|
||||
|
||||
// Silence warning C4244: 'initializing': conversion from 'int' to 'short',
|
||||
// possible loss of data and C4100, unreferenced local parameter
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4244 4100)
|
||||
|
||||
|
||||
namespace testing {
|
||||
namespace gmock_matchers_test {
|
||||
namespace {
|
||||
@ -588,8 +589,8 @@ TEST(MatcherCastTest, ValueIsNotCopied) {
|
||||
|
||||
class Base {
|
||||
public:
|
||||
virtual ~Base() {}
|
||||
Base() {}
|
||||
virtual ~Base() = default;
|
||||
Base() = default;
|
||||
|
||||
private:
|
||||
Base(const Base&) = delete;
|
||||
@ -864,7 +865,7 @@ struct Type {
|
||||
};
|
||||
|
||||
TEST(TypedEqTest, HasSpecifiedType) {
|
||||
// Verfies that the type of TypedEq<T>(v) is Matcher<T>.
|
||||
// Verifies that the type of TypedEq<T>(v) is Matcher<T>.
|
||||
Type<Matcher<int>>::IsTypeOf(TypedEq<int>(5));
|
||||
Type<Matcher<double>>::IsTypeOf(TypedEq<double>(5));
|
||||
}
|
||||
@ -1530,7 +1531,7 @@ TEST(PairTest, MatchesCorrectly) {
|
||||
EXPECT_THAT(p, Pair(25, "foo"));
|
||||
EXPECT_THAT(p, Pair(Ge(20), HasSubstr("o")));
|
||||
|
||||
// 'first' doesnt' match, but 'second' matches.
|
||||
// 'first' doesn't match, but 'second' matches.
|
||||
EXPECT_THAT(p, Not(Pair(42, "foo")));
|
||||
EXPECT_THAT(p, Not(Pair(Lt(25), "foo")));
|
||||
|
||||
@ -1545,7 +1546,7 @@ TEST(PairTest, MatchesCorrectly) {
|
||||
|
||||
TEST(PairTest, WorksWithMoveOnly) {
|
||||
pair<std::unique_ptr<int>, std::unique_ptr<int>> p;
|
||||
p.second.reset(new int(7));
|
||||
p.second = std::make_unique<int>(7);
|
||||
EXPECT_THAT(p, Pair(Eq(nullptr), Ne(nullptr)));
|
||||
}
|
||||
|
||||
@ -1768,6 +1769,15 @@ TEST(StartsWithTest, CanDescribeSelf) {
|
||||
EXPECT_EQ("starts with \"Hi\"", Describe(m));
|
||||
}
|
||||
|
||||
TEST(StartsWithTest, WorksWithStringMatcherOnStringViewMatchee) {
|
||||
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
EXPECT_THAT(internal::StringView("talk to me goose"),
|
||||
StartsWith(std::string("talk")));
|
||||
#else
|
||||
GTEST_SKIP() << "Not applicable without internal::StringView.";
|
||||
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
}
|
||||
|
||||
// Tests EndsWith(s).
|
||||
|
||||
TEST(EndsWithTest, MatchesStringWithGivenSuffix) {
|
||||
@ -1805,11 +1815,13 @@ TEST(WhenBase64UnescapedTest, MatchesUnescapedBase64Strings) {
|
||||
EXPECT_FALSE(m1.Matches("invalid base64"));
|
||||
EXPECT_FALSE(m1.Matches("aGVsbG8gd29ybGQ=")); // hello world
|
||||
EXPECT_TRUE(m1.Matches("aGVsbG8gd29ybGQh")); // hello world!
|
||||
EXPECT_TRUE(m1.Matches("+/-_IQ")); // \xfb\xff\xbf!
|
||||
|
||||
const Matcher<const std::string&> m2 = WhenBase64Unescaped(EndsWith("!"));
|
||||
EXPECT_FALSE(m2.Matches("invalid base64"));
|
||||
EXPECT_FALSE(m2.Matches("aGVsbG8gd29ybGQ=")); // hello world
|
||||
EXPECT_TRUE(m2.Matches("aGVsbG8gd29ybGQh")); // hello world!
|
||||
EXPECT_TRUE(m2.Matches("+/-_IQ")); // \xfb\xff\xbf!
|
||||
|
||||
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
const Matcher<const internal::StringView&> m3 =
|
||||
@ -1817,6 +1829,7 @@ TEST(WhenBase64UnescapedTest, MatchesUnescapedBase64Strings) {
|
||||
EXPECT_FALSE(m3.Matches("invalid base64"));
|
||||
EXPECT_FALSE(m3.Matches("aGVsbG8gd29ybGQ=")); // hello world
|
||||
EXPECT_TRUE(m3.Matches("aGVsbG8gd29ybGQh")); // hello world!
|
||||
EXPECT_TRUE(m3.Matches("+/-_IQ")); // \xfb\xff\xbf!
|
||||
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
}
|
||||
|
||||
@ -2354,6 +2367,4 @@ TEST(PolymorphicMatcherTest, CanAccessImpl) {
|
||||
} // namespace gmock_matchers_test
|
||||
} // namespace testing
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4244 4100
|
||||
|
@ -31,13 +31,23 @@
|
||||
//
|
||||
// This file tests some commonly used argument matchers.
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <deque>
|
||||
#include <forward_list>
|
||||
#include <iterator>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
// Silence warning C4244: 'initializing': conversion from 'int' to 'short',
|
||||
// possible loss of data and C4100, unreferenced local parameter
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4244)
|
||||
#pragma warning(disable : 4100)
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4244 4100)
|
||||
|
||||
#include "test/gmock-matchers_test.h"
|
||||
|
||||
@ -1182,8 +1192,8 @@ TEST(SizeIsTest, WorksWithMinimalistCustomType) {
|
||||
|
||||
TEST(SizeIsTest, CanDescribeSelf) {
|
||||
Matcher<vector<int>> m = SizeIs(2);
|
||||
EXPECT_EQ("size is equal to 2", Describe(m));
|
||||
EXPECT_EQ("size isn't equal to 2", DescribeNegation(m));
|
||||
EXPECT_EQ("has a size that is equal to 2", Describe(m));
|
||||
EXPECT_EQ("has a size that isn't equal to 2", DescribeNegation(m));
|
||||
}
|
||||
|
||||
TEST(SizeIsTest, ExplainsResult) {
|
||||
@ -1826,8 +1836,8 @@ TEST(UnorderedElementsAreArrayTest, SucceedsWhenExpected) {
|
||||
}
|
||||
|
||||
TEST(UnorderedElementsAreArrayTest, VectorBool) {
|
||||
const bool a[] = {0, 1, 0, 1, 1};
|
||||
const bool b[] = {1, 0, 1, 1, 0};
|
||||
const bool a[] = {false, true, false, true, true};
|
||||
const bool b[] = {true, false, true, true, false};
|
||||
std::vector<bool> expected(std::begin(a), std::end(a));
|
||||
std::vector<bool> actual(std::begin(b), std::end(b));
|
||||
StringMatchResultListener listener;
|
||||
@ -2778,7 +2788,7 @@ TEST(ElementsAreTest, WorksWithNativeArrayPassedByReference) {
|
||||
|
||||
class NativeArrayPassedAsPointerAndSize {
|
||||
public:
|
||||
NativeArrayPassedAsPointerAndSize() {}
|
||||
NativeArrayPassedAsPointerAndSize() = default;
|
||||
|
||||
MOCK_METHOD(void, Helper, (int* array, int size));
|
||||
|
||||
@ -3124,6 +3134,4 @@ TEST(ContainsTest, WorksForTwoDimensionalNativeArray) {
|
||||
} // namespace gmock_matchers_test
|
||||
} // namespace testing
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4244 4100
|
||||
|
@ -31,13 +31,19 @@
|
||||
//
|
||||
// This file tests some commonly used argument matchers.
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
// Silence warning C4244: 'initializing': conversion from 'int' to 'short',
|
||||
// possible loss of data and C4100, unreferenced local parameter
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4244)
|
||||
#pragma warning(disable : 4100)
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4244 4100)
|
||||
|
||||
#include "test/gmock-matchers_test.h"
|
||||
|
||||
@ -202,7 +208,7 @@ TEST(IsTrueTest, IsTrueIsFalse) {
|
||||
EXPECT_THAT(nonnull_unique, Not(IsFalse()));
|
||||
}
|
||||
|
||||
#if GTEST_HAS_TYPED_TEST
|
||||
#ifdef GTEST_HAS_TYPED_TEST
|
||||
// Tests ContainerEq with different container types, and
|
||||
// different element types.
|
||||
|
||||
@ -863,7 +869,7 @@ TEST(ArgsTest, AcceptsOneTemplateArg) {
|
||||
}
|
||||
|
||||
TEST(ArgsTest, AcceptsTwoTemplateArgs) {
|
||||
const std::tuple<short, int, long> t(4, 5, 6L); // NOLINT
|
||||
const std::tuple<short, int, long> t(short{4}, 5, 6L); // NOLINT
|
||||
|
||||
EXPECT_THAT(t, (Args<0, 1>(Lt())));
|
||||
EXPECT_THAT(t, (Args<1, 2>(Lt())));
|
||||
@ -871,13 +877,13 @@ TEST(ArgsTest, AcceptsTwoTemplateArgs) {
|
||||
}
|
||||
|
||||
TEST(ArgsTest, AcceptsRepeatedTemplateArgs) {
|
||||
const std::tuple<short, int, long> t(4, 5, 6L); // NOLINT
|
||||
const std::tuple<short, int, long> t(short{4}, 5, 6L); // NOLINT
|
||||
EXPECT_THAT(t, (Args<0, 0>(Eq())));
|
||||
EXPECT_THAT(t, Not(Args<1, 1>(Ne())));
|
||||
}
|
||||
|
||||
TEST(ArgsTest, AcceptsDecreasingTemplateArgs) {
|
||||
const std::tuple<short, int, long> t(4, 5, 6L); // NOLINT
|
||||
const std::tuple<short, int, long> t(short{4}, 5, 6L); // NOLINT
|
||||
EXPECT_THAT(t, (Args<2, 0>(Gt())));
|
||||
EXPECT_THAT(t, Not(Args<2, 1>(Lt())));
|
||||
}
|
||||
@ -892,7 +898,7 @@ TEST(ArgsTest, AcceptsMoreTemplateArgsThanArityOfOriginalTuple) {
|
||||
}
|
||||
|
||||
TEST(ArgsTest, CanBeNested) {
|
||||
const std::tuple<short, int, long, int> t(4, 5, 6L, 6); // NOLINT
|
||||
const std::tuple<short, int, long, int> t(short{4}, 5, 6L, 6); // NOLINT
|
||||
EXPECT_THAT(t, (Args<1, 2, 3>(Args<1, 2>(Eq()))));
|
||||
EXPECT_THAT(t, (Args<0, 1, 3>(Args<0, 2>(Lt()))));
|
||||
}
|
||||
@ -1615,6 +1621,20 @@ TEST(MatcherPMacroTest, WorksOnMoveOnlyType) {
|
||||
EXPECT_THAT(p, Not(UniquePointee(2)));
|
||||
}
|
||||
|
||||
MATCHER(EnsureNoUnusedButMarkedUnusedWarning, "") { return (arg % 2) == 0; }
|
||||
|
||||
TEST(MockMethodMockFunctionTest, EnsureNoUnusedButMarkedUnusedWarning) {
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic error "-Wused-but-marked-unused"
|
||||
#endif
|
||||
// https://github.com/google/googletest/issues/4055
|
||||
EXPECT_THAT(0, EnsureNoUnusedButMarkedUnusedWarning());
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
#if GTEST_HAS_EXCEPTIONS
|
||||
|
||||
// std::function<void()> is used below for compatibility with older copies of
|
||||
@ -1778,8 +1798,8 @@ TEST(ThrowsPredicateCompilesTest, ExceptionMatcherAcceptsBroadType) {
|
||||
{
|
||||
Matcher<uint64_t> inner = Eq(10);
|
||||
Matcher<std::function<void()>> matcher = Throws<uint32_t>(inner);
|
||||
EXPECT_TRUE(matcher.Matches([]() { throw(uint32_t) 10; }));
|
||||
EXPECT_FALSE(matcher.Matches([]() { throw(uint32_t) 11; }));
|
||||
EXPECT_TRUE(matcher.Matches([]() { throw (uint32_t)10; }));
|
||||
EXPECT_FALSE(matcher.Matches([]() { throw (uint32_t)11; }));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1800,6 +1820,4 @@ TEST(ThrowsPredicateCompilesTest, MessageMatcherAcceptsNonMatcher) {
|
||||
} // namespace gmock_matchers_test
|
||||
} // namespace testing
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4244 4100
|
||||
|
@ -148,9 +148,9 @@ class GreaterThanMatcher : public MatcherInterface<T> {
|
||||
};
|
||||
|
||||
// Names and instantiates a new instance of GTestMatcherTestP.
|
||||
#define INSTANTIATE_GTEST_MATCHER_TEST_P(TestSuite) \
|
||||
using TestSuite##P = GTestMatcherTestP; \
|
||||
INSTANTIATE_TEST_SUITE_P(MatcherInterface, TestSuite##P, Values(false)); \
|
||||
#define INSTANTIATE_GTEST_MATCHER_TEST_P(TestSuite) \
|
||||
using TestSuite##P = GTestMatcherTestP; \
|
||||
INSTANTIATE_TEST_SUITE_P(MatcherInterface, TestSuite##P, Values(false)); \
|
||||
INSTANTIATE_TEST_SUITE_P(GtestMatcher, TestSuite##P, Values(true))
|
||||
|
||||
class GTestMatcherTestP : public testing::TestWithParam<bool> {
|
||||
|
@ -31,22 +31,23 @@
|
||||
//
|
||||
// This file tests the built-in actions in gmock-actions.h.
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4577)
|
||||
#endif
|
||||
|
||||
#include "gmock/gmock-more-actions.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest-spi.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4577)
|
||||
|
||||
namespace testing {
|
||||
namespace gmock_more_actions_test {
|
||||
|
||||
@ -84,6 +85,16 @@ struct UnaryFunctor {
|
||||
int operator()(bool x) { return x ? 1 : -1; }
|
||||
};
|
||||
|
||||
struct UnaryMoveOnlyFunctor : UnaryFunctor {
|
||||
UnaryMoveOnlyFunctor() = default;
|
||||
UnaryMoveOnlyFunctor(const UnaryMoveOnlyFunctor&) = delete;
|
||||
UnaryMoveOnlyFunctor(UnaryMoveOnlyFunctor&&) = default;
|
||||
};
|
||||
|
||||
struct OneShotUnaryFunctor {
|
||||
int operator()(bool x) && { return x ? 1 : -1; }
|
||||
};
|
||||
|
||||
const char* Binary(const char* input, short n) { return input + n; } // NOLINT
|
||||
|
||||
int Ternary(int x, char y, short z) { return x + y + z; } // NOLINT
|
||||
@ -676,7 +687,7 @@ TEST(SetArrayArgumentTest, SetsTheNthArrayWithIteratorArgument) {
|
||||
Action<MyFunction> a = SetArrayArgument<1>(letters.begin(), letters.end());
|
||||
|
||||
std::string s;
|
||||
a.Perform(std::make_tuple(true, back_inserter(s)));
|
||||
a.Perform(std::make_tuple(true, std::back_inserter(s)));
|
||||
EXPECT_EQ(letters, s);
|
||||
}
|
||||
|
||||
@ -697,12 +708,24 @@ TEST(InvokeArgumentTest, Function0) {
|
||||
EXPECT_EQ(1, a.Perform(std::make_tuple(2, &Nullary)));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a unary function.
|
||||
// Tests using InvokeArgument with a unary functor.
|
||||
TEST(InvokeArgumentTest, Functor1) {
|
||||
Action<int(UnaryFunctor)> a = InvokeArgument<0>(true); // NOLINT
|
||||
EXPECT_EQ(1, a.Perform(std::make_tuple(UnaryFunctor())));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a unary move-only functor.
|
||||
TEST(InvokeArgumentTest, Functor1MoveOnly) {
|
||||
Action<int(UnaryMoveOnlyFunctor)> a = InvokeArgument<0>(true); // NOLINT
|
||||
EXPECT_EQ(1, a.Perform(std::make_tuple(UnaryMoveOnlyFunctor())));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a one-shot unary functor.
|
||||
TEST(InvokeArgumentTest, OneShotFunctor1) {
|
||||
Action<int(OneShotUnaryFunctor)> a = InvokeArgument<0>(true); // NOLINT
|
||||
EXPECT_EQ(1, a.Perform(std::make_tuple(OneShotUnaryFunctor())));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a 5-ary function.
|
||||
TEST(InvokeArgumentTest, Function5) {
|
||||
Action<int(int (*)(int, int, int, int, int))> a = // NOLINT
|
||||
@ -805,6 +828,22 @@ TEST(InvokeArgumentTest, ByExplicitConstReferenceFunction) {
|
||||
EXPECT_FALSE(a.Perform(std::make_tuple(&ReferencesGlobalDouble)));
|
||||
}
|
||||
|
||||
TEST(InvokeArgumentTest, MoveOnlyType) {
|
||||
struct Marker {};
|
||||
struct {
|
||||
// Method takes a unique_ptr (to a type we don't care about), and an
|
||||
// invocable type.
|
||||
MOCK_METHOD(bool, MockMethod,
|
||||
(std::unique_ptr<Marker>, std::function<int()>), ());
|
||||
} mock;
|
||||
|
||||
ON_CALL(mock, MockMethod(_, _)).WillByDefault(InvokeArgument<1>());
|
||||
|
||||
// This compiles, but is a little opaque as a workaround:
|
||||
ON_CALL(mock, MockMethod(_, _))
|
||||
.WillByDefault(WithArg<1>(InvokeArgument<0>()));
|
||||
}
|
||||
|
||||
// Tests DoAll(a1, a2).
|
||||
TEST(DoAllTest, TwoActions) {
|
||||
int n = 0;
|
||||
@ -982,11 +1021,7 @@ TEST(DoAllTest, ImplicitlyConvertsActionArguments) {
|
||||
// is expanded and macro expansion cannot contain #pragma. Therefore
|
||||
// we suppress them here.
|
||||
// Also suppress C4503 decorated name length exceeded, name was truncated
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4100)
|
||||
#pragma warning(disable : 4503)
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100 4503)
|
||||
// Tests the ACTION*() macro family.
|
||||
|
||||
// Tests that ACTION() can define an action that doesn't reference the
|
||||
@ -1548,3 +1583,6 @@ TEST(ActionTemplateTest, CanBeOverloadedOnNumberOfValueParameters) {
|
||||
|
||||
} // namespace gmock_more_actions_test
|
||||
} // namespace testing
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100 4503
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4577
|
||||
|
@ -40,7 +40,7 @@
|
||||
// clash with ::testing::Mock.
|
||||
class Mock {
|
||||
public:
|
||||
Mock() {}
|
||||
Mock() = default;
|
||||
|
||||
MOCK_METHOD0(DoThis, void());
|
||||
|
||||
@ -78,7 +78,7 @@ class CallsMockMethodInDestructor {
|
||||
|
||||
class Foo {
|
||||
public:
|
||||
virtual ~Foo() {}
|
||||
virtual ~Foo() = default;
|
||||
|
||||
virtual void DoThis() = 0;
|
||||
virtual int DoThat(bool flag) = 0;
|
||||
@ -86,7 +86,7 @@ class Foo {
|
||||
|
||||
class MockFoo : public Foo {
|
||||
public:
|
||||
MockFoo() {}
|
||||
MockFoo() = default;
|
||||
void Delete() { delete this; }
|
||||
|
||||
MOCK_METHOD0(DoThis, void());
|
||||
@ -109,7 +109,7 @@ class MockBar {
|
||||
(a10 ? 'T' : 'F');
|
||||
}
|
||||
|
||||
virtual ~MockBar() {}
|
||||
virtual ~MockBar() = default;
|
||||
|
||||
const std::string& str() const { return str_; }
|
||||
|
||||
|
@ -98,7 +98,7 @@ class NonDefaultConstructible {
|
||||
|
||||
class MockA {
|
||||
public:
|
||||
MockA() {}
|
||||
MockA() = default;
|
||||
|
||||
MOCK_METHOD1(DoA, void(int n));
|
||||
MOCK_METHOD1(ReturnResult, Result(int n));
|
||||
@ -113,7 +113,7 @@ class MockA {
|
||||
|
||||
class MockB {
|
||||
public:
|
||||
MockB() {}
|
||||
MockB() = default;
|
||||
|
||||
MOCK_CONST_METHOD0(DoB, int()); // NOLINT
|
||||
MOCK_METHOD1(DoB, int(int n)); // NOLINT
|
||||
@ -125,7 +125,7 @@ class MockB {
|
||||
|
||||
class ReferenceHoldingMock {
|
||||
public:
|
||||
ReferenceHoldingMock() {}
|
||||
ReferenceHoldingMock() = default;
|
||||
|
||||
MOCK_METHOD1(AcceptReference, void(std::shared_ptr<MockA>*));
|
||||
|
||||
@ -143,12 +143,12 @@ class ReferenceHoldingMock {
|
||||
|
||||
class CC {
|
||||
public:
|
||||
virtual ~CC() {}
|
||||
virtual ~CC() = default;
|
||||
virtual int Method() = 0;
|
||||
};
|
||||
class MockCC : public CC {
|
||||
public:
|
||||
MockCC() {}
|
||||
MockCC() = default;
|
||||
|
||||
MOCK_METHOD0(Method, int());
|
||||
|
||||
@ -739,11 +739,12 @@ TEST(ExpectCallTest, CatchesTooFewCalls) {
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
{ // NOLINT
|
||||
MockB b;
|
||||
EXPECT_CALL(b, DoB(5)).Times(AtLeast(2));
|
||||
EXPECT_CALL(b, DoB(5)).Description("DoB Method").Times(AtLeast(2));
|
||||
|
||||
b.DoB(5);
|
||||
},
|
||||
"Actual function call count doesn't match EXPECT_CALL(b, DoB(5))...\n"
|
||||
"Actual function \"DoB Method\" call count "
|
||||
"doesn't match EXPECT_CALL(b, DoB(5))...\n"
|
||||
" Expected: to be called at least twice\n"
|
||||
" Actual: called once - unsatisfied and active");
|
||||
}
|
||||
@ -803,39 +804,40 @@ TEST(ExpectCallTest, InfersCardinality1WhenThereIsWillRepeatedly) {
|
||||
"to be called at least once");
|
||||
}
|
||||
|
||||
#if defined(__cplusplus) && __cplusplus >= 201703L
|
||||
#if defined(GTEST_INTERNAL_CPLUSPLUS_LANG) && \
|
||||
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L
|
||||
|
||||
// It should be possible to return a non-moveable type from a mock action in
|
||||
// C++17 and above, where it's guaranteed that such a type can be initialized
|
||||
// from a prvalue returned from a function.
|
||||
TEST(ExpectCallTest, NonMoveableType) {
|
||||
// Define a non-moveable result type.
|
||||
struct Result {
|
||||
explicit Result(int x_in) : x(x_in) {}
|
||||
Result(Result&&) = delete;
|
||||
struct NonMoveableStruct {
|
||||
explicit NonMoveableStruct(int x_in) : x(x_in) {}
|
||||
NonMoveableStruct(NonMoveableStruct&&) = delete;
|
||||
|
||||
int x;
|
||||
};
|
||||
|
||||
static_assert(!std::is_move_constructible_v<Result>);
|
||||
static_assert(!std::is_copy_constructible_v<Result>);
|
||||
static_assert(!std::is_move_constructible_v<NonMoveableStruct>);
|
||||
static_assert(!std::is_copy_constructible_v<NonMoveableStruct>);
|
||||
|
||||
static_assert(!std::is_move_assignable_v<Result>);
|
||||
static_assert(!std::is_copy_assignable_v<Result>);
|
||||
static_assert(!std::is_move_assignable_v<NonMoveableStruct>);
|
||||
static_assert(!std::is_copy_assignable_v<NonMoveableStruct>);
|
||||
|
||||
// We should be able to use a callable that returns that result as both a
|
||||
// OnceAction and an Action, whether the callable ignores arguments or not.
|
||||
const auto return_17 = [] { return Result(17); };
|
||||
const auto return_17 = [] { return NonMoveableStruct(17); };
|
||||
|
||||
static_cast<void>(OnceAction<Result()>{return_17});
|
||||
static_cast<void>(Action<Result()>{return_17});
|
||||
static_cast<void>(OnceAction<NonMoveableStruct()>{return_17});
|
||||
static_cast<void>(Action<NonMoveableStruct()>{return_17});
|
||||
|
||||
static_cast<void>(OnceAction<Result(int)>{return_17});
|
||||
static_cast<void>(Action<Result(int)>{return_17});
|
||||
static_cast<void>(OnceAction<NonMoveableStruct(int)>{return_17});
|
||||
static_cast<void>(Action<NonMoveableStruct(int)>{return_17});
|
||||
|
||||
// It should be possible to return the result end to end through an
|
||||
// EXPECT_CALL statement, with both WillOnce and WillRepeatedly.
|
||||
MockFunction<Result()> mock;
|
||||
MockFunction<NonMoveableStruct()> mock;
|
||||
EXPECT_CALL(mock, Call) //
|
||||
.WillOnce(return_17) //
|
||||
.WillRepeatedly(return_17);
|
||||
@ -904,7 +906,7 @@ TEST(ExpectCallTest, TakesDefaultActionWhenWillListIsExhausted) {
|
||||
" - returning default value."));
|
||||
}
|
||||
|
||||
TEST(FunctionMockerMessageTest, ReportsExpectCallLocationForExhausedActions) {
|
||||
TEST(FunctionMockerMessageTest, ReportsExpectCallLocationForExhaustedActions) {
|
||||
MockB b;
|
||||
std::string expect_call_location = FormatFileLocation(__FILE__, __LINE__ + 1);
|
||||
EXPECT_CALL(b, DoB()).Times(AnyNumber()).WillOnce(Return(1));
|
||||
@ -1087,16 +1089,7 @@ TEST(UnexpectedCallTest, UnsatisfiedPrerequisites) {
|
||||
|
||||
// Verifies that the failure message contains the two unsatisfied
|
||||
// pre-requisites but not the satisfied one.
|
||||
#if GTEST_USES_PCRE
|
||||
EXPECT_THAT(
|
||||
r.message(),
|
||||
ContainsRegex(
|
||||
// PCRE has trouble using (.|\n) to match any character, but
|
||||
// supports the (?s) prefix for using . to match any character.
|
||||
"(?s)the following immediate pre-requisites are not satisfied:\n"
|
||||
".*: pre-requisite #0\n"
|
||||
".*: pre-requisite #1"));
|
||||
#elif GTEST_USES_POSIX_RE
|
||||
#ifdef GTEST_USES_POSIX_RE
|
||||
EXPECT_THAT(r.message(),
|
||||
ContainsRegex(
|
||||
// POSIX RE doesn't understand the (?s) prefix, but has no
|
||||
@ -1111,7 +1104,7 @@ TEST(UnexpectedCallTest, UnsatisfiedPrerequisites) {
|
||||
"the following immediate pre-requisites are not satisfied:"));
|
||||
EXPECT_THAT(r.message(), ContainsRegex(": pre-requisite #0"));
|
||||
EXPECT_THAT(r.message(), ContainsRegex(": pre-requisite #1"));
|
||||
#endif // GTEST_USES_PCRE
|
||||
#endif // GTEST_USES_POSIX_RE
|
||||
|
||||
b.DoB(1);
|
||||
b.DoB(3);
|
||||
@ -1148,10 +1141,11 @@ TEST(ExcessiveCallTest, DoesDefaultAction) {
|
||||
// When there is no ON_CALL(), the default value for the return type
|
||||
// should be returned.
|
||||
MockB b;
|
||||
EXPECT_CALL(b, DoB(0)).Times(0);
|
||||
EXPECT_CALL(b, DoB(0)).Description("DoB Method").Times(0);
|
||||
int n = -1;
|
||||
EXPECT_NONFATAL_FAILURE(n = b.DoB(0),
|
||||
"Mock function called more times than expected");
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
n = b.DoB(0),
|
||||
"Mock function \"DoB Method\" called more times than expected");
|
||||
EXPECT_EQ(0, n);
|
||||
}
|
||||
|
||||
@ -1159,10 +1153,11 @@ TEST(ExcessiveCallTest, DoesDefaultAction) {
|
||||
// the failure message contains the argument values.
|
||||
TEST(ExcessiveCallTest, GeneratesFailureForVoidFunction) {
|
||||
MockA a;
|
||||
EXPECT_CALL(a, DoA(_)).Times(0);
|
||||
EXPECT_CALL(a, DoA(_)).Description("DoA Method").Times(0);
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
a.DoA(9),
|
||||
"Mock function called more times than expected - returning directly.\n"
|
||||
"Mock function \"DoA Method\" called more times than expected - "
|
||||
"returning directly.\n"
|
||||
" Function call: DoA(9)\n"
|
||||
" Expected: to be never called\n"
|
||||
" Actual: called once - over-saturated and active");
|
||||
@ -1776,16 +1771,11 @@ TEST(DeletingMockEarlyTest, Success2) {
|
||||
|
||||
// Suppresses warning on unreferenced formal parameter in MSVC with
|
||||
// -W4.
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4100)
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)
|
||||
|
||||
ACTION_P(Delete, ptr) { delete ptr; }
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100
|
||||
|
||||
TEST(DeletingMockEarlyTest, CanDeleteSelfInActionReturningVoid) {
|
||||
MockA* const a = new MockA;
|
||||
@ -1892,7 +1882,7 @@ struct Unprintable {
|
||||
|
||||
class MockC {
|
||||
public:
|
||||
MockC() {}
|
||||
MockC() = default;
|
||||
|
||||
MOCK_METHOD6(VoidMethod, void(bool cond, int n, std::string s, void* p,
|
||||
const Printable& x, Unprintable y));
|
||||
@ -2061,7 +2051,7 @@ class GMockVerboseFlagTest : public VerboseFlagPreservingFixture {
|
||||
"See "
|
||||
"https://github.com/google/googletest/blob/main/docs/"
|
||||
"gmock_cook_book.md#"
|
||||
"knowing-when-to-expect for details.";
|
||||
"knowing-when-to-expect-useoncall for details.";
|
||||
|
||||
// A void-returning function.
|
||||
CaptureStdout();
|
||||
@ -2132,7 +2122,7 @@ void PrintTo(PrintMeNot /* dummy */, ::std::ostream* /* os */) {
|
||||
|
||||
class LogTestHelper {
|
||||
public:
|
||||
LogTestHelper() {}
|
||||
LogTestHelper() = default;
|
||||
|
||||
MOCK_METHOD1(Foo, PrintMeNot(PrintMeNot));
|
||||
|
||||
@ -2599,14 +2589,7 @@ TEST(ParameterlessExpectationsTest,
|
||||
} // namespace
|
||||
} // namespace testing
|
||||
|
||||
// Allows the user to define their own main and then invoke gmock_main
|
||||
// from it. This might be necessary on some platforms which require
|
||||
// specific setup and teardown.
|
||||
#if GMOCK_RENAME_MAIN
|
||||
int gmock_main(int argc, char** argv) {
|
||||
#else
|
||||
int main(int argc, char** argv) {
|
||||
#endif // GMOCK_RENAME_MAIN
|
||||
testing::InitGoogleMock(&argc, argv);
|
||||
// Ensures that the tests pass no matter what value of
|
||||
// --gmock_catch_leaked_mocks and --gmock_verbose the user specifies.
|
||||
|
@ -29,6 +29,8 @@
|
||||
|
||||
// Tests Google Mock's functionality that depends on exceptions.
|
||||
|
||||
#include <exception>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
|
@ -54,50 +54,59 @@ class GMockLeakTest(gmock_test_utils.TestCase):
|
||||
def testCatchesLeakedMockByDefault(self):
|
||||
self.assertNotEqual(
|
||||
0,
|
||||
gmock_test_utils.Subprocess(TEST_WITH_EXPECT_CALL,
|
||||
env=environ).exit_code)
|
||||
gmock_test_utils.Subprocess(
|
||||
TEST_WITH_EXPECT_CALL, env=environ
|
||||
).exit_code,
|
||||
)
|
||||
self.assertNotEqual(
|
||||
0,
|
||||
gmock_test_utils.Subprocess(TEST_WITH_ON_CALL,
|
||||
env=environ).exit_code)
|
||||
0, gmock_test_utils.Subprocess(TEST_WITH_ON_CALL, env=environ).exit_code
|
||||
)
|
||||
|
||||
def testDoesNotCatchLeakedMockWhenDisabled(self):
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
0,
|
||||
gmock_test_utils.Subprocess(TEST_WITH_EXPECT_CALL +
|
||||
['--gmock_catch_leaked_mocks=0'],
|
||||
env=environ).exit_code)
|
||||
self.assertEquals(
|
||||
gmock_test_utils.Subprocess(
|
||||
TEST_WITH_EXPECT_CALL + ['--gmock_catch_leaked_mocks=0'],
|
||||
env=environ,
|
||||
).exit_code,
|
||||
)
|
||||
self.assertEqual(
|
||||
0,
|
||||
gmock_test_utils.Subprocess(TEST_WITH_ON_CALL +
|
||||
['--gmock_catch_leaked_mocks=0'],
|
||||
env=environ).exit_code)
|
||||
gmock_test_utils.Subprocess(
|
||||
TEST_WITH_ON_CALL + ['--gmock_catch_leaked_mocks=0'], env=environ
|
||||
).exit_code,
|
||||
)
|
||||
|
||||
def testCatchesLeakedMockWhenEnabled(self):
|
||||
self.assertNotEqual(
|
||||
0,
|
||||
gmock_test_utils.Subprocess(TEST_WITH_EXPECT_CALL +
|
||||
['--gmock_catch_leaked_mocks'],
|
||||
env=environ).exit_code)
|
||||
gmock_test_utils.Subprocess(
|
||||
TEST_WITH_EXPECT_CALL + ['--gmock_catch_leaked_mocks'], env=environ
|
||||
).exit_code,
|
||||
)
|
||||
self.assertNotEqual(
|
||||
0,
|
||||
gmock_test_utils.Subprocess(TEST_WITH_ON_CALL +
|
||||
['--gmock_catch_leaked_mocks'],
|
||||
env=environ).exit_code)
|
||||
gmock_test_utils.Subprocess(
|
||||
TEST_WITH_ON_CALL + ['--gmock_catch_leaked_mocks'], env=environ
|
||||
).exit_code,
|
||||
)
|
||||
|
||||
def testCatchesLeakedMockWhenEnabledWithExplictFlagValue(self):
|
||||
self.assertNotEqual(
|
||||
0,
|
||||
gmock_test_utils.Subprocess(TEST_WITH_EXPECT_CALL +
|
||||
['--gmock_catch_leaked_mocks=1'],
|
||||
env=environ).exit_code)
|
||||
gmock_test_utils.Subprocess(
|
||||
TEST_WITH_EXPECT_CALL + ['--gmock_catch_leaked_mocks=1'],
|
||||
env=environ,
|
||||
).exit_code,
|
||||
)
|
||||
|
||||
def testCatchesMultipleLeakedMocks(self):
|
||||
self.assertNotEqual(
|
||||
0,
|
||||
gmock_test_utils.Subprocess(TEST_MULTIPLE_LEAKS +
|
||||
['--gmock_catch_leaked_mocks'],
|
||||
env=environ).exit_code)
|
||||
gmock_test_utils.Subprocess(
|
||||
TEST_MULTIPLE_LEAKS + ['--gmock_catch_leaked_mocks'], env=environ
|
||||
).exit_code,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -40,13 +40,13 @@ using ::testing::Return;
|
||||
|
||||
class FooInterface {
|
||||
public:
|
||||
virtual ~FooInterface() {}
|
||||
virtual ~FooInterface() = default;
|
||||
virtual void DoThis() = 0;
|
||||
};
|
||||
|
||||
class MockFoo : public FooInterface {
|
||||
public:
|
||||
MockFoo() {}
|
||||
MockFoo() = default;
|
||||
|
||||
MOCK_METHOD0(DoThis, void());
|
||||
|
||||
|
@ -116,7 +116,7 @@
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
#if !GTEST_OS_WINDOWS_MOBILE
|
||||
#ifndef GTEST_OS_WINDOWS_MOBILE
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
@ -181,12 +181,13 @@ using testing::WithArg;
|
||||
using testing::WithArgs;
|
||||
using testing::WithoutArgs;
|
||||
|
||||
#if !GTEST_OS_WINDOWS_MOBILE
|
||||
#ifndef GTEST_OS_WINDOWS_MOBILE
|
||||
using testing::SetErrnoAndReturn;
|
||||
#endif
|
||||
|
||||
#if GTEST_HAS_EXCEPTIONS
|
||||
using testing::Throw;
|
||||
using testing::Rethrow;
|
||||
#endif
|
||||
|
||||
using testing::ContainsRegex;
|
||||
@ -194,7 +195,7 @@ using testing::MatchesRegex;
|
||||
|
||||
class Interface {
|
||||
public:
|
||||
virtual ~Interface() {}
|
||||
virtual ~Interface() = default;
|
||||
virtual void VoidFromString(char* str) = 0;
|
||||
virtual char* StringFromString(char* str) = 0;
|
||||
virtual int IntFromString(char* str) = 0;
|
||||
@ -208,7 +209,7 @@ class Interface {
|
||||
|
||||
class Mock : public Interface {
|
||||
public:
|
||||
Mock() {}
|
||||
Mock() = default;
|
||||
|
||||
MOCK_METHOD1(VoidFromString, void(char* str));
|
||||
MOCK_METHOD1(StringFromString, char*(char* str));
|
||||
@ -306,7 +307,7 @@ TEST(LinkTest, TestSetArrayArgument) {
|
||||
mock.VoidFromString(&ch);
|
||||
}
|
||||
|
||||
#if !GTEST_OS_WINDOWS_MOBILE
|
||||
#ifndef GTEST_OS_WINDOWS_MOBILE
|
||||
|
||||
// Tests the linkage of the SetErrnoAndReturn action.
|
||||
TEST(LinkTest, TestSetErrnoAndReturn) {
|
||||
@ -416,6 +417,14 @@ TEST(LinkTest, TestThrow) {
|
||||
EXPECT_CALL(mock, VoidFromString(_)).WillOnce(Throw(42));
|
||||
EXPECT_THROW(mock.VoidFromString(nullptr), int);
|
||||
}
|
||||
// Tests the linkage of the Rethrow action.
|
||||
TEST(LinkTest, TestRethrow) {
|
||||
Mock mock;
|
||||
|
||||
EXPECT_CALL(mock, VoidFromString(_))
|
||||
.WillOnce(Rethrow(std::make_exception_ptr(42)));
|
||||
EXPECT_THROW(mock.VoidFromString(nullptr), int);
|
||||
}
|
||||
#endif // GTEST_HAS_EXCEPTIONS
|
||||
|
||||
// The ACTION*() macros trigger warning C4100 (unreferenced formal
|
||||
@ -423,10 +432,7 @@ TEST(LinkTest, TestThrow) {
|
||||
// the macro definition, as the warnings are generated when the macro
|
||||
// is expanded and macro expansion cannot contain #pragma. Therefore
|
||||
// we suppress them here.
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4100)
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)
|
||||
|
||||
// Tests the linkage of actions created using ACTION macro.
|
||||
namespace {
|
||||
@ -459,9 +465,7 @@ ACTION_P2(ReturnEqualsEitherOf, first, second) {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100
|
||||
|
||||
TEST(LinkTest, TestActionP2Macro) {
|
||||
Mock mock;
|
||||
|
@ -39,7 +39,7 @@ gmock_output_test.py
|
||||
|
||||
"""
|
||||
|
||||
from io import open # pylint: disable=redefined-builtin, g-importing-member
|
||||
from io import open # pylint: disable=redefined-builtin, g-importing-member
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
@ -159,15 +159,22 @@ class GMockOutputTest(gmock_test_utils.TestCase):
|
||||
golden_file = open(GOLDEN_PATH, 'rb')
|
||||
golden = golden_file.read().decode('utf-8')
|
||||
golden_file.close()
|
||||
# On Windows the repository might have been checked out with \r\n line
|
||||
# endings, so normalize it here.
|
||||
golden = ToUnixLineEnding(golden)
|
||||
|
||||
# The normalized output should match the golden file.
|
||||
self.assertEqual(golden, output)
|
||||
|
||||
# The raw output should contain 2 leaked mock object errors for
|
||||
# test GMockOutputTest.CatchesLeakedMocks.
|
||||
self.assertEqual(['GMockOutputTest.CatchesLeakedMocks',
|
||||
'GMockOutputTest.CatchesLeakedMocks'],
|
||||
leaky_tests)
|
||||
self.assertEqual(
|
||||
[
|
||||
'GMockOutputTest.CatchesLeakedMocks',
|
||||
'GMockOutputTest.CatchesLeakedMocks',
|
||||
],
|
||||
leaky_tests,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -38,10 +38,7 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
// Silence C4100 (unreferenced formal parameter)
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4100)
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)
|
||||
|
||||
using testing::_;
|
||||
using testing::AnyNumber;
|
||||
@ -55,7 +52,7 @@ using testing::Value;
|
||||
|
||||
class MockFoo {
|
||||
public:
|
||||
MockFoo() {}
|
||||
MockFoo() = default;
|
||||
|
||||
MOCK_METHOD3(Bar, char(const std::string& s, int i, double x));
|
||||
MOCK_METHOD2(Bar2, bool(int x, int y));
|
||||
@ -286,6 +283,4 @@ int main(int argc, char** argv) {
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100
|
||||
|
@ -40,6 +40,7 @@ FILE:#: EXPECT_CALL(foo_, Bar2(0, _))...
|
||||
Actual: 1
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.UnexpectedCall
|
||||
[ RUN ] GMockOutputTest.UnexpectedCallToVoidFunction
|
||||
unknown file: Failure
|
||||
@ -53,6 +54,7 @@ FILE:#: EXPECT_CALL(foo_, Bar3(0, _))...
|
||||
Actual: 1
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.UnexpectedCallToVoidFunction
|
||||
[ RUN ] GMockOutputTest.ExcessiveCall
|
||||
FILE:#: Failure
|
||||
@ -61,6 +63,7 @@ Mock function called more times than expected - returning default value.
|
||||
Returns: false
|
||||
Expected: to be called once
|
||||
Actual: called twice - over-saturated and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.ExcessiveCall
|
||||
[ RUN ] GMockOutputTest.ExcessiveCallToVoidFunction
|
||||
FILE:#: Failure
|
||||
@ -68,6 +71,7 @@ Mock function called more times than expected - returning directly.
|
||||
Function call: Bar3(0, 1)
|
||||
Expected: to be called once
|
||||
Actual: called twice - over-saturated and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.ExcessiveCallToVoidFunction
|
||||
[ RUN ] GMockOutputTest.UninterestingCall
|
||||
|
||||
@ -75,14 +79,14 @@ GMOCK WARNING:
|
||||
Uninteresting mock function call - returning default value.
|
||||
Function call: Bar2(0, 1)
|
||||
Returns: false
|
||||
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md#knowing-when-to-expect for details.
|
||||
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md#knowing-when-to-expect-useoncall for details.
|
||||
[ OK ] GMockOutputTest.UninterestingCall
|
||||
[ RUN ] GMockOutputTest.UninterestingCallToVoidFunction
|
||||
|
||||
GMOCK WARNING:
|
||||
Uninteresting mock function call - returning directly.
|
||||
Function call: Bar3(0, 1)
|
||||
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md#knowing-when-to-expect for details.
|
||||
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md#knowing-when-to-expect-useoncall for details.
|
||||
[ OK ] GMockOutputTest.UninterestingCallToVoidFunction
|
||||
[ RUN ] GMockOutputTest.RetiredExpectation
|
||||
unknown file: Failure
|
||||
@ -104,6 +108,7 @@ FILE:#: tried expectation #1: EXPECT_CALL(foo_, Bar2(0, 0))...
|
||||
Actual: 1
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.RetiredExpectation
|
||||
[ RUN ] GMockOutputTest.UnsatisfiedPrerequisite
|
||||
unknown file: Failure
|
||||
@ -125,6 +130,7 @@ FILE:#: pre-requisite #0
|
||||
(end of pre-requisites)
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.UnsatisfiedPrerequisite
|
||||
[ RUN ] GMockOutputTest.UnsatisfiedPrerequisites
|
||||
unknown file: Failure
|
||||
@ -147,6 +153,7 @@ FILE:#: pre-requisite #1
|
||||
(end of pre-requisites)
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.UnsatisfiedPrerequisites
|
||||
[ RUN ] GMockOutputTest.UnsatisfiedWith
|
||||
FILE:#: Failure
|
||||
@ -154,16 +161,19 @@ Actual function call count doesn't match EXPECT_CALL(foo_, Bar2(_, _))...
|
||||
Expected args: are a pair where the first >= the second
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.UnsatisfiedWith
|
||||
[ RUN ] GMockOutputTest.UnsatisfiedExpectation
|
||||
FILE:#: Failure
|
||||
Actual function call count doesn't match EXPECT_CALL(foo_, Bar2(0, _))...
|
||||
Expected: to be called twice
|
||||
Actual: called once - unsatisfied and active
|
||||
|
||||
FILE:#: Failure
|
||||
Actual function call count doesn't match EXPECT_CALL(foo_, Bar(_, _, _))...
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.UnsatisfiedExpectation
|
||||
[ RUN ] GMockOutputTest.MismatchArguments
|
||||
unknown file: Failure
|
||||
@ -180,6 +190,7 @@ FILE:#: EXPECT_CALL(foo_, Bar(Ref(s), _, Ge(0)))...
|
||||
Actual: -0.1
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.MismatchArguments
|
||||
[ RUN ] GMockOutputTest.MismatchWith
|
||||
unknown file: Failure
|
||||
@ -194,6 +205,7 @@ FILE:#: EXPECT_CALL(foo_, Bar2(Ge(2), Ge(1)))...
|
||||
Actual: don't match
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.MismatchWith
|
||||
[ RUN ] GMockOutputTest.MismatchArgumentsAndWith
|
||||
unknown file: Failure
|
||||
@ -210,6 +222,7 @@ FILE:#: EXPECT_CALL(foo_, Bar2(Ge(2), Ge(1)))...
|
||||
Actual: don't match
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.MismatchArgumentsAndWith
|
||||
[ RUN ] GMockOutputTest.UnexpectedCallWithDefaultAction
|
||||
unknown file: Failure
|
||||
@ -227,6 +240,7 @@ FILE:#: EXPECT_CALL(foo_, Bar2(2, 2))...
|
||||
Actual: 0
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
|
||||
unknown file: Failure
|
||||
|
||||
Unexpected mock function call - taking default action specified at:
|
||||
@ -242,6 +256,7 @@ FILE:#: EXPECT_CALL(foo_, Bar2(2, 2))...
|
||||
Actual: 0
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.UnexpectedCallWithDefaultAction
|
||||
[ RUN ] GMockOutputTest.ExcessiveCallWithDefaultAction
|
||||
FILE:#: Failure
|
||||
@ -251,6 +266,7 @@ FILE:#:
|
||||
Returns: true
|
||||
Expected: to be called once
|
||||
Actual: called twice - over-saturated and active
|
||||
|
||||
FILE:#: Failure
|
||||
Mock function called more times than expected - taking default action specified at:
|
||||
FILE:#:
|
||||
@ -258,6 +274,7 @@ FILE:#:
|
||||
Returns: false
|
||||
Expected: to be called once
|
||||
Actual: called twice - over-saturated and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.ExcessiveCallWithDefaultAction
|
||||
[ RUN ] GMockOutputTest.UninterestingCallWithDefaultAction
|
||||
|
||||
@ -266,14 +283,14 @@ Uninteresting mock function call - taking default action specified at:
|
||||
FILE:#:
|
||||
Function call: Bar2(2, 2)
|
||||
Returns: true
|
||||
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md#knowing-when-to-expect for details.
|
||||
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md#knowing-when-to-expect-useoncall for details.
|
||||
|
||||
GMOCK WARNING:
|
||||
Uninteresting mock function call - taking default action specified at:
|
||||
FILE:#:
|
||||
Function call: Bar2(1, 1)
|
||||
Returns: false
|
||||
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md#knowing-when-to-expect for details.
|
||||
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md#knowing-when-to-expect-useoncall for details.
|
||||
[ OK ] GMockOutputTest.UninterestingCallWithDefaultAction
|
||||
[ RUN ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction
|
||||
|
||||
@ -292,7 +309,8 @@ Stack trace:
|
||||
FILE:#: Failure
|
||||
Value of: (std::pair<int, bool>(42, true))
|
||||
Expected: is pair (first: is >= 48, second: true)
|
||||
Actual: (42, true) (of type std::pair<int, bool>)
|
||||
Actual: (42, true) (of type std::pair<int,bool>)
|
||||
|
||||
[ FAILED ] GMockOutputTest.PrintsMatcher
|
||||
[ FAILED ] GMockOutputTest.UnexpectedCall
|
||||
[ FAILED ] GMockOutputTest.UnexpectedCallToVoidFunction
|
||||
|
@ -174,6 +174,6 @@ TEST(WideInitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
|
||||
// Makes sure Google Mock flags can be accessed in code.
|
||||
TEST(FlagTest, IsAccessibleInCode) {
|
||||
bool dummy =
|
||||
GMOCK_FLAG_GET(catch_leaked_mocks) && GMOCK_FLAG_GET(verbose) == "";
|
||||
GMOCK_FLAG_GET(catch_leaked_mocks) && GMOCK_FLAG_GET(verbose).empty();
|
||||
(void)dummy; // Avoids the "unused local variable" warning.
|
||||
}
|
||||
|
@ -77,9 +77,6 @@ def GetExitStatus(exit_code):
|
||||
return -1
|
||||
|
||||
|
||||
# Suppresses the "Invalid const name" lint complaint
|
||||
# pylint: disable-msg=C6409
|
||||
|
||||
# Exposes utilities from gtest_test_utils.
|
||||
Subprocess = gtest_test_utils.Subprocess
|
||||
TestCase = gtest_test_utils.TestCase
|
||||
@ -87,8 +84,6 @@ environ = gtest_test_utils.environ
|
||||
SetEnvVar = gtest_test_utils.SetEnvVar
|
||||
PREMATURE_EXIT_FILE_ENV_VAR = gtest_test_utils.PREMATURE_EXIT_FILE_ENV_VAR
|
||||
|
||||
# pylint: enable-msg=C6409
|
||||
|
||||
|
||||
def Main():
|
||||
"""Runs the unit test."""
|
||||
|
@ -5,7 +5,7 @@
|
||||
# CMake build script for Google Test.
|
||||
#
|
||||
# To run the tests for Google Test itself on Linux, use 'make test' or
|
||||
# ctest. You can select which tests to run using 'ctest -R regex'.
|
||||
# ctest. You can select which tests to run using 'ctest -R regex'.
|
||||
# For more options, run 'ctest --help'.
|
||||
|
||||
# When other libraries are using a shared version of runtime libraries,
|
||||
@ -35,7 +35,7 @@ endif()
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Project-wide settings
|
||||
# Project-wide settings.
|
||||
|
||||
# Name of the project.
|
||||
#
|
||||
@ -44,21 +44,16 @@ endif()
|
||||
# ${gtest_BINARY_DIR}.
|
||||
# Language "C" is required for find_package(Threads).
|
||||
|
||||
# Project version:
|
||||
# Project version.
|
||||
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
cmake_policy(SET CMP0048 NEW)
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(gtest VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)
|
||||
|
||||
if (POLICY CMP0063) # Visibility
|
||||
cmake_policy(SET CMP0063 NEW)
|
||||
endif (POLICY CMP0063)
|
||||
|
||||
if (COMMAND set_up_hermetic_build)
|
||||
set_up_hermetic_build()
|
||||
endif()
|
||||
|
||||
# These commands only run if this is the main project
|
||||
# These commands only run if this is the main project.
|
||||
if(CMAKE_PROJECT_NAME STREQUAL "gtest" OR CMAKE_PROJECT_NAME STREQUAL "googletest-distribution")
|
||||
|
||||
# BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to
|
||||
@ -88,7 +83,7 @@ include(cmake/internal_utils.cmake)
|
||||
config_compiler_and_linker() # Defined in internal_utils.cmake.
|
||||
|
||||
# Needed to set the namespace for both the export targets and the
|
||||
# alias libraries
|
||||
# alias libraries.
|
||||
set(cmake_package_name GTest CACHE INTERNAL "")
|
||||
|
||||
# Create the CMake package file descriptors.
|
||||
@ -100,12 +95,14 @@ if (INSTALL_GTEST)
|
||||
set(version_file "${generated_dir}/${cmake_package_name}ConfigVersion.cmake")
|
||||
write_basic_package_version_file(${version_file} VERSION ${GOOGLETEST_VERSION} COMPATIBILITY AnyNewerVersion)
|
||||
install(EXPORT ${targets_export_name}
|
||||
COMPONENT "${PROJECT_NAME}"
|
||||
NAMESPACE ${cmake_package_name}::
|
||||
DESTINATION ${cmake_files_install_dir})
|
||||
set(config_file "${generated_dir}/${cmake_package_name}Config.cmake")
|
||||
configure_package_config_file("${gtest_SOURCE_DIR}/cmake/Config.cmake.in"
|
||||
"${config_file}" INSTALL_DESTINATION ${cmake_files_install_dir})
|
||||
install(FILES ${version_file} ${config_file}
|
||||
COMPONENT "${PROJECT_NAME}"
|
||||
DESTINATION ${cmake_files_install_dir})
|
||||
endif()
|
||||
|
||||
@ -117,44 +114,55 @@ include_directories(${gtest_build_include_dirs})
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Defines the gtest & gtest_main libraries. User tests should link
|
||||
# Defines the gtest & gtest_main libraries. User tests should link
|
||||
# with one of them.
|
||||
|
||||
# Google Test libraries. We build them using more strict warnings than what
|
||||
# Google Test libraries. We build them using more strict warnings than what
|
||||
# are used for other targets, to ensure that gtest can be compiled by a user
|
||||
# aggressive about warnings.
|
||||
cxx_library(gtest "${cxx_strict}" src/gtest-all.cc)
|
||||
set_target_properties(gtest PROPERTIES VERSION ${GOOGLETEST_VERSION})
|
||||
if(GTEST_HAS_ABSL)
|
||||
target_compile_definitions(gtest PUBLIC GTEST_HAS_ABSL=1)
|
||||
target_link_libraries(gtest PUBLIC
|
||||
absl::failure_signal_handler
|
||||
absl::stacktrace
|
||||
absl::symbolize
|
||||
absl::flags_parse
|
||||
absl::flags_reflection
|
||||
absl::flags_usage
|
||||
absl::strings
|
||||
absl::any
|
||||
absl::optional
|
||||
absl::variant
|
||||
re2::re2
|
||||
)
|
||||
endif()
|
||||
cxx_library(gtest_main "${cxx_strict}" src/gtest_main.cc)
|
||||
set_target_properties(gtest_main PROPERTIES VERSION ${GOOGLETEST_VERSION})
|
||||
# If the CMake version supports it, attach header directory information
|
||||
# to the targets for when we are part of a parent build (ie being pulled
|
||||
# in via add_subdirectory() rather than being a standalone build).
|
||||
if (DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11")
|
||||
string(REPLACE ";" "$<SEMICOLON>" dirs "${gtest_build_include_dirs}")
|
||||
target_include_directories(gtest SYSTEM INTERFACE
|
||||
"$<BUILD_INTERFACE:${dirs}>"
|
||||
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
|
||||
target_include_directories(gtest_main SYSTEM INTERFACE
|
||||
"$<BUILD_INTERFACE:${dirs}>"
|
||||
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "QNX")
|
||||
string(REPLACE ";" "$<SEMICOLON>" dirs "${gtest_build_include_dirs}")
|
||||
target_include_directories(gtest SYSTEM INTERFACE
|
||||
"$<BUILD_INTERFACE:${dirs}>"
|
||||
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
|
||||
target_include_directories(gtest_main SYSTEM INTERFACE
|
||||
"$<BUILD_INTERFACE:${dirs}>"
|
||||
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "QNX" AND CMAKE_SYSTEM_VERSION VERSION_GREATER_EQUAL 7.1)
|
||||
target_link_libraries(gtest PUBLIC regex)
|
||||
endif()
|
||||
target_link_libraries(gtest_main PUBLIC gtest)
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Install rules
|
||||
# Install rules.
|
||||
install_project(gtest gtest_main)
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Samples on how to link user tests with gtest or gtest_main.
|
||||
#
|
||||
# They are not built by default. To build them, set the
|
||||
# gtest_build_samples option to ON. You can do it by running ccmake
|
||||
# They are not built by default. To build them, set the
|
||||
# gtest_build_samples option to ON. You can do it by running ccmake
|
||||
# or specifying the -Dgtest_build_samples=ON flag when running cmake.
|
||||
|
||||
if (gtest_build_samples)
|
||||
@ -177,8 +185,8 @@ endif()
|
||||
# You can skip this section if you aren't interested in testing
|
||||
# Google Test itself.
|
||||
#
|
||||
# The tests are not built by default. To build them, set the
|
||||
# gtest_build_tests option to ON. You can do it by running ccmake
|
||||
# The tests are not built by default. To build them, set the
|
||||
# gtest_build_tests option to ON. You can do it by running ccmake
|
||||
# or specifying the -Dgtest_build_tests=ON flag when running cmake.
|
||||
|
||||
if (gtest_build_tests)
|
||||
@ -260,7 +268,7 @@ if (gtest_build_tests)
|
||||
py_test(gtest_skip_environment_check_output_test)
|
||||
|
||||
# Visual Studio .NET 2003 does not support STL with exceptions disabled.
|
||||
if (NOT MSVC OR MSVC_VERSION GREATER 1310) # 1310 is Visual Studio .NET 2003
|
||||
if (NOT MSVC OR MSVC_VERSION GREATER 1310) # 1310 is Visual Studio .NET 2003
|
||||
cxx_executable_with_flags(
|
||||
googletest-catch-exceptions-no-ex-test_
|
||||
"${cxx_no_exception}"
|
||||
|
@ -12,7 +12,7 @@ GoogleTest comes with a CMake build script
|
||||
([CMakeLists.txt](https://github.com/google/googletest/blob/main/CMakeLists.txt))
|
||||
that can be used on a wide range of platforms ("C" stands for cross-platform.).
|
||||
If you don't have CMake installed already, you can download it for free from
|
||||
<http://www.cmake.org/>.
|
||||
<https://cmake.org/>.
|
||||
|
||||
CMake works by generating native makefiles or build projects that can be used in
|
||||
the compiler environment of your choice. You can either build GoogleTest as a
|
||||
@ -25,7 +25,7 @@ When building GoogleTest as a standalone project, the typical workflow starts
|
||||
with
|
||||
|
||||
```
|
||||
git clone https://github.com/google/googletest.git -b release-1.12.0
|
||||
git clone https://github.com/google/googletest.git -b v1.14.0
|
||||
cd googletest # Main directory of the cloned repository.
|
||||
mkdir build # Create a directory to hold the build output.
|
||||
cd build
|
||||
@ -124,12 +124,12 @@ match the project in which it is included.
|
||||
|
||||
#### C++ Standard Version
|
||||
|
||||
An environment that supports C++11 is required in order to successfully build
|
||||
An environment that supports C++14 is required in order to successfully build
|
||||
GoogleTest. One way to ensure this is to specify the standard in the top-level
|
||||
project, for example by using the `set(CMAKE_CXX_STANDARD 11)` command. If this
|
||||
is not feasible, for example in a C project using GoogleTest for validation,
|
||||
then it can be specified by adding it to the options for cmake via the
|
||||
`DCMAKE_CXX_FLAGS` option.
|
||||
project, for example by using the `set(CMAKE_CXX_STANDARD 14)` command along
|
||||
with `set(CMAKE_CXX_STANDARD_REQUIRED ON)`. If this is not feasible, for example
|
||||
in a C project using GoogleTest for validation, then it can be specified by
|
||||
adding it to the options for cmake via the`-DCMAKE_CXX_FLAGS` option.
|
||||
|
||||
### Tweaking GoogleTest
|
||||
|
||||
@ -145,18 +145,22 @@ We list the most frequently used macros below. For a complete list, see file
|
||||
### Multi-threaded Tests
|
||||
|
||||
GoogleTest is thread-safe where the pthread library is available. After
|
||||
`#include "gtest/gtest.h"`, you can check the
|
||||
`#include <gtest/gtest.h>`, you can check the
|
||||
`GTEST_IS_THREADSAFE` macro to see whether this is the case (yes if the macro is
|
||||
`#defined` to 1, no if it's undefined.).
|
||||
|
||||
If GoogleTest doesn't correctly detect whether pthread is available in your
|
||||
environment, you can force it with
|
||||
|
||||
-DGTEST_HAS_PTHREAD=1
|
||||
```
|
||||
-DGTEST_HAS_PTHREAD=1
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
-DGTEST_HAS_PTHREAD=0
|
||||
```
|
||||
-DGTEST_HAS_PTHREAD=0
|
||||
```
|
||||
|
||||
When GoogleTest uses pthread, you may need to add flags to your compiler and/or
|
||||
linker to select the pthread library, or you'll get link errors. If you use the
|
||||
@ -172,23 +176,27 @@ as a DLL on Windows) if you prefer.
|
||||
|
||||
To compile *gtest* as a shared library, add
|
||||
|
||||
-DGTEST_CREATE_SHARED_LIBRARY=1
|
||||
```
|
||||
-DGTEST_CREATE_SHARED_LIBRARY=1
|
||||
```
|
||||
|
||||
to the compiler flags. You'll also need to tell the linker to produce a shared
|
||||
library instead - consult your linker's manual for how to do it.
|
||||
|
||||
To compile your *tests* that use the gtest shared library, add
|
||||
|
||||
-DGTEST_LINKED_AS_SHARED_LIBRARY=1
|
||||
```
|
||||
-DGTEST_LINKED_AS_SHARED_LIBRARY=1
|
||||
```
|
||||
|
||||
to the compiler flags.
|
||||
|
||||
Note: while the above steps aren't technically necessary today when using some
|
||||
compilers (e.g. GCC), they may become necessary in the future, if we decide to
|
||||
improve the speed of loading the library (see
|
||||
<http://gcc.gnu.org/wiki/Visibility> for details). Therefore you are recommended
|
||||
to always add the above flags when using GoogleTest as a shared library.
|
||||
Otherwise a future release of GoogleTest may break your build script.
|
||||
<https://gcc.gnu.org/wiki/Visibility> for details). Therefore you are
|
||||
recommended to always add the above flags when using GoogleTest as a shared
|
||||
library. Otherwise a future release of GoogleTest may break your build script.
|
||||
|
||||
### Avoiding Macro Name Clashes
|
||||
|
||||
@ -200,7 +208,9 @@ rename its macro to avoid the conflict.
|
||||
Specifically, if both GoogleTest and some other code define macro FOO, you can
|
||||
add
|
||||
|
||||
-DGTEST_DONT_DEFINE_FOO=1
|
||||
```
|
||||
-DGTEST_DONT_DEFINE_FOO=1
|
||||
```
|
||||
|
||||
to the compiler flags to tell GoogleTest to change the macro's name from `FOO`
|
||||
to `GTEST_FOO`. Currently `FOO` can be `ASSERT_EQ`, `ASSERT_FALSE`, `ASSERT_GE`,
|
||||
@ -208,10 +218,14 @@ to `GTEST_FOO`. Currently `FOO` can be `ASSERT_EQ`, `ASSERT_FALSE`, `ASSERT_GE`,
|
||||
`EXPECT_FALSE`, `EXPECT_TRUE`, `FAIL`, `SUCCEED`, `TEST`, or `TEST_F`. For
|
||||
example, with `-DGTEST_DONT_DEFINE_TEST=1`, you'll need to write
|
||||
|
||||
GTEST_TEST(SomeTest, DoesThis) { ... }
|
||||
```
|
||||
GTEST_TEST(SomeTest, DoesThis) { ... }
|
||||
```
|
||||
|
||||
instead of
|
||||
|
||||
TEST(SomeTest, DoesThis) { ... }
|
||||
```
|
||||
TEST(SomeTest, DoesThis) { ... }
|
||||
```
|
||||
|
||||
in order to define a test.
|
||||
|
@ -4,6 +4,10 @@ if (@GTEST_HAS_PTHREAD@)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG @THREADS_PREFER_PTHREAD_FLAG@)
|
||||
find_dependency(Threads)
|
||||
endif()
|
||||
if (@GTEST_HAS_ABSL@)
|
||||
find_dependency(absl)
|
||||
find_dependency(re2)
|
||||
endif()
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake")
|
||||
check_required_components("@project_name@")
|
||||
|
@ -12,17 +12,14 @@
|
||||
# Test and Google Mock's option() definitions, and thus must be
|
||||
# called *after* the options have been defined.
|
||||
|
||||
if (POLICY CMP0054)
|
||||
cmake_policy(SET CMP0054 NEW)
|
||||
endif (POLICY CMP0054)
|
||||
|
||||
# Tweaks CMake's default compiler/linker settings to suit Google Test's needs.
|
||||
#
|
||||
# This must be a macro(), as inside a function string() can only
|
||||
# update variables in the function scope.
|
||||
macro(fix_default_compiler_settings_)
|
||||
if (MSVC)
|
||||
# For MSVC, CMake sets certain flags to defaults we want to override.
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC|Clang")
|
||||
# For MSVC and Clang, CMake sets certain flags to defaults we want to
|
||||
# override.
|
||||
# This replacement code is taken from sample in the CMake Wiki at
|
||||
# https://gitlab.kitware.com/cmake/community/wikis/FAQ#dynamic-replace.
|
||||
foreach (flag_var
|
||||
@ -32,13 +29,17 @@ macro(fix_default_compiler_settings_)
|
||||
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
||||
if (NOT BUILD_SHARED_LIBS AND NOT gtest_force_shared_crt)
|
||||
# When Google Test is built as a shared library, it should also use
|
||||
# shared runtime libraries. Otherwise, it may end up with multiple
|
||||
# shared runtime libraries. Otherwise, it may end up with multiple
|
||||
# copies of runtime library data in different modules, resulting in
|
||||
# hard-to-find crashes. When it is built as a static library, it is
|
||||
# preferable to use CRT as static libraries, as we don't have to rely
|
||||
# on CRT DLLs being available. CMake always defaults to using shared
|
||||
# CRT libraries, so we override that default here.
|
||||
string(REPLACE "/MD" "-MT" ${flag_var} "${${flag_var}}")
|
||||
|
||||
# When using Ninja with Clang, static builds pass -D_DLL on Windows.
|
||||
# This is incorrect and should not happen, so we fix that here.
|
||||
string(REPLACE "-D_DLL" "" ${flag_var} "${${flag_var}}")
|
||||
endif()
|
||||
|
||||
# We prefer more strict warning checking for building Google Test.
|
||||
@ -54,11 +55,11 @@ macro(fix_default_compiler_settings_)
|
||||
endmacro()
|
||||
|
||||
# Defines the compiler/linker flags used to build Google Test and
|
||||
# Google Mock. You can tweak these definitions to suit your need. A
|
||||
# Google Mock. You can tweak these definitions to suit your need. A
|
||||
# variable's value is empty before it's explicitly assigned to.
|
||||
macro(config_compiler_and_linker)
|
||||
# Note: pthreads on MinGW is not supported, even if available
|
||||
# instead, we use windows threading primitives
|
||||
# instead, we use windows threading primitives.
|
||||
unset(GTEST_HAS_PTHREAD)
|
||||
if (NOT gtest_disable_pthreads AND NOT MINGW)
|
||||
# Defines CMAKE_USE_PTHREADS_INIT and CMAKE_THREAD_LIBS_INIT.
|
||||
@ -78,28 +79,38 @@ macro(config_compiler_and_linker)
|
||||
set(cxx_exception_flags "-EHsc -D_HAS_EXCEPTIONS=1")
|
||||
set(cxx_no_exception_flags "-EHs-c- -D_HAS_EXCEPTIONS=0")
|
||||
set(cxx_no_rtti_flags "-GR-")
|
||||
# Suppress "unreachable code" warning
|
||||
# http://stackoverflow.com/questions/3232669 explains the issue.
|
||||
# Suppress "unreachable code" warning,
|
||||
# https://stackoverflow.com/questions/3232669 explains the issue.
|
||||
set(cxx_base_flags "${cxx_base_flags} -wd4702")
|
||||
# Ensure MSVC treats source files as UTF-8 encoded.
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
set(cxx_base_flags "${cxx_base_flags} -utf-8")
|
||||
endif()
|
||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
set(cxx_base_flags "-Wall -Wshadow -Wconversion")
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM")
|
||||
set(cxx_base_flags "${cxx_base_flags} /fp:precise -Wno-inconsistent-missing-override -Wno-microsoft-exception-spec -Wno-unused-function -Wno-unused-but-set-variable")
|
||||
endif()
|
||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR
|
||||
CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM")
|
||||
set(cxx_base_flags "-Wall -Wshadow -Wconversion -Wundef")
|
||||
set(cxx_exception_flags "-fexceptions")
|
||||
set(cxx_no_exception_flags "-fno-exceptions")
|
||||
set(cxx_strict_flags "-W -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wunused-parameter -Wcast-align -Wchar-subscripts -Winline -Wredundant-decls")
|
||||
set(cxx_strict_flags "-W -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wunused-parameter -Wcast-align -Winline -Wredundant-decls")
|
||||
set(cxx_no_rtti_flags "-fno-rtti")
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
set(cxx_strict_flags "${cxx_strict_flags} -Wchar-subscripts")
|
||||
endif()
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM")
|
||||
set(cxx_base_flags "${cxx_base_flags} -Wno-implicit-float-size-conversion -ffp-model=precise")
|
||||
endif()
|
||||
elseif (CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(cxx_base_flags "-Wall -Wshadow")
|
||||
set(cxx_base_flags "-Wall -Wshadow -Wundef")
|
||||
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0)
|
||||
set(cxx_base_flags "${cxx_base_flags} -Wno-error=dangling-else")
|
||||
endif()
|
||||
set(cxx_exception_flags "-fexceptions")
|
||||
set(cxx_no_exception_flags "-fno-exceptions")
|
||||
# Until version 4.3.2, GCC doesn't define a macro to indicate
|
||||
# whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI
|
||||
# whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI
|
||||
# explicitly.
|
||||
set(cxx_no_rtti_flags "-fno-rtti -DGTEST_HAS_RTTI=0")
|
||||
set(cxx_strict_flags
|
||||
@ -116,7 +127,7 @@ macro(config_compiler_and_linker)
|
||||
set(cxx_exception_flags "-qeh")
|
||||
set(cxx_no_exception_flags "-qnoeh")
|
||||
# Until version 9.0, Visual Age doesn't define a macro to indicate
|
||||
# whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI
|
||||
# whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI
|
||||
# explicitly.
|
||||
set(cxx_no_rtti_flags "-qnortti -DGTEST_HAS_RTTI=0")
|
||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "HP")
|
||||
@ -146,7 +157,7 @@ macro(config_compiler_and_linker)
|
||||
set(cxx_strict "${cxx_default} ${cxx_strict_flags}")
|
||||
endmacro()
|
||||
|
||||
# Defines the gtest & gtest_main libraries. User tests should link
|
||||
# Defines the gtest & gtest_main libraries. User tests should link
|
||||
# with one of them.
|
||||
function(cxx_library_with_type name type cxx_flags)
|
||||
# type can be either STATIC or SHARED to denote a static or shared library.
|
||||
@ -156,7 +167,7 @@ function(cxx_library_with_type name type cxx_flags)
|
||||
set_target_properties(${name}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "${cxx_flags}")
|
||||
# Set the output directory for build artifacts
|
||||
# Set the output directory for build artifacts.
|
||||
set_target_properties(${name}
|
||||
PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
||||
@ -164,7 +175,7 @@ function(cxx_library_with_type name type cxx_flags)
|
||||
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
||||
PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
||||
COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
|
||||
# make PDBs match library name
|
||||
# Make PDBs match library name.
|
||||
get_target_property(pdb_debug_postfix ${name} DEBUG_POSTFIX)
|
||||
set_target_properties(${name}
|
||||
PROPERTIES
|
||||
@ -177,23 +188,14 @@ function(cxx_library_with_type name type cxx_flags)
|
||||
set_target_properties(${name}
|
||||
PROPERTIES
|
||||
COMPILE_DEFINITIONS "GTEST_CREATE_SHARED_LIBRARY=1")
|
||||
if (NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11")
|
||||
target_compile_definitions(${name} INTERFACE
|
||||
$<INSTALL_INTERFACE:GTEST_LINKED_AS_SHARED_LIBRARY=1>)
|
||||
endif()
|
||||
target_compile_definitions(${name} INTERFACE
|
||||
$<INSTALL_INTERFACE:GTEST_LINKED_AS_SHARED_LIBRARY=1>)
|
||||
endif()
|
||||
if (DEFINED GTEST_HAS_PTHREAD)
|
||||
if ("${CMAKE_VERSION}" VERSION_LESS "3.1.0")
|
||||
set(threads_spec ${CMAKE_THREAD_LIBS_INIT})
|
||||
else()
|
||||
set(threads_spec Threads::Threads)
|
||||
endif()
|
||||
target_link_libraries(${name} PUBLIC ${threads_spec})
|
||||
target_link_libraries(${name} PUBLIC Threads::Threads)
|
||||
endif()
|
||||
|
||||
if (NOT "${CMAKE_VERSION}" VERSION_LESS "3.8")
|
||||
target_compile_features(${name} PUBLIC cxx_std_14)
|
||||
endif()
|
||||
target_compile_features(${name} PUBLIC cxx_std_14)
|
||||
endfunction()
|
||||
|
||||
########################################################################
|
||||
@ -210,7 +212,7 @@ endfunction()
|
||||
|
||||
# cxx_executable_with_flags(name cxx_flags libs srcs...)
|
||||
#
|
||||
# creates a named C++ executable that depends on the given libraries and
|
||||
# Creates a named C++ executable that depends on the given libraries and
|
||||
# is built from the given source files with the given compiler flags.
|
||||
function(cxx_executable_with_flags name cxx_flags libs)
|
||||
add_executable(${name} ${ARGN})
|
||||
@ -237,32 +239,21 @@ endfunction()
|
||||
|
||||
# cxx_executable(name dir lib srcs...)
|
||||
#
|
||||
# creates a named target that depends on the given libs and is built
|
||||
# from the given source files. dir/name.cc is implicitly included in
|
||||
# Creates a named target that depends on the given libs and is built
|
||||
# from the given source files. dir/name.cc is implicitly included in
|
||||
# the source file list.
|
||||
function(cxx_executable name dir libs)
|
||||
cxx_executable_with_flags(
|
||||
${name} "${cxx_default}" "${libs}" "${dir}/${name}.cc" ${ARGN})
|
||||
endfunction()
|
||||
|
||||
# CMP0094 policy enables finding a Python executable in the LOCATION order, as
|
||||
# specified by the PATH environment variable.
|
||||
if (POLICY CMP0094)
|
||||
cmake_policy(SET CMP0094 NEW)
|
||||
endif()
|
||||
|
||||
# Sets PYTHONINTERP_FOUND and PYTHON_EXECUTABLE.
|
||||
if ("${CMAKE_VERSION}" VERSION_LESS "3.12.0")
|
||||
find_package(PythonInterp)
|
||||
else()
|
||||
find_package(Python COMPONENTS Interpreter)
|
||||
set(PYTHONINTERP_FOUND ${Python_Interpreter_FOUND})
|
||||
set(PYTHON_EXECUTABLE ${Python_EXECUTABLE})
|
||||
if(gtest_build_tests)
|
||||
find_package(Python3)
|
||||
endif()
|
||||
|
||||
# cxx_test_with_flags(name cxx_flags libs srcs...)
|
||||
#
|
||||
# creates a named C++ test that depends on the given libs and is built
|
||||
# Creates a named C++ test that depends on the given libs and is built
|
||||
# from the given source files with the given compiler flags.
|
||||
function(cxx_test_with_flags name cxx_flags libs)
|
||||
cxx_executable_with_flags(${name} "${cxx_flags}" "${libs}" ${ARGN})
|
||||
@ -271,8 +262,8 @@ endfunction()
|
||||
|
||||
# cxx_test(name libs srcs...)
|
||||
#
|
||||
# creates a named test target that depends on the given libs and is
|
||||
# built from the given source files. Unlike cxx_test_with_flags,
|
||||
# Creates a named test target that depends on the given libs and is
|
||||
# built from the given source files. Unlike cxx_test_with_flags,
|
||||
# test/name.cc is already implicitly included in the source file list.
|
||||
function(cxx_test name libs)
|
||||
cxx_test_with_flags("${name}" "${cxx_default}" "${libs}"
|
||||
@ -281,37 +272,25 @@ endfunction()
|
||||
|
||||
# py_test(name)
|
||||
#
|
||||
# creates a Python test with the given name whose main module is in
|
||||
# test/name.py. It does nothing if Python is not installed.
|
||||
# Creates a Python test with the given name whose main module is in
|
||||
# test/name.py. It does nothing if Python is not installed.
|
||||
function(py_test name)
|
||||
if (PYTHONINTERP_FOUND)
|
||||
if ("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_GREATER 3.1)
|
||||
if (CMAKE_CONFIGURATION_TYPES)
|
||||
# Multi-configuration build generators as for Visual Studio save
|
||||
# output in a subdirectory of CMAKE_CURRENT_BINARY_DIR (Debug,
|
||||
# Release etc.), so we have to provide it here.
|
||||
add_test(NAME ${name}
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py
|
||||
--build_dir=${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG> ${ARGN})
|
||||
else (CMAKE_CONFIGURATION_TYPES)
|
||||
# Single-configuration build generators like Makefile generators
|
||||
# don't have subdirs below CMAKE_CURRENT_BINARY_DIR.
|
||||
add_test(NAME ${name}
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py
|
||||
--build_dir=${CMAKE_CURRENT_BINARY_DIR} ${ARGN})
|
||||
endif (CMAKE_CONFIGURATION_TYPES)
|
||||
else()
|
||||
# ${CMAKE_CURRENT_BINARY_DIR} is known at configuration time, so we can
|
||||
# directly bind it from cmake. ${CTEST_CONFIGURATION_TYPE} is known
|
||||
# only at ctest runtime (by calling ctest -c <Configuration>), so
|
||||
# we have to escape $ to delay variable substitution here.
|
||||
add_test(NAME ${name}
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py
|
||||
--build_dir=${CMAKE_CURRENT_BINARY_DIR}/\${CTEST_CONFIGURATION_TYPE} ${ARGN})
|
||||
endif()
|
||||
# Make the Python import path consistent between Bazel and CMake.
|
||||
set_tests_properties(${name} PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_SOURCE_DIR})
|
||||
endif(PYTHONINTERP_FOUND)
|
||||
if (NOT Python3_Interpreter_FOUND)
|
||||
return()
|
||||
endif()
|
||||
|
||||
get_cmake_property(is_multi "GENERATOR_IS_MULTI_CONFIG")
|
||||
set(build_dir "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
if (is_multi)
|
||||
set(build_dir "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>")
|
||||
endif()
|
||||
|
||||
add_test(NAME ${name}
|
||||
COMMAND Python3::Interpreter ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py
|
||||
--build_dir=${build_dir} ${ARGN})
|
||||
|
||||
# Make the Python import path consistent between Bazel and CMake.
|
||||
set_tests_properties(${name} PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_SOURCE_DIR})
|
||||
endfunction()
|
||||
|
||||
# install_project(targets...)
|
||||
@ -320,21 +299,24 @@ endfunction()
|
||||
function(install_project)
|
||||
if(INSTALL_GTEST)
|
||||
install(DIRECTORY "${PROJECT_SOURCE_DIR}/include/"
|
||||
COMPONENT "${PROJECT_NAME}"
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
# Install the project targets.
|
||||
install(TARGETS ${ARGN}
|
||||
EXPORT ${targets_export_name}
|
||||
COMPONENT "${PROJECT_NAME}"
|
||||
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||
# Install PDBs
|
||||
# Install PDBs.
|
||||
foreach(t ${ARGN})
|
||||
get_target_property(t_pdb_name ${t} COMPILE_PDB_NAME)
|
||||
get_target_property(t_pdb_name_debug ${t} COMPILE_PDB_NAME_DEBUG)
|
||||
get_target_property(t_pdb_output_directory ${t} PDB_OUTPUT_DIRECTORY)
|
||||
install(FILES
|
||||
"${t_pdb_output_directory}/\${CMAKE_INSTALL_CONFIG_NAME}/$<$<CONFIG:Debug>:${t_pdb_name_debug}>$<$<NOT:$<CONFIG:Debug>>:${t_pdb_name}>.pdb"
|
||||
COMPONENT "${PROJECT_NAME}"
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
OPTIONAL)
|
||||
endforeach()
|
||||
@ -345,6 +327,7 @@ function(install_project)
|
||||
configure_file("${PROJECT_SOURCE_DIR}/cmake/${t}.pc.in"
|
||||
"${configured_pc}" @ONLY)
|
||||
install(FILES "${configured_pc}"
|
||||
COMPONENT "${PROJECT_NAME}"
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||
endforeach()
|
||||
endif()
|
||||
|
@ -129,7 +129,7 @@ namespace testing {
|
||||
//
|
||||
// Expected: Foo() is even
|
||||
// Actual: it's 5
|
||||
//
|
||||
|
||||
class GTEST_API_ AssertionResult {
|
||||
public:
|
||||
// Copy constructor.
|
||||
@ -181,7 +181,7 @@ class GTEST_API_ AssertionResult {
|
||||
// assertion's expectation). When nothing has been streamed into the
|
||||
// object, returns an empty string.
|
||||
const char* message() const {
|
||||
return message_.get() != nullptr ? message_->c_str() : "";
|
||||
return message_ != nullptr ? message_->c_str() : "";
|
||||
}
|
||||
// Deprecated; please use message() instead.
|
||||
const char* failure_message() const { return message(); }
|
||||
@ -204,7 +204,7 @@ class GTEST_API_ AssertionResult {
|
||||
private:
|
||||
// Appends the contents of message to message_.
|
||||
void AppendMessage(const Message& a_message) {
|
||||
if (message_.get() == nullptr) message_.reset(new ::std::string);
|
||||
if (message_ == nullptr) message_ = ::std::make_unique<::std::string>();
|
||||
message_->append(a_message.GetString().c_str());
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ GTEST_DECLARE_string_(death_test_style);
|
||||
|
||||
namespace testing {
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
#ifdef GTEST_HAS_DEATH_TEST
|
||||
|
||||
namespace internal {
|
||||
|
||||
@ -203,7 +203,7 @@ class GTEST_API_ ExitedWithCode {
|
||||
const int exit_code_;
|
||||
};
|
||||
|
||||
#if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
|
||||
#if !defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_FUCHSIA)
|
||||
// Tests that an exit code describes an exit due to termination by a
|
||||
// given signal.
|
||||
class GTEST_API_ KilledBySignal {
|
||||
@ -328,7 +328,7 @@ class GTEST_API_ KilledBySignal {
|
||||
// death tests are supported; otherwise they just issue a warning. This is
|
||||
// useful when you are combining death test assertions with normal test
|
||||
// assertions in one test.
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
#ifdef GTEST_HAS_DEATH_TEST
|
||||
#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
EXPECT_DEATH(statement, regex)
|
||||
#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
|
@ -40,6 +40,7 @@
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
@ -106,13 +107,13 @@ class MatchResultListener {
|
||||
MatchResultListener& operator=(const MatchResultListener&) = delete;
|
||||
};
|
||||
|
||||
inline MatchResultListener::~MatchResultListener() {}
|
||||
inline MatchResultListener::~MatchResultListener() = default;
|
||||
|
||||
// An instance of a subclass of this knows how to describe itself as a
|
||||
// matcher.
|
||||
class GTEST_API_ MatcherDescriberInterface {
|
||||
public:
|
||||
virtual ~MatcherDescriberInterface() {}
|
||||
virtual ~MatcherDescriberInterface() = default;
|
||||
|
||||
// Describes this matcher to an ostream. The function should print
|
||||
// a verb phrase that describes the property a value matching this
|
||||
@ -178,43 +179,6 @@ class MatcherInterface : public MatcherDescriberInterface {
|
||||
|
||||
namespace internal {
|
||||
|
||||
struct AnyEq {
|
||||
template <typename A, typename B>
|
||||
bool operator()(const A& a, const B& b) const {
|
||||
return a == b;
|
||||
}
|
||||
};
|
||||
struct AnyNe {
|
||||
template <typename A, typename B>
|
||||
bool operator()(const A& a, const B& b) const {
|
||||
return a != b;
|
||||
}
|
||||
};
|
||||
struct AnyLt {
|
||||
template <typename A, typename B>
|
||||
bool operator()(const A& a, const B& b) const {
|
||||
return a < b;
|
||||
}
|
||||
};
|
||||
struct AnyGt {
|
||||
template <typename A, typename B>
|
||||
bool operator()(const A& a, const B& b) const {
|
||||
return a > b;
|
||||
}
|
||||
};
|
||||
struct AnyLe {
|
||||
template <typename A, typename B>
|
||||
bool operator()(const A& a, const B& b) const {
|
||||
return a <= b;
|
||||
}
|
||||
};
|
||||
struct AnyGe {
|
||||
template <typename A, typename B>
|
||||
bool operator()(const A& a, const B& b) const {
|
||||
return a >= b;
|
||||
}
|
||||
};
|
||||
|
||||
// A match result listener that ignores the explanation.
|
||||
class DummyMatchResultListener : public MatchResultListener {
|
||||
public:
|
||||
@ -530,7 +494,7 @@ template <>
|
||||
class GTEST_API_ Matcher<const std::string&>
|
||||
: public internal::MatcherBase<const std::string&> {
|
||||
public:
|
||||
Matcher() {}
|
||||
Matcher() = default;
|
||||
|
||||
explicit Matcher(const MatcherInterface<const std::string&>* impl)
|
||||
: internal::MatcherBase<const std::string&>(impl) {}
|
||||
@ -552,7 +516,7 @@ template <>
|
||||
class GTEST_API_ Matcher<std::string>
|
||||
: public internal::MatcherBase<std::string> {
|
||||
public:
|
||||
Matcher() {}
|
||||
Matcher() = default;
|
||||
|
||||
explicit Matcher(const MatcherInterface<const std::string&>* impl)
|
||||
: internal::MatcherBase<std::string>(impl) {}
|
||||
@ -580,7 +544,7 @@ template <>
|
||||
class GTEST_API_ Matcher<const internal::StringView&>
|
||||
: public internal::MatcherBase<const internal::StringView&> {
|
||||
public:
|
||||
Matcher() {}
|
||||
Matcher() = default;
|
||||
|
||||
explicit Matcher(const MatcherInterface<const internal::StringView&>* impl)
|
||||
: internal::MatcherBase<const internal::StringView&>(impl) {}
|
||||
@ -606,7 +570,7 @@ template <>
|
||||
class GTEST_API_ Matcher<internal::StringView>
|
||||
: public internal::MatcherBase<internal::StringView> {
|
||||
public:
|
||||
Matcher() {}
|
||||
Matcher() = default;
|
||||
|
||||
explicit Matcher(const MatcherInterface<const internal::StringView&>* impl)
|
||||
: internal::MatcherBase<internal::StringView>(impl) {}
|
||||
@ -758,50 +722,53 @@ class ComparisonBase {
|
||||
};
|
||||
|
||||
template <typename Rhs>
|
||||
class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq> {
|
||||
class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>> {
|
||||
public:
|
||||
explicit EqMatcher(const Rhs& rhs)
|
||||
: ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq>(rhs) {}
|
||||
: ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>>(rhs) {}
|
||||
static const char* Desc() { return "is equal to"; }
|
||||
static const char* NegatedDesc() { return "isn't equal to"; }
|
||||
};
|
||||
template <typename Rhs>
|
||||
class NeMatcher : public ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe> {
|
||||
class NeMatcher
|
||||
: public ComparisonBase<NeMatcher<Rhs>, Rhs, std::not_equal_to<>> {
|
||||
public:
|
||||
explicit NeMatcher(const Rhs& rhs)
|
||||
: ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe>(rhs) {}
|
||||
: ComparisonBase<NeMatcher<Rhs>, Rhs, std::not_equal_to<>>(rhs) {}
|
||||
static const char* Desc() { return "isn't equal to"; }
|
||||
static const char* NegatedDesc() { return "is equal to"; }
|
||||
};
|
||||
template <typename Rhs>
|
||||
class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt> {
|
||||
class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>> {
|
||||
public:
|
||||
explicit LtMatcher(const Rhs& rhs)
|
||||
: ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt>(rhs) {}
|
||||
: ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>>(rhs) {}
|
||||
static const char* Desc() { return "is <"; }
|
||||
static const char* NegatedDesc() { return "isn't <"; }
|
||||
};
|
||||
template <typename Rhs>
|
||||
class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt> {
|
||||
class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>> {
|
||||
public:
|
||||
explicit GtMatcher(const Rhs& rhs)
|
||||
: ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt>(rhs) {}
|
||||
: ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>>(rhs) {}
|
||||
static const char* Desc() { return "is >"; }
|
||||
static const char* NegatedDesc() { return "isn't >"; }
|
||||
};
|
||||
template <typename Rhs>
|
||||
class LeMatcher : public ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe> {
|
||||
class LeMatcher
|
||||
: public ComparisonBase<LeMatcher<Rhs>, Rhs, std::less_equal<>> {
|
||||
public:
|
||||
explicit LeMatcher(const Rhs& rhs)
|
||||
: ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe>(rhs) {}
|
||||
: ComparisonBase<LeMatcher<Rhs>, Rhs, std::less_equal<>>(rhs) {}
|
||||
static const char* Desc() { return "is <="; }
|
||||
static const char* NegatedDesc() { return "isn't <="; }
|
||||
};
|
||||
template <typename Rhs>
|
||||
class GeMatcher : public ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe> {
|
||||
class GeMatcher
|
||||
: public ComparisonBase<GeMatcher<Rhs>, Rhs, std::greater_equal<>> {
|
||||
public:
|
||||
explicit GeMatcher(const Rhs& rhs)
|
||||
: ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe>(rhs) {}
|
||||
: ComparisonBase<GeMatcher<Rhs>, Rhs, std::greater_equal<>>(rhs) {}
|
||||
static const char* Desc() { return "is >="; }
|
||||
static const char* NegatedDesc() { return "isn't >="; }
|
||||
};
|
||||
|
@ -50,10 +50,19 @@
|
||||
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/strings/has_absl_stringify.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#endif // GTEST_HAS_ABSL
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||
/* class A needs to have dll-interface to be used by clients of class B */)
|
||||
|
||||
@ -109,8 +118,17 @@ class GTEST_API_ Message {
|
||||
*ss_ << str;
|
||||
}
|
||||
|
||||
// Streams a non-pointer value to this object.
|
||||
template <typename T>
|
||||
// Streams a non-pointer value to this object. If building a version of
|
||||
// GoogleTest with ABSL, this overload is only enabled if the value does not
|
||||
// have an AbslStringify definition.
|
||||
template <
|
||||
typename T
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
,
|
||||
typename std::enable_if<!absl::HasAbslStringify<T>::value, // NOLINT
|
||||
int>::type = 0
|
||||
#endif // GTEST_HAS_ABSL
|
||||
>
|
||||
inline Message& operator<<(const T& val) {
|
||||
// Some libraries overload << for STL containers. These
|
||||
// overloads are defined in the global namespace instead of ::std.
|
||||
@ -131,6 +149,21 @@ class GTEST_API_ Message {
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
// Streams a non-pointer value with an AbslStringify definition to this
|
||||
// object.
|
||||
template <typename T,
|
||||
typename std::enable_if<absl::HasAbslStringify<T>::value, // NOLINT
|
||||
int>::type = 0>
|
||||
inline Message& operator<<(const T& val) {
|
||||
// ::operator<< is needed here for a similar reason as with the non-Abseil
|
||||
// version above
|
||||
using ::operator<<;
|
||||
*ss_ << absl::StrCat(val);
|
||||
return *this;
|
||||
}
|
||||
#endif // GTEST_HAS_ABSL
|
||||
|
||||
// Streams a pointer value to this object.
|
||||
//
|
||||
// This function is an overload of the previous one. When you
|
||||
|
@ -178,7 +178,7 @@ TEST_P(DerivedTest, DoesBlah) {
|
||||
#include <utility>
|
||||
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
#include "gtest/internal/gtest-param-util.h"
|
||||
#include "gtest/internal/gtest-param-util.h" // IWYU pragma: export
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
namespace testing {
|
||||
@ -407,9 +407,50 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
|
||||
return internal::CartesianProductHolder<Generator...>(g...);
|
||||
}
|
||||
|
||||
// ConvertGenerator() wraps a parameter generator in order to cast each produced
|
||||
// value through a known type before supplying it to the test suite
|
||||
//
|
||||
// Synopsis:
|
||||
// ConvertGenerator<T>(gen)
|
||||
// - returns a generator producing the same elements as generated by gen, but
|
||||
// each element is static_cast to type T before being returned
|
||||
//
|
||||
// It is useful when using the Combine() function to get the generated
|
||||
// parameters in a custom type instead of std::tuple
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// This will instantiate tests in test suite AnimalTest each one with
|
||||
// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
|
||||
// tuple("dog", BLACK), and tuple("dog", WHITE):
|
||||
//
|
||||
// enum Color { BLACK, GRAY, WHITE };
|
||||
// struct ParamType {
|
||||
// using TupleT = std::tuple<const char*, Color>;
|
||||
// std::string animal;
|
||||
// Color color;
|
||||
// ParamType(TupleT t) : animal(std::get<0>(t)), color(std::get<1>(t)) {}
|
||||
// };
|
||||
// class AnimalTest
|
||||
// : public testing::TestWithParam<ParamType> {...};
|
||||
//
|
||||
// TEST_P(AnimalTest, AnimalLooksNice) {...}
|
||||
//
|
||||
// INSTANTIATE_TEST_SUITE_P(AnimalVariations, AnimalTest,
|
||||
// ConvertGenerator<ParamType::TupleT>(
|
||||
// Combine(Values("cat", "dog"),
|
||||
// Values(BLACK, WHITE))));
|
||||
//
|
||||
template <typename T>
|
||||
internal::ParamConverterGenerator<T> ConvertGenerator(
|
||||
internal::ParamGenerator<T> gen) {
|
||||
return internal::ParamConverterGenerator<T>(gen);
|
||||
}
|
||||
|
||||
#define TEST_P(test_suite_name, test_name) \
|
||||
class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
|
||||
: public test_suite_name { \
|
||||
: public test_suite_name, \
|
||||
private ::testing::internal::GTestNonCopyable { \
|
||||
public: \
|
||||
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \
|
||||
void TestBody() override; \
|
||||
@ -428,12 +469,7 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
|
||||
::testing::internal::CodeLocation(__FILE__, __LINE__)); \
|
||||
return 0; \
|
||||
} \
|
||||
static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \
|
||||
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
|
||||
(const GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) &) = delete; \
|
||||
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) & operator=( \
|
||||
const GTEST_TEST_CLASS_NAME_(test_suite_name, \
|
||||
test_name) &) = delete; /* NOLINT */ \
|
||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static int gtest_registering_dummy_; \
|
||||
}; \
|
||||
int GTEST_TEST_CLASS_NAME_(test_suite_name, \
|
||||
test_name)::gtest_registering_dummy_ = \
|
||||
@ -478,8 +514,8 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
|
||||
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
|
||||
DUMMY_PARAM_))))(info); \
|
||||
} \
|
||||
static int gtest_##prefix##test_suite_name##_dummy_ \
|
||||
GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static int \
|
||||
gtest_##prefix##test_suite_name##_dummy_ = \
|
||||
::testing::UnitTest::GetInstance() \
|
||||
->parameterized_test_registry() \
|
||||
.GetTestSuitePatternHolder<test_suite_name>( \
|
||||
|
@ -43,6 +43,9 @@
|
||||
// 1. foo::PrintTo(const T&, ostream*)
|
||||
// 2. operator<<(ostream&, const T&) defined in either foo or the
|
||||
// global namespace.
|
||||
// * Prefer AbslStringify(..) to operator<<(..), per https://abseil.io/tips/215.
|
||||
// * Define foo::PrintTo(..) if the type already has AbslStringify(..), but an
|
||||
// alternative presentation in test results is of interest.
|
||||
//
|
||||
// However if T is an STL-style container then it is printed element-wise
|
||||
// unless foo::PrintTo(const T&, ostream*) is defined. Note that
|
||||
@ -108,12 +111,21 @@
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
#include "absl/strings/has_absl_stringify.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#endif // GTEST_HAS_ABSL
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
#if GTEST_INTERNAL_HAS_STD_SPAN
|
||||
#include <span> // NOLINT
|
||||
#endif // GTEST_INTERNAL_HAS_STD_SPAN
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Definitions in the internal* namespaces are subject to change without notice.
|
||||
@ -123,13 +135,32 @@ namespace internal {
|
||||
template <typename T>
|
||||
void UniversalPrint(const T& value, ::std::ostream* os);
|
||||
|
||||
template <typename T>
|
||||
struct IsStdSpan {
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
#if GTEST_INTERNAL_HAS_STD_SPAN
|
||||
template <typename E>
|
||||
struct IsStdSpan<std::span<E>> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
#endif // GTEST_INTERNAL_HAS_STD_SPAN
|
||||
|
||||
// Used to print an STL-style container when the user doesn't define
|
||||
// a PrintTo() for it.
|
||||
//
|
||||
// NOTE: Since std::span does not have const_iterator until C++23, it would
|
||||
// fail IsContainerTest before C++23. However, IsContainerTest only uses
|
||||
// the presence of const_iterator to avoid treating iterators as containers
|
||||
// because of iterator::iterator. Which means std::span satisfies the *intended*
|
||||
// condition of IsContainerTest.
|
||||
struct ContainerPrinter {
|
||||
template <typename T,
|
||||
typename = typename std::enable_if<
|
||||
(sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
|
||||
!IsRecursiveContainer<T>::value>::type>
|
||||
((sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
|
||||
!IsRecursiveContainer<T>::value) ||
|
||||
IsStdSpan<T>::value>::type>
|
||||
static void PrintValue(const T& container, std::ostream* os) {
|
||||
const size_t kMaxCount = 32; // The maximum number of elements to print.
|
||||
*os << '{';
|
||||
@ -205,12 +236,13 @@ struct StreamPrinter {
|
||||
// Don't accept member pointers here. We'd print them via implicit
|
||||
// conversion to bool, which isn't useful.
|
||||
typename = typename std::enable_if<
|
||||
!std::is_member_pointer<T>::value>::type,
|
||||
// Only accept types for which we can find a streaming operator via
|
||||
// ADL (possibly involving implicit conversions).
|
||||
typename = decltype(std::declval<std::ostream&>()
|
||||
<< std::declval<const T&>())>
|
||||
static void PrintValue(const T& value, ::std::ostream* os) {
|
||||
!std::is_member_pointer<T>::value>::type>
|
||||
// Only accept types for which we can find a streaming operator via
|
||||
// ADL (possibly involving implicit conversions).
|
||||
// (Use SFINAE via return type, because it seems GCC < 12 doesn't handle name
|
||||
// lookup properly when we do it in the template parameter list.)
|
||||
static auto PrintValue(const T& value,
|
||||
::std::ostream* os) -> decltype((void)(*os << value)) {
|
||||
// Call streaming operator found by ADL, possibly with implicit conversions
|
||||
// of the arguments.
|
||||
*os << value;
|
||||
@ -258,6 +290,17 @@ struct ConvertibleToStringViewPrinter {
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
struct ConvertibleToAbslStringifyPrinter {
|
||||
template <typename T,
|
||||
typename = typename std::enable_if<
|
||||
absl::HasAbslStringify<T>::value>::type> // NOLINT
|
||||
static void PrintValue(const T& value, ::std::ostream* os) {
|
||||
*os << absl::StrCat(value);
|
||||
}
|
||||
};
|
||||
#endif // GTEST_HAS_ABSL
|
||||
|
||||
// Prints the given number of bytes in the given object to the given
|
||||
// ostream.
|
||||
GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes,
|
||||
@ -296,8 +339,8 @@ struct FindFirstPrinter<
|
||||
// - Print containers (they have begin/end/etc).
|
||||
// - Print function pointers.
|
||||
// - Print object pointers.
|
||||
// - Use the stream operator, if available.
|
||||
// - Print protocol buffers.
|
||||
// - Use the stream operator, if available.
|
||||
// - Print types convertible to BiggestInt.
|
||||
// - Print types convertible to StringView, if available.
|
||||
// - Fallback to printing the raw bytes of the object.
|
||||
@ -305,9 +348,13 @@ template <typename T>
|
||||
void PrintWithFallback(const T& value, ::std::ostream* os) {
|
||||
using Printer = typename FindFirstPrinter<
|
||||
T, void, ContainerPrinter, FunctionPointerPrinter, PointerPrinter,
|
||||
ProtobufPrinter,
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
ConvertibleToAbslStringifyPrinter,
|
||||
#endif // GTEST_HAS_ABSL
|
||||
internal_stream_operator_without_lexical_name_lookup::StreamPrinter,
|
||||
ProtobufPrinter, ConvertibleToIntegerPrinter,
|
||||
ConvertibleToStringViewPrinter, RawBytesPrinter, FallbackPrinter>::type;
|
||||
ConvertibleToIntegerPrinter, ConvertibleToStringViewPrinter,
|
||||
RawBytesPrinter, FallbackPrinter>::type;
|
||||
Printer::PrintValue(value, os);
|
||||
}
|
||||
|
||||
@ -472,7 +519,7 @@ GTEST_API_ void PrintTo(char32_t c, ::std::ostream* os);
|
||||
inline void PrintTo(char16_t c, ::std::ostream* os) {
|
||||
PrintTo(ImplicitCast_<char32_t>(c), os);
|
||||
}
|
||||
#ifdef __cpp_char8_t
|
||||
#ifdef __cpp_lib_char8_t
|
||||
inline void PrintTo(char8_t c, ::std::ostream* os) {
|
||||
PrintTo(ImplicitCast_<char32_t>(c), os);
|
||||
}
|
||||
@ -484,6 +531,101 @@ GTEST_API_ void PrintTo(__uint128_t v, ::std::ostream* os);
|
||||
GTEST_API_ void PrintTo(__int128_t v, ::std::ostream* os);
|
||||
#endif // __SIZEOF_INT128__
|
||||
|
||||
// The default resolution used to print floating-point values uses only
|
||||
// 6 digits, which can be confusing if a test compares two values whose
|
||||
// difference lies in the 7th digit. So we'd like to print out numbers
|
||||
// in full precision.
|
||||
// However if the value is something simple like 1.1, full will print a
|
||||
// long string like 1.100000001 due to floating-point numbers not using
|
||||
// a base of 10. This routiune returns an appropriate resolution for a
|
||||
// given floating-point number, that is, 6 if it will be accurate, or a
|
||||
// max_digits10 value (full precision) if it won't, for values between
|
||||
// 0.0001 and one million.
|
||||
// It does this by computing what those digits would be (by multiplying
|
||||
// by an appropriate power of 10), then dividing by that power again to
|
||||
// see if gets the original value back.
|
||||
// A similar algorithm applies for values larger than one million; note
|
||||
// that for those values, we must divide to get a six-digit number, and
|
||||
// then multiply to possibly get the original value again.
|
||||
template <typename FloatType>
|
||||
int AppropriateResolution(FloatType val) {
|
||||
int full = std::numeric_limits<FloatType>::max_digits10;
|
||||
if (val < 0) val = -val;
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||
#endif
|
||||
if (val < 1000000) {
|
||||
FloatType mulfor6 = 1e10;
|
||||
// Without these static casts, the template instantiation for float would
|
||||
// fail to compile when -Wdouble-promotion is enabled, as the arithmetic and
|
||||
// comparison logic would promote floats to doubles.
|
||||
if (val >= static_cast<FloatType>(100000.0)) { // 100,000 to 999,999
|
||||
mulfor6 = 1.0;
|
||||
} else if (val >= static_cast<FloatType>(10000.0)) {
|
||||
mulfor6 = 1e1;
|
||||
} else if (val >= static_cast<FloatType>(1000.0)) {
|
||||
mulfor6 = 1e2;
|
||||
} else if (val >= static_cast<FloatType>(100.0)) {
|
||||
mulfor6 = 1e3;
|
||||
} else if (val >= static_cast<FloatType>(10.0)) {
|
||||
mulfor6 = 1e4;
|
||||
} else if (val >= static_cast<FloatType>(1.0)) {
|
||||
mulfor6 = 1e5;
|
||||
} else if (val >= static_cast<FloatType>(0.1)) {
|
||||
mulfor6 = 1e6;
|
||||
} else if (val >= static_cast<FloatType>(0.01)) {
|
||||
mulfor6 = 1e7;
|
||||
} else if (val >= static_cast<FloatType>(0.001)) {
|
||||
mulfor6 = 1e8;
|
||||
} else if (val >= static_cast<FloatType>(0.0001)) {
|
||||
mulfor6 = 1e9;
|
||||
}
|
||||
if (static_cast<FloatType>(static_cast<int32_t>(
|
||||
val * mulfor6 + (static_cast<FloatType>(0.5)))) /
|
||||
mulfor6 ==
|
||||
val)
|
||||
return 6;
|
||||
} else if (val < static_cast<FloatType>(1e10)) {
|
||||
FloatType divfor6 = static_cast<FloatType>(1.0);
|
||||
if (val >= static_cast<FloatType>(1e9)) { // 1,000,000,000 to 9,999,999,999
|
||||
divfor6 = 10000;
|
||||
} else if (val >=
|
||||
static_cast<FloatType>(1e8)) { // 100,000,000 to 999,999,999
|
||||
divfor6 = 1000;
|
||||
} else if (val >=
|
||||
static_cast<FloatType>(1e7)) { // 10,000,000 to 99,999,999
|
||||
divfor6 = 100;
|
||||
} else if (val >= static_cast<FloatType>(1e6)) { // 1,000,000 to 9,999,999
|
||||
divfor6 = 10;
|
||||
}
|
||||
if (static_cast<FloatType>(static_cast<int32_t>(
|
||||
val / divfor6 + (static_cast<FloatType>(0.5)))) *
|
||||
divfor6 ==
|
||||
val)
|
||||
return 6;
|
||||
}
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
return full;
|
||||
}
|
||||
|
||||
inline void PrintTo(float f, ::std::ostream* os) {
|
||||
auto old_precision = os->precision();
|
||||
os->precision(AppropriateResolution(f));
|
||||
*os << f;
|
||||
os->precision(old_precision);
|
||||
}
|
||||
|
||||
inline void PrintTo(double d, ::std::ostream* os) {
|
||||
auto old_precision = os->precision();
|
||||
os->precision(AppropriateResolution(d));
|
||||
*os << d;
|
||||
os->precision(old_precision);
|
||||
}
|
||||
|
||||
// Overloads for C strings.
|
||||
GTEST_API_ void PrintTo(const char* s, ::std::ostream* os);
|
||||
inline void PrintTo(char* s, ::std::ostream* os) {
|
||||
@ -504,7 +646,7 @@ inline void PrintTo(const unsigned char* s, ::std::ostream* os) {
|
||||
inline void PrintTo(unsigned char* s, ::std::ostream* os) {
|
||||
PrintTo(ImplicitCast_<const void*>(s), os);
|
||||
}
|
||||
#ifdef __cpp_char8_t
|
||||
#ifdef __cpp_lib_char8_t
|
||||
// Overloads for u8 strings.
|
||||
GTEST_API_ void PrintTo(const char8_t* s, ::std::ostream* os);
|
||||
inline void PrintTo(char8_t* s, ::std::ostream* os) {
|
||||
@ -774,7 +916,7 @@ class UniversalPrinter<Variant<T...>> {
|
||||
public:
|
||||
static void Print(const Variant<T...>& value, ::std::ostream* os) {
|
||||
*os << '(';
|
||||
#if GTEST_HAS_ABSL
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
absl::visit(Visitor{os, value.index()}, value);
|
||||
#else
|
||||
std::visit(Visitor{os, value.index()}, value);
|
||||
@ -824,7 +966,7 @@ void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) {
|
||||
GTEST_API_ void UniversalPrintArray(const char* begin, size_t len,
|
||||
::std::ostream* os);
|
||||
|
||||
#ifdef __cpp_char8_t
|
||||
#ifdef __cpp_lib_char8_t
|
||||
// This overload prints a (const) char8_t array compactly.
|
||||
GTEST_API_ void UniversalPrintArray(const char8_t* begin, size_t len,
|
||||
::std::ostream* os);
|
||||
@ -891,6 +1033,13 @@ class UniversalTersePrinter<T&> {
|
||||
UniversalPrint(value, os);
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
class UniversalTersePrinter<std::reference_wrapper<T>> {
|
||||
public:
|
||||
static void Print(std::reference_wrapper<T> value, ::std::ostream* os) {
|
||||
UniversalTersePrinter<T>::Print(value.get(), os);
|
||||
}
|
||||
};
|
||||
template <typename T, size_t N>
|
||||
class UniversalTersePrinter<T[N]> {
|
||||
public:
|
||||
@ -913,7 +1062,7 @@ template <>
|
||||
class UniversalTersePrinter<char*> : public UniversalTersePrinter<const char*> {
|
||||
};
|
||||
|
||||
#ifdef __cpp_char8_t
|
||||
#ifdef __cpp_lib_char8_t
|
||||
template <>
|
||||
class UniversalTersePrinter<const char8_t*> {
|
||||
public:
|
||||
|
@ -33,6 +33,8 @@
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||
|
@ -35,6 +35,8 @@
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
||||
|
||||
#include <iosfwd>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
@ -131,7 +133,7 @@ std::ostream& operator<<(std::ostream& os, const TestPartResult& result);
|
||||
// virtual.
|
||||
class GTEST_API_ TestPartResultArray {
|
||||
public:
|
||||
TestPartResultArray() {}
|
||||
TestPartResultArray() = default;
|
||||
|
||||
// Appends the given TestPartResult to the array.
|
||||
void Append(const TestPartResult& result);
|
||||
@ -152,7 +154,7 @@ class GTEST_API_ TestPartResultArray {
|
||||
// This interface knows how to report a test part result.
|
||||
class GTEST_API_ TestPartResultReporterInterface {
|
||||
public:
|
||||
virtual ~TestPartResultReporterInterface() {}
|
||||
virtual ~TestPartResultReporterInterface() = default;
|
||||
|
||||
virtual void ReportTestPartResult(const TestPartResult& result) = 0;
|
||||
};
|
||||
|
@ -194,33 +194,34 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
|
||||
typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type \
|
||||
GTEST_NAME_GENERATOR_(CaseName)
|
||||
|
||||
#define TYPED_TEST(CaseName, TestName) \
|
||||
static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1, \
|
||||
"test-name must not be empty"); \
|
||||
template <typename gtest_TypeParam_> \
|
||||
class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
|
||||
: public CaseName<gtest_TypeParam_> { \
|
||||
private: \
|
||||
typedef CaseName<gtest_TypeParam_> TestFixture; \
|
||||
typedef gtest_TypeParam_ TypeParam; \
|
||||
void TestBody() override; \
|
||||
}; \
|
||||
static bool gtest_##CaseName##_##TestName##_registered_ \
|
||||
GTEST_ATTRIBUTE_UNUSED_ = ::testing::internal::TypeParameterizedTest< \
|
||||
CaseName, \
|
||||
::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_(CaseName, \
|
||||
TestName)>, \
|
||||
GTEST_TYPE_PARAMS_( \
|
||||
CaseName)>::Register("", \
|
||||
::testing::internal::CodeLocation( \
|
||||
__FILE__, __LINE__), \
|
||||
GTEST_STRINGIFY_(CaseName), \
|
||||
GTEST_STRINGIFY_(TestName), 0, \
|
||||
::testing::internal::GenerateNames< \
|
||||
GTEST_NAME_GENERATOR_(CaseName), \
|
||||
GTEST_TYPE_PARAMS_(CaseName)>()); \
|
||||
template <typename gtest_TypeParam_> \
|
||||
void GTEST_TEST_CLASS_NAME_(CaseName, \
|
||||
#define TYPED_TEST(CaseName, TestName) \
|
||||
static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1, \
|
||||
"test-name must not be empty"); \
|
||||
template <typename gtest_TypeParam_> \
|
||||
class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
|
||||
: public CaseName<gtest_TypeParam_> { \
|
||||
private: \
|
||||
typedef CaseName<gtest_TypeParam_> TestFixture; \
|
||||
typedef gtest_TypeParam_ TypeParam; \
|
||||
void TestBody() override; \
|
||||
}; \
|
||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool \
|
||||
gtest_##CaseName##_##TestName##_registered_ = \
|
||||
::testing::internal::TypeParameterizedTest< \
|
||||
CaseName, \
|
||||
::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_( \
|
||||
CaseName, TestName)>, \
|
||||
GTEST_TYPE_PARAMS_( \
|
||||
CaseName)>::Register("", \
|
||||
::testing::internal::CodeLocation( \
|
||||
__FILE__, __LINE__), \
|
||||
GTEST_STRINGIFY_(CaseName), \
|
||||
GTEST_STRINGIFY_(TestName), 0, \
|
||||
::testing::internal::GenerateNames< \
|
||||
GTEST_NAME_GENERATOR_(CaseName), \
|
||||
GTEST_TYPE_PARAMS_(CaseName)>()); \
|
||||
template <typename gtest_TypeParam_> \
|
||||
void GTEST_TEST_CLASS_NAME_(CaseName, \
|
||||
TestName)<gtest_TypeParam_>::TestBody()
|
||||
|
||||
// Legacy API is deprecated but still available
|
||||
@ -267,31 +268,32 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
|
||||
TYPED_TEST_SUITE_P
|
||||
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
|
||||
#define TYPED_TEST_P(SuiteName, TestName) \
|
||||
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
|
||||
template <typename gtest_TypeParam_> \
|
||||
class TestName : public SuiteName<gtest_TypeParam_> { \
|
||||
private: \
|
||||
typedef SuiteName<gtest_TypeParam_> TestFixture; \
|
||||
typedef gtest_TypeParam_ TypeParam; \
|
||||
void TestBody() override; \
|
||||
}; \
|
||||
static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \
|
||||
__FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \
|
||||
GTEST_STRINGIFY_(TestName)); \
|
||||
} \
|
||||
template <typename gtest_TypeParam_> \
|
||||
void GTEST_SUITE_NAMESPACE_( \
|
||||
#define TYPED_TEST_P(SuiteName, TestName) \
|
||||
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
|
||||
template <typename gtest_TypeParam_> \
|
||||
class TestName : public SuiteName<gtest_TypeParam_> { \
|
||||
private: \
|
||||
typedef SuiteName<gtest_TypeParam_> TestFixture; \
|
||||
typedef gtest_TypeParam_ TypeParam; \
|
||||
void TestBody() override; \
|
||||
}; \
|
||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool \
|
||||
gtest_##TestName##_defined_ = \
|
||||
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \
|
||||
__FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \
|
||||
GTEST_STRINGIFY_(TestName)); \
|
||||
} \
|
||||
template <typename gtest_TypeParam_> \
|
||||
void GTEST_SUITE_NAMESPACE_( \
|
||||
SuiteName)::TestName<gtest_TypeParam_>::TestBody()
|
||||
|
||||
// Note: this won't work correctly if the trailing arguments are macros.
|
||||
#define REGISTER_TYPED_TEST_SUITE_P(SuiteName, ...) \
|
||||
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
|
||||
typedef ::testing::internal::Templates<__VA_ARGS__> gtest_AllTests_; \
|
||||
typedef ::testing::internal::Templates<__VA_ARGS__> gtest_AllTests_; \
|
||||
} \
|
||||
static const char* const GTEST_REGISTERED_TEST_NAMES_( \
|
||||
SuiteName) GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static const char* const \
|
||||
GTEST_REGISTERED_TEST_NAMES_(SuiteName) = \
|
||||
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \
|
||||
GTEST_STRINGIFY_(SuiteName), __FILE__, __LINE__, #__VA_ARGS__)
|
||||
|
||||
@ -303,22 +305,24 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
|
||||
REGISTER_TYPED_TEST_SUITE_P
|
||||
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
|
||||
#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \
|
||||
static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \
|
||||
"test-suit-prefix must not be empty"); \
|
||||
static bool gtest_##Prefix##_##SuiteName GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
::testing::internal::TypeParameterizedTestSuite< \
|
||||
SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \
|
||||
::testing::internal::GenerateTypeList<Types>::type>:: \
|
||||
Register(GTEST_STRINGIFY_(Prefix), \
|
||||
::testing::internal::CodeLocation(__FILE__, __LINE__), \
|
||||
>EST_TYPED_TEST_SUITE_P_STATE_(SuiteName), \
|
||||
GTEST_STRINGIFY_(SuiteName), \
|
||||
GTEST_REGISTERED_TEST_NAMES_(SuiteName), \
|
||||
::testing::internal::GenerateNames< \
|
||||
::testing::internal::NameGeneratorSelector< \
|
||||
__VA_ARGS__>::type, \
|
||||
::testing::internal::GenerateTypeList<Types>::type>())
|
||||
#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \
|
||||
static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \
|
||||
"test-suit-prefix must not be empty"); \
|
||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool \
|
||||
gtest_##Prefix##_##SuiteName = \
|
||||
::testing::internal::TypeParameterizedTestSuite< \
|
||||
SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \
|
||||
::testing::internal::GenerateTypeList<Types>::type>:: \
|
||||
Register( \
|
||||
GTEST_STRINGIFY_(Prefix), \
|
||||
::testing::internal::CodeLocation(__FILE__, __LINE__), \
|
||||
>EST_TYPED_TEST_SUITE_P_STATE_(SuiteName), \
|
||||
GTEST_STRINGIFY_(SuiteName), \
|
||||
GTEST_REGISTERED_TEST_NAMES_(SuiteName), \
|
||||
::testing::internal::GenerateNames< \
|
||||
::testing::internal::NameGeneratorSelector< \
|
||||
__VA_ARGS__>::type, \
|
||||
::testing::internal::GenerateTypeList<Types>::type>())
|
||||
|
||||
// Legacy API is deprecated but still available
|
||||
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
|
@ -50,22 +50,26 @@
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest-assertion-result.h"
|
||||
#include "gtest/gtest-death-test.h"
|
||||
#include "gtest/gtest-matchers.h"
|
||||
#include "gtest/gtest-message.h"
|
||||
#include "gtest/gtest-param-test.h"
|
||||
#include "gtest/gtest-printers.h"
|
||||
#include "gtest/gtest-test-part.h"
|
||||
#include "gtest/gtest-typed-test.h"
|
||||
#include "gtest/gtest_pred_impl.h"
|
||||
#include "gtest/gtest_prod.h"
|
||||
#include "gtest/gtest-assertion-result.h" // IWYU pragma: export
|
||||
#include "gtest/gtest-death-test.h" // IWYU pragma: export
|
||||
#include "gtest/gtest-matchers.h" // IWYU pragma: export
|
||||
#include "gtest/gtest-message.h" // IWYU pragma: export
|
||||
#include "gtest/gtest-param-test.h" // IWYU pragma: export
|
||||
#include "gtest/gtest-printers.h" // IWYU pragma: export
|
||||
#include "gtest/gtest-test-part.h" // IWYU pragma: export
|
||||
#include "gtest/gtest-typed-test.h" // IWYU pragma: export
|
||||
#include "gtest/gtest_pred_impl.h" // IWYU pragma: export
|
||||
#include "gtest/gtest_prod.h" // IWYU pragma: export
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
#include "gtest/internal/gtest-string.h"
|
||||
|
||||
@ -161,11 +165,7 @@ namespace testing {
|
||||
|
||||
// Silence C4100 (unreferenced formal parameter) and 4805
|
||||
// unsafe mix of type 'const int' and type 'const bool'
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4805)
|
||||
#pragma warning(disable : 4100)
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4805 4100)
|
||||
|
||||
// The upper limit for valid stack trace depths.
|
||||
const int kMaxStackTraceDepth = 100;
|
||||
@ -190,6 +190,17 @@ void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
|
||||
const std::string& message);
|
||||
std::set<std::string>* GetIgnoredParameterizedTestSuites();
|
||||
|
||||
// A base class that prevents subclasses from being copyable.
|
||||
// We do this instead of using '= delete' so as to avoid triggering warnings
|
||||
// inside user code regarding any of our declarations.
|
||||
class GTestNonCopyable {
|
||||
public:
|
||||
GTestNonCopyable() = default;
|
||||
GTestNonCopyable(const GTestNonCopyable&) = delete;
|
||||
GTestNonCopyable& operator=(const GTestNonCopyable&) = delete;
|
||||
~GTestNonCopyable() = default;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// The friend relationship of some of these classes is cyclic.
|
||||
@ -285,7 +296,13 @@ class GTEST_API_ Test {
|
||||
// SetUp/TearDown method of Environment objects registered with Google
|
||||
// Test) will be output as attributes of the <testsuites> element.
|
||||
static void RecordProperty(const std::string& key, const std::string& value);
|
||||
static void RecordProperty(const std::string& key, int value);
|
||||
// We do not define a custom serialization except for values that can be
|
||||
// converted to int64_t, but other values could be logged in this way.
|
||||
template <typename T, std::enable_if_t<std::is_convertible<T, int64_t>::value,
|
||||
bool> = true>
|
||||
static void RecordProperty(const std::string& key, const T& value) {
|
||||
RecordProperty(key, (Message() << value).GetString());
|
||||
}
|
||||
|
||||
protected:
|
||||
// Creates a Test object.
|
||||
@ -533,14 +550,14 @@ class GTEST_API_ TestInfo {
|
||||
// Returns the name of the parameter type, or NULL if this is not a typed
|
||||
// or a type-parameterized test.
|
||||
const char* type_param() const {
|
||||
if (type_param_.get() != nullptr) return type_param_->c_str();
|
||||
if (type_param_ != nullptr) return type_param_->c_str();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Returns the text representation of the value parameter, or NULL if this
|
||||
// is not a value-parameterized test.
|
||||
const char* value_param() const {
|
||||
if (value_param_.get() != nullptr) return value_param_->c_str();
|
||||
if (value_param_ != nullptr) return value_param_->c_str();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -582,7 +599,7 @@ class GTEST_API_ TestInfo {
|
||||
const TestResult* result() const { return &result_; }
|
||||
|
||||
private:
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
#ifdef GTEST_HAS_DEATH_TEST
|
||||
friend class internal::DefaultDeathTestFactory;
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
friend class Test;
|
||||
@ -590,7 +607,7 @@ class GTEST_API_ TestInfo {
|
||||
friend class internal::UnitTestImpl;
|
||||
friend class internal::StreamingListenerTest;
|
||||
friend TestInfo* internal::MakeAndRegisterTestInfo(
|
||||
const char* test_suite_name, const char* name, const char* type_param,
|
||||
std::string test_suite_name, const char* name, const char* type_param,
|
||||
const char* value_param, internal::CodeLocation code_location,
|
||||
internal::TypeId fixture_class_id, internal::SetUpTestSuiteFunc set_up_tc,
|
||||
internal::TearDownTestSuiteFunc tear_down_tc,
|
||||
@ -598,7 +615,7 @@ class GTEST_API_ TestInfo {
|
||||
|
||||
// Constructs a TestInfo object. The newly constructed instance assumes
|
||||
// ownership of the factory object.
|
||||
TestInfo(const std::string& test_suite_name, const std::string& name,
|
||||
TestInfo(std::string test_suite_name, std::string name,
|
||||
const char* a_type_param, // NULL if not a type-parameterized test
|
||||
const char* a_value_param, // NULL if not a value-parameterized test
|
||||
internal::CodeLocation a_code_location,
|
||||
@ -666,7 +683,7 @@ class GTEST_API_ TestSuite {
|
||||
// this is not a type-parameterized test.
|
||||
// set_up_tc: pointer to the function that sets up the test suite
|
||||
// tear_down_tc: pointer to the function that tears down the test suite
|
||||
TestSuite(const char* name, const char* a_type_param,
|
||||
TestSuite(const std::string& name, const char* a_type_param,
|
||||
internal::SetUpTestSuiteFunc set_up_tc,
|
||||
internal::TearDownTestSuiteFunc tear_down_tc);
|
||||
|
||||
@ -679,7 +696,7 @@ class GTEST_API_ TestSuite {
|
||||
// Returns the name of the parameter type, or NULL if this is not a
|
||||
// type-parameterized test suite.
|
||||
const char* type_param() const {
|
||||
if (type_param_.get() != nullptr) return type_param_->c_str();
|
||||
if (type_param_ != nullptr) return type_param_->c_str();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -876,7 +893,7 @@ class GTEST_API_ TestSuite {
|
||||
class Environment {
|
||||
public:
|
||||
// The d'tor is virtual as we need to subclass Environment.
|
||||
virtual ~Environment() {}
|
||||
virtual ~Environment() = default;
|
||||
|
||||
// Override this to define how to set up the environment.
|
||||
virtual void SetUp() {}
|
||||
@ -907,7 +924,7 @@ class GTEST_API_ AssertionException
|
||||
// the order the corresponding events are fired.
|
||||
class TestEventListener {
|
||||
public:
|
||||
virtual ~TestEventListener() {}
|
||||
virtual ~TestEventListener() = default;
|
||||
|
||||
// Fired before any test activity starts.
|
||||
virtual void OnTestProgramStart(const UnitTest& unit_test) = 0;
|
||||
@ -1037,6 +1054,10 @@ class GTEST_API_ TestEventListeners {
|
||||
return default_xml_generator_;
|
||||
}
|
||||
|
||||
// Controls whether events will be forwarded by the repeater to the
|
||||
// listeners in the list.
|
||||
void SuppressEventForwarding(bool);
|
||||
|
||||
private:
|
||||
friend class TestSuite;
|
||||
friend class TestInfo;
|
||||
@ -1066,7 +1087,6 @@ class GTEST_API_ TestEventListeners {
|
||||
// Controls whether events will be forwarded by the repeater to the
|
||||
// listeners in the list.
|
||||
bool EventForwardingEnabled() const;
|
||||
void SuppressEventForwarding();
|
||||
|
||||
// The actual list of listeners.
|
||||
internal::TestEventRepeater* repeater_;
|
||||
@ -1242,6 +1262,20 @@ class GTEST_API_ UnitTest {
|
||||
// total_test_suite_count() - 1. If i is not in that range, returns NULL.
|
||||
TestSuite* GetMutableTestSuite(int i);
|
||||
|
||||
// Invokes OsStackTrackGetterInterface::UponLeavingGTest. UponLeavingGTest()
|
||||
// should be called immediately before Google Test calls user code. It saves
|
||||
// some information about the current stack that CurrentStackTrace() will use
|
||||
// to find and hide Google Test stack frames.
|
||||
void UponLeavingGTest();
|
||||
|
||||
// Sets the TestSuite object for the test that's currently running.
|
||||
void set_current_test_suite(TestSuite* a_current_test_suite)
|
||||
GTEST_LOCK_EXCLUDED_(mutex_);
|
||||
|
||||
// Sets the TestInfo object for the test that's currently running.
|
||||
void set_current_test_info(TestInfo* a_current_test_info)
|
||||
GTEST_LOCK_EXCLUDED_(mutex_);
|
||||
|
||||
// Accessors for the implementation object.
|
||||
internal::UnitTestImpl* impl() { return impl_; }
|
||||
const internal::UnitTestImpl* impl() const { return impl_; }
|
||||
@ -1250,6 +1284,8 @@ class GTEST_API_ UnitTest {
|
||||
// members of UnitTest.
|
||||
friend class ScopedTrace;
|
||||
friend class Test;
|
||||
friend class TestInfo;
|
||||
friend class TestSuite;
|
||||
friend class internal::AssertHelper;
|
||||
friend class internal::StreamingListenerTest;
|
||||
friend class internal::UnitTestRecordPropertyTestHelper;
|
||||
@ -1553,12 +1589,12 @@ AssertionResult CmpHelperFloatingPointEQ(const char* lhs_expression,
|
||||
}
|
||||
|
||||
::std::stringstream lhs_ss;
|
||||
lhs_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
|
||||
<< lhs_value;
|
||||
lhs_ss.precision(std::numeric_limits<RawType>::digits10 + 2);
|
||||
lhs_ss << lhs_value;
|
||||
|
||||
::std::stringstream rhs_ss;
|
||||
rhs_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
|
||||
<< rhs_value;
|
||||
rhs_ss.precision(std::numeric_limits<RawType>::digits10 + 2);
|
||||
rhs_ss << rhs_value;
|
||||
|
||||
return EqFailure(lhs_expression, rhs_expression,
|
||||
StringStreamToString(&lhs_ss), StringStreamToString(&rhs_ss),
|
||||
@ -1625,7 +1661,7 @@ class GTEST_API_ AssertHelper {
|
||||
// the GetParam() method.
|
||||
//
|
||||
// Use it with one of the parameter generator defining functions, like Range(),
|
||||
// Values(), ValuesIn(), Bool(), and Combine().
|
||||
// Values(), ValuesIn(), Bool(), Combine(), and ConvertGenerator<T>().
|
||||
//
|
||||
// class FooTest : public ::testing::TestWithParam<int> {
|
||||
// protected:
|
||||
@ -1653,7 +1689,7 @@ template <typename T>
|
||||
class WithParamInterface {
|
||||
public:
|
||||
typedef T ParamType;
|
||||
virtual ~WithParamInterface() {}
|
||||
virtual ~WithParamInterface() = default;
|
||||
|
||||
// The current parameter value. Is also available in the test fixture's
|
||||
// constructor.
|
||||
@ -1723,14 +1759,15 @@ class TestWithParam : public Test, public WithParamInterface<T> {};
|
||||
#define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed")
|
||||
|
||||
// Like GTEST_FAIL(), but at the given source file location.
|
||||
#define GTEST_FAIL_AT(file, line) \
|
||||
GTEST_MESSAGE_AT_(file, line, "Failed", \
|
||||
::testing::TestPartResult::kFatalFailure)
|
||||
#define GTEST_FAIL_AT(file, line) \
|
||||
return GTEST_MESSAGE_AT_(file, line, "Failed", \
|
||||
::testing::TestPartResult::kFatalFailure)
|
||||
|
||||
// Define this macro to 1 to omit the definition of FAIL(), which is a
|
||||
// generic name and clashes with some other libraries.
|
||||
#if !GTEST_DONT_DEFINE_FAIL
|
||||
#if !(defined(GTEST_DONT_DEFINE_FAIL) && GTEST_DONT_DEFINE_FAIL)
|
||||
#define FAIL() GTEST_FAIL()
|
||||
#define FAIL_AT(file, line) GTEST_FAIL_AT(file, line)
|
||||
#endif
|
||||
|
||||
// Generates a success with a generic message.
|
||||
@ -1738,7 +1775,7 @@ class TestWithParam : public Test, public WithParamInterface<T> {};
|
||||
|
||||
// Define this macro to 1 to omit the definition of SUCCEED(), which
|
||||
// is a generic name and clashes with some other libraries.
|
||||
#if !GTEST_DONT_DEFINE_SUCCEED
|
||||
#if !(defined(GTEST_DONT_DEFINE_SUCCEED) && GTEST_DONT_DEFINE_SUCCEED)
|
||||
#define SUCCEED() GTEST_SUCCEED()
|
||||
#endif
|
||||
|
||||
@ -1782,19 +1819,19 @@ class TestWithParam : public Test, public WithParamInterface<T> {};
|
||||
// Define these macros to 1 to omit the definition of the corresponding
|
||||
// EXPECT or ASSERT, which clashes with some users' own code.
|
||||
|
||||
#if !GTEST_DONT_DEFINE_EXPECT_TRUE
|
||||
#if !(defined(GTEST_DONT_DEFINE_EXPECT_TRUE) && GTEST_DONT_DEFINE_EXPECT_TRUE)
|
||||
#define EXPECT_TRUE(condition) GTEST_EXPECT_TRUE(condition)
|
||||
#endif
|
||||
|
||||
#if !GTEST_DONT_DEFINE_EXPECT_FALSE
|
||||
#if !(defined(GTEST_DONT_DEFINE_EXPECT_FALSE) && GTEST_DONT_DEFINE_EXPECT_FALSE)
|
||||
#define EXPECT_FALSE(condition) GTEST_EXPECT_FALSE(condition)
|
||||
#endif
|
||||
|
||||
#if !GTEST_DONT_DEFINE_ASSERT_TRUE
|
||||
#if !(defined(GTEST_DONT_DEFINE_ASSERT_TRUE) && GTEST_DONT_DEFINE_ASSERT_TRUE)
|
||||
#define ASSERT_TRUE(condition) GTEST_ASSERT_TRUE(condition)
|
||||
#endif
|
||||
|
||||
#if !GTEST_DONT_DEFINE_ASSERT_FALSE
|
||||
#if !(defined(GTEST_DONT_DEFINE_ASSERT_FALSE) && GTEST_DONT_DEFINE_ASSERT_FALSE)
|
||||
#define ASSERT_FALSE(condition) GTEST_ASSERT_FALSE(condition)
|
||||
#endif
|
||||
|
||||
@ -1873,27 +1910,27 @@ class TestWithParam : public Test, public WithParamInterface<T> {};
|
||||
// Define macro GTEST_DONT_DEFINE_ASSERT_XY to 1 to omit the definition of
|
||||
// ASSERT_XY(), which clashes with some users' own code.
|
||||
|
||||
#if !GTEST_DONT_DEFINE_ASSERT_EQ
|
||||
#if !(defined(GTEST_DONT_DEFINE_ASSERT_EQ) && GTEST_DONT_DEFINE_ASSERT_EQ)
|
||||
#define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2)
|
||||
#endif
|
||||
|
||||
#if !GTEST_DONT_DEFINE_ASSERT_NE
|
||||
#if !(defined(GTEST_DONT_DEFINE_ASSERT_NE) && GTEST_DONT_DEFINE_ASSERT_NE)
|
||||
#define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2)
|
||||
#endif
|
||||
|
||||
#if !GTEST_DONT_DEFINE_ASSERT_LE
|
||||
#if !(defined(GTEST_DONT_DEFINE_ASSERT_LE) && GTEST_DONT_DEFINE_ASSERT_LE)
|
||||
#define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2)
|
||||
#endif
|
||||
|
||||
#if !GTEST_DONT_DEFINE_ASSERT_LT
|
||||
#if !(defined(GTEST_DONT_DEFINE_ASSERT_LT) && GTEST_DONT_DEFINE_ASSERT_LT)
|
||||
#define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2)
|
||||
#endif
|
||||
|
||||
#if !GTEST_DONT_DEFINE_ASSERT_GE
|
||||
#if !(defined(GTEST_DONT_DEFINE_ASSERT_GE) && GTEST_DONT_DEFINE_ASSERT_GE)
|
||||
#define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2)
|
||||
#endif
|
||||
|
||||
#if !GTEST_DONT_DEFINE_ASSERT_GT
|
||||
#if !(defined(GTEST_DONT_DEFINE_ASSERT_GT) && GTEST_DONT_DEFINE_ASSERT_GT)
|
||||
#define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2)
|
||||
#endif
|
||||
|
||||
@ -1981,7 +2018,7 @@ GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2,
|
||||
GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2,
|
||||
double val1, double val2);
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
|
||||
// Macros that test for HRESULT failure and success, these are only useful
|
||||
// on Windows, and rely on Windows SDK macros and APIs to compile.
|
||||
@ -2063,9 +2100,7 @@ class GTEST_API_ ScopedTrace {
|
||||
|
||||
ScopedTrace(const ScopedTrace&) = delete;
|
||||
ScopedTrace& operator=(const ScopedTrace&) = delete;
|
||||
} GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its
|
||||
// c'tor and d'tor. Therefore it doesn't
|
||||
// need to be used otherwise.
|
||||
};
|
||||
|
||||
// Causes a trace (including the source file path, the current line
|
||||
// number, and the given message) to be included in every test failure
|
||||
@ -2082,8 +2117,8 @@ class GTEST_API_ ScopedTrace {
|
||||
// Assuming that each thread maintains its own stack of traces.
|
||||
// Therefore, a SCOPED_TRACE() would (correctly) only affect the
|
||||
// assertions in its own thread.
|
||||
#define SCOPED_TRACE(message) \
|
||||
::testing::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)( \
|
||||
#define SCOPED_TRACE(message) \
|
||||
const ::testing::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)( \
|
||||
__FILE__, __LINE__, (message))
|
||||
|
||||
// Compile-time assertion for type equality.
|
||||
@ -2153,7 +2188,7 @@ constexpr bool StaticAssertTypeEq() noexcept {
|
||||
|
||||
// Define this macro to 1 to omit the definition of TEST(), which
|
||||
// is a generic name and clashes with some other libraries.
|
||||
#if !GTEST_DONT_DEFINE_TEST
|
||||
#if !(defined(GTEST_DONT_DEFINE_TEST) && GTEST_DONT_DEFINE_TEST)
|
||||
#define TEST(test_suite_name, test_name) GTEST_TEST(test_suite_name, test_name)
|
||||
#endif
|
||||
|
||||
@ -2185,17 +2220,22 @@ constexpr bool StaticAssertTypeEq() noexcept {
|
||||
#define GTEST_TEST_F(test_fixture, test_name) \
|
||||
GTEST_TEST_(test_fixture, test_name, test_fixture, \
|
||||
::testing::internal::GetTypeId<test_fixture>())
|
||||
#if !GTEST_DONT_DEFINE_TEST_F
|
||||
#if !(defined(GTEST_DONT_DEFINE_TEST_F) && GTEST_DONT_DEFINE_TEST_F)
|
||||
#define TEST_F(test_fixture, test_name) GTEST_TEST_F(test_fixture, test_name)
|
||||
#endif
|
||||
|
||||
// Returns a path to temporary directory.
|
||||
// Tries to determine an appropriate directory for the platform.
|
||||
// Returns a path to a temporary directory, which should be writable. It is
|
||||
// implementation-dependent whether or not the path is terminated by the
|
||||
// directory-separator character.
|
||||
GTEST_API_ std::string TempDir();
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
// Returns a path to a directory that contains ancillary data files that might
|
||||
// be used by tests. It is implementation dependent whether or not the path is
|
||||
// terminated by the directory-separator character. The directory and the files
|
||||
// in it should be considered read-only.
|
||||
GTEST_API_ std::string SrcDir();
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4805 4100
|
||||
|
||||
// Dynamically registers a test with the framework.
|
||||
//
|
||||
@ -2284,7 +2324,8 @@ TestInfo* RegisterTest(const char* test_suite_name, const char* test_name,
|
||||
// tests are successful, or 1 otherwise.
|
||||
//
|
||||
// RUN_ALL_TESTS() should be invoked after the command line has been
|
||||
// parsed by InitGoogleTest().
|
||||
// parsed by InitGoogleTest(). RUN_ALL_TESTS will tear down and delete any
|
||||
// installed environments and should only be called once per binary.
|
||||
//
|
||||
// This function was formerly a macro; thus, it is in the global
|
||||
// namespace and has an all-caps name.
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest-matchers.h"
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
@ -51,12 +52,10 @@ GTEST_DECLARE_string_(internal_run_death_test);
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Names of the flags (needed for parsing Google Test flags).
|
||||
const char kDeathTestStyleFlag[] = "death_test_style";
|
||||
const char kDeathTestUseFork[] = "death_test_use_fork";
|
||||
// Name of the flag (needed for parsing Google Test flag).
|
||||
const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
#ifdef GTEST_HAS_DEATH_TEST
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||
/* class A needs to have dll-interface to be used by clients of class B */)
|
||||
@ -72,7 +71,7 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||
//
|
||||
// exit status: The integer exit information in the format specified
|
||||
// by wait(2)
|
||||
// exit code: The integer code passed to exit(3), _exit(2), or
|
||||
// exit code: The integer code passed to exit(3), _Exit(2), or
|
||||
// returned from main()
|
||||
class GTEST_API_ DeathTest {
|
||||
public:
|
||||
@ -87,7 +86,7 @@ class GTEST_API_ DeathTest {
|
||||
static bool Create(const char* statement, Matcher<const std::string&> matcher,
|
||||
const char* file, int line, DeathTest** test);
|
||||
DeathTest();
|
||||
virtual ~DeathTest() {}
|
||||
virtual ~DeathTest() = default;
|
||||
|
||||
// A helper class that aborts a death test when it's deleted.
|
||||
class ReturnSentinel {
|
||||
@ -99,7 +98,7 @@ class GTEST_API_ DeathTest {
|
||||
DeathTest* const test_;
|
||||
ReturnSentinel(const ReturnSentinel&) = delete;
|
||||
ReturnSentinel& operator=(const ReturnSentinel&) = delete;
|
||||
} GTEST_ATTRIBUTE_UNUSED_;
|
||||
};
|
||||
|
||||
// An enumeration of possible roles that may be taken when a death
|
||||
// test is encountered. EXECUTE means that the death test logic should
|
||||
@ -152,7 +151,7 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
||||
// Factory interface for death tests. May be mocked out for testing.
|
||||
class DeathTestFactory {
|
||||
public:
|
||||
virtual ~DeathTestFactory() {}
|
||||
virtual ~DeathTestFactory() = default;
|
||||
virtual bool Create(const char* statement,
|
||||
Matcher<const std::string&> matcher, const char* file,
|
||||
int line, DeathTest** test) = 0;
|
||||
@ -237,7 +236,7 @@ inline Matcher<const ::std::string&> MakeDeathTestMatcher(
|
||||
} \
|
||||
break; \
|
||||
case ::testing::internal::DeathTest::EXECUTE_TEST: { \
|
||||
::testing::internal::DeathTest::ReturnSentinel gtest_sentinel( \
|
||||
const ::testing::internal::DeathTest::ReturnSentinel gtest_sentinel( \
|
||||
gtest_dt); \
|
||||
GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \
|
||||
gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
|
||||
|
@ -42,11 +42,17 @@
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
#include "gtest/internal/gtest-string.h"
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||
/* class A needs to have dll-interface to be used by clients of class B */)
|
||||
|
||||
#if GTEST_HAS_FILE_SYSTEM
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
@ -65,8 +71,9 @@ class GTEST_API_ FilePath {
|
||||
public:
|
||||
FilePath() : pathname_("") {}
|
||||
FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) {}
|
||||
FilePath(FilePath&& rhs) noexcept : pathname_(std::move(rhs.pathname_)) {}
|
||||
|
||||
explicit FilePath(const std::string& pathname) : pathname_(pathname) {
|
||||
explicit FilePath(std::string pathname) : pathname_(std::move(pathname)) {
|
||||
Normalize();
|
||||
}
|
||||
|
||||
@ -74,6 +81,10 @@ class GTEST_API_ FilePath {
|
||||
Set(rhs);
|
||||
return *this;
|
||||
}
|
||||
FilePath& operator=(FilePath&& rhs) noexcept {
|
||||
pathname_ = std::move(rhs.pathname_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Set(const FilePath& rhs) { pathname_ = rhs.pathname_; }
|
||||
|
||||
@ -199,6 +210,16 @@ class GTEST_API_ FilePath {
|
||||
// separators. Returns NULL if no path separator was found.
|
||||
const char* FindLastPathSeparator() const;
|
||||
|
||||
// Returns the length of the path root, including the directory separator at
|
||||
// the end of the prefix. Returns zero by definition if the path is relative.
|
||||
// Examples:
|
||||
// - [Windows] "..\Sibling" => 0
|
||||
// - [Windows] "\Windows" => 1
|
||||
// - [Windows] "C:/Windows\Notepad.exe" => 3
|
||||
// - [Windows] "\\Host\Share\C$/Windows" => 13
|
||||
// - [UNIX] "/bin" => 1
|
||||
size_t CalculateRootLength() const;
|
||||
|
||||
std::string pathname_;
|
||||
}; // class FilePath
|
||||
|
||||
@ -207,4 +228,6 @@ class GTEST_API_ FilePath {
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
||||
|
||||
#endif // GTEST_HAS_FILE_SYSTEM
|
||||
|
||||
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||
|
@ -41,7 +41,7 @@
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
#if GTEST_OS_LINUX
|
||||
#ifdef GTEST_OS_LINUX
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
@ -58,12 +58,12 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <iomanip>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest-message.h"
|
||||
@ -78,7 +78,7 @@
|
||||
//
|
||||
// will result in the token foo__LINE__, instead of foo followed by
|
||||
// the current line number. For more details, see
|
||||
// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6
|
||||
// https://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6
|
||||
#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar)
|
||||
#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo##bar
|
||||
|
||||
@ -169,7 +169,7 @@ namespace edit_distance {
|
||||
// All edits cost the same, with replace having lower priority than
|
||||
// add/remove.
|
||||
// Simple implementation of the Wagner-Fischer algorithm.
|
||||
// See http://en.wikipedia.org/wiki/Wagner-Fischer_algorithm
|
||||
// See https://en.wikipedia.org/wiki/Wagner-Fischer_algorithm
|
||||
enum EditType { kMatch, kAdd, kRemove, kReplace };
|
||||
GTEST_API_ std::vector<EditType> CalculateOptimalEdits(
|
||||
const std::vector<size_t>& left, const std::vector<size_t>& right);
|
||||
@ -236,7 +236,7 @@ GTEST_API_ std::string GetBoolAssertionFailureMessage(
|
||||
// For double, there are 11 exponent bits and 52 fraction bits.
|
||||
//
|
||||
// More details can be found at
|
||||
// http://en.wikipedia.org/wiki/IEEE_floating-point_standard.
|
||||
// https://en.wikipedia.org/wiki/IEEE_floating-point_standard.
|
||||
//
|
||||
// Template parameter:
|
||||
//
|
||||
@ -281,7 +281,7 @@ class FloatingPoint {
|
||||
// bits. Therefore, 4 should be enough for ordinary use.
|
||||
//
|
||||
// See the following article for more details on ULP:
|
||||
// http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
|
||||
// https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
|
||||
static const uint32_t kMaxUlps = 4;
|
||||
|
||||
// Constructs a FloatingPoint from a raw floating-point number.
|
||||
@ -306,9 +306,6 @@ class FloatingPoint {
|
||||
// Returns the floating-point number that represent positive infinity.
|
||||
static RawType Infinity() { return ReinterpretBits(kExponentBitMask); }
|
||||
|
||||
// Returns the maximum representable finite floating-point number.
|
||||
static RawType Max();
|
||||
|
||||
// Non-static methods
|
||||
|
||||
// Returns the bits that represents this number.
|
||||
@ -365,7 +362,7 @@ class FloatingPoint {
|
||||
// N - 1 (the biggest number representable using
|
||||
// sign-and-magnitude) is represented by 2N - 1.
|
||||
//
|
||||
// Read http://en.wikipedia.org/wiki/Signed_number_representations
|
||||
// Read https://en.wikipedia.org/wiki/Signed_number_representations
|
||||
// for more details on signed number representations.
|
||||
static Bits SignAndMagnitudeToBiased(const Bits& sam) {
|
||||
if (kSignBitMask & sam) {
|
||||
@ -389,17 +386,6 @@ class FloatingPoint {
|
||||
FloatingPointUnion u_;
|
||||
};
|
||||
|
||||
// We cannot use std::numeric_limits<T>::max() as it clashes with the max()
|
||||
// macro defined by <windows.h>.
|
||||
template <>
|
||||
inline float FloatingPoint<float>::Max() {
|
||||
return FLT_MAX;
|
||||
}
|
||||
template <>
|
||||
inline double FloatingPoint<double>::Max() {
|
||||
return DBL_MAX;
|
||||
}
|
||||
|
||||
// Typedefs the instances of the FloatingPoint template class that we
|
||||
// care to use.
|
||||
typedef FloatingPoint<float> Float;
|
||||
@ -448,7 +434,7 @@ GTEST_API_ TypeId GetTestTypeId();
|
||||
// of a Test object.
|
||||
class TestFactoryBase {
|
||||
public:
|
||||
virtual ~TestFactoryBase() {}
|
||||
virtual ~TestFactoryBase() = default;
|
||||
|
||||
// Creates a test instance to run. The instance is both created and destroyed
|
||||
// within TestInfoImpl::Run()
|
||||
@ -470,7 +456,7 @@ class TestFactoryImpl : public TestFactoryBase {
|
||||
Test* CreateTest() override { return new TestClass; }
|
||||
};
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
|
||||
// Predicate-formatters for implementing the HRESULT checking macros
|
||||
// {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}
|
||||
@ -488,8 +474,8 @@ using SetUpTestSuiteFunc = void (*)();
|
||||
using TearDownTestSuiteFunc = void (*)();
|
||||
|
||||
struct CodeLocation {
|
||||
CodeLocation(const std::string& a_file, int a_line)
|
||||
: file(a_file), line(a_line) {}
|
||||
CodeLocation(std::string a_file, int a_line)
|
||||
: file(std::move(a_file)), line(a_line) {}
|
||||
|
||||
std::string file;
|
||||
int line;
|
||||
@ -569,7 +555,7 @@ struct SuiteApiResolver : T {
|
||||
// type_param: the name of the test's type parameter, or NULL if
|
||||
// this is not a typed or a type-parameterized test.
|
||||
// value_param: text representation of the test's value parameter,
|
||||
// or NULL if this is not a type-parameterized test.
|
||||
// or NULL if this is not a value-parameterized test.
|
||||
// code_location: code location where the test is defined
|
||||
// fixture_class_id: ID of the test fixture class
|
||||
// set_up_tc: pointer to the function that sets up the test suite
|
||||
@ -578,7 +564,7 @@ struct SuiteApiResolver : T {
|
||||
// The newly created TestInfo instance will assume
|
||||
// ownership of the factory object.
|
||||
GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
|
||||
const char* test_suite_name, const char* name, const char* type_param,
|
||||
std::string test_suite_name, const char* name, const char* type_param,
|
||||
const char* value_param, CodeLocation code_location,
|
||||
TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc,
|
||||
TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory);
|
||||
@ -609,8 +595,7 @@ class GTEST_API_ TypedTestSuitePState {
|
||||
fflush(stderr);
|
||||
posix::Abort();
|
||||
}
|
||||
registered_tests_.insert(
|
||||
::std::make_pair(test_name, CodeLocation(file, line)));
|
||||
registered_tests_.emplace(test_name, CodeLocation(file, line));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -714,7 +699,7 @@ class TypeParameterizedTest {
|
||||
// specified in INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, TestSuite,
|
||||
// Types). Valid values for 'index' are [0, N - 1] where N is the
|
||||
// length of Types.
|
||||
static bool Register(const char* prefix, const CodeLocation& code_location,
|
||||
static bool Register(const char* prefix, CodeLocation code_location,
|
||||
const char* case_name, const char* test_names, int index,
|
||||
const std::vector<std::string>& type_names =
|
||||
GenerateNames<DefaultNameGenerator, Types>()) {
|
||||
@ -726,8 +711,7 @@ class TypeParameterizedTest {
|
||||
// list.
|
||||
MakeAndRegisterTestInfo(
|
||||
(std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name +
|
||||
"/" + type_names[static_cast<size_t>(index)])
|
||||
.c_str(),
|
||||
"/" + type_names[static_cast<size_t>(index)]),
|
||||
StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(),
|
||||
GetTypeName<Type>().c_str(),
|
||||
nullptr, // No value parameter.
|
||||
@ -739,13 +723,9 @@ class TypeParameterizedTest {
|
||||
new TestFactoryImpl<TestClass>);
|
||||
|
||||
// Next, recurses (at compile time) with the tail of the type list.
|
||||
return TypeParameterizedTest<Fixture, TestSel,
|
||||
typename Types::Tail>::Register(prefix,
|
||||
code_location,
|
||||
case_name,
|
||||
test_names,
|
||||
index + 1,
|
||||
type_names);
|
||||
return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail>::
|
||||
Register(prefix, std::move(code_location), case_name, test_names,
|
||||
index + 1, type_names);
|
||||
}
|
||||
};
|
||||
|
||||
@ -753,7 +733,7 @@ class TypeParameterizedTest {
|
||||
template <GTEST_TEMPLATE_ Fixture, class TestSel>
|
||||
class TypeParameterizedTest<Fixture, TestSel, internal::None> {
|
||||
public:
|
||||
static bool Register(const char* /*prefix*/, const CodeLocation&,
|
||||
static bool Register(const char* /*prefix*/, CodeLocation,
|
||||
const char* /*case_name*/, const char* /*test_names*/,
|
||||
int /*index*/,
|
||||
const std::vector<std::string>& =
|
||||
@ -800,7 +780,8 @@ class TypeParameterizedTestSuite {
|
||||
|
||||
// Next, recurses (at compile time) with the tail of the test list.
|
||||
return TypeParameterizedTestSuite<Fixture, typename Tests::Tail,
|
||||
Types>::Register(prefix, code_location,
|
||||
Types>::Register(prefix,
|
||||
std::move(code_location),
|
||||
state, case_name,
|
||||
SkipComma(test_names),
|
||||
type_names);
|
||||
@ -913,8 +894,10 @@ class HasDebugStringAndShortDebugString {
|
||||
HasDebugStringType::value && HasShortDebugStringType::value;
|
||||
};
|
||||
|
||||
#ifdef GTEST_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
|
||||
template <typename T>
|
||||
constexpr bool HasDebugStringAndShortDebugString<T>::value;
|
||||
#endif
|
||||
|
||||
// When the compiler sees expression IsContainerTest<C>(0), if C is an
|
||||
// STL-style container class, the first overload of IsContainerTest
|
||||
@ -1154,40 +1137,6 @@ class NativeArray {
|
||||
void (NativeArray::*clone_)(const Element*, size_t);
|
||||
};
|
||||
|
||||
// Backport of std::index_sequence.
|
||||
template <size_t... Is>
|
||||
struct IndexSequence {
|
||||
using type = IndexSequence;
|
||||
};
|
||||
|
||||
// Double the IndexSequence, and one if plus_one is true.
|
||||
template <bool plus_one, typename T, size_t sizeofT>
|
||||
struct DoubleSequence;
|
||||
template <size_t... I, size_t sizeofT>
|
||||
struct DoubleSequence<true, IndexSequence<I...>, sizeofT> {
|
||||
using type = IndexSequence<I..., (sizeofT + I)..., 2 * sizeofT>;
|
||||
};
|
||||
template <size_t... I, size_t sizeofT>
|
||||
struct DoubleSequence<false, IndexSequence<I...>, sizeofT> {
|
||||
using type = IndexSequence<I..., (sizeofT + I)...>;
|
||||
};
|
||||
|
||||
// Backport of std::make_index_sequence.
|
||||
// It uses O(ln(N)) instantiation depth.
|
||||
template <size_t N>
|
||||
struct MakeIndexSequenceImpl
|
||||
: DoubleSequence<N % 2 == 1, typename MakeIndexSequenceImpl<N / 2>::type,
|
||||
N / 2>::type {};
|
||||
|
||||
template <>
|
||||
struct MakeIndexSequenceImpl<0> : IndexSequence<> {};
|
||||
|
||||
template <size_t N>
|
||||
using MakeIndexSequence = typename MakeIndexSequenceImpl<N>::type;
|
||||
|
||||
template <typename... T>
|
||||
using IndexSequenceFor = typename MakeIndexSequence<sizeof...(T)>::type;
|
||||
|
||||
template <size_t>
|
||||
struct Ignore {
|
||||
Ignore(...); // NOLINT
|
||||
@ -1196,7 +1145,7 @@ struct Ignore {
|
||||
template <typename>
|
||||
struct ElemFromListImpl;
|
||||
template <size_t... I>
|
||||
struct ElemFromListImpl<IndexSequence<I...>> {
|
||||
struct ElemFromListImpl<std::index_sequence<I...>> {
|
||||
// We make Ignore a template to solve a problem with MSVC.
|
||||
// A non-template Ignore would work fine with `decltype(Ignore(I))...`, but
|
||||
// MSVC doesn't understand how to deal with that pack expansion.
|
||||
@ -1207,9 +1156,8 @@ struct ElemFromListImpl<IndexSequence<I...>> {
|
||||
|
||||
template <size_t N, typename... T>
|
||||
struct ElemFromList {
|
||||
using type =
|
||||
decltype(ElemFromListImpl<typename MakeIndexSequence<N>::type>::Apply(
|
||||
static_cast<T (*)()>(nullptr)...));
|
||||
using type = decltype(ElemFromListImpl<std::make_index_sequence<N>>::Apply(
|
||||
static_cast<T (*)()>(nullptr)...));
|
||||
};
|
||||
|
||||
struct FlatTupleConstructTag {};
|
||||
@ -1234,9 +1182,9 @@ template <typename Derived, typename Idx>
|
||||
struct FlatTupleBase;
|
||||
|
||||
template <size_t... Idx, typename... T>
|
||||
struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>>
|
||||
struct FlatTupleBase<FlatTuple<T...>, std::index_sequence<Idx...>>
|
||||
: FlatTupleElemBase<FlatTuple<T...>, Idx>... {
|
||||
using Indices = IndexSequence<Idx...>;
|
||||
using Indices = std::index_sequence<Idx...>;
|
||||
FlatTupleBase() = default;
|
||||
template <typename... Args>
|
||||
explicit FlatTupleBase(FlatTupleConstructTag, Args&&... args)
|
||||
@ -1271,14 +1219,15 @@ struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>>
|
||||
// implementations.
|
||||
// FlatTuple and ElemFromList are not recursive and have a fixed depth
|
||||
// regardless of T...
|
||||
// MakeIndexSequence, on the other hand, it is recursive but with an
|
||||
// std::make_index_sequence, on the other hand, it is recursive but with an
|
||||
// instantiation depth of O(ln(N)).
|
||||
template <typename... T>
|
||||
class FlatTuple
|
||||
: private FlatTupleBase<FlatTuple<T...>,
|
||||
typename MakeIndexSequence<sizeof...(T)>::type> {
|
||||
using Indices = typename FlatTupleBase<
|
||||
FlatTuple<T...>, typename MakeIndexSequence<sizeof...(T)>::type>::Indices;
|
||||
std::make_index_sequence<sizeof...(T)>> {
|
||||
using Indices =
|
||||
typename FlatTupleBase<FlatTuple<T...>,
|
||||
std::make_index_sequence<sizeof...(T)>>::Indices;
|
||||
|
||||
public:
|
||||
FlatTuple() = default;
|
||||
@ -1508,19 +1457,20 @@ class NeverThrown {
|
||||
gtest_ar_, text, #actual, #expected) \
|
||||
.c_str())
|
||||
|
||||
#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (::testing::internal::AlwaysTrue()) { \
|
||||
::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \
|
||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||
if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \
|
||||
goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \
|
||||
} \
|
||||
} else \
|
||||
GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__) \
|
||||
: fail("Expected: " #statement \
|
||||
" doesn't generate new fatal " \
|
||||
"failures in the current thread.\n" \
|
||||
#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (::testing::internal::AlwaysTrue()) { \
|
||||
const ::testing::internal::HasNewFatalFailureHelper \
|
||||
gtest_fatal_failure_checker; \
|
||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||
if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \
|
||||
goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \
|
||||
} \
|
||||
} else /* NOLINT */ \
|
||||
GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__) \
|
||||
: fail("Expected: " #statement \
|
||||
" doesn't generate new fatal " \
|
||||
"failures in the current thread.\n" \
|
||||
" Actual: it does.")
|
||||
|
||||
// Expands to the name of the class that implements the given test.
|
||||
@ -1551,7 +1501,8 @@ class NeverThrown {
|
||||
\
|
||||
private: \
|
||||
void TestBody() override; \
|
||||
static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_; \
|
||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static ::testing::TestInfo* const \
|
||||
test_info_; \
|
||||
}; \
|
||||
\
|
||||
::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \
|
||||
|
@ -40,10 +40,14 @@
|
||||
|
||||
#include <cassert>
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@ -82,7 +86,7 @@ namespace internal {
|
||||
// TEST_P macro is used to define two tests with the same name
|
||||
// but in different namespaces.
|
||||
GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name,
|
||||
CodeLocation code_location);
|
||||
const CodeLocation& code_location);
|
||||
|
||||
template <typename>
|
||||
class ParamGeneratorInterface;
|
||||
@ -94,7 +98,7 @@ class ParamGenerator;
|
||||
template <typename T>
|
||||
class ParamIteratorInterface {
|
||||
public:
|
||||
virtual ~ParamIteratorInterface() {}
|
||||
virtual ~ParamIteratorInterface() = default;
|
||||
// A pointer to the base generator instance.
|
||||
// Used only for the purposes of iterator comparison
|
||||
// to make sure that two iterators belong to the same generator.
|
||||
@ -168,7 +172,7 @@ class ParamGeneratorInterface {
|
||||
public:
|
||||
typedef T ParamType;
|
||||
|
||||
virtual ~ParamGeneratorInterface() {}
|
||||
virtual ~ParamGeneratorInterface() = default;
|
||||
|
||||
// Generator interface definition
|
||||
virtual ParamIteratorInterface<T>* Begin() const = 0;
|
||||
@ -212,7 +216,7 @@ class RangeGenerator : public ParamGeneratorInterface<T> {
|
||||
end_(end),
|
||||
step_(step),
|
||||
end_index_(CalculateEndIndex(begin, end, step)) {}
|
||||
~RangeGenerator() override {}
|
||||
~RangeGenerator() override = default;
|
||||
|
||||
ParamIteratorInterface<T>* Begin() const override {
|
||||
return new Iterator(this, begin_, 0, step_);
|
||||
@ -227,7 +231,7 @@ class RangeGenerator : public ParamGeneratorInterface<T> {
|
||||
Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
|
||||
IncrementT step)
|
||||
: base_(base), value_(value), index_(index), step_(step) {}
|
||||
~Iterator() override {}
|
||||
~Iterator() override = default;
|
||||
|
||||
const ParamGeneratorInterface<T>* BaseGenerator() const override {
|
||||
return base_;
|
||||
@ -296,7 +300,7 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
|
||||
template <typename ForwardIterator>
|
||||
ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
|
||||
: container_(begin, end) {}
|
||||
~ValuesInIteratorRangeGenerator() override {}
|
||||
~ValuesInIteratorRangeGenerator() override = default;
|
||||
|
||||
ParamIteratorInterface<T>* Begin() const override {
|
||||
return new Iterator(this, container_.begin());
|
||||
@ -313,7 +317,7 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
|
||||
Iterator(const ParamGeneratorInterface<T>* base,
|
||||
typename ContainerType::const_iterator iterator)
|
||||
: base_(base), iterator_(iterator) {}
|
||||
~Iterator() override {}
|
||||
~Iterator() override = default;
|
||||
|
||||
const ParamGeneratorInterface<T>* BaseGenerator() const override {
|
||||
return base_;
|
||||
@ -376,9 +380,7 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
|
||||
// integer test parameter index.
|
||||
template <class ParamType>
|
||||
std::string DefaultParamName(const TestParamInfo<ParamType>& info) {
|
||||
Message name_stream;
|
||||
name_stream << info.index;
|
||||
return name_stream.GetString();
|
||||
return std::to_string(info.index);
|
||||
}
|
||||
|
||||
template <typename T = int>
|
||||
@ -417,7 +419,7 @@ class ParameterizedTestFactory : public TestFactoryBase {
|
||||
template <class ParamType>
|
||||
class TestMetaFactoryBase {
|
||||
public:
|
||||
virtual ~TestMetaFactoryBase() {}
|
||||
virtual ~TestMetaFactoryBase() = default;
|
||||
|
||||
virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;
|
||||
};
|
||||
@ -436,7 +438,7 @@ class TestMetaFactory
|
||||
public:
|
||||
using ParamType = typename TestSuite::ParamType;
|
||||
|
||||
TestMetaFactory() {}
|
||||
TestMetaFactory() = default;
|
||||
|
||||
TestFactoryBase* CreateTestFactory(ParamType parameter) override {
|
||||
return new ParameterizedTestFactory<TestSuite>(parameter);
|
||||
@ -459,7 +461,7 @@ class TestMetaFactory
|
||||
// and calls RegisterTests() on each of them when asked.
|
||||
class ParameterizedTestSuiteInfoBase {
|
||||
public:
|
||||
virtual ~ParameterizedTestSuiteInfoBase() {}
|
||||
virtual ~ParameterizedTestSuiteInfoBase() = default;
|
||||
|
||||
// Base part of test suite name for display purposes.
|
||||
virtual const std::string& GetTestSuiteName() const = 0;
|
||||
@ -510,9 +512,10 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
||||
typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
|
||||
using ParamNameGeneratorFunc = std::string(const TestParamInfo<ParamType>&);
|
||||
|
||||
explicit ParameterizedTestSuiteInfo(const char* name,
|
||||
explicit ParameterizedTestSuiteInfo(std::string name,
|
||||
CodeLocation code_location)
|
||||
: test_suite_name_(name), code_location_(code_location) {}
|
||||
: test_suite_name_(std::move(name)),
|
||||
code_location_(std::move(code_location)) {}
|
||||
|
||||
// Test suite base name for display purposes.
|
||||
const std::string& GetTestSuiteName() const override {
|
||||
@ -526,20 +529,21 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
||||
// prefix). test_base_name is the name of an individual test without
|
||||
// parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
|
||||
// test suite base name and DoBar is test base name.
|
||||
void AddTestPattern(const char* test_suite_name, const char* test_base_name,
|
||||
void AddTestPattern(const char*,
|
||||
const char* test_base_name,
|
||||
TestMetaFactoryBase<ParamType>* meta_factory,
|
||||
CodeLocation code_location) {
|
||||
tests_.push_back(std::shared_ptr<TestInfo>(new TestInfo(
|
||||
test_suite_name, test_base_name, meta_factory, code_location)));
|
||||
tests_.emplace_back(
|
||||
new TestInfo(test_base_name, meta_factory, std::move(code_location)));
|
||||
}
|
||||
// INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information
|
||||
// about a generator.
|
||||
int AddTestSuiteInstantiation(const std::string& instantiation_name,
|
||||
int AddTestSuiteInstantiation(std::string instantiation_name,
|
||||
GeneratorCreationFunc* func,
|
||||
ParamNameGeneratorFunc* name_func,
|
||||
const char* file, int line) {
|
||||
instantiations_.push_back(
|
||||
InstantiationInfo(instantiation_name, func, name_func, file, line));
|
||||
instantiations_.emplace_back(std::move(instantiation_name), func, name_func,
|
||||
file, line);
|
||||
return 0; // Return value used only to run this method in namespace scope.
|
||||
}
|
||||
// UnitTest class invokes this method to register tests in this test suite
|
||||
@ -550,60 +554,61 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
||||
void RegisterTests() override {
|
||||
bool generated_instantiations = false;
|
||||
|
||||
for (typename TestInfoContainer::iterator test_it = tests_.begin();
|
||||
test_it != tests_.end(); ++test_it) {
|
||||
std::shared_ptr<TestInfo> test_info = *test_it;
|
||||
for (typename InstantiationContainer::iterator gen_it =
|
||||
instantiations_.begin();
|
||||
gen_it != instantiations_.end(); ++gen_it) {
|
||||
const std::string& instantiation_name = gen_it->name;
|
||||
ParamGenerator<ParamType> generator((*gen_it->generator)());
|
||||
ParamNameGeneratorFunc* name_func = gen_it->name_func;
|
||||
const char* file = gen_it->file;
|
||||
int line = gen_it->line;
|
||||
std::string test_suite_name;
|
||||
std::string test_name;
|
||||
for (const std::shared_ptr<TestInfo>& test_info : tests_) {
|
||||
for (const InstantiationInfo& instantiation : instantiations_) {
|
||||
const std::string& instantiation_name = instantiation.name;
|
||||
ParamGenerator<ParamType> generator((*instantiation.generator)());
|
||||
ParamNameGeneratorFunc* name_func = instantiation.name_func;
|
||||
const char* file = instantiation.file;
|
||||
int line = instantiation.line;
|
||||
|
||||
std::string test_suite_name;
|
||||
if (!instantiation_name.empty())
|
||||
test_suite_name = instantiation_name + "/";
|
||||
test_suite_name += test_info->test_suite_base_name;
|
||||
else
|
||||
test_suite_name.clear();
|
||||
test_suite_name += test_suite_name_;
|
||||
|
||||
size_t i = 0;
|
||||
std::set<std::string> test_param_names;
|
||||
for (typename ParamGenerator<ParamType>::iterator param_it =
|
||||
generator.begin();
|
||||
param_it != generator.end(); ++param_it, ++i) {
|
||||
for (const auto& param : generator) {
|
||||
generated_instantiations = true;
|
||||
|
||||
Message test_name_stream;
|
||||
test_name.clear();
|
||||
|
||||
std::string param_name =
|
||||
name_func(TestParamInfo<ParamType>(*param_it, i));
|
||||
name_func(TestParamInfo<ParamType>(param, i));
|
||||
|
||||
GTEST_CHECK_(IsValidParamName(param_name))
|
||||
<< "Parameterized test name '" << param_name
|
||||
<< "' is invalid, in " << file << " line " << line << std::endl;
|
||||
<< "' is invalid (contains spaces, dashes, or any "
|
||||
"non-alphanumeric characters other than underscores), in "
|
||||
<< file << " line " << line << "" << std::endl;
|
||||
|
||||
GTEST_CHECK_(test_param_names.count(param_name) == 0)
|
||||
<< "Duplicate parameterized test name '" << param_name << "', in "
|
||||
<< file << " line " << line << std::endl;
|
||||
|
||||
test_param_names.insert(param_name);
|
||||
|
||||
if (!test_info->test_base_name.empty()) {
|
||||
test_name_stream << test_info->test_base_name << "/";
|
||||
test_name.append(test_info->test_base_name).append("/");
|
||||
}
|
||||
test_name_stream << param_name;
|
||||
test_name += param_name;
|
||||
|
||||
test_param_names.insert(std::move(param_name));
|
||||
|
||||
MakeAndRegisterTestInfo(
|
||||
test_suite_name.c_str(), test_name_stream.GetString().c_str(),
|
||||
test_suite_name, test_name.c_str(),
|
||||
nullptr, // No type parameter.
|
||||
PrintToString(*param_it).c_str(), test_info->code_location,
|
||||
PrintToString(param).c_str(), test_info->code_location,
|
||||
GetTestSuiteTypeId(),
|
||||
SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line),
|
||||
SuiteApiResolver<TestSuite>::GetTearDownCaseOrSuite(file, line),
|
||||
test_info->test_meta_factory->CreateTestFactory(*param_it));
|
||||
} // for param_it
|
||||
} // for gen_it
|
||||
} // for test_it
|
||||
test_info->test_meta_factory->CreateTestFactory(param));
|
||||
++i;
|
||||
} // for param
|
||||
} // for instantiation
|
||||
} // for test_info
|
||||
|
||||
if (!generated_instantiations) {
|
||||
// There are no generaotrs, or they all generate nothing ...
|
||||
@ -616,15 +621,13 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
||||
// LocalTestInfo structure keeps information about a single test registered
|
||||
// with TEST_P macro.
|
||||
struct TestInfo {
|
||||
TestInfo(const char* a_test_suite_base_name, const char* a_test_base_name,
|
||||
TestInfo(const char* a_test_base_name,
|
||||
TestMetaFactoryBase<ParamType>* a_test_meta_factory,
|
||||
CodeLocation a_code_location)
|
||||
: test_suite_base_name(a_test_suite_base_name),
|
||||
test_base_name(a_test_base_name),
|
||||
: test_base_name(a_test_base_name),
|
||||
test_meta_factory(a_test_meta_factory),
|
||||
code_location(a_code_location) {}
|
||||
code_location(std::move(a_code_location)) {}
|
||||
|
||||
const std::string test_suite_base_name;
|
||||
const std::string test_base_name;
|
||||
const std::unique_ptr<TestMetaFactoryBase<ParamType>> test_meta_factory;
|
||||
const CodeLocation code_location;
|
||||
@ -634,11 +637,10 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
||||
// <Instantiation name, Sequence generator creation function,
|
||||
// Name generator function, Source file, Source line>
|
||||
struct InstantiationInfo {
|
||||
InstantiationInfo(const std::string& name_in,
|
||||
GeneratorCreationFunc* generator_in,
|
||||
InstantiationInfo(std::string name_in, GeneratorCreationFunc* generator_in,
|
||||
ParamNameGeneratorFunc* name_func_in, const char* file_in,
|
||||
int line_in)
|
||||
: name(name_in),
|
||||
: name(std::move(name_in)),
|
||||
generator(generator_in),
|
||||
name_func(name_func_in),
|
||||
file(file_in),
|
||||
@ -688,7 +690,7 @@ using ParameterizedTestCaseInfo = ParameterizedTestSuiteInfo<TestCase>;
|
||||
// ParameterizedTestSuiteInfo descriptors.
|
||||
class ParameterizedTestSuiteRegistry {
|
||||
public:
|
||||
ParameterizedTestSuiteRegistry() {}
|
||||
ParameterizedTestSuiteRegistry() = default;
|
||||
~ParameterizedTestSuiteRegistry() {
|
||||
for (auto& test_suite_info : test_suite_infos_) {
|
||||
delete test_suite_info;
|
||||
@ -699,29 +701,32 @@ class ParameterizedTestSuiteRegistry {
|
||||
// tests and instantiations of a particular test suite.
|
||||
template <class TestSuite>
|
||||
ParameterizedTestSuiteInfo<TestSuite>* GetTestSuitePatternHolder(
|
||||
const char* test_suite_name, CodeLocation code_location) {
|
||||
std::string test_suite_name, CodeLocation code_location) {
|
||||
ParameterizedTestSuiteInfo<TestSuite>* typed_test_info = nullptr;
|
||||
for (auto& test_suite_info : test_suite_infos_) {
|
||||
if (test_suite_info->GetTestSuiteName() == test_suite_name) {
|
||||
if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {
|
||||
// Complain about incorrect usage of Google Test facilities
|
||||
// and terminate the program since we cannot guaranty correct
|
||||
// test suite setup and tear-down in this case.
|
||||
ReportInvalidTestSuiteType(test_suite_name, code_location);
|
||||
posix::Abort();
|
||||
} else {
|
||||
// At this point we are sure that the object we found is of the same
|
||||
// type we are looking for, so we downcast it to that type
|
||||
// without further checks.
|
||||
typed_test_info = CheckedDowncastToActualType<
|
||||
ParameterizedTestSuiteInfo<TestSuite>>(test_suite_info);
|
||||
}
|
||||
break;
|
||||
|
||||
auto item_it = suite_name_to_info_index_.find(test_suite_name);
|
||||
if (item_it != suite_name_to_info_index_.end()) {
|
||||
auto* test_suite_info = test_suite_infos_[item_it->second];
|
||||
if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {
|
||||
// Complain about incorrect usage of Google Test facilities
|
||||
// and terminate the program since we cannot guaranty correct
|
||||
// test suite setup and tear-down in this case.
|
||||
ReportInvalidTestSuiteType(test_suite_name.c_str(), code_location);
|
||||
posix::Abort();
|
||||
} else {
|
||||
// At this point we are sure that the object we found is of the same
|
||||
// type we are looking for, so we downcast it to that type
|
||||
// without further checks.
|
||||
typed_test_info =
|
||||
CheckedDowncastToActualType<ParameterizedTestSuiteInfo<TestSuite>>(
|
||||
test_suite_info);
|
||||
}
|
||||
}
|
||||
if (typed_test_info == nullptr) {
|
||||
typed_test_info = new ParameterizedTestSuiteInfo<TestSuite>(
|
||||
test_suite_name, code_location);
|
||||
test_suite_name, std::move(code_location));
|
||||
suite_name_to_info_index_.emplace(std::move(test_suite_name),
|
||||
test_suite_infos_.size());
|
||||
test_suite_infos_.push_back(typed_test_info);
|
||||
}
|
||||
return typed_test_info;
|
||||
@ -735,8 +740,9 @@ class ParameterizedTestSuiteRegistry {
|
||||
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
template <class TestCase>
|
||||
ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
|
||||
const char* test_case_name, CodeLocation code_location) {
|
||||
return GetTestSuitePatternHolder<TestCase>(test_case_name, code_location);
|
||||
std::string test_case_name, CodeLocation code_location) {
|
||||
return GetTestSuitePatternHolder<TestCase>(std::move(test_case_name),
|
||||
std::move(code_location));
|
||||
}
|
||||
|
||||
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
@ -745,6 +751,7 @@ class ParameterizedTestSuiteRegistry {
|
||||
using TestSuiteInfoContainer = ::std::vector<ParameterizedTestSuiteInfoBase*>;
|
||||
|
||||
TestSuiteInfoContainer test_suite_infos_;
|
||||
::std::unordered_map<std::string, size_t> suite_name_to_info_index_;
|
||||
|
||||
ParameterizedTestSuiteRegistry(const ParameterizedTestSuiteRegistry&) =
|
||||
delete;
|
||||
@ -771,7 +778,7 @@ class TypeParameterizedTestSuiteRegistry {
|
||||
private:
|
||||
struct TypeParameterizedTestSuiteInfo {
|
||||
explicit TypeParameterizedTestSuiteInfo(CodeLocation c)
|
||||
: code_location(c), instantiated(false) {}
|
||||
: code_location(std::move(c)), instantiated(false) {}
|
||||
|
||||
CodeLocation code_location;
|
||||
bool instantiated;
|
||||
@ -791,10 +798,7 @@ internal::ParamGenerator<typename Container::value_type> ValuesIn(
|
||||
namespace internal {
|
||||
// Used in the Values() function to provide polymorphic capabilities.
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4100)
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)
|
||||
|
||||
template <typename... Ts>
|
||||
class ValueArray {
|
||||
@ -803,21 +807,19 @@ class ValueArray {
|
||||
|
||||
template <typename T>
|
||||
operator ParamGenerator<T>() const { // NOLINT
|
||||
return ValuesIn(MakeVector<T>(MakeIndexSequence<sizeof...(Ts)>()));
|
||||
return ValuesIn(MakeVector<T>(std::make_index_sequence<sizeof...(Ts)>()));
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename T, size_t... I>
|
||||
std::vector<T> MakeVector(IndexSequence<I...>) const {
|
||||
std::vector<T> MakeVector(std::index_sequence<I...>) const {
|
||||
return std::vector<T>{static_cast<T>(v_.template Get<I>())...};
|
||||
}
|
||||
|
||||
FlatTuple<Ts...> v_;
|
||||
};
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100
|
||||
|
||||
template <typename... T>
|
||||
class CartesianProductGenerator
|
||||
@ -827,7 +829,7 @@ class CartesianProductGenerator
|
||||
|
||||
CartesianProductGenerator(const std::tuple<ParamGenerator<T>...>& g)
|
||||
: generators_(g) {}
|
||||
~CartesianProductGenerator() override {}
|
||||
~CartesianProductGenerator() override = default;
|
||||
|
||||
ParamIteratorInterface<ParamType>* Begin() const override {
|
||||
return new Iterator(this, generators_, false);
|
||||
@ -840,7 +842,7 @@ class CartesianProductGenerator
|
||||
template <class I>
|
||||
class IteratorImpl;
|
||||
template <size_t... I>
|
||||
class IteratorImpl<IndexSequence<I...>>
|
||||
class IteratorImpl<std::index_sequence<I...>>
|
||||
: public ParamIteratorInterface<ParamType> {
|
||||
public:
|
||||
IteratorImpl(const ParamGeneratorInterface<ParamType>* base,
|
||||
@ -852,7 +854,7 @@ class CartesianProductGenerator
|
||||
current_(is_end ? end_ : begin_) {
|
||||
ComputeCurrentValue();
|
||||
}
|
||||
~IteratorImpl() override {}
|
||||
~IteratorImpl() override = default;
|
||||
|
||||
const ParamGeneratorInterface<ParamType>* BaseGenerator() const override {
|
||||
return base_;
|
||||
@ -931,7 +933,7 @@ class CartesianProductGenerator
|
||||
std::shared_ptr<ParamType> current_value_;
|
||||
};
|
||||
|
||||
using Iterator = IteratorImpl<typename MakeIndexSequence<sizeof...(T)>::type>;
|
||||
using Iterator = IteratorImpl<std::make_index_sequence<sizeof...(T)>>;
|
||||
|
||||
std::tuple<ParamGenerator<T>...> generators_;
|
||||
};
|
||||
@ -950,6 +952,78 @@ class CartesianProductHolder {
|
||||
std::tuple<Gen...> generators_;
|
||||
};
|
||||
|
||||
template <typename From, typename To>
|
||||
class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
|
||||
public:
|
||||
ParamGeneratorConverter(ParamGenerator<From> gen) // NOLINT
|
||||
: generator_(std::move(gen)) {}
|
||||
|
||||
ParamIteratorInterface<To>* Begin() const override {
|
||||
return new Iterator(this, generator_.begin(), generator_.end());
|
||||
}
|
||||
ParamIteratorInterface<To>* End() const override {
|
||||
return new Iterator(this, generator_.end(), generator_.end());
|
||||
}
|
||||
|
||||
private:
|
||||
class Iterator : public ParamIteratorInterface<To> {
|
||||
public:
|
||||
Iterator(const ParamGeneratorInterface<To>* base, ParamIterator<From> it,
|
||||
ParamIterator<From> end)
|
||||
: base_(base), it_(it), end_(end) {
|
||||
if (it_ != end_) value_ = std::make_shared<To>(static_cast<To>(*it_));
|
||||
}
|
||||
~Iterator() override = default;
|
||||
|
||||
const ParamGeneratorInterface<To>* BaseGenerator() const override {
|
||||
return base_;
|
||||
}
|
||||
void Advance() override {
|
||||
++it_;
|
||||
if (it_ != end_) value_ = std::make_shared<To>(static_cast<To>(*it_));
|
||||
}
|
||||
ParamIteratorInterface<To>* Clone() const override {
|
||||
return new Iterator(*this);
|
||||
}
|
||||
const To* Current() const override { return value_.get(); }
|
||||
bool Equals(const ParamIteratorInterface<To>& other) const override {
|
||||
// Having the same base generator guarantees that the other
|
||||
// iterator is of the same type and we can downcast.
|
||||
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
|
||||
<< "The program attempted to compare iterators "
|
||||
<< "from different generators." << std::endl;
|
||||
const ParamIterator<From> other_it =
|
||||
CheckedDowncastToActualType<const Iterator>(&other)->it_;
|
||||
return it_ == other_it;
|
||||
}
|
||||
|
||||
private:
|
||||
Iterator(const Iterator& other) = default;
|
||||
|
||||
const ParamGeneratorInterface<To>* const base_;
|
||||
ParamIterator<From> it_;
|
||||
ParamIterator<From> end_;
|
||||
std::shared_ptr<To> value_;
|
||||
}; // class ParamGeneratorConverter::Iterator
|
||||
|
||||
ParamGenerator<From> generator_;
|
||||
}; // class ParamGeneratorConverter
|
||||
|
||||
template <class Gen>
|
||||
class ParamConverterGenerator {
|
||||
public:
|
||||
ParamConverterGenerator(ParamGenerator<Gen> g) // NOLINT
|
||||
: generator_(std::move(g)) {}
|
||||
|
||||
template <typename T>
|
||||
operator ParamGenerator<T>() const { // NOLINT
|
||||
return ParamGenerator<T>(new ParamGeneratorConverter<Gen, T>(generator_));
|
||||
}
|
||||
|
||||
private:
|
||||
ParamGenerator<Gen> generator_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
|
@ -56,6 +56,8 @@
|
||||
#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE)
|
||||
#define GTEST_OS_WINDOWS_PHONE 1
|
||||
#define GTEST_OS_WINDOWS_TV_TITLE 1
|
||||
#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_GAMES)
|
||||
#define GTEST_OS_WINDOWS_GAMES 1
|
||||
#else
|
||||
// WINAPI_FAMILY defined but no known partition matched.
|
||||
// Default to desktop.
|
||||
@ -111,6 +113,12 @@
|
||||
#define GTEST_OS_ESP32 1
|
||||
#elif defined(__XTENSA__)
|
||||
#define GTEST_OS_XTENSA 1
|
||||
#elif defined(__hexagon__)
|
||||
#define GTEST_OS_QURT 1
|
||||
#elif defined(CPU_QN9090) || defined(CPU_QN9090HN)
|
||||
#define GTEST_OS_NXP_QN9090 1
|
||||
#elif defined(NRF52)
|
||||
#define GTEST_OS_NRF52 1
|
||||
#endif // __CYGWIN__
|
||||
|
||||
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -51,6 +51,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
@ -72,7 +73,7 @@ class GTEST_API_ String {
|
||||
// memory using malloc().
|
||||
static const char* CloneCString(const char* c_str);
|
||||
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
#ifdef GTEST_OS_WINDOWS_MOBILE
|
||||
// Windows CE does not have the 'ANSI' versions of Win32 APIs. To be
|
||||
// able to pass strings to Win32 APIs on CE we need to convert them
|
||||
// to 'Unicode', UTF-16.
|
||||
|
@ -37,6 +37,10 @@
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
|
||||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
// #ifdef __GNUC__ is too general here. It is possible to use gcc without using
|
||||
@ -63,6 +67,22 @@ inline std::string CanonicalizeForStdLibVersioning(std::string s) {
|
||||
s.erase(strlen("std"), end - strlen("std"));
|
||||
}
|
||||
}
|
||||
|
||||
// Strip redundant spaces in typename to match MSVC
|
||||
// For example, std::pair<int, bool> -> std::pair<int,bool>
|
||||
static const char to_search[] = ", ";
|
||||
static const char replace_str[] = ",";
|
||||
size_t pos = 0;
|
||||
while (true) {
|
||||
// Get the next occurrence from the current position
|
||||
pos = s.find(to_search, pos);
|
||||
if (pos == std::string::npos) {
|
||||
break;
|
||||
}
|
||||
// Replace this occurrence of substring
|
||||
s.replace(pos, strlen(to_search), replace_str);
|
||||
pos += strlen(replace_str);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -81,6 +101,20 @@ inline std::string GetTypeName(const std::type_info& type) {
|
||||
const std::string name_str(status == 0 ? readable_name : name);
|
||||
free(readable_name);
|
||||
return CanonicalizeForStdLibVersioning(name_str);
|
||||
#elif defined(_MSC_VER)
|
||||
// Strip struct and class due to differences between
|
||||
// MSVC and other compilers. std::pair<int,bool> is printed as
|
||||
// "struct std::pair<int,bool>" when using MSVC vs "std::pair<int, bool>" with
|
||||
// other compilers.
|
||||
std::string s = name;
|
||||
// Only strip the leading "struct " and "class ", so uses rfind == 0 to
|
||||
// ensure that
|
||||
if (s.rfind("struct ", 0) == 0) {
|
||||
s = s.substr(strlen("struct "));
|
||||
} else if (s.rfind("class ", 0) == 0) {
|
||||
s = s.substr(strlen("class "));
|
||||
}
|
||||
return s;
|
||||
#else
|
||||
return name;
|
||||
#endif // GTEST_HAS_CXXABI_H_ || __HP_aCC
|
||||
|
@ -39,7 +39,7 @@
|
||||
// The prime table interface.
|
||||
class PrimeTable {
|
||||
public:
|
||||
virtual ~PrimeTable() {}
|
||||
virtual ~PrimeTable() = default;
|
||||
|
||||
// Returns true if and only if n is a prime number.
|
||||
virtual bool IsPrime(int n) const = 0;
|
||||
@ -78,8 +78,9 @@ class PreCalculatedPrimeTable : public PrimeTable {
|
||||
public:
|
||||
// 'max' specifies the maximum number the prime table holds.
|
||||
explicit PreCalculatedPrimeTable(int max)
|
||||
: is_prime_size_(max + 1), is_prime_(new bool[max + 1]) {
|
||||
CalculatePrimesUpTo(max);
|
||||
: is_prime_size_(std::max(1, max + 1)),
|
||||
is_prime_(new bool[static_cast<size_t>(is_prime_size_)]) {
|
||||
CalculatePrimesUpTo(is_prime_size_ - 1);
|
||||
}
|
||||
~PreCalculatedPrimeTable() override { delete[] is_prime_; }
|
||||
|
||||
|
@ -38,7 +38,6 @@ using ::testing::InitGoogleTest;
|
||||
using ::testing::Test;
|
||||
using ::testing::TestEventListeners;
|
||||
using ::testing::TestInfo;
|
||||
using ::testing::TestPartResult;
|
||||
using ::testing::UnitTest;
|
||||
|
||||
namespace {
|
||||
|
@ -32,6 +32,8 @@
|
||||
// and each test is given one combination as a parameter.
|
||||
|
||||
// Use class definitions to test from this header.
|
||||
#include <tuple>
|
||||
|
||||
#include "prime_tables.h"
|
||||
#include "gtest/gtest.h"
|
||||
namespace {
|
||||
|
@ -40,7 +40,6 @@ using ::testing::Test;
|
||||
using ::testing::TestEventListeners;
|
||||
using ::testing::TestInfo;
|
||||
using ::testing::TestPartResult;
|
||||
using ::testing::TestSuite;
|
||||
using ::testing::UnitTest;
|
||||
namespace {
|
||||
// Provides alternative output mode which produces minimal amount of
|
||||
|
@ -44,7 +44,7 @@ namespace testing {
|
||||
// Used in EXPECT_TRUE/FALSE(assertion_result).
|
||||
AssertionResult::AssertionResult(const AssertionResult& other)
|
||||
: success_(other.success_),
|
||||
message_(other.message_.get() != nullptr
|
||||
message_(other.message_ != nullptr
|
||||
? new ::std::string(*other.message_)
|
||||
: static_cast< ::std::string*>(nullptr)) {}
|
||||
|
||||
@ -58,7 +58,7 @@ void AssertionResult::swap(AssertionResult& other) {
|
||||
// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
|
||||
AssertionResult AssertionResult::operator!() const {
|
||||
AssertionResult negation(!success_);
|
||||
if (message_.get() != nullptr) negation << *message_;
|
||||
if (message_ != nullptr) negation << *message_;
|
||||
return negation;
|
||||
}
|
||||
|
||||
|
@ -32,15 +32,21 @@
|
||||
|
||||
#include "gtest/gtest-death-test.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/internal/custom/gtest.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
#ifdef GTEST_HAS_DEATH_TEST
|
||||
|
||||
#if GTEST_OS_MAC
|
||||
#ifdef GTEST_OS_MAC
|
||||
#include <crt_externs.h>
|
||||
#endif // GTEST_OS_MAC
|
||||
|
||||
@ -48,24 +54,24 @@
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
|
||||
#if GTEST_OS_LINUX
|
||||
#ifdef GTEST_OS_LINUX
|
||||
#include <signal.h>
|
||||
#endif // GTEST_OS_LINUX
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/mman.h>
|
||||
#include <sys/wait.h>
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
#if GTEST_OS_QNX
|
||||
#ifdef GTEST_OS_QNX
|
||||
#include <spawn.h>
|
||||
#endif // GTEST_OS_QNX
|
||||
|
||||
#if GTEST_OS_FUCHSIA
|
||||
#ifdef GTEST_OS_FUCHSIA
|
||||
#include <lib/fdio/fd.h>
|
||||
#include <lib/fdio/io.h>
|
||||
#include <lib/fdio/spawn.h>
|
||||
@ -111,7 +117,7 @@ GTEST_DEFINE_string_(
|
||||
GTEST_DEFINE_bool_(
|
||||
death_test_use_fork,
|
||||
testing::internal::BoolFromGTestEnv("death_test_use_fork", false),
|
||||
"Instructs to use fork()/_exit() instead of clone() in death tests. "
|
||||
"Instructs to use fork()/_Exit() instead of clone() in death tests. "
|
||||
"Ignored and always uses fork() on POSIX systems where clone() is not "
|
||||
"implemented. Useful when running under valgrind or similar tools if "
|
||||
"those do not support clone(). Valgrind 3.3.1 will just fail if "
|
||||
@ -131,13 +137,13 @@ GTEST_DEFINE_string_(
|
||||
|
||||
namespace testing {
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
#ifdef GTEST_HAS_DEATH_TEST
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Valid only for fast death tests. Indicates the code is running in the
|
||||
// child process of a fast style death test.
|
||||
#if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
|
||||
#if !defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_FUCHSIA)
|
||||
static bool g_in_fast_death_test_child = false;
|
||||
#endif
|
||||
|
||||
@ -147,7 +153,7 @@ static bool g_in_fast_death_test_child = false;
|
||||
// tests. IMPORTANT: This is an internal utility. Using it may break the
|
||||
// implementation of death tests. User code MUST NOT use it.
|
||||
bool InDeathTestChild() {
|
||||
#if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
|
||||
#if defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_FUCHSIA)
|
||||
|
||||
// On Windows and Fuchsia, death tests are thread-safe regardless of the value
|
||||
// of the death_test_style flag.
|
||||
@ -169,7 +175,7 @@ ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) {}
|
||||
|
||||
// ExitedWithCode function-call operator.
|
||||
bool ExitedWithCode::operator()(int exit_status) const {
|
||||
#if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
|
||||
#if defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_FUCHSIA)
|
||||
|
||||
return exit_status == exit_code_;
|
||||
|
||||
@ -180,7 +186,7 @@ bool ExitedWithCode::operator()(int exit_status) const {
|
||||
#endif // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
|
||||
}
|
||||
|
||||
#if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
|
||||
#if !defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_FUCHSIA)
|
||||
// KilledBySignal constructor.
|
||||
KilledBySignal::KilledBySignal(int signum) : signum_(signum) {}
|
||||
|
||||
@ -207,7 +213,7 @@ namespace internal {
|
||||
static std::string ExitSummary(int exit_code) {
|
||||
Message m;
|
||||
|
||||
#if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
|
||||
#if defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_FUCHSIA)
|
||||
|
||||
m << "Exited with exit status " << exit_code;
|
||||
|
||||
@ -234,7 +240,7 @@ bool ExitedUnsuccessfully(int exit_status) {
|
||||
return !ExitedWithCode(0)(exit_status);
|
||||
}
|
||||
|
||||
#if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
|
||||
#if !defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_FUCHSIA)
|
||||
// Generates a textual failure message when a death test finds more than
|
||||
// one thread running, or cannot determine the number of threads, prior
|
||||
// to executing the given statement. It is the responsibility of the
|
||||
@ -263,7 +269,7 @@ static const char kDeathTestReturned = 'R';
|
||||
static const char kDeathTestThrew = 'T';
|
||||
static const char kDeathTestInternalError = 'I';
|
||||
|
||||
#if GTEST_OS_FUCHSIA
|
||||
#ifdef GTEST_OS_FUCHSIA
|
||||
|
||||
// File descriptor used for the pipe in the child process.
|
||||
static const int kFuchsiaReadPipeFd = 3;
|
||||
@ -295,7 +301,7 @@ enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW };
|
||||
fputc(kDeathTestInternalError, parent);
|
||||
fprintf(parent, "%s", message.c_str());
|
||||
fflush(parent);
|
||||
_exit(1);
|
||||
_Exit(1);
|
||||
} else {
|
||||
fprintf(stderr, "%s", message.c_str());
|
||||
fflush(stderr);
|
||||
@ -507,7 +513,7 @@ std::string DeathTestImpl::GetErrorLogs() { return GetCapturedStderr(); }
|
||||
// Signals that the death test code which should have exited, didn't.
|
||||
// Should be called only in a death test child process.
|
||||
// Writes a status byte to the child's status file descriptor, then
|
||||
// calls _exit(1).
|
||||
// calls _Exit(1).
|
||||
void DeathTestImpl::Abort(AbortReason reason) {
|
||||
// The parent process considers the death test to be a failure if
|
||||
// it finds any data in our pipe. So, here we write a single flag byte
|
||||
@ -519,13 +525,13 @@ void DeathTestImpl::Abort(AbortReason reason) {
|
||||
GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1));
|
||||
// We are leaking the descriptor here because on some platforms (i.e.,
|
||||
// when built as Windows DLL), destructors of global objects will still
|
||||
// run after calling _exit(). On such systems, write_fd_ will be
|
||||
// run after calling _Exit(). On such systems, write_fd_ will be
|
||||
// indirectly closed from the destructor of UnitTestImpl, causing double
|
||||
// close if it is also closed here. On debug configurations, double close
|
||||
// may assert. As there are no in-process buffers to flush here, we are
|
||||
// relying on the OS to close the descriptor after the process terminates
|
||||
// when the destructors are not run.
|
||||
_exit(1); // Exits w/o any normal exit hooks (we were supposed to crash)
|
||||
_Exit(1); // Exits w/o any normal exit hooks (we were supposed to crash)
|
||||
}
|
||||
|
||||
// Returns an indented copy of stderr output for a death test.
|
||||
@ -621,7 +627,21 @@ bool DeathTestImpl::Passed(bool status_ok) {
|
||||
return success;
|
||||
}
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
#ifndef GTEST_OS_WINDOWS
|
||||
// Note: The return value points into args, so the return value's lifetime is
|
||||
// bound to that of args.
|
||||
static std::vector<char*> CreateArgvFromArgs(std::vector<std::string>& args) {
|
||||
std::vector<char*> result;
|
||||
result.reserve(args.size() + 1);
|
||||
for (auto& arg : args) {
|
||||
result.push_back(&arg[0]);
|
||||
}
|
||||
result.push_back(nullptr); // Extra null terminator.
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
// WindowsDeathTest implements death tests on Windows. Due to the
|
||||
// specifics of starting new processes on Windows, death tests there are
|
||||
// always threadsafe, and Google Test considers the
|
||||
@ -765,7 +785,7 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
|
||||
StreamableToString(static_cast<unsigned int>(::GetCurrentProcessId())) +
|
||||
// size_t has the same width as pointers on both 32-bit and 64-bit
|
||||
// Windows platforms.
|
||||
// See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx.
|
||||
// See https://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx.
|
||||
"|" + StreamableToString(reinterpret_cast<size_t>(write_handle)) + "|" +
|
||||
StreamableToString(reinterpret_cast<size_t>(event_handle_.Get()));
|
||||
|
||||
@ -808,7 +828,7 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
|
||||
return OVERSEE_TEST;
|
||||
}
|
||||
|
||||
#elif GTEST_OS_FUCHSIA
|
||||
#elif defined(GTEST_OS_FUCHSIA)
|
||||
|
||||
class FuchsiaDeathTest : public DeathTestImpl {
|
||||
public:
|
||||
@ -836,36 +856,6 @@ class FuchsiaDeathTest : public DeathTestImpl {
|
||||
zx::socket stderr_socket_;
|
||||
};
|
||||
|
||||
// Utility class for accumulating command-line arguments.
|
||||
class Arguments {
|
||||
public:
|
||||
Arguments() { args_.push_back(nullptr); }
|
||||
|
||||
~Arguments() {
|
||||
for (std::vector<char*>::iterator i = args_.begin(); i != args_.end();
|
||||
++i) {
|
||||
free(*i);
|
||||
}
|
||||
}
|
||||
void AddArgument(const char* argument) {
|
||||
args_.insert(args_.end() - 1, posix::StrDup(argument));
|
||||
}
|
||||
|
||||
template <typename Str>
|
||||
void AddArguments(const ::std::vector<Str>& arguments) {
|
||||
for (typename ::std::vector<Str>::const_iterator i = arguments.begin();
|
||||
i != arguments.end(); ++i) {
|
||||
args_.insert(args_.end() - 1, posix::StrDup(i->c_str()));
|
||||
}
|
||||
}
|
||||
char* const* Argv() { return &args_[0]; }
|
||||
|
||||
int size() { return static_cast<int>(args_.size()) - 1; }
|
||||
|
||||
private:
|
||||
std::vector<char*> args_;
|
||||
};
|
||||
|
||||
// Waits for the child in a death test to exit, returning its exit
|
||||
// status, or 0 if no child process exists. As a side effect, sets the
|
||||
// outcome data member.
|
||||
@ -986,10 +976,10 @@ DeathTest::TestRole FuchsiaDeathTest::AssumeRole() {
|
||||
kInternalRunDeathTestFlag + "=" + file_ +
|
||||
"|" + StreamableToString(line_) + "|" +
|
||||
StreamableToString(death_test_index);
|
||||
Arguments args;
|
||||
args.AddArguments(GetInjectableArgvs());
|
||||
args.AddArgument(filter_flag.c_str());
|
||||
args.AddArgument(internal_flag.c_str());
|
||||
|
||||
std::vector<std::string> args = GetInjectableArgvs();
|
||||
args.push_back(filter_flag);
|
||||
args.push_back(internal_flag);
|
||||
|
||||
// Build the pipe for communication with the child.
|
||||
zx_status_t status;
|
||||
@ -1041,8 +1031,14 @@ DeathTest::TestRole FuchsiaDeathTest::AssumeRole() {
|
||||
GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
|
||||
|
||||
// Spawn the child process.
|
||||
status = fdio_spawn_etc(child_job, FDIO_SPAWN_CLONE_ALL, args.Argv()[0],
|
||||
args.Argv(), nullptr, 2, spawn_actions,
|
||||
// Note: The test component must have `fuchsia.process.Launcher` declared
|
||||
// in its manifest. (Fuchsia integration tests require creating a
|
||||
// "Fuchsia Test Component" which contains a "Fuchsia Component Manifest")
|
||||
// Launching processes is a privileged operation in Fuchsia, and the
|
||||
// declaration indicates that the ability is required for the component.
|
||||
std::vector<char*> argv = CreateArgvFromArgs(args);
|
||||
status = fdio_spawn_etc(child_job, FDIO_SPAWN_CLONE_ALL, argv[0], argv.data(),
|
||||
nullptr, 2, spawn_actions,
|
||||
child_process_.reset_and_get_address(), nullptr);
|
||||
GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
|
||||
|
||||
@ -1134,7 +1130,7 @@ DeathTest::TestRole NoExecDeathTest::AssumeRole() {
|
||||
LogToStderr();
|
||||
// Event forwarding to the listeners of event listener API mush be shut
|
||||
// down in death test subprocesses.
|
||||
GetUnitTestImpl()->listeners()->SuppressEventForwarding();
|
||||
GetUnitTestImpl()->listeners()->SuppressEventForwarding(true);
|
||||
g_in_fast_death_test_child = true;
|
||||
return EXECUTE_TEST;
|
||||
} else {
|
||||
@ -1173,34 +1169,6 @@ class ExecDeathTest : public ForkingDeathTest {
|
||||
const int line_;
|
||||
};
|
||||
|
||||
// Utility class for accumulating command-line arguments.
|
||||
class Arguments {
|
||||
public:
|
||||
Arguments() { args_.push_back(nullptr); }
|
||||
|
||||
~Arguments() {
|
||||
for (std::vector<char*>::iterator i = args_.begin(); i != args_.end();
|
||||
++i) {
|
||||
free(*i);
|
||||
}
|
||||
}
|
||||
void AddArgument(const char* argument) {
|
||||
args_.insert(args_.end() - 1, posix::StrDup(argument));
|
||||
}
|
||||
|
||||
template <typename Str>
|
||||
void AddArguments(const ::std::vector<Str>& arguments) {
|
||||
for (typename ::std::vector<Str>::const_iterator i = arguments.begin();
|
||||
i != arguments.end(); ++i) {
|
||||
args_.insert(args_.end() - 1, posix::StrDup(i->c_str()));
|
||||
}
|
||||
}
|
||||
char* const* Argv() { return &args_[0]; }
|
||||
|
||||
private:
|
||||
std::vector<char*> args_;
|
||||
};
|
||||
|
||||
// A struct that encompasses the arguments to the child process of a
|
||||
// threadsafe-style death test process.
|
||||
struct ExecDeathTestArgs {
|
||||
@ -1208,7 +1176,7 @@ struct ExecDeathTestArgs {
|
||||
int close_fd; // File descriptor to close; the read end of a pipe
|
||||
};
|
||||
|
||||
#if GTEST_OS_QNX
|
||||
#ifdef GTEST_OS_QNX
|
||||
extern "C" char** environ;
|
||||
#else // GTEST_OS_QNX
|
||||
// The main function for a threadsafe-style death test child process.
|
||||
@ -1289,7 +1257,7 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
|
||||
ExecDeathTestArgs args = {argv, close_fd};
|
||||
pid_t child_pid = -1;
|
||||
|
||||
#if GTEST_OS_QNX
|
||||
#ifdef GTEST_OS_QNX
|
||||
// Obtains the current directory and sets it to be closed in the child
|
||||
// process.
|
||||
const int cwd_fd = open(".", O_RDONLY);
|
||||
@ -1320,7 +1288,7 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
|
||||
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd));
|
||||
|
||||
#else // GTEST_OS_QNX
|
||||
#if GTEST_OS_LINUX
|
||||
#ifdef GTEST_OS_LINUX
|
||||
// When a SIGPROF signal is received while fork() or clone() are executing,
|
||||
// the process may hang. To avoid this, we ignore SIGPROF here and re-enable
|
||||
// it after the call to fork()/clone() is complete.
|
||||
@ -1367,11 +1335,10 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
|
||||
#endif // GTEST_HAS_CLONE
|
||||
|
||||
if (use_fork && (child_pid = fork()) == 0) {
|
||||
ExecDeathTestChildMain(&args);
|
||||
_exit(0);
|
||||
_Exit(ExecDeathTestChildMain(&args));
|
||||
}
|
||||
#endif // GTEST_OS_QNX
|
||||
#if GTEST_OS_LINUX
|
||||
#ifdef GTEST_OS_LINUX
|
||||
GTEST_DEATH_TEST_CHECK_SYSCALL_(
|
||||
sigaction(SIGPROF, &saved_sigprof_action, nullptr));
|
||||
#endif // GTEST_OS_LINUX
|
||||
@ -1410,10 +1377,9 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() {
|
||||
StreamableToString(line_) + "|" +
|
||||
StreamableToString(death_test_index) + "|" +
|
||||
StreamableToString(pipe_fd[1]);
|
||||
Arguments args;
|
||||
args.AddArguments(GetArgvsForDeathTestChildProcess());
|
||||
args.AddArgument(filter_flag.c_str());
|
||||
args.AddArgument(internal_flag.c_str());
|
||||
std::vector<std::string> args = GetArgvsForDeathTestChildProcess();
|
||||
args.push_back(filter_flag);
|
||||
args.push_back(internal_flag);
|
||||
|
||||
DeathTest::set_last_death_test_message("");
|
||||
|
||||
@ -1422,7 +1388,8 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() {
|
||||
// is necessary.
|
||||
FlushInfoLog();
|
||||
|
||||
const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]);
|
||||
std::vector<char*> argv = CreateArgvFromArgs(args);
|
||||
const pid_t child_pid = ExecDeathTestSpawnChild(argv.data(), pipe_fd[0]);
|
||||
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
|
||||
set_child_pid(child_pid);
|
||||
set_read_fd(pipe_fd[0]);
|
||||
@ -1463,14 +1430,14 @@ bool DefaultDeathTestFactory::Create(const char* statement,
|
||||
}
|
||||
}
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
|
||||
if (GTEST_FLAG_GET(death_test_style) == "threadsafe" ||
|
||||
GTEST_FLAG_GET(death_test_style) == "fast") {
|
||||
*test = new WindowsDeathTest(statement, std::move(matcher), file, line);
|
||||
}
|
||||
|
||||
#elif GTEST_OS_FUCHSIA
|
||||
#elif defined(GTEST_OS_FUCHSIA)
|
||||
|
||||
if (GTEST_FLAG_GET(death_test_style) == "threadsafe" ||
|
||||
GTEST_FLAG_GET(death_test_style) == "fast") {
|
||||
@ -1497,7 +1464,7 @@ bool DefaultDeathTestFactory::Create(const char* statement,
|
||||
return true;
|
||||
}
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
// Recreates the pipe and event handles from the provided parameters,
|
||||
// signals the event, and returns a file descriptor wrapped around the pipe
|
||||
// handle. This function is called in the child process only.
|
||||
@ -1564,7 +1531,7 @@ static int GetStatusFileDescriptor(unsigned int parent_process_id,
|
||||
// initialized from the GTEST_FLAG(internal_run_death_test) flag if
|
||||
// the flag is specified; otherwise returns NULL.
|
||||
InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
|
||||
if (GTEST_FLAG_GET(internal_run_death_test) == "") return nullptr;
|
||||
if (GTEST_FLAG_GET(internal_run_death_test).empty()) return nullptr;
|
||||
|
||||
// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we
|
||||
// can use it here.
|
||||
@ -1574,7 +1541,7 @@ InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
|
||||
SplitString(GTEST_FLAG_GET(internal_run_death_test), '|', &fields);
|
||||
int write_fd = -1;
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
|
||||
unsigned int parent_process_id = 0;
|
||||
size_t write_handle_as_size_t = 0;
|
||||
@ -1591,7 +1558,7 @@ InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
|
||||
write_fd = GetStatusFileDescriptor(parent_process_id, write_handle_as_size_t,
|
||||
event_handle_as_size_t);
|
||||
|
||||
#elif GTEST_OS_FUCHSIA
|
||||
#elif defined(GTEST_OS_FUCHSIA)
|
||||
|
||||
if (fields.size() != 3 || !ParseNaturalNumber(fields[1], &line) ||
|
||||
!ParseNaturalNumber(fields[2], &index)) {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user