Compare commits
152
Commits
v1.12.0-pre
...
v1.13.x
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b796f7d446 | ||
|
|
ac7a126f39 | ||
|
|
356fc30125 | ||
|
|
b5401fef68 | ||
|
|
a652ae0575 | ||
|
|
9345421658 | ||
|
|
e5e46b09a1 | ||
|
|
0296d7d370 | ||
|
|
3a99ab6d83 | ||
|
|
71140c3ca7 | ||
|
|
5ab508a01f | ||
|
|
b3bfebd796 | ||
|
|
a4e0be898b | ||
|
|
3fa7f983c6 | ||
|
|
41fe6be7d7 | ||
|
|
e38ef3be88 | ||
|
|
ad54e90f57 | ||
|
|
b0846aaf37 | ||
|
|
516940f16d | ||
|
|
d454936a0c | ||
|
|
97459e54ec | ||
|
|
1f643f71d4 | ||
|
|
a16bfcfda1 | ||
|
|
e68764c147 | ||
|
|
519beb0e52 | ||
|
|
834698cc9b | ||
|
|
9c332145b7 | ||
|
|
4408a0288b | ||
|
|
0e6aac2571 | ||
|
|
42c6f57f3c | ||
|
|
148ab827ca | ||
|
|
9c990a7b1e | ||
|
|
912db74253 | ||
|
|
4b7f9453c5 | ||
|
|
44c03643cf | ||
|
|
6b63c98ac4 | ||
|
|
386c7665f5 | ||
|
|
a4f02ef389 | ||
|
|
66366cea56 | ||
|
|
3026483ae5 | ||
|
|
90171d1061 | ||
|
|
03597a01ee | ||
|
|
09e1c64f86 | ||
|
|
0d26378919 | ||
|
|
f3eb2b7e38 | ||
|
|
e07617d6c6 | ||
|
|
6bad847991 | ||
|
|
f372c76026 | ||
|
|
26d3ab5442 | ||
|
|
6d71d901e1 | ||
|
|
88c59752c0 | ||
|
|
6f149520a1 | ||
|
|
a9b2f0495c | ||
|
|
137b6e2770 | ||
|
|
a41c3d0fb8 | ||
|
|
67174c7675 | ||
|
|
d29b143bda | ||
|
|
1d505b8e40 | ||
|
|
d9bb8412d6 | ||
|
|
671cfb7dbf | ||
|
|
0231584a60 | ||
|
|
9fbb657503 | ||
|
|
67e264834a | ||
|
|
08935483cb | ||
|
|
4052e05c29 | ||
|
|
8c4dc11539 | ||
|
|
93f08be653 | ||
|
|
79d0399dba | ||
|
|
d1a0039b97 | ||
|
|
19387c9dd5 | ||
|
|
c43b916a96 | ||
|
|
4924e0610a | ||
|
|
24683e2d6a | ||
|
|
e23cdb78e9 | ||
|
|
dfa6735236 | ||
|
|
9836817d82 | ||
|
|
83bd792e36 | ||
|
|
7a3abfec0a | ||
|
|
173dd7c7d6 | ||
|
|
63907e1bfe | ||
|
|
05cc575c65 | ||
|
|
56070d8903 | ||
|
|
1336c4b6d1 | ||
|
|
7cafeff7bd | ||
|
|
4fa8cfe3f4 | ||
|
|
c29315dda4 | ||
|
|
0f6885405c | ||
|
|
0e0d9feefa | ||
|
|
9080381758 | ||
|
|
afd902e992 | ||
|
|
dd969ed5fe | ||
|
|
25cc5777a1 | ||
|
|
91c3669f21 | ||
|
|
c0e032efe5 | ||
|
|
7274ec1864 | ||
|
|
4c9a3bb62b | ||
|
|
5b909beeec | ||
|
|
6045bf2ade | ||
|
|
fa3f444be1 | ||
|
|
3280a930bf | ||
|
|
dd7a9d29a3 | ||
|
|
3bc8fb3723 | ||
|
|
b1e9b6323a | ||
|
|
aa2e91fd69 | ||
|
|
61720589cb | ||
|
|
7735334a46 | ||
|
|
43a6712a0c | ||
|
|
71feea653b | ||
|
|
91480a4e79 | ||
|
|
760acf30e3 | ||
|
|
2d1cd6ee27 | ||
|
|
3655149a60 | ||
|
|
a2d6ee847e | ||
|
|
96ddde1235 | ||
|
|
bea621c3c3 | ||
|
|
78aa2ba440 | ||
|
|
4086e92d86 | ||
|
|
2e1346de56 | ||
|
|
8f01400b77 | ||
|
|
4556086674 | ||
|
|
e009c3d3dc | ||
|
|
7107c44188 | ||
|
|
4219e7254c | ||
|
|
644a4bea02 | ||
|
|
6c57d607c7 | ||
|
|
2cf9987ce3 | ||
|
|
96f51426e4 | ||
|
|
219af0d535 | ||
|
|
d9335595b4 | ||
|
|
9406a60c78 | ||
|
|
cdbed602b9 | ||
|
|
dd72ed19fe | ||
|
|
d0af91ead3 | ||
|
|
1547c2acc8 | ||
|
|
66d2463610 | ||
|
|
64df55449a | ||
|
|
dfa990f942 | ||
|
|
df4b8edee0 | ||
|
|
5eaa113903 | ||
|
|
72901486ba | ||
|
|
b9d2e1f62f | ||
|
|
5376968f69 | ||
|
|
fde6af6790 | ||
|
|
b59ae848d1 | ||
|
|
f2f099fb70 | ||
|
|
1b772a9bc4 | ||
|
|
358a3f6e3e | ||
|
|
b3f3819a62 | ||
|
|
3d1dcac4c4 | ||
|
|
a86777edf9 | ||
|
|
6f3f9a9e61 | ||
|
|
7da4a4114a |
@@ -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.
|
|
||||||
@@ -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
|
||||||
@@ -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.
|
|
||||||
|
|
||||||
@@ -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
|
||||||
@@ -1 +1,5 @@
|
|||||||
blank_issues_enabled: false
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: Get Help
|
||||||
|
url: https://github.com/google/googletest/discussions
|
||||||
|
about: Please ask and answer questions here.
|
||||||
|
|||||||
@@ -4,37 +4,40 @@ on:
|
|||||||
push:
|
push:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|
||||||
|
env:
|
||||||
|
BAZEL_CXXOPTS: -std=c++14
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Linux:
|
Linux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Tests
|
- name: Tests
|
||||||
run: bazel test --test_output=errors //...
|
run: bazel test --cxxopt=-std=c++14 --features=external_include_paths --test_output=errors ...
|
||||||
|
|
||||||
MacOs:
|
macOS:
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Tests
|
- name: Tests
|
||||||
run: bazel test --test_output=errors //...
|
run: bazel test --cxxopt=-std=c++14 --features=external_include_paths --test_output=errors ...
|
||||||
|
|
||||||
|
|
||||||
Windows:
|
Windows:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Tests
|
- name: Tests
|
||||||
run: bazel test --test_output=errors //...
|
run: bazel test --cxxopt=/std:c++14 --features=external_include_paths --test_output=errors ...
|
||||||
|
|||||||
+6
-1
@@ -7,12 +7,16 @@ if (POLICY CMP0048)
|
|||||||
cmake_policy(SET CMP0048 NEW)
|
cmake_policy(SET CMP0048 NEW)
|
||||||
endif (POLICY CMP0048)
|
endif (POLICY CMP0048)
|
||||||
|
|
||||||
|
if (POLICY CMP0069)
|
||||||
|
cmake_policy(SET CMP0069 NEW)
|
||||||
|
endif (POLICY CMP0069)
|
||||||
|
|
||||||
if (POLICY CMP0077)
|
if (POLICY CMP0077)
|
||||||
cmake_policy(SET CMP0077 NEW)
|
cmake_policy(SET CMP0077 NEW)
|
||||||
endif (POLICY CMP0077)
|
endif (POLICY CMP0077)
|
||||||
|
|
||||||
project(googletest-distribution)
|
project(googletest-distribution)
|
||||||
set(GOOGLETEST_VERSION 1.11.0)
|
set(GOOGLETEST_VERSION 1.13.0)
|
||||||
|
|
||||||
if(NOT CYGWIN AND NOT MSYS AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL QNX)
|
if(NOT CYGWIN AND NOT MSYS AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL QNX)
|
||||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
@@ -26,6 +30,7 @@ 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(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(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(BUILD_GMOCK)
|
if(BUILD_GMOCK)
|
||||||
add_subdirectory( googlemock )
|
add_subdirectory( googlemock )
|
||||||
|
|||||||
+2
-2
@@ -80,8 +80,8 @@ fairly rigid coding style, as defined by the
|
|||||||
[google-styleguide](https://github.com/google/styleguide) project. All patches
|
[google-styleguide](https://github.com/google/styleguide) project. All patches
|
||||||
will be expected to conform to the style outlined
|
will be expected to conform to the style outlined
|
||||||
[here](https://google.github.io/styleguide/cppguide.html). Use
|
[here](https://google.github.io/styleguide/cppguide.html). Use
|
||||||
[.clang-format](https://github.com/google/googletest/blob/master/.clang-format)
|
[.clang-format](https://github.com/google/googletest/blob/main/.clang-format) to
|
||||||
to check your formatting.
|
check your formatting.
|
||||||
|
|
||||||
## Requirements for Contributors
|
## Requirements for Contributors
|
||||||
|
|
||||||
|
|||||||
@@ -15,11 +15,14 @@ Our documentation is now live on GitHub Pages at
|
|||||||
https://google.github.io/googletest/. We recommend browsing the documentation on
|
https://google.github.io/googletest/. We recommend browsing the documentation on
|
||||||
GitHub Pages rather than directly in the repository.
|
GitHub Pages rather than directly in the repository.
|
||||||
|
|
||||||
#### Release 1.11.0
|
#### Release 1.12.1
|
||||||
|
|
||||||
[Release 1.11.0](https://github.com/google/googletest/releases/tag/release-1.11.0)
|
[Release 1.12.1](https://github.com/google/googletest/releases/tag/release-1.12.1)
|
||||||
is now available.
|
is now available.
|
||||||
|
|
||||||
|
The 1.12.x branch will be the last to support C++11. Future releases will
|
||||||
|
require at least C++14.
|
||||||
|
|
||||||
#### Coming Soon
|
#### Coming Soon
|
||||||
|
|
||||||
* We are planning to take a dependency on
|
* We are planning to take a dependency on
|
||||||
@@ -56,39 +59,12 @@ More information about building GoogleTest can be found at
|
|||||||
|
|
||||||
## Supported Platforms
|
## Supported Platforms
|
||||||
|
|
||||||
GoogleTest requires a codebase and compiler compliant with the C++11 standard or
|
GoogleTest follows Google's
|
||||||
newer.
|
[Foundational C++ Support Policy](https://opensource.google/documentation/policies/cplusplus-support).
|
||||||
|
See
|
||||||
The GoogleTest code is officially supported on the following platforms.
|
[this table](https://github.com/google/oss-policies-info/blob/main/foundational-cxx-support-matrix.md)
|
||||||
Operating systems or tools not listed below are community-supported. For
|
for a list of currently supported versions compilers, platforms, and build
|
||||||
community-supported platforms, patches that do not complicate the code may be
|
tools.
|
||||||
considered.
|
|
||||||
|
|
||||||
If you notice any problems on your platform, please file an issue on the
|
|
||||||
[GoogleTest GitHub Issue Tracker](https://github.com/google/googletest/issues).
|
|
||||||
Pull requests containing fixes are welcome!
|
|
||||||
|
|
||||||
### Operating Systems
|
|
||||||
|
|
||||||
* Linux
|
|
||||||
* macOS
|
|
||||||
* Windows
|
|
||||||
|
|
||||||
### Compilers
|
|
||||||
|
|
||||||
* gcc 5.0+
|
|
||||||
* clang 5.0+
|
|
||||||
* MSVC 2015+
|
|
||||||
|
|
||||||
**macOS users:** Xcode 9.3+ provides clang 5.0+.
|
|
||||||
|
|
||||||
### Build Systems
|
|
||||||
|
|
||||||
* [Bazel](https://bazel.build/)
|
|
||||||
* [CMake](https://cmake.org/)
|
|
||||||
|
|
||||||
**Note:** Bazel is the build system used by the team internally and in tests.
|
|
||||||
CMake is supported on a best-effort basis and by the community.
|
|
||||||
|
|
||||||
## Who Is Using GoogleTest?
|
## Who Is Using GoogleTest?
|
||||||
|
|
||||||
@@ -135,7 +111,7 @@ that generates stub code for GoogleTest.
|
|||||||
## Contributing Changes
|
## Contributing Changes
|
||||||
|
|
||||||
Please read
|
Please read
|
||||||
[`CONTRIBUTING.md`](https://github.com/google/googletest/blob/master/CONTRIBUTING.md)
|
[`CONTRIBUTING.md`](https://github.com/google/googletest/blob/main/CONTRIBUTING.md)
|
||||||
for details on how to contribute to this project.
|
for details on how to contribute to this project.
|
||||||
|
|
||||||
Happy testing!
|
Happy testing!
|
||||||
|
|||||||
@@ -3,37 +3,38 @@ workspace(name = "com_google_googletest")
|
|||||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||||
|
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "com_google_absl",
|
name = "com_google_absl", # 2023-01-10T21:08:25Z
|
||||||
sha256 = "1a1745b5ee81392f5ea4371a4ca41e55d446eeaee122903b2eaffbd8a3b67a2b",
|
sha256 = "f9a4e749f42c386a32a90fddf0e2913ed408d10c42f7f33ccf4c59ac4f0d1d05",
|
||||||
strip_prefix = "abseil-cpp-01cc6567cff77738e416a7ddc17de2d435a780ce",
|
strip_prefix = "abseil-cpp-52835439ca90d86b27bf8cd1708296e95604d724",
|
||||||
urls = ["https://github.com/abseil/abseil-cpp/archive/01cc6567cff77738e416a7ddc17de2d435a780ce.zip"], # 2022-06-21T19:28:27Z
|
urls = ["https://github.com/abseil/abseil-cpp/archive/52835439ca90d86b27bf8cd1708296e95604d724.zip"],
|
||||||
)
|
)
|
||||||
|
|
||||||
# Note this must use a commit from the `abseil` branch of the RE2 project.
|
# Note this must use a commit from the `abseil` branch of the RE2 project.
|
||||||
# https://github.com/google/re2/tree/abseil
|
# https://github.com/google/re2/tree/abseil
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "com_googlesource_code_re2",
|
name = "com_googlesource_code_re2", # 2022-12-21T14:29:10Z
|
||||||
sha256 = "0a890c2aa0bb05b2ce906a15efb520d0f5ad4c7d37b8db959c43772802991887",
|
sha256 = "b9ce3a51beebb38534d11d40f8928d40509b9e18a735f6a4a97ad3d014c87cb5",
|
||||||
strip_prefix = "re2-a427f10b9fb4622dd6d8643032600aa1b50fbd12",
|
strip_prefix = "re2-d0b1f8f2ecc2ea74956c7608b6f915175314ff0e",
|
||||||
urls = ["https://github.com/google/re2/archive/a427f10b9fb4622dd6d8643032600aa1b50fbd12.zip"], # 2022-06-09
|
urls = ["https://github.com/google/re2/archive/d0b1f8f2ecc2ea74956c7608b6f915175314ff0e.zip"],
|
||||||
)
|
)
|
||||||
|
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "rules_python",
|
name = "rules_python", # 2023-01-10T22:00:51Z
|
||||||
sha256 = "0b460f17771258341528753b1679335b629d1d25e3af28eda47d009c103a6e15",
|
sha256 = "5de54486a60ad8948dabe49605bb1c08053e04001a431ab3e96745b4d97a4419",
|
||||||
strip_prefix = "rules_python-aef17ad72919d184e5edb7abf61509eb78e57eda",
|
strip_prefix = "rules_python-70cce26432187a60b4e950118791385e6fb3c26f",
|
||||||
urls = ["https://github.com/bazelbuild/rules_python/archive/aef17ad72919d184e5edb7abf61509eb78e57eda.zip"], # 2022-06-21T23:44:47Z
|
urls = ["https://github.com/bazelbuild/rules_python/archive/70cce26432187a60b4e950118791385e6fb3c26f.zip"],
|
||||||
)
|
)
|
||||||
|
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "bazel_skylib",
|
name = "bazel_skylib", # 2022-11-16T18:29:32Z
|
||||||
urls = ["https://github.com/bazelbuild/bazel-skylib/releases/download/1.2.1/bazel-skylib-1.2.1.tar.gz"],
|
sha256 = "a22290c26d29d3ecca286466f7f295ac6cbe32c0a9da3a91176a90e0725e3649",
|
||||||
sha256 = "f7be3474d42aae265405a592bb7da8e171919d74c16f082a5457840f06054728",
|
strip_prefix = "bazel-skylib-5bfcb1a684550626ce138fe0fe8f5f702b3764c3",
|
||||||
|
urls = ["https://github.com/bazelbuild/bazel-skylib/archive/5bfcb1a684550626ce138fe0fe8f5f702b3764c3.zip"],
|
||||||
)
|
)
|
||||||
|
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "platforms",
|
name = "platforms", # 2022-11-09T19:18:22Z
|
||||||
sha256 = "a879ea428c6d56ab0ec18224f976515948822451473a80d06c2e50af0bbe5121",
|
sha256 = "b4a3b45dc4202e2b3e34e3bc49d2b5b37295fc23ea58d88fb9e01f3642ad9b55",
|
||||||
strip_prefix = "platforms-da5541f26b7de1dc8e04c075c99df5351742a4a2",
|
strip_prefix = "platforms-3fbc687756043fb58a407c2ea8c944bc2fe1d922",
|
||||||
urls = ["https://github.com/bazelbuild/platforms/archive/da5541f26b7de1dc8e04c075c99df5351742a4a2.zip"], # 2022-05-27
|
urls = ["https://github.com/bazelbuild/platforms/archive/3fbc687756043fb58a407c2ea8c944bc2fe1d922.zip"],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ if [[ -z ${GTEST_ROOT:-} ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -z ${STD:-} ]]; then
|
if [[ -z ${STD:-} ]]; then
|
||||||
STD="c++11 c++14 c++17 c++20"
|
STD="c++14 c++17 c++20"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Test the CMake build
|
# Test the CMake build
|
||||||
@@ -55,7 +55,7 @@ for cc in /usr/local/bin/gcc /opt/llvm/clang/bin/clang; do
|
|||||||
${LINUX_LATEST_CONTAINER} \
|
${LINUX_LATEST_CONTAINER} \
|
||||||
/bin/bash -c "
|
/bin/bash -c "
|
||||||
cmake /src \
|
cmake /src \
|
||||||
-DCMAKE_CXX_STANDARD=11 \
|
-DCMAKE_CXX_STANDARD=14 \
|
||||||
-Dgtest_build_samples=ON \
|
-Dgtest_build_samples=ON \
|
||||||
-Dgtest_build_tests=ON \
|
-Dgtest_build_tests=ON \
|
||||||
-Dgmock_build_tests=ON \
|
-Dgmock_build_tests=ON \
|
||||||
@@ -72,6 +72,7 @@ time docker run \
|
|||||||
--workdir="/src" \
|
--workdir="/src" \
|
||||||
--rm \
|
--rm \
|
||||||
--env="CC=/usr/local/bin/gcc" \
|
--env="CC=/usr/local/bin/gcc" \
|
||||||
|
--env="BAZEL_CXXOPTS=-std=c++14" \
|
||||||
${LINUX_GCC_FLOOR_CONTAINER} \
|
${LINUX_GCC_FLOOR_CONTAINER} \
|
||||||
/usr/local/bin/bazel test ... \
|
/usr/local/bin/bazel test ... \
|
||||||
--copt="-Wall" \
|
--copt="-Wall" \
|
||||||
@@ -79,6 +80,7 @@ time docker run \
|
|||||||
--copt="-Wuninitialized" \
|
--copt="-Wuninitialized" \
|
||||||
--copt="-Wno-error=pragmas" \
|
--copt="-Wno-error=pragmas" \
|
||||||
--distdir="/bazel-distdir" \
|
--distdir="/bazel-distdir" \
|
||||||
|
--features=external_include_paths \
|
||||||
--keep_going \
|
--keep_going \
|
||||||
--show_timestamps \
|
--show_timestamps \
|
||||||
--test_output=errors
|
--test_output=errors
|
||||||
@@ -99,6 +101,7 @@ for std in ${STD}; do
|
|||||||
--copt="-Wuninitialized" \
|
--copt="-Wuninitialized" \
|
||||||
--define="absl=${absl}" \
|
--define="absl=${absl}" \
|
||||||
--distdir="/bazel-distdir" \
|
--distdir="/bazel-distdir" \
|
||||||
|
--features=external_include_paths \
|
||||||
--keep_going \
|
--keep_going \
|
||||||
--show_timestamps \
|
--show_timestamps \
|
||||||
--test_output=errors
|
--test_output=errors
|
||||||
@@ -122,6 +125,7 @@ for std in ${STD}; do
|
|||||||
--copt="-Wuninitialized" \
|
--copt="-Wuninitialized" \
|
||||||
--define="absl=${absl}" \
|
--define="absl=${absl}" \
|
||||||
--distdir="/bazel-distdir" \
|
--distdir="/bazel-distdir" \
|
||||||
|
--features=external_include_paths \
|
||||||
--keep_going \
|
--keep_going \
|
||||||
--linkopt="--gcc-toolchain=/usr/local" \
|
--linkopt="--gcc-toolchain=/usr/local" \
|
||||||
--show_timestamps \
|
--show_timestamps \
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ for cmake_off_on in OFF ON; do
|
|||||||
BUILD_DIR=$(mktemp -d build_dir.XXXXXXXX)
|
BUILD_DIR=$(mktemp -d build_dir.XXXXXXXX)
|
||||||
cd ${BUILD_DIR}
|
cd ${BUILD_DIR}
|
||||||
time cmake ${GTEST_ROOT} \
|
time cmake ${GTEST_ROOT} \
|
||||||
-DCMAKE_CXX_STANDARD=11 \
|
-DCMAKE_CXX_STANDARD=14 \
|
||||||
-Dgtest_build_samples=ON \
|
-Dgtest_build_samples=ON \
|
||||||
-Dgtest_build_tests=ON \
|
-Dgtest_build_tests=ON \
|
||||||
-Dgmock_build_tests=ON \
|
-Dgmock_build_tests=ON \
|
||||||
@@ -53,7 +53,7 @@ done
|
|||||||
# Test the Bazel build
|
# Test the Bazel build
|
||||||
|
|
||||||
# If we are running on Kokoro, check for a versioned Bazel binary.
|
# If we are running on Kokoro, check for a versioned Bazel binary.
|
||||||
KOKORO_GFILE_BAZEL_BIN="bazel-3.7.0-darwin-x86_64"
|
KOKORO_GFILE_BAZEL_BIN="bazel-5.1.1-darwin-x86_64"
|
||||||
if [[ ${KOKORO_GFILE_DIR:-} ]] && [[ -f ${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN} ]]; then
|
if [[ ${KOKORO_GFILE_DIR:-} ]] && [[ -f ${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN} ]]; then
|
||||||
BAZEL_BIN="${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN}"
|
BAZEL_BIN="${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN}"
|
||||||
chmod +x ${BAZEL_BIN}
|
chmod +x ${BAZEL_BIN}
|
||||||
@@ -66,7 +66,9 @@ for absl in 0 1; do
|
|||||||
${BAZEL_BIN} test ... \
|
${BAZEL_BIN} test ... \
|
||||||
--copt="-Wall" \
|
--copt="-Wall" \
|
||||||
--copt="-Werror" \
|
--copt="-Werror" \
|
||||||
|
--cxxopt="-std=c++14" \
|
||||||
--define="absl=${absl}" \
|
--define="absl=${absl}" \
|
||||||
|
--features=external_include_paths \
|
||||||
--keep_going \
|
--keep_going \
|
||||||
--show_timestamps \
|
--show_timestamps \
|
||||||
--test_output=errors
|
--test_output=errors
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
SETLOCAL ENABLEDELAYEDEXPANSION
|
||||||
|
|
||||||
|
SET BAZEL_EXE=%KOKORO_GFILE_DIR%\bazel-5.1.1-windows-x86_64.exe
|
||||||
|
|
||||||
|
SET PATH=C:\Python37;%PATH%
|
||||||
|
SET BAZEL_PYTHON=C:\python37\python.exe
|
||||||
|
SET BAZEL_SH=C:\tools\msys64\usr\bin\bash.exe
|
||||||
|
SET CMAKE_BIN="C:\Program Files\CMake\bin\cmake.exe"
|
||||||
|
SET CTEST_BIN="C:\Program Files\CMake\bin\ctest.exe"
|
||||||
|
SET CTEST_OUTPUT_ON_FAILURE=1
|
||||||
|
|
||||||
|
IF EXIST git\googletest (
|
||||||
|
CD git\googletest
|
||||||
|
) ELSE IF EXIST github\googletest (
|
||||||
|
CD github\googletest
|
||||||
|
)
|
||||||
|
|
||||||
|
IF %errorlevel% neq 0 EXIT /B 1
|
||||||
|
|
||||||
|
:: ----------------------------------------------------------------------------
|
||||||
|
:: CMake Visual Studio 15 2017 Win64
|
||||||
|
MKDIR cmake_msvc2017
|
||||||
|
CD cmake_msvc2017
|
||||||
|
|
||||||
|
%CMAKE_BIN% .. ^
|
||||||
|
-G "Visual Studio 15 2017 Win64" ^
|
||||||
|
-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_msvc2017
|
||||||
|
|
||||||
|
:: ----------------------------------------------------------------------------
|
||||||
|
:: Bazel Visual Studio 15 2017 Win64
|
||||||
|
|
||||||
|
SET BAZEL_VC=C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC
|
||||||
|
%BAZEL_EXE% test ... ^
|
||||||
|
--compilation_mode=dbg ^
|
||||||
|
--copt=/std:c++14 ^
|
||||||
|
--copt=/WX ^
|
||||||
|
--features=external_include_paths ^
|
||||||
|
--keep_going ^
|
||||||
|
--test_output=errors ^
|
||||||
|
--test_tag_filters=-no_test_msvc2017
|
||||||
|
IF %errorlevel% neq 0 EXIT /B 1
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
<div class="footer">
|
<div class="footer">
|
||||||
GoogleTest ·
|
GoogleTest ·
|
||||||
<a href="https://github.com/google/googletest">GitHub Repository</a> ·
|
<a href="https://github.com/google/googletest">GitHub Repository</a> ·
|
||||||
<a href="https://github.com/google/googletest/blob/master/LICENSE">License</a> ·
|
<a href="https://github.com/google/googletest/blob/main/LICENSE">License</a> ·
|
||||||
<a href="https://policies.google.com/privacy">Privacy Policy</a>
|
<a href="https://policies.google.com/privacy">Privacy Policy</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+17
-8
@@ -487,7 +487,7 @@ When built with Bazel and using Abseil, googletest uses the
|
|||||||
systems (Linux, Cygwin, Mac), googletest uses the
|
systems (Linux, Cygwin, Mac), googletest uses the
|
||||||
[POSIX extended regular expression](http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.html#tag_09_04)
|
[POSIX extended regular expression](http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.html#tag_09_04)
|
||||||
syntax. To learn about POSIX syntax, you may want to read this
|
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](http://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
|
lacks many features. For example, we don't support union (`"x|y"`), grouping
|
||||||
@@ -1095,6 +1095,11 @@ instantiation of the test suite. The next argument is the name of the test
|
|||||||
pattern, and the last is the
|
pattern, and the last is the
|
||||||
[parameter generator](reference/testing.md#param-generators).
|
[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
|
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
|
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
|
actual test suite name. Remember to pick unique prefixes for different
|
||||||
@@ -1142,8 +1147,8 @@ GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FooTest);
|
|||||||
|
|
||||||
You can see [sample7_unittest.cc] and [sample8_unittest.cc] for more examples.
|
You can see [sample7_unittest.cc] and [sample8_unittest.cc] for more examples.
|
||||||
|
|
||||||
[sample7_unittest.cc]: https://github.com/google/googletest/blob/master/googletest/samples/sample7_unittest.cc "Parameterized Test example"
|
[sample7_unittest.cc]: https://github.com/google/googletest/blob/main/googletest/samples/sample7_unittest.cc "Parameterized Test example"
|
||||||
[sample8_unittest.cc]: https://github.com/google/googletest/blob/master/googletest/samples/sample8_unittest.cc "Parameterized Test example with multiple parameters"
|
[sample8_unittest.cc]: https://github.com/google/googletest/blob/main/googletest/samples/sample8_unittest.cc "Parameterized Test example with multiple parameters"
|
||||||
|
|
||||||
### Creating Value-Parameterized Abstract Tests
|
### Creating Value-Parameterized Abstract Tests
|
||||||
|
|
||||||
@@ -1294,7 +1299,7 @@ TYPED_TEST(FooTest, HasPropertyA) { ... }
|
|||||||
|
|
||||||
You can see [sample6_unittest.cc] for a complete example.
|
You can see [sample6_unittest.cc] for a complete example.
|
||||||
|
|
||||||
[sample6_unittest.cc]: https://github.com/google/googletest/blob/master/googletest/samples/sample6_unittest.cc "Typed Test example"
|
[sample6_unittest.cc]: https://github.com/google/googletest/blob/main/googletest/samples/sample6_unittest.cc "Typed Test example"
|
||||||
|
|
||||||
## Type-Parameterized Tests
|
## Type-Parameterized Tests
|
||||||
|
|
||||||
@@ -1733,7 +1738,7 @@ You can do so by adding one line:
|
|||||||
Now, sit back and enjoy a completely different output from your tests. For more
|
Now, sit back and enjoy a completely different output from your tests. For more
|
||||||
details, see [sample9_unittest.cc].
|
details, see [sample9_unittest.cc].
|
||||||
|
|
||||||
[sample9_unittest.cc]: https://github.com/google/googletest/blob/master/googletest/samples/sample9_unittest.cc "Event listener example"
|
[sample9_unittest.cc]: https://github.com/google/googletest/blob/main/googletest/samples/sample9_unittest.cc "Event listener example"
|
||||||
|
|
||||||
You may append more than one listener to the list. When an `On*Start()` or
|
You may append more than one listener to the list. When an `On*Start()` or
|
||||||
`OnTestPartResult()` event is fired, the listeners will receive it in the order
|
`OnTestPartResult()` event is fired, the listeners will receive it in the order
|
||||||
@@ -1760,7 +1765,7 @@ by the former.
|
|||||||
|
|
||||||
See [sample10_unittest.cc] for an example of a failure-raising listener.
|
See [sample10_unittest.cc] for an example of a failure-raising listener.
|
||||||
|
|
||||||
[sample10_unittest.cc]: https://github.com/google/googletest/blob/master/googletest/samples/sample10_unittest.cc "Failure-raising listener example"
|
[sample10_unittest.cc]: https://github.com/google/googletest/blob/main/googletest/samples/sample10_unittest.cc "Failure-raising listener example"
|
||||||
|
|
||||||
## Running Test Programs: Advanced Options
|
## Running Test Programs: Advanced Options
|
||||||
|
|
||||||
@@ -1908,8 +1913,12 @@ Repeat the tests whose name matches the filter 1000 times.
|
|||||||
|
|
||||||
If your test program contains
|
If your test program contains
|
||||||
[global set-up/tear-down](#global-set-up-and-tear-down) code, it will be
|
[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
|
repeated in each iteration as well, as the flakiness may be in it. To avoid
|
||||||
specify the repeat count by setting the `GTEST_REPEAT` environment variable.
|
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
|
### Shuffling the Tests
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -267,7 +267,7 @@ If necessary, you can continue to derive test fixtures from a derived fixture.
|
|||||||
GoogleTest has no limit on how deep the hierarchy can be.
|
GoogleTest has no limit on how deep the hierarchy can be.
|
||||||
|
|
||||||
For a complete example using derived test fixtures, see
|
For a complete example using derived test fixtures, see
|
||||||
[sample5_unittest.cc](https://github.com/google/googletest/blob/master/googletest/samples/sample5_unittest.cc).
|
[sample5_unittest.cc](https://github.com/google/googletest/blob/main/googletest/samples/sample5_unittest.cc).
|
||||||
|
|
||||||
## My compiler complains "void value not ignored as it ought to be." What does this mean?
|
## My compiler complains "void value not ignored as it ought to be." What does this mean?
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
// Sets the default action for return type std::unique_ptr<Buzz> to
|
||||||
// creating a new Buzz every time.
|
// creating a new Buzz every time.
|
||||||
DefaultValue<std::unique_ptr<Buzz>>::SetFactory(
|
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
|
// When this fires, the default action of MakeBuzz() will run, which
|
||||||
// will return a new Buzz object.
|
// will return a new Buzz object.
|
||||||
|
|||||||
+15
-14
@@ -904,7 +904,7 @@ using ::testing::Contains;
|
|||||||
using ::testing::Property;
|
using ::testing::Property;
|
||||||
|
|
||||||
inline constexpr auto HasFoo = [](const auto& f) {
|
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"));
|
EXPECT_THAT(x, HasFoo("blah"));
|
||||||
@@ -1158,7 +1158,7 @@ int IsEven(int n) { return (n % 2) == 0 ? 1 : 0; }
|
|||||||
```
|
```
|
||||||
|
|
||||||
Note that the predicate function / functor doesn't have to return `bool`. It
|
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) ...`.
|
`if (condition) ...`.
|
||||||
|
|
||||||
### Matching Arguments that Are Not Copyable
|
### Matching Arguments that Are Not Copyable
|
||||||
@@ -1345,7 +1345,7 @@ class BarPlusBazEqMatcher {
|
|||||||
|
|
||||||
...
|
...
|
||||||
Foo foo;
|
Foo foo;
|
||||||
EXPECT_CALL(foo, BarPlusBazEq(5))...;
|
EXPECT_THAT(foo, BarPlusBazEq(5))...;
|
||||||
```
|
```
|
||||||
|
|
||||||
### Matching Containers
|
### Matching Containers
|
||||||
@@ -1424,11 +1424,12 @@ Use `Pair` when comparing maps or other associative containers.
|
|||||||
{% raw %}
|
{% raw %}
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
using testing::ElementsAre;
|
using ::testing::UnorderedElementsAre;
|
||||||
using testing::Pair;
|
using ::testing::Pair;
|
||||||
...
|
...
|
||||||
std::map<string, int> m = {{"a", 1}, {"b", 2}, {"c", 3}};
|
absl::flat_hash_map<string, int> m = {{"a", 1}, {"b", 2}, {"c", 3}};
|
||||||
EXPECT_THAT(m, ElementsAre(Pair("a", 1), Pair("b", 2), Pair("c", 3)));
|
EXPECT_THAT(m, UnorderedElementsAre(
|
||||||
|
Pair("a", 1), Pair("b", 2), Pair("c", 3)));
|
||||||
```
|
```
|
||||||
|
|
||||||
{% endraw %}
|
{% endraw %}
|
||||||
@@ -1445,8 +1446,8 @@ using testing::Pair;
|
|||||||
* If the container is passed by pointer instead of by reference, just write
|
* If the container is passed by pointer instead of by reference, just write
|
||||||
`Pointee(ElementsAre*(...))`.
|
`Pointee(ElementsAre*(...))`.
|
||||||
* The order of elements *matters* for `ElementsAre*()`. If you are using it
|
* The order of elements *matters* for `ElementsAre*()`. If you are using it
|
||||||
with containers whose element order are undefined (e.g. `hash_map`) you
|
with containers whose element order are undefined (such as a
|
||||||
should use `WhenSorted` around `ElementsAre`.
|
`std::unordered_map`) you should use `UnorderedElementsAre`.
|
||||||
|
|
||||||
### Sharing Matchers
|
### Sharing Matchers
|
||||||
|
|
||||||
@@ -1903,7 +1904,7 @@ using testing::ReturnPointee;
|
|||||||
### Combining Actions
|
### Combining Actions
|
||||||
|
|
||||||
Want to do more than one thing when a function is called? That's fine. `DoAll()`
|
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.
|
last action in the sequence will be used.
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
@@ -2783,7 +2784,7 @@ If you just need to return a pre-defined move-only value, you can use the
|
|||||||
// When this fires, the unique_ptr<> specified by ByMove(...) will
|
// When this fires, the unique_ptr<> specified by ByMove(...) will
|
||||||
// be returned.
|
// be returned.
|
||||||
EXPECT_CALL(mock_buzzer_, MakeBuzz("world"))
|
EXPECT_CALL(mock_buzzer_, MakeBuzz("world"))
|
||||||
.WillOnce(Return(ByMove(MakeUnique<Buzz>(AccessLevel::kInternal))));
|
.WillOnce(Return(ByMove(std::make_unique<Buzz>(AccessLevel::kInternal))));
|
||||||
|
|
||||||
EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("world"));
|
EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("world"));
|
||||||
```
|
```
|
||||||
@@ -2804,7 +2805,7 @@ pretty much anything you want:
|
|||||||
```cpp
|
```cpp
|
||||||
EXPECT_CALL(mock_buzzer_, MakeBuzz("x"))
|
EXPECT_CALL(mock_buzzer_, MakeBuzz("x"))
|
||||||
.WillRepeatedly([](StringPiece text) {
|
.WillRepeatedly([](StringPiece text) {
|
||||||
return MakeUnique<Buzz>(AccessLevel::kInternal);
|
return std::make_unique<Buzz>(AccessLevel::kInternal);
|
||||||
});
|
});
|
||||||
|
|
||||||
EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("x"));
|
EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("x"));
|
||||||
@@ -2823,7 +2824,7 @@ can always use `Return`, or a [lambda or functor](#FunctionsAsActions):
|
|||||||
using ::testing::Unused;
|
using ::testing::Unused;
|
||||||
|
|
||||||
EXPECT_CALL(mock_buzzer_, ShareBuzz(NotNull(), _)).WillOnce(Return(true));
|
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);
|
0);
|
||||||
|
|
||||||
EXPECT_CALL(mock_buzzer_, ShareBuzz(_, _)).WillOnce(
|
EXPECT_CALL(mock_buzzer_, ShareBuzz(_, _)).WillOnce(
|
||||||
@@ -2867,7 +2868,7 @@ method:
|
|||||||
// When one calls ShareBuzz() on the MockBuzzer like this, the call is
|
// When one calls ShareBuzz() on the MockBuzzer like this, the call is
|
||||||
// forwarded to DoShareBuzz(), which is mocked. Therefore this statement
|
// forwarded to DoShareBuzz(), which is mocked. Therefore this statement
|
||||||
// will trigger the above EXPECT_CALL.
|
// 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
|
### Making the Compilation Faster
|
||||||
|
|||||||
@@ -274,6 +274,7 @@ First, define a fixture class. By convention, you should give it the name
|
|||||||
class QueueTest : public ::testing::Test {
|
class QueueTest : public ::testing::Test {
|
||||||
protected:
|
protected:
|
||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
|
// q0_ remains empty
|
||||||
q1_.Enqueue(1);
|
q1_.Enqueue(1);
|
||||||
q2_.Enqueue(2);
|
q2_.Enqueue(2);
|
||||||
q2_.Enqueue(3);
|
q2_.Enqueue(3);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ we recommend this tutorial as a starting point.
|
|||||||
To complete this tutorial, you'll need:
|
To complete this tutorial, you'll need:
|
||||||
|
|
||||||
* A compatible operating system (e.g. Linux, macOS, Windows).
|
* A compatible operating system (e.g. Linux, macOS, Windows).
|
||||||
* A compatible C++ compiler that supports at least C++11.
|
* A compatible C++ compiler that supports at least C++14.
|
||||||
* [Bazel](https://bazel.build/), the preferred build system used by the
|
* [Bazel](https://bazel.build/), the preferred build system used by the
|
||||||
GoogleTest team.
|
GoogleTest team.
|
||||||
|
|
||||||
@@ -17,11 +17,10 @@ See [Supported Platforms](platforms.md) for more information about platforms
|
|||||||
compatible with GoogleTest.
|
compatible with GoogleTest.
|
||||||
|
|
||||||
If you don't already have Bazel installed, see the
|
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}
|
{: .callout .note} Note: The terminal commands in this tutorial show a Unix
|
||||||
Note: The terminal commands in this tutorial show a Unix shell prompt, but the
|
shell prompt, but the commands work on the Windows command line as well.
|
||||||
commands work on the Windows command line as well.
|
|
||||||
|
|
||||||
## Set up a Bazel workspace
|
## Set up a Bazel workspace
|
||||||
|
|
||||||
@@ -51,16 +50,16 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
|||||||
|
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "com_google_googletest",
|
name = "com_google_googletest",
|
||||||
urls = ["https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip"],
|
urls = ["https://github.com/google/googletest/archive/5ab508a01f9eb089207ee87fd547d290da39d015.zip"],
|
||||||
strip_prefix = "googletest-609281088cfefc76f9d0ce82e1ff6c30cc3591e5",
|
strip_prefix = "googletest-5ab508a01f9eb089207ee87fd547d290da39d015",
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
The above configuration declares a dependency on GoogleTest which is downloaded
|
The above configuration declares a dependency on GoogleTest which is downloaded
|
||||||
as a ZIP archive from GitHub. In the above example,
|
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
|
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.
|
Now you're ready to build C++ code that uses GoogleTest.
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ this tutorial as a starting point. If your project uses Bazel, see the
|
|||||||
To complete this tutorial, you'll need:
|
To complete this tutorial, you'll need:
|
||||||
|
|
||||||
* A compatible operating system (e.g. Linux, macOS, Windows).
|
* A compatible operating system (e.g. Linux, macOS, Windows).
|
||||||
* A compatible C++ compiler that supports at least C++11.
|
* A compatible C++ compiler that supports at least C++14.
|
||||||
* [CMake](https://cmake.org/) and a compatible build tool for building the
|
* [CMake](https://cmake.org/) and a compatible build tool for building the
|
||||||
project.
|
project.
|
||||||
* Compatible build tools include
|
* Compatible build tools include
|
||||||
@@ -52,13 +52,13 @@ To do this, in your project directory (`my_project`), create a file named
|
|||||||
cmake_minimum_required(VERSION 3.14)
|
cmake_minimum_required(VERSION 3.14)
|
||||||
project(my_project)
|
project(my_project)
|
||||||
|
|
||||||
# GoogleTest requires at least C++11
|
# GoogleTest requires at least C++14
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
|
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
googletest
|
googletest
|
||||||
URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip
|
URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
|
||||||
)
|
)
|
||||||
# For Windows: Prevent overriding the parent project's compiler/linker settings
|
# For Windows: Prevent overriding the parent project's compiler/linker settings
|
||||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||||
@@ -66,7 +66,7 @@ FetchContent_MakeAvailable(googletest)
|
|||||||
```
|
```
|
||||||
|
|
||||||
The above configuration declares a dependency on GoogleTest which is downloaded
|
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
|
the Git commit hash of the GoogleTest version to use; we recommend updating the
|
||||||
hash often to point to the latest version.
|
hash often to point to the latest version.
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ add_executable(
|
|||||||
)
|
)
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
hello_test
|
hello_test
|
||||||
gtest_main
|
GTest::gtest_main
|
||||||
)
|
)
|
||||||
|
|
||||||
include(GoogleTest)
|
include(GoogleTest)
|
||||||
|
|||||||
@@ -109,7 +109,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)`. |
|
| `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}`. |
|
| `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`. |
|
| `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
|
The optional last argument *`name_generator`* is a function or functor that
|
||||||
generates custom test name suffixes based on the test parameters. The function
|
generates custom test name suffixes based on the test parameters. The function
|
||||||
must accept an argument of type
|
must accept an argument of type
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
# Googletest Samples
|
# Googletest Samples
|
||||||
|
|
||||||
If you're like us, you'd like to look at
|
If you're like us, you'd like to look at
|
||||||
[googletest samples.](https://github.com/google/googletest/tree/master/googletest/samples)
|
[googletest samples.](https://github.com/google/googletest/blob/main/googletest/samples)
|
||||||
The sample directory has a number of well-commented samples showing how to use a
|
The sample directory has a number of well-commented samples showing how to use a
|
||||||
variety of googletest features.
|
variety of googletest features.
|
||||||
|
|
||||||
|
|||||||
@@ -122,7 +122,7 @@
|
|||||||
// MORE INFORMATION:
|
// MORE INFORMATION:
|
||||||
//
|
//
|
||||||
// To learn more about using these macros, please search for 'ACTION' on
|
// To learn more about using these macros, please search for 'ACTION' on
|
||||||
// https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md
|
// https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md
|
||||||
|
|
||||||
// IWYU pragma: private, include "gmock/gmock.h"
|
// IWYU pragma: private, include "gmock/gmock.h"
|
||||||
// IWYU pragma: friend gmock/.*
|
// IWYU pragma: friend gmock/.*
|
||||||
@@ -1428,8 +1428,10 @@ struct WithArgsAction {
|
|||||||
// MSVC complains about the I parameter pack not being
|
// MSVC complains about the I parameter pack not being
|
||||||
// expanded (error C3520) despite it being expanded in the
|
// expanded (error C3520) despite it being expanded in the
|
||||||
// type alias.
|
// type alias.
|
||||||
OnceAction<R(typename std::tuple_element<
|
// TupleElement is also an MSVC workaround.
|
||||||
I, std::tuple<Args...>>::type...)>>::value,
|
// See its definition for details.
|
||||||
|
OnceAction<R(internal::TupleElement<
|
||||||
|
I, std::tuple<Args...>>...)>>::value,
|
||||||
int>::type = 0>
|
int>::type = 0>
|
||||||
operator OnceAction<R(Args...)>() && { // NOLINT
|
operator OnceAction<R(Args...)>() && { // NOLINT
|
||||||
struct OA {
|
struct OA {
|
||||||
@@ -1453,8 +1455,10 @@ struct WithArgsAction {
|
|||||||
// MSVC complains about the I parameter pack not being
|
// MSVC complains about the I parameter pack not being
|
||||||
// expanded (error C3520) despite it being expanded in the
|
// expanded (error C3520) despite it being expanded in the
|
||||||
// type alias.
|
// type alias.
|
||||||
Action<R(typename std::tuple_element<
|
// TupleElement is also an MSVC workaround.
|
||||||
I, std::tuple<Args...>>::type...)>>::value,
|
// See its definition for details.
|
||||||
|
Action<R(internal::TupleElement<
|
||||||
|
I, std::tuple<Args...>>...)>>::value,
|
||||||
int>::type = 0>
|
int>::type = 0>
|
||||||
operator Action<R(Args...)>() const { // NOLINT
|
operator Action<R(Args...)>() const { // NOLINT
|
||||||
Action<InnerSignature<R, Args...>> converted(inner_action);
|
Action<InnerSignature<R, Args...>> converted(inner_action);
|
||||||
|
|||||||
@@ -34,8 +34,8 @@
|
|||||||
// IWYU pragma: private, include "gmock/gmock.h"
|
// IWYU pragma: private, include "gmock/gmock.h"
|
||||||
// IWYU pragma: friend gmock/.*
|
// IWYU pragma: friend gmock/.*
|
||||||
|
|
||||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
|
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_
|
||||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
|
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_
|
||||||
|
|
||||||
#include <type_traits> // IWYU pragma: keep
|
#include <type_traits> // IWYU pragma: keep
|
||||||
#include <utility> // IWYU pragma: keep
|
#include <utility> // IWYU pragma: keep
|
||||||
@@ -108,8 +108,11 @@ constexpr bool ValidateSpec(const char (&spec)[N]) {
|
|||||||
using internal::FunctionMocker;
|
using internal::FunctionMocker;
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
|
||||||
#define MOCK_METHOD(...) \
|
#define MOCK_METHOD(...) \
|
||||||
GMOCK_PP_VARIADIC_CALL(GMOCK_INTERNAL_MOCK_METHOD_ARG_, __VA_ARGS__)
|
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(...) \
|
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_1(...) \
|
||||||
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
|
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
|
||||||
@@ -511,4 +514,4 @@ using internal::FunctionMocker;
|
|||||||
#define GMOCK_MOCKER_(arity, constness, Method) \
|
#define GMOCK_MOCKER_(arity, constness, Method) \
|
||||||
GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)
|
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_
|
||||||
|
|||||||
@@ -240,7 +240,7 @@
|
|||||||
//
|
//
|
||||||
// To learn more about using these macros, please search for 'MATCHER'
|
// To learn more about using these macros, please search for 'MATCHER'
|
||||||
// on
|
// on
|
||||||
// https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md
|
// https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md
|
||||||
//
|
//
|
||||||
// This file also implements some commonly used argument matchers. More
|
// This file also implements some commonly used argument matchers. More
|
||||||
// matchers can be defined by the user implementing the
|
// matchers can be defined by the user implementing the
|
||||||
@@ -258,6 +258,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
|
#include <ios>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -2309,11 +2310,11 @@ class SizeIsMatcher {
|
|||||||
: size_matcher_(MatcherCast<SizeType>(size_matcher)) {}
|
: size_matcher_(MatcherCast<SizeType>(size_matcher)) {}
|
||||||
|
|
||||||
void DescribeTo(::std::ostream* os) const override {
|
void DescribeTo(::std::ostream* os) const override {
|
||||||
*os << "size ";
|
*os << "has a size that ";
|
||||||
size_matcher_.DescribeTo(os);
|
size_matcher_.DescribeTo(os);
|
||||||
}
|
}
|
||||||
void DescribeNegationTo(::std::ostream* os) const override {
|
void DescribeNegationTo(::std::ostream* os) const override {
|
||||||
*os << "size ";
|
*os << "has a size that ";
|
||||||
size_matcher_.DescribeNegationTo(os);
|
size_matcher_.DescribeNegationTo(os);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3235,6 +3236,21 @@ auto UnpackStructImpl(const T& t, MakeIndexSequence<16>, char) {
|
|||||||
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] = t;
|
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);
|
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) {
|
||||||
|
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) {
|
||||||
|
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) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
#endif // defined(__cpp_structured_bindings)
|
#endif // defined(__cpp_structured_bindings)
|
||||||
|
|
||||||
template <size_t I, typename T>
|
template <size_t I, typename T>
|
||||||
@@ -3301,8 +3317,8 @@ class FieldsAreMatcherImpl<Struct, IndexSequence<I...>>
|
|||||||
std::vector<StringMatchResultListener> inner_listener(sizeof...(I));
|
std::vector<StringMatchResultListener> inner_listener(sizeof...(I));
|
||||||
|
|
||||||
VariadicExpand(
|
VariadicExpand(
|
||||||
{failed_pos == ~size_t{} && !std::get<I>(matchers_).MatchAndExplain(
|
{failed_pos == ~size_t{}&& !std::get<I>(matchers_).MatchAndExplain(
|
||||||
std::get<I>(tuple), &inner_listener[I])
|
std::get<I>(tuple), &inner_listener[I])
|
||||||
? failed_pos = I
|
? failed_pos = I
|
||||||
: 0 ...});
|
: 0 ...});
|
||||||
if (failed_pos != ~size_t{}) {
|
if (failed_pos != ~size_t{}) {
|
||||||
@@ -3629,23 +3645,6 @@ class UnorderedElementsAreMatcherImpl
|
|||||||
AnalyzeElements(stl_container.begin(), stl_container.end(),
|
AnalyzeElements(stl_container.begin(), stl_container.end(),
|
||||||
&element_printouts, listener);
|
&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) &&
|
return VerifyMatchMatrix(element_printouts, matrix, listener) &&
|
||||||
FindPairing(matrix, listener);
|
FindPairing(matrix, listener);
|
||||||
}
|
}
|
||||||
@@ -4100,7 +4099,12 @@ class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
|
|||||||
const char* sep = "";
|
const char* sep = "";
|
||||||
// Workaround spurious C4189 on MSVC<=15.7 when k is empty.
|
// Workaround spurious C4189 on MSVC<=15.7 when k is empty.
|
||||||
(void)sep;
|
(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;
|
(void)dummy;
|
||||||
*os << ") ";
|
*os << ") ";
|
||||||
}
|
}
|
||||||
@@ -5467,7 +5471,13 @@ PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> ThrowsMessage(
|
|||||||
} \
|
} \
|
||||||
}; \
|
}; \
|
||||||
}; \
|
}; \
|
||||||
GTEST_ATTRIBUTE_UNUSED_ inline name##Matcher name() { return {}; } \
|
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> \
|
template <typename arg_type> \
|
||||||
bool name##Matcher::gmock_Impl<arg_type>::MatchAndExplain( \
|
bool name##Matcher::gmock_Impl<arg_type>::MatchAndExplain( \
|
||||||
const arg_type& arg, \
|
const arg_type& arg, \
|
||||||
|
|||||||
@@ -40,6 +40,9 @@
|
|||||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_
|
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_
|
||||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_
|
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "gmock/gmock-matchers.h"
|
#include "gmock/gmock-matchers.h"
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
@@ -56,14 +59,42 @@ namespace testing {
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Defines a matcher that matches an empty container. The container must
|
namespace internal {
|
||||||
// support both size() and empty(), which all STL-like containers provide.
|
|
||||||
MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") {
|
// Implements the polymorphic IsEmpty matcher, which
|
||||||
if (arg.empty()) {
|
// can be used as a Matcher<T> as long as T is either a container that defines
|
||||||
return true;
|
// empty() and size() (e.g. std::vector or std::string), or a C-style string.
|
||||||
|
class IsEmptyMatcher {
|
||||||
|
public:
|
||||||
|
// Matches anything that defines empty() and size().
|
||||||
|
template <typename MatcheeContainerType>
|
||||||
|
bool MatchAndExplain(const MatcheeContainerType& c,
|
||||||
|
MatchResultListener* listener) const {
|
||||||
|
if (c.empty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
*listener << "whose size is " << c.size();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
*result_listener << "whose size is " << arg.size();
|
|
||||||
return false;
|
// Matches C-style strings.
|
||||||
|
bool MatchAndExplain(const char* s, MatchResultListener* listener) const {
|
||||||
|
return MatchAndExplain(std::string(s), listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Describes what this matcher matches.
|
||||||
|
void DescribeTo(std::ostream* os) const { *os << "is empty"; }
|
||||||
|
|
||||||
|
void DescribeNegationTo(std::ostream* os) const { *os << "isn't empty"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
// Creates a polymorphic matcher that matches an empty container or C-style
|
||||||
|
// string. The container must support both size() and empty(), which all
|
||||||
|
// STL-like containers provide.
|
||||||
|
inline PolymorphicMatcher<internal::IsEmptyMatcher> IsEmpty() {
|
||||||
|
return MakePolymorphicMatcher(internal::IsEmptyMatcher());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define a matcher that matches a value that evaluates in boolean
|
// Define a matcher that matches a value that evaluates in boolean
|
||||||
|
|||||||
@@ -65,6 +65,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <ostream>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -656,7 +657,7 @@ class GTEST_API_ InSequence {
|
|||||||
|
|
||||||
InSequence(const InSequence&) = delete;
|
InSequence(const InSequence&) = delete;
|
||||||
InSequence& operator=(const InSequence&) = delete;
|
InSequence& operator=(const InSequence&) = delete;
|
||||||
} GTEST_ATTRIBUTE_UNUSED_;
|
};
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
@@ -706,6 +707,12 @@ class GTEST_API_ ExpectationBase {
|
|||||||
// describes it to the ostream.
|
// describes it to the ostream.
|
||||||
virtual void MaybeDescribeExtraMatcherTo(::std::ostream* os) = 0;
|
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:
|
protected:
|
||||||
friend class ::testing::Expectation;
|
friend class ::testing::Expectation;
|
||||||
friend class UntypedFunctionMockerBase;
|
friend class UntypedFunctionMockerBase;
|
||||||
@@ -772,6 +779,10 @@ class GTEST_API_ ExpectationBase {
|
|||||||
retired_ = true;
|
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.
|
// Returns true if and only if this expectation is satisfied.
|
||||||
bool IsSatisfied() const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
bool IsSatisfied() const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||||
g_gmock_mutex.AssertHeld();
|
g_gmock_mutex.AssertHeld();
|
||||||
@@ -831,6 +842,7 @@ class GTEST_API_ ExpectationBase {
|
|||||||
const char* file_; // The file that contains the expectation.
|
const char* file_; // The file that contains the expectation.
|
||||||
int line_; // The line number of the expectation.
|
int line_; // The line number of the expectation.
|
||||||
const std::string source_text_; // The EXPECT_CALL(...) source text.
|
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.
|
// True if and only if the cardinality is specified explicitly.
|
||||||
bool cardinality_specified_;
|
bool cardinality_specified_;
|
||||||
Cardinality cardinality_; // The cardinality of the expectation.
|
Cardinality cardinality_; // The cardinality of the expectation.
|
||||||
@@ -909,6 +921,13 @@ class TypedExpectation<R(Args...)> : public ExpectationBase {
|
|||||||
return *this;
|
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.
|
// Implements the .Times() clause.
|
||||||
TypedExpectation& Times(const Cardinality& a_cardinality) {
|
TypedExpectation& Times(const Cardinality& a_cardinality) {
|
||||||
ExpectationBase::UntypedTimes(a_cardinality);
|
ExpectationBase::UntypedTimes(a_cardinality);
|
||||||
@@ -1199,10 +1218,15 @@ class TypedExpectation<R(Args...)> : public ExpectationBase {
|
|||||||
::std::ostream* why)
|
::std::ostream* why)
|
||||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||||
g_gmock_mutex.AssertHeld();
|
g_gmock_mutex.AssertHeld();
|
||||||
|
const ::std::string& expectation_description = GetDescription();
|
||||||
if (IsSaturated()) {
|
if (IsSaturated()) {
|
||||||
// We have an excessive call.
|
// We have an excessive call.
|
||||||
IncrementCallCount();
|
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);
|
mocker->DescribeDefaultActionTo(args, what);
|
||||||
DescribeCallCountTo(why);
|
DescribeCallCountTo(why);
|
||||||
|
|
||||||
@@ -1217,7 +1241,11 @@ class TypedExpectation<R(Args...)> : public ExpectationBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Must be done after IncrementCount()!
|
// 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));
|
return &(GetCurrentAction(mocker, args));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -95,6 +95,24 @@ inline Element* GetRawPointer(Element* p) {
|
|||||||
return 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
|
// 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
|
// same as unsigned short when the compiler option /Zc:wchar_t- is
|
||||||
// specified. It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t
|
// specified. It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t
|
||||||
@@ -290,13 +308,6 @@ class WithoutMatchers {
|
|||||||
// Internal use only: access the singleton instance of WithoutMatchers.
|
// Internal use only: access the singleton instance of WithoutMatchers.
|
||||||
GTEST_API_ WithoutMatchers GetWithoutMatchers();
|
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
|
// 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
|
// 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
|
// when a value of type T is needed for compilation, but the statement
|
||||||
@@ -314,10 +325,6 @@ inline T Invalid() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Given a raw type (i.e. having no top-level reference or const
|
// Given a raw type (i.e. having no top-level reference or const
|
||||||
// modifier) RawContainer that's either an STL-style container or a
|
// modifier) RawContainer that's either an STL-style container or a
|
||||||
// native array, class StlContainerView<RawContainer> has the
|
// native array, class StlContainerView<RawContainer> has the
|
||||||
@@ -464,6 +471,13 @@ struct Function<R(Args...)> {
|
|||||||
template <typename R, typename... Args>
|
template <typename R, typename... Args>
|
||||||
constexpr size_t Function<R(Args...)>::ArgumentCount;
|
constexpr size_t Function<R(Args...)>::ArgumentCount;
|
||||||
|
|
||||||
|
// 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);
|
bool Base64Unescape(const std::string& encoded, std::string* decoded);
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message,
|
|||||||
}
|
}
|
||||||
std::cout << "Stack trace:\n"
|
std::cout << "Stack trace:\n"
|
||||||
<< ::testing::internal::GetCurrentOsStackTraceExceptTop(
|
<< ::testing::internal::GetCurrentOsStackTraceExceptTop(
|
||||||
::testing::UnitTest::GetInstance(), actual_to_skip);
|
actual_to_skip);
|
||||||
}
|
}
|
||||||
std::cout << ::std::flush;
|
std::cout << ::std::flush;
|
||||||
}
|
}
|
||||||
@@ -199,9 +199,10 @@ GTEST_API_ void IllegalDoDefault(const char* file, int line) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constexpr char UnBase64Impl(char c, const char* const base64, char carry) {
|
constexpr char UnBase64Impl(char c, const char* const base64, char carry) {
|
||||||
return *base64 == 0 ? static_cast<char>(65)
|
return *base64 == 0 ? static_cast<char>(65)
|
||||||
: *base64 == c ? carry
|
: *base64 == c
|
||||||
: UnBase64Impl(c, base64 + 1, carry + 1);
|
? carry
|
||||||
|
: UnBase64Impl(c, base64 + 1, static_cast<char>(carry + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t... I>
|
template <size_t... I>
|
||||||
|
|||||||
@@ -370,6 +370,23 @@ void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(
|
|||||||
bool UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix(
|
bool UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix(
|
||||||
const ::std::vector<std::string>& element_printouts,
|
const ::std::vector<std::string>& element_printouts,
|
||||||
const MatchMatrix& matrix, MatchResultListener* listener) const {
|
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;
|
bool result = true;
|
||||||
::std::vector<char> element_matched(matrix.LhsSize(), 0);
|
::std::vector<char> element_matched(matrix.LhsSize(), 0);
|
||||||
::std::vector<char> matcher_matched(matrix.RhsSize(), 0);
|
::std::vector<char> matcher_matched(matrix.RhsSize(), 0);
|
||||||
|
|||||||
@@ -51,6 +51,9 @@
|
|||||||
#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC
|
#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC
|
||||||
#include <unistd.h> // NOLINT
|
#include <unistd.h> // NOLINT
|
||||||
#endif
|
#endif
|
||||||
|
#if GTEST_OS_QURT
|
||||||
|
#include <qurt_event.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// Silence C4800 (C4800: 'int *const ': forcing value
|
// Silence C4800 (C4800: 'int *const ': forcing value
|
||||||
// to bool 'true' or 'false') for MSVC 15
|
// to bool 'true' or 'false') for MSVC 15
|
||||||
@@ -295,7 +298,7 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg) {
|
|||||||
"call should not happen. Do not suppress it by blindly adding "
|
"call should not happen. Do not suppress it by blindly adding "
|
||||||
"an EXPECT_CALL() if you don't mean to enforce the call. "
|
"an EXPECT_CALL() if you don't mean to enforce the call. "
|
||||||
"See "
|
"See "
|
||||||
"https://github.com/google/googletest/blob/master/docs/"
|
"https://github.com/google/googletest/blob/main/docs/"
|
||||||
"gmock_cook_book.md#"
|
"gmock_cook_book.md#"
|
||||||
"knowing-when-to-expect for details.\n",
|
"knowing-when-to-expect for details.\n",
|
||||||
stack_frames_to_skip);
|
stack_frames_to_skip);
|
||||||
@@ -406,8 +409,15 @@ bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()
|
|||||||
} else if (!untyped_expectation->IsSatisfied()) {
|
} else if (!untyped_expectation->IsSatisfied()) {
|
||||||
expectations_met = false;
|
expectations_met = false;
|
||||||
::std::stringstream ss;
|
::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
|
// No need to show the source file location of the expectation
|
||||||
// in the description, as the Expect() call that follows already
|
// in the description, as the Expect() call that follows already
|
||||||
// takes care of it.
|
// takes care of it.
|
||||||
@@ -435,7 +445,7 @@ bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()
|
|||||||
return expectations_met;
|
return expectations_met;
|
||||||
}
|
}
|
||||||
|
|
||||||
CallReaction intToCallReaction(int mock_behavior) {
|
static CallReaction intToCallReaction(int mock_behavior) {
|
||||||
if (mock_behavior >= kAllow && mock_behavior <= kFail) {
|
if (mock_behavior >= kAllow && mock_behavior <= kFail) {
|
||||||
return static_cast<internal::CallReaction>(mock_behavior);
|
return static_cast<internal::CallReaction>(mock_behavior);
|
||||||
}
|
}
|
||||||
@@ -519,8 +529,12 @@ class MockObjectRegistry {
|
|||||||
// RUN_ALL_TESTS() has already returned when this destructor is
|
// RUN_ALL_TESTS() has already returned when this destructor is
|
||||||
// called. Therefore we cannot use the normal Google Test
|
// called. Therefore we cannot use the normal Google Test
|
||||||
// failure reporting mechanism.
|
// failure reporting mechanism.
|
||||||
|
#if GTEST_OS_QURT
|
||||||
|
qurt_exception_raise_fatal();
|
||||||
|
#else
|
||||||
_exit(1); // We cannot call exit() as it is not reentrant and
|
_exit(1); // We cannot call exit() as it is not reentrant and
|
||||||
// may already have been called.
|
// may already have been called.
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -466,7 +466,7 @@ TEST(DefaultValueOfReferenceTest, IsInitiallyUnset) {
|
|||||||
EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible&>::IsSet());
|
EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible&>::IsSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that DefaultValue<T&>::Exists is false initiallly.
|
// Tests that DefaultValue<T&>::Exists is false initially.
|
||||||
TEST(DefaultValueOfReferenceTest, IsInitiallyNotExisting) {
|
TEST(DefaultValueOfReferenceTest, IsInitiallyNotExisting) {
|
||||||
EXPECT_FALSE(DefaultValue<int&>::Exists());
|
EXPECT_FALSE(DefaultValue<int&>::Exists());
|
||||||
EXPECT_FALSE(DefaultValue<MyDefaultConstructible&>::Exists());
|
EXPECT_FALSE(DefaultValue<MyDefaultConstructible&>::Exists());
|
||||||
@@ -684,7 +684,7 @@ TEST(ReturnTest, SupportsReferenceLikeReturnType) {
|
|||||||
// A reference wrapper for std::vector<int>, implicitly convertible from it.
|
// A reference wrapper for std::vector<int>, implicitly convertible from it.
|
||||||
struct Result {
|
struct Result {
|
||||||
const std::vector<int>* v;
|
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
|
// Set up an action for a mock function that returns the reference wrapper
|
||||||
@@ -717,7 +717,7 @@ TEST(ReturnTest, PrefersConversionOperator) {
|
|||||||
struct Out {
|
struct Out {
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
explicit Out(const int x) : x(x) {}
|
explicit Out(const int val) : x(val) {}
|
||||||
explicit Out(const In&) : x(0) {}
|
explicit Out(const In&) : x(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -807,7 +807,7 @@ TEST(ReturnTest, MoveOnlyResultType) {
|
|||||||
"");
|
"");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that Return(v) is covaraint.
|
// Tests that Return(v) is covariant.
|
||||||
|
|
||||||
struct Base {
|
struct Base {
|
||||||
bool operator==(const Base&) { return true; }
|
bool operator==(const Base&) { return true; }
|
||||||
|
|||||||
@@ -958,6 +958,21 @@ TEST(MockMethodMockFunctionTest, MockMethodSizeOverhead) {
|
|||||||
EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(MockMethodSizes0));
|
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 hasTwoParams(int, int);
|
||||||
void MaybeThrows();
|
void MaybeThrows();
|
||||||
void DoesntThrow() noexcept;
|
void DoesntThrow() noexcept;
|
||||||
|
|||||||
@@ -39,6 +39,8 @@
|
|||||||
#pragma warning(disable : 4100)
|
#pragma warning(disable : 4100)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "test/gmock-matchers_test.h"
|
#include "test/gmock-matchers_test.h"
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
@@ -983,6 +985,30 @@ TEST(ComparisonBaseTest, WorksWithMoveOnly) {
|
|||||||
helper.Call(MoveOnly(1));
|
helper.Call(MoveOnly(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(IsEmptyTest, MatchesContainer) {
|
||||||
|
const Matcher<std::vector<int>> m = IsEmpty();
|
||||||
|
std::vector<int> a = {};
|
||||||
|
std::vector<int> b = {1};
|
||||||
|
EXPECT_TRUE(m.Matches(a));
|
||||||
|
EXPECT_FALSE(m.Matches(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(IsEmptyTest, MatchesStdString) {
|
||||||
|
const Matcher<std::string> m = IsEmpty();
|
||||||
|
std::string a = "z";
|
||||||
|
std::string b = "";
|
||||||
|
EXPECT_FALSE(m.Matches(a));
|
||||||
|
EXPECT_TRUE(m.Matches(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(IsEmptyTest, MatchesCString) {
|
||||||
|
const Matcher<const char*> m = IsEmpty();
|
||||||
|
const char a[] = "";
|
||||||
|
const char b[] = "x";
|
||||||
|
EXPECT_TRUE(m.Matches(a));
|
||||||
|
EXPECT_FALSE(m.Matches(b));
|
||||||
|
}
|
||||||
|
|
||||||
// Tests that IsNull() matches any NULL pointer of any type.
|
// Tests that IsNull() matches any NULL pointer of any type.
|
||||||
TEST(IsNullTest, MatchesNullPointer) {
|
TEST(IsNullTest, MatchesNullPointer) {
|
||||||
Matcher<int*> m1 = IsNull();
|
Matcher<int*> m1 = IsNull();
|
||||||
@@ -1684,6 +1710,21 @@ TEST(FieldsAreTest, StructuredBindings) {
|
|||||||
};
|
};
|
||||||
EXPECT_THAT(MyVarType16{},
|
EXPECT_THAT(MyVarType16{},
|
||||||
FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
|
FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
|
||||||
|
struct MyVarType17 {
|
||||||
|
int a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q;
|
||||||
|
};
|
||||||
|
EXPECT_THAT(MyVarType17{},
|
||||||
|
FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
|
||||||
|
struct MyVarType18 {
|
||||||
|
int a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r;
|
||||||
|
};
|
||||||
|
EXPECT_THAT(MyVarType18{},
|
||||||
|
FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
|
||||||
|
struct MyVarType19 {
|
||||||
|
int a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s;
|
||||||
|
};
|
||||||
|
EXPECT_THAT(MyVarType19{}, FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1182,8 +1182,8 @@ TEST(SizeIsTest, WorksWithMinimalistCustomType) {
|
|||||||
|
|
||||||
TEST(SizeIsTest, CanDescribeSelf) {
|
TEST(SizeIsTest, CanDescribeSelf) {
|
||||||
Matcher<vector<int>> m = SizeIs(2);
|
Matcher<vector<int>> m = SizeIs(2);
|
||||||
EXPECT_EQ("size is equal to 2", Describe(m));
|
EXPECT_EQ("has a size that is equal to 2", Describe(m));
|
||||||
EXPECT_EQ("size isn't equal to 2", DescribeNegation(m));
|
EXPECT_EQ("has a size that isn't equal to 2", DescribeNegation(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SizeIsTest, ExplainsResult) {
|
TEST(SizeIsTest, ExplainsResult) {
|
||||||
|
|||||||
@@ -1561,7 +1561,7 @@ TEST(AnyOfArrayTest, Matchers) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(AnyOfArrayTestP, ExplainsMatchResultCorrectly) {
|
TEST_P(AnyOfArrayTestP, ExplainsMatchResultCorrectly) {
|
||||||
// AnyOfArray and AllOfArry use the same underlying template-template,
|
// AnyOfArray and AllOfArray use the same underlying template-template,
|
||||||
// thus it is sufficient to test one here.
|
// thus it is sufficient to test one here.
|
||||||
const std::vector<int> v0{};
|
const std::vector<int> v0{};
|
||||||
const std::vector<int> v1{1};
|
const std::vector<int> v1{1};
|
||||||
@@ -1615,6 +1615,20 @@ TEST(MatcherPMacroTest, WorksOnMoveOnlyType) {
|
|||||||
EXPECT_THAT(p, Not(UniquePointee(2)));
|
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
|
#if GTEST_HAS_EXCEPTIONS
|
||||||
|
|
||||||
// std::function<void()> is used below for compatibility with older copies of
|
// std::function<void()> is used below for compatibility with older copies of
|
||||||
|
|||||||
@@ -739,11 +739,12 @@ TEST(ExpectCallTest, CatchesTooFewCalls) {
|
|||||||
EXPECT_NONFATAL_FAILURE(
|
EXPECT_NONFATAL_FAILURE(
|
||||||
{ // NOLINT
|
{ // NOLINT
|
||||||
MockB b;
|
MockB b;
|
||||||
EXPECT_CALL(b, DoB(5)).Times(AtLeast(2));
|
EXPECT_CALL(b, DoB(5)).Description("DoB Method").Times(AtLeast(2));
|
||||||
|
|
||||||
b.DoB(5);
|
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"
|
" Expected: to be called at least twice\n"
|
||||||
" Actual: called once - unsatisfied and active");
|
" Actual: called once - unsatisfied and active");
|
||||||
}
|
}
|
||||||
@@ -1064,7 +1065,7 @@ TEST(UnexpectedCallTest, UnmatchedArguments) {
|
|||||||
|
|
||||||
// Tests that Google Mock explains that an expectation with
|
// Tests that Google Mock explains that an expectation with
|
||||||
// unsatisfied pre-requisites doesn't match the call.
|
// unsatisfied pre-requisites doesn't match the call.
|
||||||
TEST(UnexpectedCallTest, UnsatisifiedPrerequisites) {
|
TEST(UnexpectedCallTest, UnsatisfiedPrerequisites) {
|
||||||
Sequence s1, s2;
|
Sequence s1, s2;
|
||||||
MockB b;
|
MockB b;
|
||||||
EXPECT_CALL(b, DoB(1)).InSequence(s1);
|
EXPECT_CALL(b, DoB(1)).InSequence(s1);
|
||||||
@@ -1148,10 +1149,11 @@ TEST(ExcessiveCallTest, DoesDefaultAction) {
|
|||||||
// When there is no ON_CALL(), the default value for the return type
|
// When there is no ON_CALL(), the default value for the return type
|
||||||
// should be returned.
|
// should be returned.
|
||||||
MockB b;
|
MockB b;
|
||||||
EXPECT_CALL(b, DoB(0)).Times(0);
|
EXPECT_CALL(b, DoB(0)).Description("DoB Method").Times(0);
|
||||||
int n = -1;
|
int n = -1;
|
||||||
EXPECT_NONFATAL_FAILURE(n = b.DoB(0),
|
EXPECT_NONFATAL_FAILURE(
|
||||||
"Mock function called more times than expected");
|
n = b.DoB(0),
|
||||||
|
"Mock function \"DoB Method\" called more times than expected");
|
||||||
EXPECT_EQ(0, n);
|
EXPECT_EQ(0, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1159,10 +1161,11 @@ TEST(ExcessiveCallTest, DoesDefaultAction) {
|
|||||||
// the failure message contains the argument values.
|
// the failure message contains the argument values.
|
||||||
TEST(ExcessiveCallTest, GeneratesFailureForVoidFunction) {
|
TEST(ExcessiveCallTest, GeneratesFailureForVoidFunction) {
|
||||||
MockA a;
|
MockA a;
|
||||||
EXPECT_CALL(a, DoA(_)).Times(0);
|
EXPECT_CALL(a, DoA(_)).Description("DoA Method").Times(0);
|
||||||
EXPECT_NONFATAL_FAILURE(
|
EXPECT_NONFATAL_FAILURE(
|
||||||
a.DoA(9),
|
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"
|
" Function call: DoA(9)\n"
|
||||||
" Expected: to be never called\n"
|
" Expected: to be never called\n"
|
||||||
" Actual: called once - over-saturated and active");
|
" Actual: called once - over-saturated and active");
|
||||||
@@ -2059,7 +2062,7 @@ class GMockVerboseFlagTest : public VerboseFlagPreservingFixture {
|
|||||||
"call should not happen. Do not suppress it by blindly adding "
|
"call should not happen. Do not suppress it by blindly adding "
|
||||||
"an EXPECT_CALL() if you don't mean to enforce the call. "
|
"an EXPECT_CALL() if you don't mean to enforce the call. "
|
||||||
"See "
|
"See "
|
||||||
"https://github.com/google/googletest/blob/master/docs/"
|
"https://github.com/google/googletest/blob/main/docs/"
|
||||||
"gmock_cook_book.md#"
|
"gmock_cook_book.md#"
|
||||||
"knowing-when-to-expect for details.";
|
"knowing-when-to-expect for details.";
|
||||||
|
|
||||||
|
|||||||
@@ -159,6 +159,9 @@ class GMockOutputTest(gmock_test_utils.TestCase):
|
|||||||
golden_file = open(GOLDEN_PATH, 'rb')
|
golden_file = open(GOLDEN_PATH, 'rb')
|
||||||
golden = golden_file.read().decode('utf-8')
|
golden = golden_file.read().decode('utf-8')
|
||||||
golden_file.close()
|
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.
|
# The normalized output should match the golden file.
|
||||||
self.assertEqual(golden, output)
|
self.assertEqual(golden, output)
|
||||||
|
|||||||
@@ -75,14 +75,14 @@ GMOCK WARNING:
|
|||||||
Uninteresting mock function call - returning default value.
|
Uninteresting mock function call - returning default value.
|
||||||
Function call: Bar2(0, 1)
|
Function call: Bar2(0, 1)
|
||||||
Returns: false
|
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/master/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 for details.
|
||||||
[ OK ] GMockOutputTest.UninterestingCall
|
[ OK ] GMockOutputTest.UninterestingCall
|
||||||
[ RUN ] GMockOutputTest.UninterestingCallToVoidFunction
|
[ RUN ] GMockOutputTest.UninterestingCallToVoidFunction
|
||||||
|
|
||||||
GMOCK WARNING:
|
GMOCK WARNING:
|
||||||
Uninteresting mock function call - returning directly.
|
Uninteresting mock function call - returning directly.
|
||||||
Function call: Bar3(0, 1)
|
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/master/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 for details.
|
||||||
[ OK ] GMockOutputTest.UninterestingCallToVoidFunction
|
[ OK ] GMockOutputTest.UninterestingCallToVoidFunction
|
||||||
[ RUN ] GMockOutputTest.RetiredExpectation
|
[ RUN ] GMockOutputTest.RetiredExpectation
|
||||||
unknown file: Failure
|
unknown file: Failure
|
||||||
@@ -266,14 +266,14 @@ Uninteresting mock function call - taking default action specified at:
|
|||||||
FILE:#:
|
FILE:#:
|
||||||
Function call: Bar2(2, 2)
|
Function call: Bar2(2, 2)
|
||||||
Returns: true
|
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/master/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 for details.
|
||||||
|
|
||||||
GMOCK WARNING:
|
GMOCK WARNING:
|
||||||
Uninteresting mock function call - taking default action specified at:
|
Uninteresting mock function call - taking default action specified at:
|
||||||
FILE:#:
|
FILE:#:
|
||||||
Function call: Bar2(1, 1)
|
Function call: Bar2(1, 1)
|
||||||
Returns: false
|
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/master/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 for details.
|
||||||
[ OK ] GMockOutputTest.UninterestingCallWithDefaultAction
|
[ OK ] GMockOutputTest.UninterestingCallWithDefaultAction
|
||||||
[ RUN ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction
|
[ RUN ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction
|
||||||
|
|
||||||
|
|||||||
@@ -125,6 +125,22 @@ include_directories(${gtest_build_include_dirs})
|
|||||||
# aggressive about warnings.
|
# aggressive about warnings.
|
||||||
cxx_library(gtest "${cxx_strict}" src/gtest-all.cc)
|
cxx_library(gtest "${cxx_strict}" src/gtest-all.cc)
|
||||||
set_target_properties(gtest PROPERTIES VERSION ${GOOGLETEST_VERSION})
|
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)
|
cxx_library(gtest_main "${cxx_strict}" src/gtest_main.cc)
|
||||||
set_target_properties(gtest_main PROPERTIES VERSION ${GOOGLETEST_VERSION})
|
set_target_properties(gtest_main PROPERTIES VERSION ${GOOGLETEST_VERSION})
|
||||||
# If the CMake version supports it, attach header directory information
|
# If the CMake version supports it, attach header directory information
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ depends on which build system you use, and is usually straightforward.
|
|||||||
### Build with CMake
|
### Build with CMake
|
||||||
|
|
||||||
GoogleTest comes with a CMake build script
|
GoogleTest comes with a CMake build script
|
||||||
([CMakeLists.txt](https://github.com/google/googletest/blob/master/CMakeLists.txt))
|
([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.).
|
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
|
If you don't have CMake installed already, you can download it for free from
|
||||||
<http://www.cmake.org/>.
|
<http://www.cmake.org/>.
|
||||||
@@ -25,7 +25,7 @@ When building GoogleTest as a standalone project, the typical workflow starts
|
|||||||
with
|
with
|
||||||
|
|
||||||
```
|
```
|
||||||
git clone https://github.com/google/googletest.git -b release-1.11.0
|
git clone https://github.com/google/googletest.git -b release-1.12.1
|
||||||
cd googletest # Main directory of the cloned repository.
|
cd googletest # Main directory of the cloned repository.
|
||||||
mkdir build # Create a directory to hold the build output.
|
mkdir build # Create a directory to hold the build output.
|
||||||
cd build
|
cd build
|
||||||
@@ -94,7 +94,7 @@ include(FetchContent)
|
|||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
googletest
|
googletest
|
||||||
# Specify the commit you depend on and update it regularly.
|
# Specify the commit you depend on and update it regularly.
|
||||||
URL https://github.com/google/googletest/archive/e2239ee6043f73722e7aa812a459f54a28552929.zip
|
URL https://github.com/google/googletest/archive/5376968f6948923e2411081fd9372e71a59d8e77.zip
|
||||||
)
|
)
|
||||||
# For Windows: Prevent overriding the parent project's compiler/linker settings
|
# For Windows: Prevent overriding the parent project's compiler/linker settings
|
||||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||||
@@ -140,7 +140,7 @@ command line. Generally, these macros are named like `GTEST_XYZ` and you define
|
|||||||
them to either 1 or 0 to enable or disable a certain feature.
|
them to either 1 or 0 to enable or disable a certain feature.
|
||||||
|
|
||||||
We list the most frequently used macros below. For a complete list, see file
|
We list the most frequently used macros below. For a complete list, see file
|
||||||
[include/gtest/internal/gtest-port.h](https://github.com/google/googletest/blob/master/googletest/include/gtest/internal/gtest-port.h).
|
[include/gtest/internal/gtest-port.h](https://github.com/google/googletest/blob/main/googletest/include/gtest/internal/gtest-port.h).
|
||||||
|
|
||||||
### Multi-threaded Tests
|
### Multi-threaded Tests
|
||||||
|
|
||||||
@@ -186,9 +186,9 @@ to the compiler flags.
|
|||||||
Note: while the above steps aren't technically necessary today when using some
|
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
|
compilers (e.g. GCC), they may become necessary in the future, if we decide to
|
||||||
improve the speed of loading the library (see
|
improve the speed of loading the library (see
|
||||||
<http://gcc.gnu.org/wiki/Visibility> for details). Therefore you are recommended
|
<https://gcc.gnu.org/wiki/Visibility> for details). Therefore you are
|
||||||
to always add the above flags when using GoogleTest as a shared library.
|
recommended to always add the above flags when using GoogleTest as a shared
|
||||||
Otherwise a future release of GoogleTest may break your build script.
|
library. Otherwise a future release of GoogleTest may break your build script.
|
||||||
|
|
||||||
### Avoiding Macro Name Clashes
|
### Avoiding Macro Name Clashes
|
||||||
|
|
||||||
|
|||||||
@@ -21,8 +21,9 @@ endif (POLICY CMP0054)
|
|||||||
# This must be a macro(), as inside a function string() can only
|
# This must be a macro(), as inside a function string() can only
|
||||||
# update variables in the function scope.
|
# update variables in the function scope.
|
||||||
macro(fix_default_compiler_settings_)
|
macro(fix_default_compiler_settings_)
|
||||||
if (MSVC)
|
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC|Clang")
|
||||||
# For MSVC, CMake sets certain flags to defaults we want to override.
|
# 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
|
# This replacement code is taken from sample in the CMake Wiki at
|
||||||
# https://gitlab.kitware.com/cmake/community/wikis/FAQ#dynamic-replace.
|
# https://gitlab.kitware.com/cmake/community/wikis/FAQ#dynamic-replace.
|
||||||
foreach (flag_var
|
foreach (flag_var
|
||||||
@@ -39,6 +40,10 @@ macro(fix_default_compiler_settings_)
|
|||||||
# on CRT DLLs being available. CMake always defaults to using shared
|
# on CRT DLLs being available. CMake always defaults to using shared
|
||||||
# CRT libraries, so we override that default here.
|
# CRT libraries, so we override that default here.
|
||||||
string(REPLACE "/MD" "-MT" ${flag_var} "${${flag_var}}")
|
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()
|
endif()
|
||||||
|
|
||||||
# We prefer more strict warning checking for building Google Test.
|
# We prefer more strict warning checking for building Google Test.
|
||||||
@@ -82,7 +87,9 @@ macro(config_compiler_and_linker)
|
|||||||
# http://stackoverflow.com/questions/3232669 explains the issue.
|
# http://stackoverflow.com/questions/3232669 explains the issue.
|
||||||
set(cxx_base_flags "${cxx_base_flags} -wd4702")
|
set(cxx_base_flags "${cxx_base_flags} -wd4702")
|
||||||
# Ensure MSVC treats source files as UTF-8 encoded.
|
# Ensure MSVC treats source files as UTF-8 encoded.
|
||||||
set(cxx_base_flags "${cxx_base_flags} -utf-8")
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||||
|
set(cxx_base_flags "${cxx_base_flags} -utf-8")
|
||||||
|
endif()
|
||||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
set(cxx_base_flags "-Wall -Wshadow -Wconversion")
|
set(cxx_base_flags "-Wall -Wshadow -Wconversion")
|
||||||
set(cxx_exception_flags "-fexceptions")
|
set(cxx_exception_flags "-fexceptions")
|
||||||
@@ -160,7 +167,8 @@ function(cxx_library_with_type name type cxx_flags)
|
|||||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
||||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
||||||
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
||||||
PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
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)
|
get_target_property(pdb_debug_postfix ${name} DEBUG_POSTFIX)
|
||||||
set_target_properties(${name}
|
set_target_properties(${name}
|
||||||
@@ -189,7 +197,7 @@ function(cxx_library_with_type name type cxx_flags)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (NOT "${CMAKE_VERSION}" VERSION_LESS "3.8")
|
if (NOT "${CMAKE_VERSION}" VERSION_LESS "3.8")
|
||||||
target_compile_features(${name} PUBLIC cxx_std_11)
|
target_compile_features(${name} PUBLIC cxx_std_14)
|
||||||
endif()
|
endif()
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
@@ -242,6 +250,12 @@ function(cxx_executable name dir libs)
|
|||||||
${name} "${cxx_default}" "${libs}" "${dir}/${name}.cc" ${ARGN})
|
${name} "${cxx_default}" "${libs}" "${dir}/${name}.cc" ${ARGN})
|
||||||
endfunction()
|
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.
|
# Sets PYTHONINTERP_FOUND and PYTHON_EXECUTABLE.
|
||||||
if ("${CMAKE_VERSION}" VERSION_LESS "3.12.0")
|
if ("${CMAKE_VERSION}" VERSION_LESS "3.12.0")
|
||||||
find_package(PythonInterp)
|
find_package(PythonInterp)
|
||||||
|
|||||||
@@ -842,7 +842,7 @@ class MatchesRegexMatcher {
|
|||||||
template <class MatcheeStringType>
|
template <class MatcheeStringType>
|
||||||
bool MatchAndExplain(const MatcheeStringType& s,
|
bool MatchAndExplain(const MatcheeStringType& s,
|
||||||
MatchResultListener* /* listener */) const {
|
MatchResultListener* /* listener */) const {
|
||||||
const std::string& s2(s);
|
const std::string s2(s);
|
||||||
return full_match_ ? RE::FullMatch(s2, *regex_)
|
return full_match_ ? RE::FullMatch(s2, *regex_)
|
||||||
: RE::PartialMatch(s2, *regex_);
|
: RE::PartialMatch(s2, *regex_);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,9 @@
|
|||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <ostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "gtest/internal/gtest-port.h"
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
|
||||||
|
|||||||
@@ -407,9 +407,49 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
|
|||||||
return internal::CartesianProductHolder<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) \
|
#define TEST_P(test_suite_name, test_name) \
|
||||||
class GTEST_TEST_CLASS_NAME_(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: \
|
public: \
|
||||||
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \
|
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \
|
||||||
void TestBody() override; \
|
void TestBody() override; \
|
||||||
@@ -429,11 +469,6 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
|
|||||||
return 0; \
|
return 0; \
|
||||||
} \
|
} \
|
||||||
static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \
|
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 */ \
|
|
||||||
}; \
|
}; \
|
||||||
int GTEST_TEST_CLASS_NAME_(test_suite_name, \
|
int GTEST_TEST_CLASS_NAME_(test_suite_name, \
|
||||||
test_name)::gtest_registering_dummy_ = \
|
test_name)::gtest_registering_dummy_ = \
|
||||||
|
|||||||
@@ -108,6 +108,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <typeinfo>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -384,7 +385,7 @@ GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char32_t);
|
|||||||
|
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string);
|
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string);
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string);
|
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string);
|
||||||
#ifdef __cpp_char8_t
|
#ifdef __cpp_lib_char8_t
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char8_t, ::std::u8string);
|
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char8_t, ::std::u8string);
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char8_t, ::std::u8string);
|
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char8_t, ::std::u8string);
|
||||||
#endif
|
#endif
|
||||||
@@ -484,6 +485,81 @@ GTEST_API_ void PrintTo(__uint128_t v, ::std::ostream* os);
|
|||||||
GTEST_API_ void PrintTo(__int128_t v, ::std::ostream* os);
|
GTEST_API_ void PrintTo(__int128_t v, ::std::ostream* os);
|
||||||
#endif // __SIZEOF_INT128__
|
#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;
|
||||||
|
|
||||||
|
if (val < 1000000) {
|
||||||
|
FloatType mulfor6 = 1e10;
|
||||||
|
if (val >= 100000.0) { // 100,000 to 999,999
|
||||||
|
mulfor6 = 1.0;
|
||||||
|
} else if (val >= 10000.0) {
|
||||||
|
mulfor6 = 1e1;
|
||||||
|
} else if (val >= 1000.0) {
|
||||||
|
mulfor6 = 1e2;
|
||||||
|
} else if (val >= 100.0) {
|
||||||
|
mulfor6 = 1e3;
|
||||||
|
} else if (val >= 10.0) {
|
||||||
|
mulfor6 = 1e4;
|
||||||
|
} else if (val >= 1.0) {
|
||||||
|
mulfor6 = 1e5;
|
||||||
|
} else if (val >= 0.1) {
|
||||||
|
mulfor6 = 1e6;
|
||||||
|
} else if (val >= 0.01) {
|
||||||
|
mulfor6 = 1e7;
|
||||||
|
} else if (val >= 0.001) {
|
||||||
|
mulfor6 = 1e8;
|
||||||
|
} else if (val >= 0.0001) {
|
||||||
|
mulfor6 = 1e9;
|
||||||
|
}
|
||||||
|
if (static_cast<int32_t>(val * mulfor6 + 0.5) / mulfor6 == val) return 6;
|
||||||
|
} else if (val < 1e10) {
|
||||||
|
FloatType divfor6 = 1.0;
|
||||||
|
if (val >= 1e9) { // 1,000,000,000 to 9,999,999,999
|
||||||
|
divfor6 = 10000;
|
||||||
|
} else if (val >= 1e8) { // 100,000,000 to 999,999,999
|
||||||
|
divfor6 = 1000;
|
||||||
|
} else if (val >= 1e7) { // 10,000,000 to 99,999,999
|
||||||
|
divfor6 = 100;
|
||||||
|
} else if (val >= 1e6) { // 1,000,000 to 9,999,999
|
||||||
|
divfor6 = 10;
|
||||||
|
}
|
||||||
|
if (static_cast<int32_t>(val / divfor6 + 0.5) * divfor6 == val) return 6;
|
||||||
|
}
|
||||||
|
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.
|
// Overloads for C strings.
|
||||||
GTEST_API_ void PrintTo(const char* s, ::std::ostream* os);
|
GTEST_API_ void PrintTo(const char* s, ::std::ostream* os);
|
||||||
inline void PrintTo(char* s, ::std::ostream* os) {
|
inline void PrintTo(char* s, ::std::ostream* os) {
|
||||||
@@ -556,7 +632,7 @@ inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Overloads for ::std::u8string
|
// Overloads for ::std::u8string
|
||||||
#ifdef __cpp_char8_t
|
#ifdef __cpp_lib_char8_t
|
||||||
GTEST_API_ void PrintU8StringTo(const ::std::u8string& s, ::std::ostream* os);
|
GTEST_API_ void PrintU8StringTo(const ::std::u8string& s, ::std::ostream* os);
|
||||||
inline void PrintTo(const ::std::u8string& s, ::std::ostream* os) {
|
inline void PrintTo(const ::std::u8string& s, ::std::ostream* os) {
|
||||||
PrintU8StringTo(s, os);
|
PrintU8StringTo(s, os);
|
||||||
@@ -891,6 +967,13 @@ class UniversalTersePrinter<T&> {
|
|||||||
UniversalPrint(value, os);
|
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>
|
template <typename T, size_t N>
|
||||||
class UniversalTersePrinter<T[N]> {
|
class UniversalTersePrinter<T[N]> {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -33,6 +33,8 @@
|
|||||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_
|
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_
|
||||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_
|
#define GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||||
|
|||||||
@@ -35,6 +35,8 @@
|
|||||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
#define GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
||||||
|
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
#include <ostream>
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "gtest/internal/gtest-internal.h"
|
#include "gtest/internal/gtest-internal.h"
|
||||||
|
|||||||
@@ -50,9 +50,14 @@
|
|||||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_H_
|
#define GOOGLETEST_INCLUDE_GTEST_GTEST_H_
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <iomanip>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
#include <set>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -190,6 +195,17 @@ void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
|
|||||||
const std::string& message);
|
const std::string& message);
|
||||||
std::set<std::string>* GetIgnoredParameterizedTestSuites();
|
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
|
} // namespace internal
|
||||||
|
|
||||||
// The friend relationship of some of these classes is cyclic.
|
// The friend relationship of some of these classes is cyclic.
|
||||||
@@ -285,7 +301,7 @@ class GTEST_API_ Test {
|
|||||||
// SetUp/TearDown method of Environment objects registered with Google
|
// SetUp/TearDown method of Environment objects registered with Google
|
||||||
// Test) will be output as attributes of the <testsuites> element.
|
// 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, const std::string& value);
|
||||||
static void RecordProperty(const std::string& key, int value);
|
static void RecordProperty(const std::string& key, int64_t value);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Creates a Test object.
|
// Creates a Test object.
|
||||||
@@ -1625,7 +1641,7 @@ class GTEST_API_ AssertHelper {
|
|||||||
// the GetParam() method.
|
// the GetParam() method.
|
||||||
//
|
//
|
||||||
// Use it with one of the parameter generator defining functions, like Range(),
|
// 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> {
|
// class FooTest : public ::testing::TestWithParam<int> {
|
||||||
// protected:
|
// protected:
|
||||||
@@ -1723,9 +1739,9 @@ class TestWithParam : public Test, public WithParamInterface<T> {};
|
|||||||
#define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed")
|
#define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed")
|
||||||
|
|
||||||
// Like GTEST_FAIL(), but at the given source file location.
|
// Like GTEST_FAIL(), but at the given source file location.
|
||||||
#define GTEST_FAIL_AT(file, line) \
|
#define GTEST_FAIL_AT(file, line) \
|
||||||
GTEST_MESSAGE_AT_(file, line, "Failed", \
|
return GTEST_MESSAGE_AT_(file, line, "Failed", \
|
||||||
::testing::TestPartResult::kFatalFailure)
|
::testing::TestPartResult::kFatalFailure)
|
||||||
|
|
||||||
// Define this macro to 1 to omit the definition of FAIL(), which is a
|
// Define this macro to 1 to omit the definition of FAIL(), which is a
|
||||||
// generic name and clashes with some other libraries.
|
// generic name and clashes with some other libraries.
|
||||||
@@ -2063,9 +2079,7 @@ class GTEST_API_ ScopedTrace {
|
|||||||
|
|
||||||
ScopedTrace(const ScopedTrace&) = delete;
|
ScopedTrace(const ScopedTrace&) = delete;
|
||||||
ScopedTrace& operator=(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
|
// Causes a trace (including the source file path, the current line
|
||||||
// number, and the given message) to be included in every test failure
|
// number, and the given message) to be included in every test failure
|
||||||
@@ -2189,10 +2203,17 @@ constexpr bool StaticAssertTypeEq() noexcept {
|
|||||||
#define TEST_F(test_fixture, test_name) GTEST_TEST_F(test_fixture, test_name)
|
#define TEST_F(test_fixture, test_name) GTEST_TEST_F(test_fixture, test_name)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Returns a path to temporary directory.
|
// Returns a path to a temporary directory, which should be writable. It is
|
||||||
// Tries to determine an appropriate directory for the platform.
|
// implementation-dependent whether or not the path is terminated by the
|
||||||
|
// directory-separator character.
|
||||||
GTEST_API_ std::string TempDir();
|
GTEST_API_ std::string TempDir();
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "gtest/gtest-matchers.h"
|
#include "gtest/gtest-matchers.h"
|
||||||
#include "gtest/internal/gtest-internal.h"
|
#include "gtest/internal/gtest-internal.h"
|
||||||
@@ -99,7 +100,7 @@ class GTEST_API_ DeathTest {
|
|||||||
DeathTest* const test_;
|
DeathTest* const test_;
|
||||||
ReturnSentinel(const ReturnSentinel&) = delete;
|
ReturnSentinel(const ReturnSentinel&) = delete;
|
||||||
ReturnSentinel& operator=(const ReturnSentinel&) = delete;
|
ReturnSentinel& operator=(const ReturnSentinel&) = delete;
|
||||||
} GTEST_ATTRIBUTE_UNUSED_;
|
};
|
||||||
|
|
||||||
// An enumeration of possible roles that may be taken when a death
|
// An enumeration of possible roles that may be taken when a death
|
||||||
// test is encountered. EXECUTE means that the death test logic should
|
// test is encountered. EXECUTE means that the death test logic should
|
||||||
|
|||||||
@@ -42,11 +42,16 @@
|
|||||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "gtest/internal/gtest-port.h"
|
||||||
#include "gtest/internal/gtest-string.h"
|
#include "gtest/internal/gtest-string.h"
|
||||||
|
|
||||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||||
/* class A needs to have dll-interface to be used by clients of class B */)
|
/* class A needs to have dll-interface to be used by clients of class B */)
|
||||||
|
|
||||||
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
@@ -199,6 +204,16 @@ class GTEST_API_ FilePath {
|
|||||||
// separators. Returns NULL if no path separator was found.
|
// separators. Returns NULL if no path separator was found.
|
||||||
const char* FindLastPathSeparator() const;
|
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_;
|
std::string pathname_;
|
||||||
}; // class FilePath
|
}; // class FilePath
|
||||||
|
|
||||||
@@ -207,4 +222,6 @@ class GTEST_API_ FilePath {
|
|||||||
|
|
||||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
||||||
|
|
||||||
|
#endif // GTEST_HAS_FILE_SYSTEM
|
||||||
|
|
||||||
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||||
|
|||||||
@@ -57,12 +57,14 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <functional>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "gtest/gtest-message.h"
|
#include "gtest/gtest-message.h"
|
||||||
@@ -461,7 +463,7 @@ class TestFactoryBase {
|
|||||||
TestFactoryBase& operator=(const TestFactoryBase&) = delete;
|
TestFactoryBase& operator=(const TestFactoryBase&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
// This class provides implementation of TeastFactoryBase interface.
|
// This class provides implementation of TestFactoryBase interface.
|
||||||
// It is used in TEST and TEST_F macros.
|
// It is used in TEST and TEST_F macros.
|
||||||
template <class TestClass>
|
template <class TestClass>
|
||||||
class TestFactoryImpl : public TestFactoryBase {
|
class TestFactoryImpl : public TestFactoryBase {
|
||||||
@@ -631,7 +633,7 @@ class GTEST_API_ TypedTestSuitePState {
|
|||||||
const char* registered_tests);
|
const char* registered_tests);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef ::std::map<std::string, CodeLocation> RegisteredTestsMap;
|
typedef ::std::map<std::string, CodeLocation, std::less<>> RegisteredTestsMap;
|
||||||
|
|
||||||
bool registered_;
|
bool registered_;
|
||||||
RegisteredTestsMap registered_tests_;
|
RegisteredTestsMap registered_tests_;
|
||||||
@@ -829,8 +831,7 @@ class TypeParameterizedTestSuite<Fixture, internal::None, Types> {
|
|||||||
// For example, if Foo() calls Bar(), which in turn calls
|
// For example, if Foo() calls Bar(), which in turn calls
|
||||||
// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in
|
// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in
|
||||||
// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
|
// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
|
||||||
GTEST_API_ std::string GetCurrentOsStackTraceExceptTop(UnitTest* unit_test,
|
GTEST_API_ std::string GetCurrentOsStackTraceExceptTop(int skip_count);
|
||||||
int skip_count);
|
|
||||||
|
|
||||||
// Helpers for suppressing warnings on unreachable code or constant
|
// Helpers for suppressing warnings on unreachable code or constant
|
||||||
// condition.
|
// condition.
|
||||||
|
|||||||
@@ -40,8 +40,11 @@
|
|||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <ostream>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@@ -950,6 +953,78 @@ class CartesianProductHolder {
|
|||||||
std::tuple<Gen...> generators_;
|
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 {}
|
||||||
|
|
||||||
|
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 internal
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
|
||||||
|
|||||||
@@ -111,6 +111,8 @@
|
|||||||
#define GTEST_OS_ESP32 1
|
#define GTEST_OS_ESP32 1
|
||||||
#elif defined(__XTENSA__)
|
#elif defined(__XTENSA__)
|
||||||
#define GTEST_OS_XTENSA 1
|
#define GTEST_OS_XTENSA 1
|
||||||
|
#elif defined(__hexagon__)
|
||||||
|
#define GTEST_OS_QURT 1
|
||||||
#endif // __CYGWIN__
|
#endif // __CYGWIN__
|
||||||
|
|
||||||
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
|
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
|
||||||
|
|||||||
@@ -83,6 +83,8 @@
|
|||||||
// GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that
|
// GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that
|
||||||
// std::wstring does/doesn't work (Google Test can
|
// std::wstring does/doesn't work (Google Test can
|
||||||
// be used where std::wstring is unavailable).
|
// be used where std::wstring is unavailable).
|
||||||
|
// GTEST_HAS_FILE_SYSTEM - Define it to 1/0 to indicate whether or not a
|
||||||
|
// file system is/isn't available.
|
||||||
// GTEST_HAS_SEH - Define it to 1/0 to indicate whether the
|
// GTEST_HAS_SEH - Define it to 1/0 to indicate whether the
|
||||||
// compiler supports Microsoft's "Structured
|
// compiler supports Microsoft's "Structured
|
||||||
// Exception Handling".
|
// Exception Handling".
|
||||||
@@ -255,6 +257,19 @@
|
|||||||
// deprecated; calling a marked function
|
// deprecated; calling a marked function
|
||||||
// should generate a compiler warning
|
// should generate a compiler warning
|
||||||
|
|
||||||
|
// The definition of GTEST_INTERNAL_CPLUSPLUS_LANG comes first because it can
|
||||||
|
// potentially be used as an #include guard.
|
||||||
|
#if defined(_MSVC_LANG)
|
||||||
|
#define GTEST_INTERNAL_CPLUSPLUS_LANG _MSVC_LANG
|
||||||
|
#elif defined(__cplusplus)
|
||||||
|
#define GTEST_INTERNAL_CPLUSPLUS_LANG __cplusplus
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(GTEST_INTERNAL_CPLUSPLUS_LANG) || \
|
||||||
|
GTEST_INTERNAL_CPLUSPLUS_LANG < 201402L
|
||||||
|
#error C++ versions less than C++14 are not supported.
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <ctype.h> // for isspace, etc
|
#include <ctype.h> // for isspace, etc
|
||||||
#include <stddef.h> // for ptrdiff_t
|
#include <stddef.h> // for ptrdiff_t
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -268,6 +283,7 @@
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <ostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
// #include <mutex> // Guarded by GTEST_IS_THREADSAFE below
|
// #include <mutex> // Guarded by GTEST_IS_THREADSAFE below
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
@@ -385,7 +401,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
|||||||
// On Android, <regex.h> is only available starting with Gingerbread.
|
// On Android, <regex.h> is only available starting with Gingerbread.
|
||||||
#define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9)
|
#define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9)
|
||||||
#else
|
#else
|
||||||
#define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS && !GTEST_OS_XTENSA)
|
#define GTEST_HAS_POSIX_RE \
|
||||||
|
!(GTEST_OS_WINDOWS || GTEST_OS_XTENSA || GTEST_OS_QURT)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -457,10 +474,16 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
|||||||
// no support for it at least as recent as Froyo (2.2).
|
// no support for it at least as recent as Froyo (2.2).
|
||||||
#define GTEST_HAS_STD_WSTRING \
|
#define GTEST_HAS_STD_WSTRING \
|
||||||
(!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \
|
(!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \
|
||||||
GTEST_OS_HAIKU || GTEST_OS_ESP32 || GTEST_OS_ESP8266 || GTEST_OS_XTENSA))
|
GTEST_OS_HAIKU || GTEST_OS_ESP32 || GTEST_OS_ESP8266 || \
|
||||||
|
GTEST_OS_XTENSA || GTEST_OS_QURT))
|
||||||
|
|
||||||
#endif // GTEST_HAS_STD_WSTRING
|
#endif // GTEST_HAS_STD_WSTRING
|
||||||
|
|
||||||
|
#ifndef GTEST_HAS_FILE_SYSTEM
|
||||||
|
// Most platforms support a file system.
|
||||||
|
#define GTEST_HAS_FILE_SYSTEM 1
|
||||||
|
#endif // GTEST_HAS_FILE_SYSTEM
|
||||||
|
|
||||||
// Determines whether RTTI is available.
|
// Determines whether RTTI is available.
|
||||||
#ifndef GTEST_HAS_RTTI
|
#ifndef GTEST_HAS_RTTI
|
||||||
// The user didn't tell us whether RTTI is enabled, so we need to
|
// The user didn't tell us whether RTTI is enabled, so we need to
|
||||||
@@ -578,9 +601,11 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
|||||||
// output correctness and to implement death tests.
|
// output correctness and to implement death tests.
|
||||||
#ifndef GTEST_HAS_STREAM_REDIRECTION
|
#ifndef GTEST_HAS_STREAM_REDIRECTION
|
||||||
// By default, we assume that stream redirection is supported on all
|
// By default, we assume that stream redirection is supported on all
|
||||||
// platforms except known mobile ones.
|
// platforms except known mobile / embedded ones. Also, if the port doesn't have
|
||||||
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \
|
// a file system, stream redirection is not supported.
|
||||||
GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_XTENSA
|
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \
|
||||||
|
GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_XTENSA || \
|
||||||
|
GTEST_OS_QURT || !GTEST_HAS_FILE_SYSTEM
|
||||||
#define GTEST_HAS_STREAM_REDIRECTION 0
|
#define GTEST_HAS_STREAM_REDIRECTION 0
|
||||||
#else
|
#else
|
||||||
#define GTEST_HAS_STREAM_REDIRECTION 1
|
#define GTEST_HAS_STREAM_REDIRECTION 1
|
||||||
@@ -596,7 +621,10 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
|||||||
GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA || \
|
GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA || \
|
||||||
GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_HAIKU || \
|
GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_HAIKU || \
|
||||||
GTEST_OS_GNU_HURD)
|
GTEST_OS_GNU_HURD)
|
||||||
|
// Death tests require a file system to work properly.
|
||||||
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
#define GTEST_HAS_DEATH_TEST 1
|
#define GTEST_HAS_DEATH_TEST 1
|
||||||
|
#endif // GTEST_HAS_FILE_SYSTEM
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Determines whether to support type-driven tests.
|
// Determines whether to support type-driven tests.
|
||||||
@@ -639,41 +667,53 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
|||||||
default: // NOLINT
|
default: // NOLINT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Use this annotation at the end of a struct/class definition to
|
// GTEST_HAVE_ATTRIBUTE_
|
||||||
// prevent the compiler from optimizing away instances that are never
|
|
||||||
// used. This is useful when all interesting logic happens inside the
|
|
||||||
// c'tor and / or d'tor. Example:
|
|
||||||
//
|
//
|
||||||
// struct Foo {
|
// A function-like feature checking macro that is a wrapper around
|
||||||
// Foo() { ... }
|
// `__has_attribute`, which is defined by GCC 5+ and Clang and evaluates to a
|
||||||
// } GTEST_ATTRIBUTE_UNUSED_;
|
// nonzero constant integer if the attribute is supported or 0 if not.
|
||||||
//
|
//
|
||||||
// Also use it after a variable or parameter declaration to tell the
|
// It evaluates to zero if `__has_attribute` is not defined by the compiler.
|
||||||
|
//
|
||||||
|
// GCC: https://gcc.gnu.org/gcc-5/changes.html
|
||||||
|
// Clang: https://clang.llvm.org/docs/LanguageExtensions.html
|
||||||
|
#ifdef __has_attribute
|
||||||
|
#define GTEST_HAVE_ATTRIBUTE_(x) __has_attribute(x)
|
||||||
|
#else
|
||||||
|
#define GTEST_HAVE_ATTRIBUTE_(x) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// GTEST_HAVE_FEATURE_
|
||||||
|
//
|
||||||
|
// A function-like feature checking macro that is a wrapper around
|
||||||
|
// `__has_feature`.
|
||||||
|
#ifdef __has_feature
|
||||||
|
#define GTEST_HAVE_FEATURE_(x) __has_feature(x)
|
||||||
|
#else
|
||||||
|
#define GTEST_HAVE_FEATURE_(x) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Use this annotation after a variable or parameter declaration to tell the
|
||||||
// compiler the variable/parameter does not have to be used.
|
// compiler the variable/parameter does not have to be used.
|
||||||
#if defined(__GNUC__) && !defined(COMPILER_ICC)
|
// Example:
|
||||||
|
//
|
||||||
|
// GTEST_ATTRIBUTE_UNUSED_ int foo = bar();
|
||||||
|
#if GTEST_HAVE_ATTRIBUTE_(unused)
|
||||||
#define GTEST_ATTRIBUTE_UNUSED_ __attribute__((unused))
|
#define GTEST_ATTRIBUTE_UNUSED_ __attribute__((unused))
|
||||||
#elif defined(__clang__)
|
#else
|
||||||
#if __has_attribute(unused)
|
|
||||||
#define GTEST_ATTRIBUTE_UNUSED_ __attribute__((unused))
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#ifndef GTEST_ATTRIBUTE_UNUSED_
|
|
||||||
#define GTEST_ATTRIBUTE_UNUSED_
|
#define GTEST_ATTRIBUTE_UNUSED_
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Use this annotation before a function that takes a printf format string.
|
// Use this annotation before a function that takes a printf format string.
|
||||||
#if (defined(__GNUC__) || defined(__clang__)) && !defined(COMPILER_ICC)
|
#if GTEST_HAVE_ATTRIBUTE_(format) && defined(__MINGW_PRINTF_FORMAT)
|
||||||
#if defined(__MINGW_PRINTF_FORMAT)
|
|
||||||
// MinGW has two different printf implementations. Ensure the format macro
|
// MinGW has two different printf implementations. Ensure the format macro
|
||||||
// matches the selected implementation. See
|
// matches the selected implementation. See
|
||||||
// https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/.
|
// https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/.
|
||||||
#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \
|
#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \
|
||||||
__attribute__(( \
|
__attribute__((format(__MINGW_PRINTF_FORMAT, string_index, first_to_check)))
|
||||||
__format__(__MINGW_PRINTF_FORMAT, string_index, first_to_check)))
|
#elif GTEST_HAVE_ATTRIBUTE_(format)
|
||||||
#else
|
#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \
|
||||||
#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \
|
__attribute__((format(printf, string_index, first_to_check)))
|
||||||
__attribute__((__format__(__printf__, string_index, first_to_check)))
|
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check)
|
#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check)
|
||||||
#endif
|
#endif
|
||||||
@@ -683,11 +723,11 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
|||||||
// following the argument list:
|
// following the argument list:
|
||||||
//
|
//
|
||||||
// Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_;
|
// Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_;
|
||||||
#if defined(__GNUC__) && !defined(COMPILER_ICC)
|
#if GTEST_HAVE_ATTRIBUTE_(warn_unused_result)
|
||||||
#define GTEST_MUST_USE_RESULT_ __attribute__((warn_unused_result))
|
#define GTEST_MUST_USE_RESULT_ __attribute__((warn_unused_result))
|
||||||
#else
|
#else
|
||||||
#define GTEST_MUST_USE_RESULT_
|
#define GTEST_MUST_USE_RESULT_
|
||||||
#endif // __GNUC__ && !COMPILER_ICC
|
#endif
|
||||||
|
|
||||||
// MS C++ compiler emits warning when a conditional expression is compile time
|
// MS C++ compiler emits warning when a conditional expression is compile time
|
||||||
// constant. In some contexts this warning is false positive and needs to be
|
// constant. In some contexts this warning is false positive and needs to be
|
||||||
@@ -743,7 +783,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
|||||||
#elif GTEST_CREATE_SHARED_LIBRARY
|
#elif GTEST_CREATE_SHARED_LIBRARY
|
||||||
#define GTEST_API_ __declspec(dllexport)
|
#define GTEST_API_ __declspec(dllexport)
|
||||||
#endif
|
#endif
|
||||||
#elif __GNUC__ >= 4 || defined(__clang__)
|
#elif GTEST_HAVE_ATTRIBUTE_(visibility)
|
||||||
#define GTEST_API_ __attribute__((visibility("default")))
|
#define GTEST_API_ __attribute__((visibility("default")))
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
@@ -757,20 +797,17 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
|||||||
#define GTEST_DEFAULT_DEATH_TEST_STYLE "fast"
|
#define GTEST_DEFAULT_DEATH_TEST_STYLE "fast"
|
||||||
#endif // GTEST_DEFAULT_DEATH_TEST_STYLE
|
#endif // GTEST_DEFAULT_DEATH_TEST_STYLE
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#if GTEST_HAVE_ATTRIBUTE_(noinline)
|
||||||
// Ask the compiler to never inline a given function.
|
// Ask the compiler to never inline a given function.
|
||||||
#define GTEST_NO_INLINE_ __attribute__((noinline))
|
#define GTEST_NO_INLINE_ __attribute__((noinline))
|
||||||
#else
|
#else
|
||||||
#define GTEST_NO_INLINE_
|
#define GTEST_NO_INLINE_
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__clang__)
|
#if GTEST_HAVE_ATTRIBUTE_(disable_tail_calls)
|
||||||
// Nested ifs to avoid triggering MSVC warning.
|
|
||||||
#if __has_attribute(disable_tail_calls)
|
|
||||||
// Ask the compiler not to perform tail call optimization inside
|
// Ask the compiler not to perform tail call optimization inside
|
||||||
// the marked function.
|
// the marked function.
|
||||||
#define GTEST_NO_TAIL_CALL_ __attribute__((disable_tail_calls))
|
#define GTEST_NO_TAIL_CALL_ __attribute__((disable_tail_calls))
|
||||||
#endif
|
|
||||||
#elif __GNUC__
|
#elif __GNUC__
|
||||||
#define GTEST_NO_TAIL_CALL_ \
|
#define GTEST_NO_TAIL_CALL_ \
|
||||||
__attribute__((optimize("no-optimize-sibling-calls")))
|
__attribute__((optimize("no-optimize-sibling-calls")))
|
||||||
@@ -789,50 +826,35 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
|||||||
|
|
||||||
// A function level attribute to disable checking for use of uninitialized
|
// A function level attribute to disable checking for use of uninitialized
|
||||||
// memory when built with MemorySanitizer.
|
// memory when built with MemorySanitizer.
|
||||||
#if defined(__clang__)
|
#if GTEST_HAVE_ATTRIBUTE_(no_sanitize_memory)
|
||||||
#if __has_feature(memory_sanitizer)
|
|
||||||
#define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ __attribute__((no_sanitize_memory))
|
#define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ __attribute__((no_sanitize_memory))
|
||||||
#else
|
#else
|
||||||
#define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
|
#define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
|
||||||
#endif // __has_feature(memory_sanitizer)
|
#endif
|
||||||
#else
|
|
||||||
#define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
|
|
||||||
#endif // __clang__
|
|
||||||
|
|
||||||
// A function level attribute to disable AddressSanitizer instrumentation.
|
// A function level attribute to disable AddressSanitizer instrumentation.
|
||||||
#if defined(__clang__)
|
#if GTEST_HAVE_ATTRIBUTE_(no_sanitize_address)
|
||||||
#if __has_feature(address_sanitizer)
|
|
||||||
#define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ \
|
#define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ \
|
||||||
__attribute__((no_sanitize_address))
|
__attribute__((no_sanitize_address))
|
||||||
#else
|
#else
|
||||||
#define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
#define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
||||||
#endif // __has_feature(address_sanitizer)
|
#endif
|
||||||
#else
|
|
||||||
#define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
|
||||||
#endif // __clang__
|
|
||||||
|
|
||||||
// A function level attribute to disable HWAddressSanitizer instrumentation.
|
// A function level attribute to disable HWAddressSanitizer instrumentation.
|
||||||
#if defined(__clang__)
|
#if GTEST_HAVE_FEATURE_(hwaddress_sanitizer) && \
|
||||||
#if __has_feature(hwaddress_sanitizer)
|
GTEST_HAVE_ATTRIBUTE_(no_sanitize)
|
||||||
#define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ \
|
#define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ \
|
||||||
__attribute__((no_sanitize("hwaddress")))
|
__attribute__((no_sanitize("hwaddress")))
|
||||||
#else
|
#else
|
||||||
#define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
|
#define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
|
||||||
#endif // __has_feature(hwaddress_sanitizer)
|
#endif
|
||||||
#else
|
|
||||||
#define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
|
|
||||||
#endif // __clang__
|
|
||||||
|
|
||||||
// A function level attribute to disable ThreadSanitizer instrumentation.
|
// A function level attribute to disable ThreadSanitizer instrumentation.
|
||||||
#if defined(__clang__)
|
#if GTEST_HAVE_ATTRIBUTE_(no_sanitize_thread)
|
||||||
#if __has_feature(thread_sanitizer)
|
#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ __attribute((no_sanitize_thread))
|
||||||
#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ __attribute__((no_sanitize_thread))
|
|
||||||
#else
|
#else
|
||||||
#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
|
#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
|
||||||
#endif // __has_feature(thread_sanitizer)
|
#endif
|
||||||
#else
|
|
||||||
#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
|
|
||||||
#endif // __clang__
|
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
|
|
||||||
@@ -1710,7 +1732,7 @@ typedef GTestMutexLock MutexLock;
|
|||||||
// C-linkage. Therefore it cannot be templatized to access
|
// C-linkage. Therefore it cannot be templatized to access
|
||||||
// ThreadLocal<T>. Hence the need for class
|
// ThreadLocal<T>. Hence the need for class
|
||||||
// ThreadLocalValueHolderBase.
|
// ThreadLocalValueHolderBase.
|
||||||
class ThreadLocalValueHolderBase {
|
class GTEST_API_ ThreadLocalValueHolderBase {
|
||||||
public:
|
public:
|
||||||
virtual ~ThreadLocalValueHolderBase() {}
|
virtual ~ThreadLocalValueHolderBase() {}
|
||||||
};
|
};
|
||||||
@@ -1956,12 +1978,55 @@ inline std::string StripTrailingSpaces(std::string str) {
|
|||||||
|
|
||||||
namespace posix {
|
namespace posix {
|
||||||
|
|
||||||
// Functions with a different name on Windows.
|
// File system porting.
|
||||||
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
#if GTEST_OS_WINDOWS
|
#if GTEST_OS_WINDOWS
|
||||||
|
|
||||||
typedef struct _stat StatStruct;
|
typedef struct _stat StatStruct;
|
||||||
|
|
||||||
|
#if GTEST_OS_WINDOWS_MOBILE
|
||||||
|
inline int FileNo(FILE* file) { return reinterpret_cast<int>(_fileno(file)); }
|
||||||
|
// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this
|
||||||
|
// time and thus not defined there.
|
||||||
|
#else
|
||||||
|
inline int FileNo(FILE* file) { return _fileno(file); }
|
||||||
|
inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); }
|
||||||
|
inline int RmDir(const char* dir) { return _rmdir(dir); }
|
||||||
|
inline bool IsDir(const StatStruct& st) { return (_S_IFDIR & st.st_mode) != 0; }
|
||||||
|
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||||
|
|
||||||
|
#elif GTEST_OS_ESP8266
|
||||||
|
typedef struct stat StatStruct;
|
||||||
|
|
||||||
|
inline int FileNo(FILE* file) { return fileno(file); }
|
||||||
|
inline int Stat(const char* path, StatStruct* buf) {
|
||||||
|
// stat function not implemented on ESP8266
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
inline int RmDir(const char* dir) { return rmdir(dir); }
|
||||||
|
inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
typedef struct stat StatStruct;
|
||||||
|
|
||||||
|
inline int FileNo(FILE* file) { return fileno(file); }
|
||||||
|
inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); }
|
||||||
|
#if GTEST_OS_QURT
|
||||||
|
// QuRT doesn't support any directory functions, including rmdir
|
||||||
|
inline int RmDir(const char*) { return 0; }
|
||||||
|
#else
|
||||||
|
inline int RmDir(const char* dir) { return rmdir(dir); }
|
||||||
|
#endif
|
||||||
|
inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
|
||||||
|
|
||||||
|
#endif // GTEST_OS_WINDOWS
|
||||||
|
#endif // GTEST_HAS_FILE_SYSTEM
|
||||||
|
|
||||||
|
// Other functions with a different name on Windows.
|
||||||
|
|
||||||
|
#if GTEST_OS_WINDOWS
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
#ifdef __BORLANDC__
|
||||||
inline int DoIsATTY(int fd) { return isatty(fd); }
|
inline int DoIsATTY(int fd) { return isatty(fd); }
|
||||||
inline int StrCaseCmp(const char* s1, const char* s2) {
|
inline int StrCaseCmp(const char* s1, const char* s2) {
|
||||||
@@ -1981,46 +2046,21 @@ inline int StrCaseCmp(const char* s1, const char* s2) {
|
|||||||
inline char* StrDup(const char* src) { return _strdup(src); }
|
inline char* StrDup(const char* src) { return _strdup(src); }
|
||||||
#endif // __BORLANDC__
|
#endif // __BORLANDC__
|
||||||
|
|
||||||
#if GTEST_OS_WINDOWS_MOBILE
|
|
||||||
inline int FileNo(FILE* file) { return reinterpret_cast<int>(_fileno(file)); }
|
|
||||||
// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this
|
|
||||||
// time and thus not defined there.
|
|
||||||
#else
|
|
||||||
inline int FileNo(FILE* file) { return _fileno(file); }
|
|
||||||
inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); }
|
|
||||||
inline int RmDir(const char* dir) { return _rmdir(dir); }
|
|
||||||
inline bool IsDir(const StatStruct& st) { return (_S_IFDIR & st.st_mode) != 0; }
|
|
||||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
|
||||||
|
|
||||||
#elif GTEST_OS_ESP8266
|
#elif GTEST_OS_ESP8266
|
||||||
typedef struct stat StatStruct;
|
|
||||||
|
|
||||||
inline int FileNo(FILE* file) { return fileno(file); }
|
|
||||||
inline int DoIsATTY(int fd) { return isatty(fd); }
|
inline int DoIsATTY(int fd) { return isatty(fd); }
|
||||||
inline int Stat(const char* path, StatStruct* buf) {
|
|
||||||
// stat function not implemented on ESP8266
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
inline int StrCaseCmp(const char* s1, const char* s2) {
|
inline int StrCaseCmp(const char* s1, const char* s2) {
|
||||||
return strcasecmp(s1, s2);
|
return strcasecmp(s1, s2);
|
||||||
}
|
}
|
||||||
inline char* StrDup(const char* src) { return strdup(src); }
|
inline char* StrDup(const char* src) { return strdup(src); }
|
||||||
inline int RmDir(const char* dir) { return rmdir(dir); }
|
|
||||||
inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
typedef struct stat StatStruct;
|
|
||||||
|
|
||||||
inline int FileNo(FILE* file) { return fileno(file); }
|
|
||||||
inline int DoIsATTY(int fd) { return isatty(fd); }
|
inline int DoIsATTY(int fd) { return isatty(fd); }
|
||||||
inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); }
|
|
||||||
inline int StrCaseCmp(const char* s1, const char* s2) {
|
inline int StrCaseCmp(const char* s1, const char* s2) {
|
||||||
return strcasecmp(s1, s2);
|
return strcasecmp(s1, s2);
|
||||||
}
|
}
|
||||||
inline char* StrDup(const char* src) { return strdup(src); }
|
inline char* StrDup(const char* src) { return strdup(src); }
|
||||||
inline int RmDir(const char* dir) { return rmdir(dir); }
|
|
||||||
inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
|
|
||||||
|
|
||||||
#endif // GTEST_OS_WINDOWS
|
#endif // GTEST_OS_WINDOWS
|
||||||
|
|
||||||
@@ -2042,9 +2082,10 @@ GTEST_DISABLE_MSC_DEPRECATED_PUSH_()
|
|||||||
// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and
|
// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and
|
||||||
// StrError() aren't needed on Windows CE at this time and thus not
|
// StrError() aren't needed on Windows CE at this time and thus not
|
||||||
// defined there.
|
// defined there.
|
||||||
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && \
|
#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && \
|
||||||
!GTEST_OS_WINDOWS_RT && !GTEST_OS_ESP8266 && !GTEST_OS_XTENSA
|
!GTEST_OS_WINDOWS_RT && !GTEST_OS_ESP8266 && !GTEST_OS_XTENSA && \
|
||||||
|
!GTEST_OS_QURT
|
||||||
inline int ChDir(const char* dir) { return chdir(dir); }
|
inline int ChDir(const char* dir) { return chdir(dir); }
|
||||||
#endif
|
#endif
|
||||||
inline FILE* FOpen(const char* path, const char* mode) {
|
inline FILE* FOpen(const char* path, const char* mode) {
|
||||||
@@ -2058,14 +2099,14 @@ inline FILE* FOpen(const char* path, const char* mode) {
|
|||||||
return fopen(path, mode);
|
return fopen(path, mode);
|
||||||
#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW
|
#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW
|
||||||
}
|
}
|
||||||
#if !GTEST_OS_WINDOWS_MOBILE
|
#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT
|
||||||
inline FILE* FReopen(const char* path, const char* mode, FILE* stream) {
|
inline FILE* FReopen(const char* path, const char* mode, FILE* stream) {
|
||||||
return freopen(path, mode, stream);
|
return freopen(path, mode, stream);
|
||||||
}
|
}
|
||||||
inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); }
|
inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); }
|
||||||
#endif
|
#endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT
|
||||||
inline int FClose(FILE* fp) { return fclose(fp); }
|
inline int FClose(FILE* fp) { return fclose(fp); }
|
||||||
#if !GTEST_OS_WINDOWS_MOBILE
|
#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT
|
||||||
inline int Read(int fd, void* buf, unsigned int count) {
|
inline int Read(int fd, void* buf, unsigned int count) {
|
||||||
return static_cast<int>(read(fd, buf, count));
|
return static_cast<int>(read(fd, buf, count));
|
||||||
}
|
}
|
||||||
@@ -2073,11 +2114,17 @@ inline int Write(int fd, const void* buf, unsigned int count) {
|
|||||||
return static_cast<int>(write(fd, buf, count));
|
return static_cast<int>(write(fd, buf, count));
|
||||||
}
|
}
|
||||||
inline int Close(int fd) { return close(fd); }
|
inline int Close(int fd) { return close(fd); }
|
||||||
|
#endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT
|
||||||
|
#endif // GTEST_HAS_FILE_SYSTEM
|
||||||
|
|
||||||
|
#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT
|
||||||
inline const char* StrError(int errnum) { return strerror(errnum); }
|
inline const char* StrError(int errnum) { return strerror(errnum); }
|
||||||
#endif
|
#endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT
|
||||||
|
|
||||||
inline const char* GetEnv(const char* name) {
|
inline const char* GetEnv(const char* name) {
|
||||||
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \
|
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \
|
||||||
GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_XTENSA
|
GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_XTENSA || \
|
||||||
|
GTEST_OS_QURT
|
||||||
// We are on an embedded platform, which has no environment variables.
|
// We are on an embedded platform, which has no environment variables.
|
||||||
static_cast<void>(name); // To prevent 'unused argument' warning.
|
static_cast<void>(name); // To prevent 'unused argument' warning.
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -2109,7 +2156,7 @@ GTEST_DISABLE_MSC_DEPRECATED_POP_()
|
|||||||
// MSVC-based platforms. We map the GTEST_SNPRINTF_ macro to the appropriate
|
// MSVC-based platforms. We map the GTEST_SNPRINTF_ macro to the appropriate
|
||||||
// function in order to achieve that. We use macro definition here because
|
// function in order to achieve that. We use macro definition here because
|
||||||
// snprintf is a variadic function.
|
// snprintf is a variadic function.
|
||||||
#if _MSC_VER && !GTEST_OS_WINDOWS_MOBILE
|
#if defined(_MSC_VER) && !GTEST_OS_WINDOWS_MOBILE
|
||||||
// MSVC 2005 and above support variadic macros.
|
// MSVC 2005 and above support variadic macros.
|
||||||
#define GTEST_SNPRINTF_(buffer, size, format, ...) \
|
#define GTEST_SNPRINTF_(buffer, size, format, ...) \
|
||||||
_snprintf_s(buffer, size, size, format, __VA_ARGS__)
|
_snprintf_s(buffer, size, size, format, __VA_ARGS__)
|
||||||
|
|||||||
@@ -51,6 +51,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "gtest/internal/gtest-port.h"
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
|||||||
@@ -37,6 +37,10 @@
|
|||||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
|
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
|
||||||
#define 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"
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
|
||||||
// #ifdef __GNUC__ is too general here. It is possible to use gcc without using
|
// #ifdef __GNUC__ is too general here. It is possible to use gcc without using
|
||||||
|
|||||||
@@ -249,7 +249,7 @@ static std::string DeathTestThreadWarning(size_t thread_count) {
|
|||||||
msg << "detected " << thread_count << " threads.";
|
msg << "detected " << thread_count << " threads.";
|
||||||
}
|
}
|
||||||
msg << " See "
|
msg << " See "
|
||||||
"https://github.com/google/googletest/blob/master/docs/"
|
"https://github.com/google/googletest/blob/main/docs/"
|
||||||
"advanced.md#death-tests-and-threads"
|
"advanced.md#death-tests-and-threads"
|
||||||
<< " for more explanation and suggested solutions, especially if"
|
<< " for more explanation and suggested solutions, especially if"
|
||||||
<< " this is the last message you see before your test times out.";
|
<< " this is the last message you see before your test times out.";
|
||||||
@@ -284,7 +284,7 @@ enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW };
|
|||||||
// message is propagated back to the parent process. Otherwise, the
|
// message is propagated back to the parent process. Otherwise, the
|
||||||
// message is simply printed to stderr. In either case, the program
|
// message is simply printed to stderr. In either case, the program
|
||||||
// then exits with status 1.
|
// then exits with status 1.
|
||||||
static void DeathTestAbort(const std::string& message) {
|
[[noreturn]] static void DeathTestAbort(const std::string& message) {
|
||||||
// On a POSIX system, this function may be called from a threadsafe-style
|
// On a POSIX system, this function may be called from a threadsafe-style
|
||||||
// death test child process, which operates on a very small stack. Use
|
// death test child process, which operates on a very small stack. Use
|
||||||
// the heap for any additional non-minuscule memory requirements.
|
// the heap for any additional non-minuscule memory requirements.
|
||||||
|
|||||||
@@ -57,6 +57,8 @@
|
|||||||
#define GTEST_PATH_MAX_ _POSIX_PATH_MAX
|
#define GTEST_PATH_MAX_ _POSIX_PATH_MAX
|
||||||
#endif // GTEST_OS_WINDOWS
|
#endif // GTEST_OS_WINDOWS
|
||||||
|
|
||||||
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
@@ -96,7 +98,7 @@ static bool IsPathSeparator(char c) {
|
|||||||
FilePath FilePath::GetCurrentDir() {
|
FilePath FilePath::GetCurrentDir() {
|
||||||
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \
|
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \
|
||||||
GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_ESP32 || \
|
GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_ESP32 || \
|
||||||
GTEST_OS_XTENSA
|
GTEST_OS_XTENSA || GTEST_OS_QURT
|
||||||
// These platforms do not have a current directory, so we just return
|
// These platforms do not have a current directory, so we just return
|
||||||
// something reasonable.
|
// something reasonable.
|
||||||
return FilePath(kCurrentDirectoryString);
|
return FilePath(kCurrentDirectoryString);
|
||||||
@@ -145,6 +147,45 @@ const char* FilePath::FindLastPathSeparator() const {
|
|||||||
return last_sep;
|
return last_sep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t FilePath::CalculateRootLength() const {
|
||||||
|
const auto &path = pathname_;
|
||||||
|
auto s = path.begin();
|
||||||
|
auto end = path.end();
|
||||||
|
#if GTEST_OS_WINDOWS
|
||||||
|
if (end - s >= 2 && s[1] == ':' &&
|
||||||
|
(end - s == 2 || IsPathSeparator(s[2])) &&
|
||||||
|
(('A' <= s[0] && s[0] <= 'Z') || ('a' <= s[0] && s[0] <= 'z'))) {
|
||||||
|
// A typical absolute path like "C:\Windows" or "D:"
|
||||||
|
s += 2;
|
||||||
|
if (s != end) {
|
||||||
|
++s;
|
||||||
|
}
|
||||||
|
} else if (end - s >= 3 && IsPathSeparator(*s) && IsPathSeparator(*(s + 1))
|
||||||
|
&& !IsPathSeparator(*(s + 2))) {
|
||||||
|
// Move past the "\\" prefix in a UNC path like "\\Server\Share\Folder"
|
||||||
|
s += 2;
|
||||||
|
// Skip 2 components and their following separators ("Server\" and "Share\")
|
||||||
|
for (int i = 0; i < 2; ++i) {
|
||||||
|
while (s != end) {
|
||||||
|
bool stop = IsPathSeparator(*s);
|
||||||
|
++s;
|
||||||
|
if (stop) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (s != end && IsPathSeparator(*s)) {
|
||||||
|
// A drive-rooted path like "\Windows"
|
||||||
|
++s;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (s != end && IsPathSeparator(*s)) {
|
||||||
|
++s;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return static_cast<size_t>(s - path.begin());
|
||||||
|
}
|
||||||
|
|
||||||
// Returns a copy of the FilePath with the directory part removed.
|
// Returns a copy of the FilePath with the directory part removed.
|
||||||
// Example: FilePath("path/to/file").RemoveDirectoryName() returns
|
// Example: FilePath("path/to/file").RemoveDirectoryName() returns
|
||||||
// FilePath("file"). If there is no directory part ("just_a_file"), it returns
|
// FilePath("file"). If there is no directory part ("just_a_file"), it returns
|
||||||
@@ -246,26 +287,16 @@ bool FilePath::DirectoryExists() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if pathname describes a root directory. (Windows has one
|
// Returns true if pathname describes a root directory. (Windows has one
|
||||||
// root directory per disk drive.)
|
// root directory per disk drive. UNC share roots are also included.)
|
||||||
bool FilePath::IsRootDirectory() const {
|
bool FilePath::IsRootDirectory() const {
|
||||||
#if GTEST_OS_WINDOWS
|
size_t root_length = CalculateRootLength();
|
||||||
return pathname_.length() == 3 && IsAbsolutePath();
|
return root_length > 0 && root_length == pathname_.size() &&
|
||||||
#else
|
IsPathSeparator(pathname_[root_length - 1]);
|
||||||
return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if pathname describes an absolute path.
|
// Returns true if pathname describes an absolute path.
|
||||||
bool FilePath::IsAbsolutePath() const {
|
bool FilePath::IsAbsolutePath() const {
|
||||||
const char* const name = pathname_.c_str();
|
return CalculateRootLength() > 0;
|
||||||
#if GTEST_OS_WINDOWS
|
|
||||||
return pathname_.length() >= 3 &&
|
|
||||||
((name[0] >= 'a' && name[0] <= 'z') ||
|
|
||||||
(name[0] >= 'A' && name[0] <= 'Z')) &&
|
|
||||||
name[1] == ':' && IsPathSeparator(name[2]);
|
|
||||||
#else
|
|
||||||
return IsPathSeparator(name[0]);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a pathname for a file that does not currently exist. The pathname
|
// Returns a pathname for a file that does not currently exist. The pathname
|
||||||
@@ -323,7 +354,7 @@ bool FilePath::CreateFolder() const {
|
|||||||
delete[] unicode;
|
delete[] unicode;
|
||||||
#elif GTEST_OS_WINDOWS
|
#elif GTEST_OS_WINDOWS
|
||||||
int result = _mkdir(pathname_.c_str());
|
int result = _mkdir(pathname_.c_str());
|
||||||
#elif GTEST_OS_ESP8266 || GTEST_OS_XTENSA
|
#elif GTEST_OS_ESP8266 || GTEST_OS_XTENSA || GTEST_OS_QURT
|
||||||
// do nothing
|
// do nothing
|
||||||
int result = 0;
|
int result = 0;
|
||||||
#else
|
#else
|
||||||
@@ -347,17 +378,27 @@ FilePath FilePath::RemoveTrailingPathSeparator() const {
|
|||||||
// Removes any redundant separators that might be in the pathname.
|
// Removes any redundant separators that might be in the pathname.
|
||||||
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
|
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
|
||||||
// redundancies that might be in a pathname involving "." or "..".
|
// redundancies that might be in a pathname involving "." or "..".
|
||||||
|
// Note that "\\Host\Share" does not contain a redundancy on Windows!
|
||||||
void FilePath::Normalize() {
|
void FilePath::Normalize() {
|
||||||
auto out = pathname_.begin();
|
auto out = pathname_.begin();
|
||||||
|
|
||||||
for (const char character : pathname_) {
|
auto i = pathname_.cbegin();
|
||||||
|
#if GTEST_OS_WINDOWS
|
||||||
|
// UNC paths are treated specially
|
||||||
|
if (pathname_.end() - i >= 3 && IsPathSeparator(*i) &&
|
||||||
|
IsPathSeparator(*(i + 1)) && !IsPathSeparator(*(i + 2))) {
|
||||||
|
*(out++) = kPathSeparator;
|
||||||
|
*(out++) = kPathSeparator;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
while (i != pathname_.end()) {
|
||||||
|
const char character = *i;
|
||||||
if (!IsPathSeparator(character)) {
|
if (!IsPathSeparator(character)) {
|
||||||
*(out++) = character;
|
*(out++) = character;
|
||||||
} else if (out == pathname_.begin() || *std::prev(out) != kPathSeparator) {
|
} else if (out == pathname_.begin() || *std::prev(out) != kPathSeparator) {
|
||||||
*(out++) = kPathSeparator;
|
*(out++) = kPathSeparator;
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
pathname_.erase(out, pathname_.end());
|
pathname_.erase(out, pathname_.end());
|
||||||
@@ -365,3 +406,5 @@ void FilePath::Normalize() {
|
|||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
|
||||||
|
#endif // GTEST_HAS_FILE_SYSTEM
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -212,7 +213,7 @@ class GTestFlagSaver {
|
|||||||
int32_t stack_trace_depth_;
|
int32_t stack_trace_depth_;
|
||||||
std::string stream_result_to_;
|
std::string stream_result_to_;
|
||||||
bool throw_on_failure_;
|
bool throw_on_failure_;
|
||||||
} GTEST_ATTRIBUTE_UNUSED_;
|
};
|
||||||
|
|
||||||
// Converts a Unicode code point to a narrow string in UTF-8 encoding.
|
// Converts a Unicode code point to a narrow string in UTF-8 encoding.
|
||||||
// code_point parameter is of type UInt32 because wchar_t may not be
|
// code_point parameter is of type UInt32 because wchar_t may not be
|
||||||
@@ -396,9 +397,11 @@ class GTEST_API_ UnitTestOptions {
|
|||||||
static bool MatchesFilter(const std::string& name, const char* filter);
|
static bool MatchesFilter(const std::string& name, const char* filter);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
// Returns the current application's name, removing directory path if that
|
// Returns the current application's name, removing directory path if that
|
||||||
// is present. Used by UnitTestOptions::GetOutputFile.
|
// is present. Used by UnitTestOptions::GetOutputFile.
|
||||||
GTEST_API_ FilePath GetCurrentExecutableName();
|
GTEST_API_ FilePath GetCurrentExecutableName();
|
||||||
|
#endif // GTEST_HAS_FILE_SYSTEM
|
||||||
|
|
||||||
// The role interface for getting the OS stack trace as a string.
|
// The role interface for getting the OS stack trace as a string.
|
||||||
class OsStackTraceGetterInterface {
|
class OsStackTraceGetterInterface {
|
||||||
@@ -507,9 +510,9 @@ class GTEST_API_ UnitTestImpl {
|
|||||||
virtual ~UnitTestImpl();
|
virtual ~UnitTestImpl();
|
||||||
|
|
||||||
// There are two different ways to register your own TestPartResultReporter.
|
// There are two different ways to register your own TestPartResultReporter.
|
||||||
// You can register your own repoter to listen either only for test results
|
// You can register your own reporter to listen either only for test results
|
||||||
// from the current thread or for results from all threads.
|
// from the current thread or for results from all threads.
|
||||||
// By default, each per-thread test result repoter just passes a new
|
// By default, each per-thread test result reporter just passes a new
|
||||||
// TestPartResult to the global test result reporter, which registers the
|
// TestPartResult to the global test result reporter, which registers the
|
||||||
// test part result for the currently running test.
|
// test part result for the currently running test.
|
||||||
|
|
||||||
@@ -840,9 +843,11 @@ class GTEST_API_ UnitTestImpl {
|
|||||||
// The UnitTest object that owns this implementation object.
|
// The UnitTest object that owns this implementation object.
|
||||||
UnitTest* const parent_;
|
UnitTest* const parent_;
|
||||||
|
|
||||||
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
// The working directory when the first TEST() or TEST_F() was
|
// The working directory when the first TEST() or TEST_F() was
|
||||||
// executed.
|
// executed.
|
||||||
internal::FilePath original_working_dir_;
|
internal::FilePath original_working_dir_;
|
||||||
|
#endif // GTEST_HAS_FILE_SYSTEM
|
||||||
|
|
||||||
// The default test part result reporters.
|
// The default test part result reporters.
|
||||||
DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_;
|
DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_;
|
||||||
@@ -850,7 +855,7 @@ class GTEST_API_ UnitTestImpl {
|
|||||||
default_per_thread_test_part_result_reporter_;
|
default_per_thread_test_part_result_reporter_;
|
||||||
|
|
||||||
// Points to (but doesn't own) the global test part result reporter.
|
// Points to (but doesn't own) the global test part result reporter.
|
||||||
TestPartResultReporterInterface* global_test_part_result_repoter_;
|
TestPartResultReporterInterface* global_test_part_result_reporter_;
|
||||||
|
|
||||||
// Protects read and write access to global_test_part_result_reporter_.
|
// Protects read and write access to global_test_part_result_reporter_.
|
||||||
internal::Mutex global_test_part_result_reporter_mutex_;
|
internal::Mutex global_test_part_result_reporter_mutex_;
|
||||||
|
|||||||
@@ -315,7 +315,7 @@ void PrintTo(__uint128_t v, ::std::ostream* os) {
|
|||||||
low = low / 10 + high_mod * 1844674407370955161 + carry / 10;
|
low = low / 10 + high_mod * 1844674407370955161 + carry / 10;
|
||||||
|
|
||||||
char digit = static_cast<char>(carry % 10);
|
char digit = static_cast<char>(carry % 10);
|
||||||
*--p = '0' + digit;
|
*--p = static_cast<char>('0' + digit);
|
||||||
}
|
}
|
||||||
*os << p;
|
*os << p;
|
||||||
}
|
}
|
||||||
|
|||||||
+121
-72
@@ -58,6 +58,7 @@
|
|||||||
#include "gtest/gtest-assertion-result.h"
|
#include "gtest/gtest-assertion-result.h"
|
||||||
#include "gtest/gtest-spi.h"
|
#include "gtest/gtest-spi.h"
|
||||||
#include "gtest/internal/custom/gtest.h"
|
#include "gtest/internal/custom/gtest.h"
|
||||||
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
|
||||||
#if GTEST_OS_LINUX
|
#if GTEST_OS_LINUX
|
||||||
|
|
||||||
@@ -143,6 +144,14 @@
|
|||||||
#include "absl/strings/str_replace.h"
|
#include "absl/strings/str_replace.h"
|
||||||
#endif // GTEST_HAS_ABSL
|
#endif // GTEST_HAS_ABSL
|
||||||
|
|
||||||
|
// Checks builtin compiler feature |x| while avoiding an extra layer of #ifdefs
|
||||||
|
// at the callsite.
|
||||||
|
#if defined(__has_builtin)
|
||||||
|
#define GTEST_HAS_BUILTIN(x) __has_builtin(x)
|
||||||
|
#else
|
||||||
|
#define GTEST_HAS_BUILTIN(x) 0
|
||||||
|
#endif // defined(__has_builtin)
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
|
|
||||||
using internal::CountIf;
|
using internal::CountIf;
|
||||||
@@ -186,6 +195,7 @@ const char kStackTraceMarker[] = "\nStack trace:\n";
|
|||||||
// is specified on the command line.
|
// is specified on the command line.
|
||||||
bool g_help_flag = false;
|
bool g_help_flag = false;
|
||||||
|
|
||||||
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
// Utility function to Open File for Writing
|
// Utility function to Open File for Writing
|
||||||
static FILE* OpenFileForWriting(const std::string& output_file) {
|
static FILE* OpenFileForWriting(const std::string& output_file) {
|
||||||
FILE* fileout = nullptr;
|
FILE* fileout = nullptr;
|
||||||
@@ -200,6 +210,7 @@ static FILE* OpenFileForWriting(const std::string& output_file) {
|
|||||||
}
|
}
|
||||||
return fileout;
|
return fileout;
|
||||||
}
|
}
|
||||||
|
#endif // GTEST_HAS_FILE_SYSTEM
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
@@ -372,6 +383,8 @@ GTEST_DEFINE_string_(
|
|||||||
namespace testing {
|
namespace testing {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
|
const uint32_t Random::kMaxRange;
|
||||||
|
|
||||||
// Generates a random number from [0, range), using a Linear
|
// Generates a random number from [0, range), using a Linear
|
||||||
// Congruential Generator (LCG). Crashes if 'range' is 0 or greater
|
// Congruential Generator (LCG). Crashes if 'range' is 0 or greater
|
||||||
// than kMaxRange.
|
// than kMaxRange.
|
||||||
@@ -610,6 +623,7 @@ static ::std::vector<std::string> g_argvs;
|
|||||||
#endif // defined(GTEST_CUSTOM_GET_ARGVS_)
|
#endif // defined(GTEST_CUSTOM_GET_ARGVS_)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
// Returns the current application's name, removing directory path if that
|
// Returns the current application's name, removing directory path if that
|
||||||
// is present.
|
// is present.
|
||||||
FilePath GetCurrentExecutableName() {
|
FilePath GetCurrentExecutableName() {
|
||||||
@@ -623,6 +637,7 @@ FilePath GetCurrentExecutableName() {
|
|||||||
|
|
||||||
return result.RemoveDirectoryName();
|
return result.RemoveDirectoryName();
|
||||||
}
|
}
|
||||||
|
#endif // GTEST_HAS_FILE_SYSTEM
|
||||||
|
|
||||||
// Functions for processing the gtest_output flag.
|
// Functions for processing the gtest_output flag.
|
||||||
|
|
||||||
@@ -637,6 +652,7 @@ std::string UnitTestOptions::GetOutputFormat() {
|
|||||||
static_cast<size_t>(colon - gtest_output_flag));
|
static_cast<size_t>(colon - gtest_output_flag));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
// Returns the name of the requested output file, or the default if none
|
// Returns the name of the requested output file, or the default if none
|
||||||
// was explicitly specified.
|
// was explicitly specified.
|
||||||
std::string UnitTestOptions::GetAbsolutePathToOutputFile() {
|
std::string UnitTestOptions::GetAbsolutePathToOutputFile() {
|
||||||
@@ -667,6 +683,7 @@ std::string UnitTestOptions::GetAbsolutePathToOutputFile() {
|
|||||||
GetOutputFormat().c_str()));
|
GetOutputFormat().c_str()));
|
||||||
return result.string();
|
return result.string();
|
||||||
}
|
}
|
||||||
|
#endif // GTEST_HAS_FILE_SYSTEM
|
||||||
|
|
||||||
// Returns true if and only if the wildcard pattern matches the string. Each
|
// Returns true if and only if the wildcard pattern matches the string. Each
|
||||||
// pattern consists of regular characters, single-character wildcards (?), and
|
// pattern consists of regular characters, single-character wildcards (?), and
|
||||||
@@ -1008,14 +1025,14 @@ void DefaultPerThreadTestPartResultReporter::ReportTestPartResult(
|
|||||||
TestPartResultReporterInterface*
|
TestPartResultReporterInterface*
|
||||||
UnitTestImpl::GetGlobalTestPartResultReporter() {
|
UnitTestImpl::GetGlobalTestPartResultReporter() {
|
||||||
internal::MutexLock lock(&global_test_part_result_reporter_mutex_);
|
internal::MutexLock lock(&global_test_part_result_reporter_mutex_);
|
||||||
return global_test_part_result_repoter_;
|
return global_test_part_result_reporter_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets the global test part result reporter.
|
// Sets the global test part result reporter.
|
||||||
void UnitTestImpl::SetGlobalTestPartResultReporter(
|
void UnitTestImpl::SetGlobalTestPartResultReporter(
|
||||||
TestPartResultReporterInterface* reporter) {
|
TestPartResultReporterInterface* reporter) {
|
||||||
internal::MutexLock lock(&global_test_part_result_reporter_mutex_);
|
internal::MutexLock lock(&global_test_part_result_reporter_mutex_);
|
||||||
global_test_part_result_repoter_ = reporter;
|
global_test_part_result_reporter_ = reporter;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the test part result reporter for the current thread.
|
// Returns the test part result reporter for the current thread.
|
||||||
@@ -1113,17 +1130,24 @@ std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) {
|
|||||||
// A helper class for measuring elapsed times.
|
// A helper class for measuring elapsed times.
|
||||||
class Timer {
|
class Timer {
|
||||||
public:
|
public:
|
||||||
Timer() : start_(std::chrono::steady_clock::now()) {}
|
Timer() : start_(clock::now()) {}
|
||||||
|
|
||||||
// Return time elapsed in milliseconds since the timer was created.
|
// Return time elapsed in milliseconds since the timer was created.
|
||||||
TimeInMillis Elapsed() {
|
TimeInMillis Elapsed() {
|
||||||
return std::chrono::duration_cast<std::chrono::milliseconds>(
|
return std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||||
std::chrono::steady_clock::now() - start_)
|
clock::now() - start_)
|
||||||
.count();
|
.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::chrono::steady_clock::time_point start_;
|
// Fall back to the system_clock when building with newlib on a system
|
||||||
|
// without a monotonic clock.
|
||||||
|
#if defined(_NEWLIB_VERSION) && !defined(CLOCK_MONOTONIC)
|
||||||
|
using clock = std::chrono::system_clock;
|
||||||
|
#else
|
||||||
|
using clock = std::chrono::steady_clock;
|
||||||
|
#endif
|
||||||
|
clock::time_point start_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns a timestamp as milliseconds since the epoch. Note this time may jump
|
// Returns a timestamp as milliseconds since the epoch. Note this time may jump
|
||||||
@@ -2434,12 +2458,10 @@ void Test::TearDown() {}
|
|||||||
void Test::RecordProperty(const std::string& key, const std::string& value) {
|
void Test::RecordProperty(const std::string& key, const std::string& value) {
|
||||||
UnitTest::GetInstance()->RecordProperty(key, value);
|
UnitTest::GetInstance()->RecordProperty(key, value);
|
||||||
}
|
}
|
||||||
|
// We do not define a customary serialization except for integers,
|
||||||
// Allows user supplied key value pairs to be recorded for later output.
|
// but other values could be logged in this way.
|
||||||
void Test::RecordProperty(const std::string& key, int value) {
|
void Test::RecordProperty(const std::string& key, int64_t value) {
|
||||||
Message value_message;
|
RecordProperty(key, (Message() << value).GetString());
|
||||||
value_message << value;
|
|
||||||
RecordProperty(key, value_message.GetString().c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
@@ -2711,7 +2733,8 @@ TestInfo::TestInfo(const std::string& a_test_suite_name,
|
|||||||
internal::TypeId fixture_class_id,
|
internal::TypeId fixture_class_id,
|
||||||
internal::TestFactoryBase* factory)
|
internal::TestFactoryBase* factory)
|
||||||
: test_suite_name_(a_test_suite_name),
|
: test_suite_name_(a_test_suite_name),
|
||||||
name_(a_name),
|
// begin()/end() is MSVC 17.3.3 ASAN crash workaround (GitHub issue #3997)
|
||||||
|
name_(a_name.begin(), a_name.end()),
|
||||||
type_param_(a_type_param ? new std::string(a_type_param) : nullptr),
|
type_param_(a_type_param ? new std::string(a_type_param) : nullptr),
|
||||||
value_param_(a_value_param ? new std::string(a_value_param) : nullptr),
|
value_param_(a_value_param ? new std::string(a_value_param) : nullptr),
|
||||||
location_(a_code_location),
|
location_(a_code_location),
|
||||||
@@ -2775,37 +2798,6 @@ void ReportInvalidTestSuiteType(const char* test_suite_name,
|
|||||||
code_location.line)
|
code_location.line)
|
||||||
<< " " << errors.GetString();
|
<< " " << errors.GetString();
|
||||||
}
|
}
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
// A predicate that checks the test name of a TestInfo against a known
|
|
||||||
// value.
|
|
||||||
//
|
|
||||||
// This is used for implementation of the TestSuite class only. We put
|
|
||||||
// it in the anonymous namespace to prevent polluting the outer
|
|
||||||
// namespace.
|
|
||||||
//
|
|
||||||
// TestNameIs is copyable.
|
|
||||||
class TestNameIs {
|
|
||||||
public:
|
|
||||||
// Constructor.
|
|
||||||
//
|
|
||||||
// TestNameIs has NO default constructor.
|
|
||||||
explicit TestNameIs(const char* name) : name_(name) {}
|
|
||||||
|
|
||||||
// Returns true if and only if the test name of test_info matches name_.
|
|
||||||
bool operator()(const TestInfo* test_info) const {
|
|
||||||
return test_info && test_info->name() == name_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string name_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
// This method expands all parameterized tests registered with macros TEST_P
|
// This method expands all parameterized tests registered with macros TEST_P
|
||||||
// and INSTANTIATE_TEST_SUITE_P into regular tests and registers those.
|
// and INSTANTIATE_TEST_SUITE_P into regular tests and registers those.
|
||||||
@@ -3244,17 +3236,15 @@ bool ShouldUseColor(bool stdout_is_tty) {
|
|||||||
// On non-Windows platforms, we rely on the TERM variable.
|
// On non-Windows platforms, we rely on the TERM variable.
|
||||||
const char* const term = posix::GetEnv("TERM");
|
const char* const term = posix::GetEnv("TERM");
|
||||||
const bool term_supports_color =
|
const bool term_supports_color =
|
||||||
String::CStringEquals(term, "xterm") ||
|
term != nullptr && (String::CStringEquals(term, "xterm") ||
|
||||||
String::CStringEquals(term, "xterm-color") ||
|
String::CStringEquals(term, "xterm-color") ||
|
||||||
String::CStringEquals(term, "xterm-256color") ||
|
String::CStringEquals(term, "xterm-kitty") ||
|
||||||
String::CStringEquals(term, "screen") ||
|
String::CStringEquals(term, "screen") ||
|
||||||
String::CStringEquals(term, "screen-256color") ||
|
String::CStringEquals(term, "tmux") ||
|
||||||
String::CStringEquals(term, "tmux") ||
|
String::CStringEquals(term, "rxvt-unicode") ||
|
||||||
String::CStringEquals(term, "tmux-256color") ||
|
String::CStringEquals(term, "linux") ||
|
||||||
String::CStringEquals(term, "rxvt-unicode") ||
|
String::CStringEquals(term, "cygwin") ||
|
||||||
String::CStringEquals(term, "rxvt-unicode-256color") ||
|
String::EndsWithCaseInsensitive(term, "-256color"));
|
||||||
String::CStringEquals(term, "linux") ||
|
|
||||||
String::CStringEquals(term, "cygwin");
|
|
||||||
return stdout_is_tty && term_supports_color;
|
return stdout_is_tty && term_supports_color;
|
||||||
#endif // GTEST_OS_WINDOWS
|
#endif // GTEST_OS_WINDOWS
|
||||||
}
|
}
|
||||||
@@ -3279,7 +3269,12 @@ static void ColoredPrintf(GTestColor color, const char* fmt, ...) {
|
|||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
|
|
||||||
static const bool in_color_mode =
|
static const bool in_color_mode =
|
||||||
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0);
|
ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0);
|
||||||
|
#else
|
||||||
|
false;
|
||||||
|
#endif // GTEST_HAS_FILE_SYSTEM
|
||||||
|
|
||||||
const bool use_color = in_color_mode && (color != GTestColor::kDefault);
|
const bool use_color = in_color_mode && (color != GTestColor::kDefault);
|
||||||
|
|
||||||
if (!use_color) {
|
if (!use_color) {
|
||||||
@@ -3884,6 +3879,7 @@ void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test,
|
|||||||
|
|
||||||
// End TestEventRepeater
|
// End TestEventRepeater
|
||||||
|
|
||||||
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
// This class generates an XML output file.
|
// This class generates an XML output file.
|
||||||
class XmlUnitTestResultPrinter : public EmptyTestEventListener {
|
class XmlUnitTestResultPrinter : public EmptyTestEventListener {
|
||||||
public:
|
public:
|
||||||
@@ -4431,7 +4427,9 @@ void XmlUnitTestResultPrinter::OutputXmlTestProperties(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// End XmlUnitTestResultPrinter
|
// End XmlUnitTestResultPrinter
|
||||||
|
#endif // GTEST_HAS_FILE_SYSTEM
|
||||||
|
|
||||||
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
// This class generates an JSON output file.
|
// This class generates an JSON output file.
|
||||||
class JsonUnitTestResultPrinter : public EmptyTestEventListener {
|
class JsonUnitTestResultPrinter : public EmptyTestEventListener {
|
||||||
public:
|
public:
|
||||||
@@ -4821,6 +4819,9 @@ void JsonUnitTestResultPrinter::PrintJsonUnitTest(std::ostream* stream,
|
|||||||
// If there was a test failure outside of one of the test suites (like in a
|
// If there was a test failure outside of one of the test suites (like in a
|
||||||
// test environment) include that in the output.
|
// test environment) include that in the output.
|
||||||
if (unit_test.ad_hoc_test_result().Failed()) {
|
if (unit_test.ad_hoc_test_result().Failed()) {
|
||||||
|
if (comma) {
|
||||||
|
*stream << ",\n";
|
||||||
|
}
|
||||||
OutputJsonTestSuiteForTestResult(stream, unit_test.ad_hoc_test_result());
|
OutputJsonTestSuiteForTestResult(stream, unit_test.ad_hoc_test_result());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4869,6 +4870,7 @@ std::string JsonUnitTestResultPrinter::TestPropertiesAsJson(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// End JsonUnitTestResultPrinter
|
// End JsonUnitTestResultPrinter
|
||||||
|
#endif // GTEST_HAS_FILE_SYSTEM
|
||||||
|
|
||||||
#if GTEST_CAN_STREAM_RESULTS_
|
#if GTEST_CAN_STREAM_RESULTS_
|
||||||
|
|
||||||
@@ -4886,7 +4888,8 @@ std::string StreamingListener::UrlEncode(const char* str) {
|
|||||||
case '=':
|
case '=':
|
||||||
case '&':
|
case '&':
|
||||||
case '\n':
|
case '\n':
|
||||||
result.append("%" + String::FormatByte(static_cast<unsigned char>(ch)));
|
result.push_back('%');
|
||||||
|
result.append(String::FormatByte(static_cast<unsigned char>(ch)));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
result.push_back(ch);
|
result.push_back(ch);
|
||||||
@@ -5007,6 +5010,7 @@ void OsStackTraceGetter::UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_) {
|
|||||||
#endif // GTEST_HAS_ABSL
|
#endif // GTEST_HAS_ABSL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if GTEST_HAS_DEATH_TEST
|
||||||
// A helper class that creates the premature-exit file in its
|
// A helper class that creates the premature-exit file in its
|
||||||
// constructor and deletes the file in its destructor.
|
// constructor and deletes the file in its destructor.
|
||||||
class ScopedPrematureExitFile {
|
class ScopedPrematureExitFile {
|
||||||
@@ -5026,7 +5030,7 @@ class ScopedPrematureExitFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
~ScopedPrematureExitFile() {
|
~ScopedPrematureExitFile() {
|
||||||
#if !defined GTEST_OS_ESP8266
|
#if !GTEST_OS_ESP8266
|
||||||
if (!premature_exit_filepath_.empty()) {
|
if (!premature_exit_filepath_.empty()) {
|
||||||
int retval = remove(premature_exit_filepath_.c_str());
|
int retval = remove(premature_exit_filepath_.c_str());
|
||||||
if (retval) {
|
if (retval) {
|
||||||
@@ -5044,6 +5048,7 @@ class ScopedPrematureExitFile {
|
|||||||
ScopedPrematureExitFile(const ScopedPrematureExitFile&) = delete;
|
ScopedPrematureExitFile(const ScopedPrematureExitFile&) = delete;
|
||||||
ScopedPrematureExitFile& operator=(const ScopedPrematureExitFile&) = delete;
|
ScopedPrematureExitFile& operator=(const ScopedPrematureExitFile&) = delete;
|
||||||
};
|
};
|
||||||
|
#endif // GTEST_HAS_DEATH_TEST
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
@@ -5331,6 +5336,10 @@ void UnitTest::AddTestPartResult(TestPartResult::Type result_type,
|
|||||||
(defined(__x86_64__) || defined(__i386__)))
|
(defined(__x86_64__) || defined(__i386__)))
|
||||||
// with clang/gcc we can achieve the same effect on x86 by invoking int3
|
// with clang/gcc we can achieve the same effect on x86 by invoking int3
|
||||||
asm("int3");
|
asm("int3");
|
||||||
|
#elif GTEST_HAS_BUILTIN(__builtin_trap)
|
||||||
|
__builtin_trap();
|
||||||
|
#elif defined(SIGTRAP)
|
||||||
|
raise(SIGTRAP);
|
||||||
#else
|
#else
|
||||||
// Dereference nullptr through a volatile pointer to prevent the compiler
|
// Dereference nullptr through a volatile pointer to prevent the compiler
|
||||||
// from removing. We use this rather than abort() or __builtin_trap() for
|
// from removing. We use this rather than abort() or __builtin_trap() for
|
||||||
@@ -5365,6 +5374,7 @@ void UnitTest::RecordProperty(const std::string& key,
|
|||||||
// We don't protect this under mutex_, as we only support calling it
|
// We don't protect this under mutex_, as we only support calling it
|
||||||
// from the main thread.
|
// from the main thread.
|
||||||
int UnitTest::Run() {
|
int UnitTest::Run() {
|
||||||
|
#if GTEST_HAS_DEATH_TEST
|
||||||
const bool in_death_test_child_process =
|
const bool in_death_test_child_process =
|
||||||
GTEST_FLAG_GET(internal_run_death_test).length() > 0;
|
GTEST_FLAG_GET(internal_run_death_test).length() > 0;
|
||||||
|
|
||||||
@@ -5393,6 +5403,7 @@ int UnitTest::Run() {
|
|||||||
in_death_test_child_process
|
in_death_test_child_process
|
||||||
? nullptr
|
? nullptr
|
||||||
: internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE"));
|
: internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE"));
|
||||||
|
#endif // GTEST_HAS_DEATH_TEST
|
||||||
|
|
||||||
// Captures the value of GTEST_FLAG(catch_exceptions). This value will be
|
// Captures the value of GTEST_FLAG(catch_exceptions). This value will be
|
||||||
// used for the duration of the program.
|
// used for the duration of the program.
|
||||||
@@ -5448,11 +5459,13 @@ int UnitTest::Run() {
|
|||||||
: 1;
|
: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
// Returns the working directory when the first TEST() or TEST_F() was
|
// Returns the working directory when the first TEST() or TEST_F() was
|
||||||
// executed.
|
// executed.
|
||||||
const char* UnitTest::original_working_dir() const {
|
const char* UnitTest::original_working_dir() const {
|
||||||
return impl_->original_working_dir_.c_str();
|
return impl_->original_working_dir_.c_str();
|
||||||
}
|
}
|
||||||
|
#endif // GTEST_HAS_FILE_SYSTEM
|
||||||
|
|
||||||
// Returns the TestSuite object for the test that's currently running,
|
// Returns the TestSuite object for the test that's currently running,
|
||||||
// or NULL if no test is running.
|
// or NULL if no test is running.
|
||||||
@@ -5516,7 +5529,7 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent)
|
|||||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4355 /* using this in initializer */)
|
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4355 /* using this in initializer */)
|
||||||
default_global_test_part_result_reporter_(this),
|
default_global_test_part_result_reporter_(this),
|
||||||
default_per_thread_test_part_result_reporter_(this),
|
default_per_thread_test_part_result_reporter_(this),
|
||||||
GTEST_DISABLE_MSC_WARNINGS_POP_() global_test_part_result_repoter_(
|
GTEST_DISABLE_MSC_WARNINGS_POP_() global_test_part_result_reporter_(
|
||||||
&default_global_test_part_result_reporter_),
|
&default_global_test_part_result_reporter_),
|
||||||
per_thread_test_part_result_reporter_(
|
per_thread_test_part_result_reporter_(
|
||||||
&default_per_thread_test_part_result_reporter_),
|
&default_per_thread_test_part_result_reporter_),
|
||||||
@@ -5585,6 +5598,7 @@ void UnitTestImpl::SuppressTestEventsIfInSubprocess() {
|
|||||||
// UnitTestOptions. Must not be called before InitGoogleTest.
|
// UnitTestOptions. Must not be called before InitGoogleTest.
|
||||||
void UnitTestImpl::ConfigureXmlOutput() {
|
void UnitTestImpl::ConfigureXmlOutput() {
|
||||||
const std::string& output_format = UnitTestOptions::GetOutputFormat();
|
const std::string& output_format = UnitTestOptions::GetOutputFormat();
|
||||||
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
if (output_format == "xml") {
|
if (output_format == "xml") {
|
||||||
listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter(
|
listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter(
|
||||||
UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
|
UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
|
||||||
@@ -5595,6 +5609,10 @@ void UnitTestImpl::ConfigureXmlOutput() {
|
|||||||
GTEST_LOG_(WARNING) << "WARNING: unrecognized output format \""
|
GTEST_LOG_(WARNING) << "WARNING: unrecognized output format \""
|
||||||
<< output_format << "\" ignored.";
|
<< output_format << "\" ignored.";
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
GTEST_LOG_(ERROR) << "ERROR: alternative output formats require "
|
||||||
|
<< "GTEST_HAS_FILE_SYSTEM to be enabled";
|
||||||
|
#endif // GTEST_HAS_FILE_SYSTEM
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GTEST_CAN_STREAM_RESULTS_
|
#if GTEST_CAN_STREAM_RESULTS_
|
||||||
@@ -5757,10 +5775,12 @@ bool UnitTestImpl::RunAllTests() {
|
|||||||
// user didn't call InitGoogleTest.
|
// user didn't call InitGoogleTest.
|
||||||
PostFlagParsingInit();
|
PostFlagParsingInit();
|
||||||
|
|
||||||
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
// Even if sharding is not on, test runners may want to use the
|
// Even if sharding is not on, test runners may want to use the
|
||||||
// GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding
|
// GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding
|
||||||
// protocol.
|
// protocol.
|
||||||
internal::WriteToShardStatusFileIfNeeded();
|
internal::WriteToShardStatusFileIfNeeded();
|
||||||
|
#endif // GTEST_HAS_FILE_SYSTEM
|
||||||
|
|
||||||
// True if and only if we are in a subprocess for running a thread-safe-style
|
// True if and only if we are in a subprocess for running a thread-safe-style
|
||||||
// death test.
|
// death test.
|
||||||
@@ -5940,6 +5960,7 @@ bool UnitTestImpl::RunAllTests() {
|
|||||||
return !failed;
|
return !failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file
|
// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file
|
||||||
// if the variable is present. If a file already exists at this location, this
|
// if the variable is present. If a file already exists at this location, this
|
||||||
// function will write over it. If the variable is present, but the file cannot
|
// function will write over it. If the variable is present, but the file cannot
|
||||||
@@ -5959,6 +5980,7 @@ void WriteToShardStatusFileIfNeeded() {
|
|||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // GTEST_HAS_FILE_SYSTEM
|
||||||
|
|
||||||
// Checks whether sharding is enabled by examining the relevant
|
// Checks whether sharding is enabled by examining the relevant
|
||||||
// environment variable values. If the variables are present,
|
// environment variable values. If the variables are present,
|
||||||
@@ -6037,7 +6059,7 @@ bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) {
|
|||||||
// each TestSuite and TestInfo object.
|
// each TestSuite and TestInfo object.
|
||||||
// If shard_tests == true, further filters tests based on sharding
|
// If shard_tests == true, further filters tests based on sharding
|
||||||
// variables in the environment - see
|
// variables in the environment - see
|
||||||
// https://github.com/google/googletest/blob/master/googletest/docs/advanced.md
|
// https://github.com/google/googletest/blob/main/docs/advanced.md
|
||||||
// . Returns the number of tests that should run.
|
// . Returns the number of tests that should run.
|
||||||
int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
|
int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
|
||||||
const int32_t total_shards = shard_tests == HONOR_SHARDING_PROTOCOL
|
const int32_t total_shards = shard_tests == HONOR_SHARDING_PROTOCOL
|
||||||
@@ -6150,6 +6172,7 @@ void UnitTestImpl::ListTestsMatchingFilter() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
const std::string& output_format = UnitTestOptions::GetOutputFormat();
|
const std::string& output_format = UnitTestOptions::GetOutputFormat();
|
||||||
if (output_format == "xml" || output_format == "json") {
|
if (output_format == "xml" || output_format == "json") {
|
||||||
FILE* fileout = OpenFileForWriting(
|
FILE* fileout = OpenFileForWriting(
|
||||||
@@ -6167,6 +6190,7 @@ void UnitTestImpl::ListTestsMatchingFilter() {
|
|||||||
fprintf(fileout, "%s", StringStreamToString(&stream).c_str());
|
fprintf(fileout, "%s", StringStreamToString(&stream).c_str());
|
||||||
fclose(fileout);
|
fclose(fileout);
|
||||||
}
|
}
|
||||||
|
#endif // GTEST_HAS_FILE_SYSTEM
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets the OS stack trace getter.
|
// Sets the OS stack trace getter.
|
||||||
@@ -6245,7 +6269,7 @@ void UnitTestImpl::UnshuffleTests() {
|
|||||||
// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in
|
// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in
|
||||||
// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
|
// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
|
||||||
GTEST_NO_INLINE_ GTEST_NO_TAIL_CALL_ std::string
|
GTEST_NO_INLINE_ GTEST_NO_TAIL_CALL_ std::string
|
||||||
GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, int skip_count) {
|
GetCurrentOsStackTraceExceptTop(int skip_count) {
|
||||||
// We pass skip_count + 1 to skip this wrapper function in addition
|
// We pass skip_count + 1 to skip this wrapper function in addition
|
||||||
// to what the user really wants to skip.
|
// to what the user really wants to skip.
|
||||||
return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1);
|
return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1);
|
||||||
@@ -6555,7 +6579,7 @@ static bool ParseGoogleTestFlag(const char* const arg) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GTEST_USE_OWN_FLAGFILE_FLAG_
|
#if GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM
|
||||||
static void LoadFlagsFromFile(const std::string& path) {
|
static void LoadFlagsFromFile(const std::string& path) {
|
||||||
FILE* flagfile = posix::FOpen(path.c_str(), "r");
|
FILE* flagfile = posix::FOpen(path.c_str(), "r");
|
||||||
if (!flagfile) {
|
if (!flagfile) {
|
||||||
@@ -6571,7 +6595,7 @@ static void LoadFlagsFromFile(const std::string& path) {
|
|||||||
if (!ParseGoogleTestFlag(lines[i].c_str())) g_help_flag = true;
|
if (!ParseGoogleTestFlag(lines[i].c_str())) g_help_flag = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // GTEST_USE_OWN_FLAGFILE_FLAG_
|
#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM
|
||||||
|
|
||||||
// Parses the command line for Google Test flags, without initializing
|
// Parses the command line for Google Test flags, without initializing
|
||||||
// other parts of Google Test. The type parameter CharType can be
|
// other parts of Google Test. The type parameter CharType can be
|
||||||
@@ -6588,12 +6612,12 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
|
|||||||
bool remove_flag = false;
|
bool remove_flag = false;
|
||||||
if (ParseGoogleTestFlag(arg)) {
|
if (ParseGoogleTestFlag(arg)) {
|
||||||
remove_flag = true;
|
remove_flag = true;
|
||||||
#if GTEST_USE_OWN_FLAGFILE_FLAG_
|
#if GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM
|
||||||
} else if (ParseFlag(arg, "flagfile", &flagfile_value)) {
|
} else if (ParseFlag(arg, "flagfile", &flagfile_value)) {
|
||||||
GTEST_FLAG_SET(flagfile, flagfile_value);
|
GTEST_FLAG_SET(flagfile, flagfile_value);
|
||||||
LoadFlagsFromFile(flagfile_value);
|
LoadFlagsFromFile(flagfile_value);
|
||||||
remove_flag = true;
|
remove_flag = true;
|
||||||
#endif // GTEST_USE_OWN_FLAGFILE_FLAG_
|
#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM
|
||||||
} else if (arg_string == "--help" || HasGoogleTestFlagPrefix(arg)) {
|
} else if (arg_string == "--help" || HasGoogleTestFlagPrefix(arg)) {
|
||||||
// Both help flag and unrecognized Google Test flags (excluding
|
// Both help flag and unrecognized Google Test flags (excluding
|
||||||
// internal ones) trigger help display.
|
// internal ones) trigger help display.
|
||||||
@@ -6741,12 +6765,13 @@ void InitGoogleTest() {
|
|||||||
#endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
#endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_)
|
#if !defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_) || \
|
||||||
// Return value of first environment variable that is set and contains
|
!defined(GTEST_CUSTOM_SRCDIR_FUNCTION_)
|
||||||
// a non-empty string. If there are none, return the "fallback" string.
|
// Returns the value of the first environment variable that is set and contains
|
||||||
// Since we like the temporary directory to have a directory separator suffix,
|
// a non-empty string. If there are none, returns the "fallback" string. Adds
|
||||||
// add it if not provided in the environment variable value.
|
// the director-separator character as a suffix if not provided in the
|
||||||
static std::string GetTempDirFromEnv(
|
// environment variable value.
|
||||||
|
static std::string GetDirFromEnv(
|
||||||
std::initializer_list<const char*> environment_variables,
|
std::initializer_list<const char*> environment_variables,
|
||||||
const char* fallback, char separator) {
|
const char* fallback, char separator) {
|
||||||
for (const char* variable_name : environment_variables) {
|
for (const char* variable_name : environment_variables) {
|
||||||
@@ -6766,11 +6791,35 @@ std::string TempDir() {
|
|||||||
#if defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_)
|
#if defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_)
|
||||||
return GTEST_CUSTOM_TEMPDIR_FUNCTION_();
|
return GTEST_CUSTOM_TEMPDIR_FUNCTION_();
|
||||||
#elif GTEST_OS_WINDOWS || GTEST_OS_WINDOWS_MOBILE
|
#elif GTEST_OS_WINDOWS || GTEST_OS_WINDOWS_MOBILE
|
||||||
return GetTempDirFromEnv({"TEST_TMPDIR", "TEMP"}, "\\temp\\", '\\');
|
return GetDirFromEnv({"TEST_TMPDIR", "TEMP"}, "\\temp\\", '\\');
|
||||||
#elif GTEST_OS_LINUX_ANDROID
|
#elif GTEST_OS_LINUX_ANDROID
|
||||||
return GetTempDirFromEnv({"TEST_TMPDIR", "TMPDIR"}, "/data/local/tmp/", '/');
|
return GetDirFromEnv({"TEST_TMPDIR", "TMPDIR"}, "/data/local/tmp/", '/');
|
||||||
#else
|
#else
|
||||||
return GetTempDirFromEnv({"TEST_TMPDIR", "TMPDIR"}, "/tmp/", '/');
|
return GetDirFromEnv({"TEST_TMPDIR", "TMPDIR"}, "/tmp/", '/');
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(GTEST_CUSTOM_SRCDIR_FUNCTION_)
|
||||||
|
// Returns the directory path (including terminating separator) of the current
|
||||||
|
// executable as derived from argv[0].
|
||||||
|
static std::string GetCurrentExecutableDirectory() {
|
||||||
|
internal::FilePath argv_0(internal::GetArgvs()[0]);
|
||||||
|
return argv_0.RemoveFileName().string();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::string SrcDir() {
|
||||||
|
#if defined(GTEST_CUSTOM_SRCDIR_FUNCTION_)
|
||||||
|
return GTEST_CUSTOM_SRCDIR_FUNCTION_();
|
||||||
|
#elif GTEST_OS_WINDOWS || GTEST_OS_WINDOWS_MOBILE
|
||||||
|
return GetDirFromEnv({"TEST_SRCDIR"}, GetCurrentExecutableDirectory().c_str(),
|
||||||
|
'\\');
|
||||||
|
#elif GTEST_OS_LINUX_ANDROID
|
||||||
|
return GetDirFromEnv({"TEST_SRCDIR"}, GetCurrentExecutableDirectory().c_str(),
|
||||||
|
'/');
|
||||||
|
#else
|
||||||
|
return GetDirFromEnv({"TEST_SRCDIR"}, GetCurrentExecutableDirectory().c_str(),
|
||||||
|
'/');
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,9 +32,12 @@
|
|||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
#if GTEST_OS_ESP8266 || GTEST_OS_ESP32
|
#if GTEST_OS_ESP8266 || GTEST_OS_ESP32
|
||||||
|
// Arduino-like platforms: program entry points are setup/loop instead of main.
|
||||||
|
|
||||||
#if GTEST_OS_ESP8266
|
#if GTEST_OS_ESP8266
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void setup() { testing::InitGoogleTest(); }
|
void setup() { testing::InitGoogleTest(); }
|
||||||
|
|
||||||
void loop() { RUN_ALL_TESTS(); }
|
void loop() { RUN_ALL_TESTS(); }
|
||||||
@@ -43,7 +46,16 @@ void loop() { RUN_ALL_TESTS(); }
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#elif GTEST_OS_QURT
|
||||||
|
// QuRT: program entry point is main, but argc/argv are unusable.
|
||||||
|
|
||||||
|
GTEST_API_ int main() {
|
||||||
|
printf("Running main() from %s\n", __FILE__);
|
||||||
|
testing::InitGoogleTest();
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
|
// Normal platforms: program entry point is main, argc/argv are initialized.
|
||||||
|
|
||||||
GTEST_API_ int main(int argc, char **argv) {
|
GTEST_API_ int main(int argc, char **argv) {
|
||||||
printf("Running main() from %s\n", __FILE__);
|
printf("Running main() from %s\n", __FILE__);
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ class GTestColorTest(gtest_test_utils.TestCase):
|
|||||||
self.assert_(UsesColor('cygwin', None, None))
|
self.assert_(UsesColor('cygwin', None, None))
|
||||||
self.assert_(UsesColor('xterm', None, None))
|
self.assert_(UsesColor('xterm', None, None))
|
||||||
self.assert_(UsesColor('xterm-color', None, None))
|
self.assert_(UsesColor('xterm-color', None, None))
|
||||||
|
self.assert_(UsesColor('xterm-kitty', None, None))
|
||||||
self.assert_(UsesColor('xterm-256color', None, None))
|
self.assert_(UsesColor('xterm-256color', None, None))
|
||||||
|
|
||||||
def testFlagOnly(self):
|
def testFlagOnly(self):
|
||||||
|
|||||||
@@ -35,6 +35,8 @@
|
|||||||
// This file is #included from gtest-internal.h.
|
// This file is #included from gtest-internal.h.
|
||||||
// Do not #include this file anywhere else!
|
// Do not #include this file anywhere else!
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "gtest/internal/gtest-filepath.h"
|
#include "gtest/internal/gtest-filepath.h"
|
||||||
#include "src/gtest-internal-inl.h"
|
#include "src/gtest-internal-inl.h"
|
||||||
@@ -421,8 +423,13 @@ TEST(NormalizeTest, MultipleConsecutiveSeparatorsInMidstring) {
|
|||||||
// "/bar" == //bar" == "///bar"
|
// "/bar" == //bar" == "///bar"
|
||||||
TEST(NormalizeTest, MultipleConsecutiveSeparatorsAtStringStart) {
|
TEST(NormalizeTest, MultipleConsecutiveSeparatorsAtStringStart) {
|
||||||
EXPECT_EQ(GTEST_PATH_SEP_ "bar", FilePath(GTEST_PATH_SEP_ "bar").string());
|
EXPECT_EQ(GTEST_PATH_SEP_ "bar", FilePath(GTEST_PATH_SEP_ "bar").string());
|
||||||
|
#if GTEST_OS_WINDOWS
|
||||||
|
EXPECT_EQ(GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar",
|
||||||
|
FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string());
|
||||||
|
#else
|
||||||
EXPECT_EQ(GTEST_PATH_SEP_ "bar",
|
EXPECT_EQ(GTEST_PATH_SEP_ "bar",
|
||||||
FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string());
|
FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string());
|
||||||
|
#endif
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
GTEST_PATH_SEP_ "bar",
|
GTEST_PATH_SEP_ "bar",
|
||||||
FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string());
|
FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string());
|
||||||
@@ -621,6 +628,9 @@ TEST(FilePathTest, IsAbsolutePath) {
|
|||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
FilePath("c:/" GTEST_PATH_SEP_ "is_not" GTEST_PATH_SEP_ "relative")
|
FilePath("c:/" GTEST_PATH_SEP_ "is_not" GTEST_PATH_SEP_ "relative")
|
||||||
.IsAbsolutePath());
|
.IsAbsolutePath());
|
||||||
|
EXPECT_TRUE(FilePath("d:/Windows").IsAbsolutePath());
|
||||||
|
EXPECT_TRUE(FilePath("\\\\Host\\Share").IsAbsolutePath());
|
||||||
|
EXPECT_TRUE(FilePath("\\\\Host\\Share\\Folder").IsAbsolutePath());
|
||||||
#else
|
#else
|
||||||
EXPECT_TRUE(FilePath(GTEST_PATH_SEP_ "is_not" GTEST_PATH_SEP_ "relative")
|
EXPECT_TRUE(FilePath(GTEST_PATH_SEP_ "is_not" GTEST_PATH_SEP_ "relative")
|
||||||
.IsAbsolutePath());
|
.IsAbsolutePath());
|
||||||
@@ -637,6 +647,16 @@ TEST(FilePathTest, IsRootDirectory) {
|
|||||||
EXPECT_FALSE(FilePath("b:a").IsRootDirectory());
|
EXPECT_FALSE(FilePath("b:a").IsRootDirectory());
|
||||||
EXPECT_FALSE(FilePath("8:/").IsRootDirectory());
|
EXPECT_FALSE(FilePath("8:/").IsRootDirectory());
|
||||||
EXPECT_FALSE(FilePath("c|/").IsRootDirectory());
|
EXPECT_FALSE(FilePath("c|/").IsRootDirectory());
|
||||||
|
EXPECT_TRUE(FilePath("c:/").IsRootDirectory());
|
||||||
|
EXPECT_FALSE(FilePath("d:/Windows").IsRootDirectory());
|
||||||
|
|
||||||
|
// This is for backward compatibility, since callers (even in this library)
|
||||||
|
// have assumed IsRootDirectory() implies a trailing directory separator.
|
||||||
|
EXPECT_FALSE(FilePath("\\\\Host\\Share").IsRootDirectory());
|
||||||
|
|
||||||
|
EXPECT_TRUE(FilePath("\\\\Host\\Share\\").IsRootDirectory());
|
||||||
|
EXPECT_FALSE(FilePath("\\\\Host\\Share\\.").IsRootDirectory());
|
||||||
|
EXPECT_FALSE(FilePath("\\\\Host\\Share\\C$\\").IsRootDirectory());
|
||||||
#else
|
#else
|
||||||
EXPECT_TRUE(FilePath("/").IsRootDirectory());
|
EXPECT_TRUE(FilePath("/").IsRootDirectory());
|
||||||
EXPECT_TRUE(FilePath("//").IsRootDirectory());
|
EXPECT_TRUE(FilePath("//").IsRootDirectory());
|
||||||
|
|||||||
@@ -30,6 +30,9 @@
|
|||||||
//
|
//
|
||||||
// Tests for the Message class.
|
// Tests for the Message class.
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "gtest/gtest-message.h"
|
#include "gtest/gtest-message.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,8 @@
|
|||||||
// make-files on Windows and other platforms. Do not #include this file
|
// make-files on Windows and other platforms. Do not #include this file
|
||||||
// anywhere else!
|
// anywhere else!
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
#if GTEST_OS_WINDOWS_MOBILE
|
#if GTEST_OS_WINDOWS_MOBILE
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
@@ -51,6 +52,7 @@ using ::std::vector;
|
|||||||
using ::testing::AddGlobalTestEnvironment;
|
using ::testing::AddGlobalTestEnvironment;
|
||||||
using ::testing::Bool;
|
using ::testing::Bool;
|
||||||
using ::testing::Combine;
|
using ::testing::Combine;
|
||||||
|
using ::testing::ConvertGenerator;
|
||||||
using ::testing::Message;
|
using ::testing::Message;
|
||||||
using ::testing::Range;
|
using ::testing::Range;
|
||||||
using ::testing::TestWithParam;
|
using ::testing::TestWithParam;
|
||||||
@@ -402,7 +404,7 @@ TEST(BoolTest, BoolWorks) {
|
|||||||
TEST(CombineTest, CombineWithTwoParameters) {
|
TEST(CombineTest, CombineWithTwoParameters) {
|
||||||
const char* foo = "foo";
|
const char* foo = "foo";
|
||||||
const char* bar = "bar";
|
const char* bar = "bar";
|
||||||
const ParamGenerator<std::tuple<const char*, int> > gen =
|
const ParamGenerator<std::tuple<const char*, int>> gen =
|
||||||
Combine(Values(foo, bar), Values(3, 4));
|
Combine(Values(foo, bar), Values(3, 4));
|
||||||
|
|
||||||
std::tuple<const char*, int> expected_values[] = {
|
std::tuple<const char*, int> expected_values[] = {
|
||||||
@@ -413,7 +415,7 @@ TEST(CombineTest, CombineWithTwoParameters) {
|
|||||||
|
|
||||||
// Tests that Combine() with three parameters generates the expected sequence.
|
// Tests that Combine() with three parameters generates the expected sequence.
|
||||||
TEST(CombineTest, CombineWithThreeParameters) {
|
TEST(CombineTest, CombineWithThreeParameters) {
|
||||||
const ParamGenerator<std::tuple<int, int, int> > gen =
|
const ParamGenerator<std::tuple<int, int, int>> gen =
|
||||||
Combine(Values(0, 1), Values(3, 4), Values(5, 6));
|
Combine(Values(0, 1), Values(3, 4), Values(5, 6));
|
||||||
std::tuple<int, int, int> expected_values[] = {
|
std::tuple<int, int, int> expected_values[] = {
|
||||||
std::make_tuple(0, 3, 5), std::make_tuple(0, 3, 6),
|
std::make_tuple(0, 3, 5), std::make_tuple(0, 3, 6),
|
||||||
@@ -427,7 +429,7 @@ TEST(CombineTest, CombineWithThreeParameters) {
|
|||||||
// sequence generates a sequence with the number of elements equal to the
|
// sequence generates a sequence with the number of elements equal to the
|
||||||
// number of elements in the sequence generated by the second parameter.
|
// number of elements in the sequence generated by the second parameter.
|
||||||
TEST(CombineTest, CombineWithFirstParameterSingleValue) {
|
TEST(CombineTest, CombineWithFirstParameterSingleValue) {
|
||||||
const ParamGenerator<std::tuple<int, int> > gen =
|
const ParamGenerator<std::tuple<int, int>> gen =
|
||||||
Combine(Values(42), Values(0, 1));
|
Combine(Values(42), Values(0, 1));
|
||||||
|
|
||||||
std::tuple<int, int> expected_values[] = {std::make_tuple(42, 0),
|
std::tuple<int, int> expected_values[] = {std::make_tuple(42, 0),
|
||||||
@@ -439,7 +441,7 @@ TEST(CombineTest, CombineWithFirstParameterSingleValue) {
|
|||||||
// sequence generates a sequence with the number of elements equal to the
|
// sequence generates a sequence with the number of elements equal to the
|
||||||
// number of elements in the sequence generated by the first parameter.
|
// number of elements in the sequence generated by the first parameter.
|
||||||
TEST(CombineTest, CombineWithSecondParameterSingleValue) {
|
TEST(CombineTest, CombineWithSecondParameterSingleValue) {
|
||||||
const ParamGenerator<std::tuple<int, int> > gen =
|
const ParamGenerator<std::tuple<int, int>> gen =
|
||||||
Combine(Values(0, 1), Values(42));
|
Combine(Values(0, 1), Values(42));
|
||||||
|
|
||||||
std::tuple<int, int> expected_values[] = {std::make_tuple(0, 42),
|
std::tuple<int, int> expected_values[] = {std::make_tuple(0, 42),
|
||||||
@@ -450,7 +452,7 @@ TEST(CombineTest, CombineWithSecondParameterSingleValue) {
|
|||||||
// Tests that when the first parameter produces an empty sequence,
|
// Tests that when the first parameter produces an empty sequence,
|
||||||
// Combine() produces an empty sequence, too.
|
// Combine() produces an empty sequence, too.
|
||||||
TEST(CombineTest, CombineWithFirstParameterEmptyRange) {
|
TEST(CombineTest, CombineWithFirstParameterEmptyRange) {
|
||||||
const ParamGenerator<std::tuple<int, int> > gen =
|
const ParamGenerator<std::tuple<int, int>> gen =
|
||||||
Combine(Range(0, 0), Values(0, 1));
|
Combine(Range(0, 0), Values(0, 1));
|
||||||
VerifyGeneratorIsEmpty(gen);
|
VerifyGeneratorIsEmpty(gen);
|
||||||
}
|
}
|
||||||
@@ -458,7 +460,7 @@ TEST(CombineTest, CombineWithFirstParameterEmptyRange) {
|
|||||||
// Tests that when the second parameter produces an empty sequence,
|
// Tests that when the second parameter produces an empty sequence,
|
||||||
// Combine() produces an empty sequence, too.
|
// Combine() produces an empty sequence, too.
|
||||||
TEST(CombineTest, CombineWithSecondParameterEmptyRange) {
|
TEST(CombineTest, CombineWithSecondParameterEmptyRange) {
|
||||||
const ParamGenerator<std::tuple<int, int> > gen =
|
const ParamGenerator<std::tuple<int, int>> gen =
|
||||||
Combine(Values(0, 1), Range(1, 1));
|
Combine(Values(0, 1), Range(1, 1));
|
||||||
VerifyGeneratorIsEmpty(gen);
|
VerifyGeneratorIsEmpty(gen);
|
||||||
}
|
}
|
||||||
@@ -469,7 +471,7 @@ TEST(CombineTest, CombineWithMaxNumberOfParameters) {
|
|||||||
const char* foo = "foo";
|
const char* foo = "foo";
|
||||||
const char* bar = "bar";
|
const char* bar = "bar";
|
||||||
const ParamGenerator<
|
const ParamGenerator<
|
||||||
std::tuple<const char*, int, int, int, int, int, int, int, int, int> >
|
std::tuple<const char*, int, int, int, int, int, int, int, int, int>>
|
||||||
gen =
|
gen =
|
||||||
Combine(Values(foo, bar), Values(1), Values(2), Values(3), Values(4),
|
Combine(Values(foo, bar), Values(1), Values(2), Values(3), Values(4),
|
||||||
Values(5), Values(6), Values(7), Values(8), Values(9));
|
Values(5), Values(6), Values(7), Values(8), Values(9));
|
||||||
@@ -497,11 +499,11 @@ class NonDefaultConstructAssignString {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TEST(CombineTest, NonDefaultConstructAssign) {
|
TEST(CombineTest, NonDefaultConstructAssign) {
|
||||||
const ParamGenerator<std::tuple<int, NonDefaultConstructAssignString> > gen =
|
const ParamGenerator<std::tuple<int, NonDefaultConstructAssignString>> gen =
|
||||||
Combine(Values(0, 1), Values(NonDefaultConstructAssignString("A"),
|
Combine(Values(0, 1), Values(NonDefaultConstructAssignString("A"),
|
||||||
NonDefaultConstructAssignString("B")));
|
NonDefaultConstructAssignString("B")));
|
||||||
|
|
||||||
ParamGenerator<std::tuple<int, NonDefaultConstructAssignString> >::iterator
|
ParamGenerator<std::tuple<int, NonDefaultConstructAssignString>>::iterator
|
||||||
it = gen.begin();
|
it = gen.begin();
|
||||||
|
|
||||||
EXPECT_EQ(0, std::get<0>(*it));
|
EXPECT_EQ(0, std::get<0>(*it));
|
||||||
@@ -523,6 +525,64 @@ TEST(CombineTest, NonDefaultConstructAssign) {
|
|||||||
EXPECT_TRUE(it == gen.end());
|
EXPECT_TRUE(it == gen.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class ConstructFromT {
|
||||||
|
public:
|
||||||
|
explicit ConstructFromT(const T& t) : t_(t) {}
|
||||||
|
template <typename... Args,
|
||||||
|
typename std::enable_if<sizeof...(Args) != 1, int>::type = 0>
|
||||||
|
ConstructFromT(Args&&... args) : t_(std::forward<Args>(args)...) {}
|
||||||
|
|
||||||
|
bool operator==(const ConstructFromT& other) const { return other.t_ == t_; }
|
||||||
|
|
||||||
|
const T& get() const { return t_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
T t_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST(ConvertTest, CombineWithTwoParameters) {
|
||||||
|
const char* foo = "foo";
|
||||||
|
const char* bar = "bar";
|
||||||
|
const ParamGenerator<ConstructFromT<std::tuple<const char*, int>>> gen =
|
||||||
|
ConvertGenerator<std::tuple<const char*, int>>(
|
||||||
|
Combine(Values(foo, bar), Values(3, 4)));
|
||||||
|
|
||||||
|
ConstructFromT<std::tuple<const char*, int>> expected_values[] = {
|
||||||
|
{foo, 3}, {foo, 4}, {bar, 3}, {bar, 4}};
|
||||||
|
VerifyGenerator(gen, expected_values);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ConvertTest, NonDefaultConstructAssign) {
|
||||||
|
const ParamGenerator<
|
||||||
|
ConstructFromT<std::tuple<int, NonDefaultConstructAssignString>>>
|
||||||
|
gen = ConvertGenerator<std::tuple<int, NonDefaultConstructAssignString>>(
|
||||||
|
Combine(Values(0, 1), Values(NonDefaultConstructAssignString("A"),
|
||||||
|
NonDefaultConstructAssignString("B"))));
|
||||||
|
|
||||||
|
ParamGenerator<ConstructFromT<
|
||||||
|
std::tuple<int, NonDefaultConstructAssignString>>>::iterator it =
|
||||||
|
gen.begin();
|
||||||
|
|
||||||
|
EXPECT_EQ(0, std::get<0>(it->get()));
|
||||||
|
EXPECT_EQ("A", std::get<1>(it->get()).str());
|
||||||
|
++it;
|
||||||
|
|
||||||
|
EXPECT_EQ(0, std::get<0>(it->get()));
|
||||||
|
EXPECT_EQ("B", std::get<1>(it->get()).str());
|
||||||
|
++it;
|
||||||
|
|
||||||
|
EXPECT_EQ(1, std::get<0>(it->get()));
|
||||||
|
EXPECT_EQ("A", std::get<1>(it->get()).str());
|
||||||
|
++it;
|
||||||
|
|
||||||
|
EXPECT_EQ(1, std::get<0>(it->get()));
|
||||||
|
EXPECT_EQ("B", std::get<1>(it->get()).str());
|
||||||
|
++it;
|
||||||
|
|
||||||
|
EXPECT_TRUE(it == gen.end());
|
||||||
|
}
|
||||||
|
|
||||||
// Tests that an generator produces correct sequence after being
|
// Tests that an generator produces correct sequence after being
|
||||||
// assigned from another generator.
|
// assigned from another generator.
|
||||||
TEST(ParamGeneratorTest, AssignmentWorks) {
|
TEST(ParamGeneratorTest, AssignmentWorks) {
|
||||||
@@ -821,7 +881,7 @@ TEST_F(PREFIX_WITH_MACRO(NamingTestNonParametrized),
|
|||||||
TEST(MacroNameing, LookupNames) {
|
TEST(MacroNameing, LookupNames) {
|
||||||
std::set<std::string> know_suite_names, know_test_names;
|
std::set<std::string> know_suite_names, know_test_names;
|
||||||
|
|
||||||
auto ins = testing::UnitTest::GetInstance();
|
const auto& ins = testing::UnitTest::GetInstance();
|
||||||
int ts = 0;
|
int ts = 0;
|
||||||
while (const testing::TestSuite* suite = ins->GetTestSuite(ts++)) {
|
while (const testing::TestSuite* suite = ins->GetTestSuite(ts++)) {
|
||||||
know_suite_names.insert(suite->name());
|
know_suite_names.insert(suite->name());
|
||||||
@@ -897,7 +957,7 @@ INSTANTIATE_TEST_SUITE_P(CustomParamNameLambda, CustomLambdaNamingTest,
|
|||||||
});
|
});
|
||||||
|
|
||||||
TEST(CustomNamingTest, CheckNameRegistry) {
|
TEST(CustomNamingTest, CheckNameRegistry) {
|
||||||
::testing::UnitTest* unit_test = ::testing::UnitTest::GetInstance();
|
const auto& unit_test = ::testing::UnitTest::GetInstance();
|
||||||
std::set<std::string> test_names;
|
std::set<std::string> test_names;
|
||||||
for (int suite_num = 0; suite_num < unit_test->total_test_suite_count();
|
for (int suite_num = 0; suite_num < unit_test->total_test_suite_count();
|
||||||
++suite_num) {
|
++suite_num) {
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
#include <chrono> // NOLINT
|
#include <chrono> // NOLINT
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
#include <thread> // NOLINT
|
#include <thread> // NOLINT
|
||||||
#include <utility> // For std::pair and std::make_pair.
|
#include <utility> // For std::pair and std::make_pair.
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <forward_list>
|
#include <forward_list>
|
||||||
|
#include <functional>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
@@ -193,6 +194,11 @@ OutputStream& operator<<(OutputStream& os,
|
|||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct StreamableInLocal {};
|
||||||
|
void operator<<(::std::ostream& os, const StreamableInLocal& /* x */) {
|
||||||
|
os << "StreamableInLocal";
|
||||||
|
}
|
||||||
|
|
||||||
// A user-defined streamable but recursively-defined container type in
|
// A user-defined streamable but recursively-defined container type in
|
||||||
// a user namespace, it mimics therefore std::filesystem::path or
|
// a user namespace, it mimics therefore std::filesystem::path or
|
||||||
// boost::filesystem::path.
|
// boost::filesystem::path.
|
||||||
@@ -452,7 +458,15 @@ TEST(PrintBuiltInTypeTest, Int128) {
|
|||||||
|
|
||||||
// Floating-points.
|
// Floating-points.
|
||||||
TEST(PrintBuiltInTypeTest, FloatingPoints) {
|
TEST(PrintBuiltInTypeTest, FloatingPoints) {
|
||||||
EXPECT_EQ("1.5", Print(1.5f)); // float
|
// float (32-bit precision)
|
||||||
|
EXPECT_EQ("1.5", Print(1.5f));
|
||||||
|
|
||||||
|
EXPECT_EQ("1.0999999", Print(1.09999990f));
|
||||||
|
EXPECT_EQ("1.1", Print(1.10000002f));
|
||||||
|
EXPECT_EQ("1.10000014", Print(1.10000014f));
|
||||||
|
EXPECT_EQ("9e+09", Print(9e9f));
|
||||||
|
|
||||||
|
// double
|
||||||
EXPECT_EQ("-2.5", Print(-2.5)); // double
|
EXPECT_EQ("-2.5", Print(-2.5)); // double
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1604,6 +1618,23 @@ TEST(PrintToStringTest, ContainsNonLatin) {
|
|||||||
"\n As Text: \"From ä — ẑ\"");
|
"\n As Text: \"From ä — ẑ\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(PrintToStringTest, PrintStreamableInLocal) {
|
||||||
|
EXPECT_STREQ("StreamableInLocal",
|
||||||
|
PrintToString(foo::StreamableInLocal()).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(PrintToStringTest, PrintReferenceToStreamableInLocal) {
|
||||||
|
foo::StreamableInLocal s;
|
||||||
|
std::reference_wrapper<foo::StreamableInLocal> r(s);
|
||||||
|
EXPECT_STREQ("StreamableInLocal", PrintToString(r).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(PrintToStringTest, PrintReferenceToStreamableInGlobal) {
|
||||||
|
StreamableInGlobal s;
|
||||||
|
std::reference_wrapper<StreamableInGlobal> r(s);
|
||||||
|
EXPECT_STREQ("StreamableInGlobal", PrintToString(r).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
TEST(IsValidUTF8Test, IllFormedUTF8) {
|
TEST(IsValidUTF8Test, IllFormedUTF8) {
|
||||||
// The following test strings are ill-formed UTF-8 and are printed
|
// The following test strings are ill-formed UTF-8 and are printed
|
||||||
// as hex only (or ASCII, in case of ASCII bytes) because IsValidUTF8() is
|
// as hex only (or ASCII, in case of ASCII bytes) because IsValidUTF8() is
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include "test/gtest-typed-test_test.h"
|
#include "test/gtest-typed-test_test.h"
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ const int kTypedTests = 1;
|
|||||||
// Since tests can be run in any order, the values the accessors that track
|
// Since tests can be run in any order, the values the accessors that track
|
||||||
// test execution (such as failed_test_count) can not be predicted.
|
// test execution (such as failed_test_count) can not be predicted.
|
||||||
TEST(ApiTest, UnitTestImmutableAccessorsWork) {
|
TEST(ApiTest, UnitTestImmutableAccessorsWork) {
|
||||||
UnitTest* unit_test = UnitTest::GetInstance();
|
const auto& unit_test = UnitTest::GetInstance();
|
||||||
|
|
||||||
ASSERT_EQ(2 + kTypedTestSuites, unit_test->total_test_suite_count());
|
ASSERT_EQ(2 + kTypedTestSuites, unit_test->total_test_suite_count());
|
||||||
EXPECT_EQ(1 + kTypedTestSuites, unit_test->test_suite_to_run_count());
|
EXPECT_EQ(1 + kTypedTestSuites, unit_test->test_suite_to_run_count());
|
||||||
@@ -224,7 +224,7 @@ TEST(DISABLED_Test, Dummy2) {}
|
|||||||
class FinalSuccessChecker : public Environment {
|
class FinalSuccessChecker : public Environment {
|
||||||
protected:
|
protected:
|
||||||
void TearDown() override {
|
void TearDown() override {
|
||||||
UnitTest* unit_test = UnitTest::GetInstance();
|
const auto& unit_test = UnitTest::GetInstance();
|
||||||
|
|
||||||
EXPECT_EQ(1 + kTypedTestSuites, unit_test->successful_test_suite_count());
|
EXPECT_EQ(1 + kTypedTestSuites, unit_test->successful_test_suite_count());
|
||||||
EXPECT_EQ(3 + kTypedTests, unit_test->successful_test_count());
|
EXPECT_EQ(3 + kTypedTests, unit_test->successful_test_count());
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class SetEnv {
|
||||||
|
public:
|
||||||
|
// Sets the environment value with name `name` to `value`, unless `value` is
|
||||||
|
// nullptr, in which case it unsets it. Restores the original value on
|
||||||
|
// destruction.
|
||||||
|
SetEnv(const char* name, const char* value) : name_(name) {
|
||||||
|
const char* old_value = getenv(name);
|
||||||
|
if (old_value != nullptr) {
|
||||||
|
saved_value_ = old_value;
|
||||||
|
have_saved_value_ = true;
|
||||||
|
}
|
||||||
|
if (value == nullptr) {
|
||||||
|
GTEST_CHECK_POSIX_SUCCESS_(unsetenv(name));
|
||||||
|
} else {
|
||||||
|
GTEST_CHECK_POSIX_SUCCESS_(setenv(name, value, 1 /*overwrite*/));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~SetEnv() {
|
||||||
|
if (have_saved_value_) {
|
||||||
|
GTEST_CHECK_POSIX_SUCCESS_(
|
||||||
|
setenv(name_.c_str(), saved_value_.c_str(), 1 /*overwrite*/));
|
||||||
|
} else {
|
||||||
|
GTEST_CHECK_POSIX_SUCCESS_(unsetenv(name_.c_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string name_;
|
||||||
|
bool have_saved_value_ = false;
|
||||||
|
std::string saved_value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MakeTempDir {
|
||||||
|
public:
|
||||||
|
// Creates a directory with a unique name including `testname`.
|
||||||
|
// The destructor removes it.
|
||||||
|
explicit MakeTempDir(const std::string& testname) {
|
||||||
|
// mkdtemp requires that the last 6 characters of the input pattern
|
||||||
|
// are Xs, and the string is modified by replacing those characters.
|
||||||
|
std::string pattern = "/tmp/" + testname + "_XXXXXX";
|
||||||
|
GTEST_CHECK_(mkdtemp(pattern.data()) != nullptr);
|
||||||
|
dirname_ = pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
~MakeTempDir() { GTEST_CHECK_POSIX_SUCCESS_(rmdir(dirname_.c_str())); }
|
||||||
|
|
||||||
|
const char* DirName() const { return dirname_.c_str(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string dirname_;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool StartsWith(const std::string& str, const std::string& prefix) {
|
||||||
|
return str.substr(0, prefix.size()) == prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TempDirTest, InEnvironment) {
|
||||||
|
// Since the test infrastructure might be verifying directory existence or
|
||||||
|
// even creating subdirectories, we need to be careful that the directories we
|
||||||
|
// specify are actually valid.
|
||||||
|
MakeTempDir temp_dir("TempDirTest_InEnvironment");
|
||||||
|
SetEnv set_env("TEST_TMPDIR", temp_dir.DirName());
|
||||||
|
EXPECT_TRUE(StartsWith(testing::TempDir(), temp_dir.DirName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TempDirTest, NotInEnvironment) {
|
||||||
|
SetEnv set_env("TEST_TMPDIR", nullptr);
|
||||||
|
EXPECT_NE(testing::TempDir(), "");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SrcDirTest, InEnvironment) {
|
||||||
|
// Since the test infrastructure might be verifying directory existence or
|
||||||
|
// even creating subdirectories, we need to be careful that the directories we
|
||||||
|
// specify are actually valid.
|
||||||
|
MakeTempDir temp_dir("SrcDirTest_InEnvironment");
|
||||||
|
SetEnv set_env("TEST_SRCDIR", temp_dir.DirName());
|
||||||
|
EXPECT_TRUE(StartsWith(testing::SrcDir(), temp_dir.DirName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SrcDirTest, NotInEnvironment) {
|
||||||
|
SetEnv set_env("TEST_SRCDIR", nullptr);
|
||||||
|
EXPECT_NE(testing::SrcDir(), "");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
@@ -45,6 +45,7 @@
|
|||||||
// stand-alone regression test.
|
// stand-alone regression test.
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
#include "gtest/gtest-spi.h"
|
#include "gtest/gtest-spi.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) {
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
@@ -3454,10 +3455,10 @@ TEST_F(NoFatalFailureTest, MessageIsStreamable) {
|
|||||||
TestPartResultArray gtest_failures;
|
TestPartResultArray gtest_failures;
|
||||||
{
|
{
|
||||||
ScopedFakeTestPartResultReporter gtest_reporter(>est_failures);
|
ScopedFakeTestPartResultReporter gtest_reporter(>est_failures);
|
||||||
EXPECT_NO_FATAL_FAILURE(FAIL() << "foo") << "my message";
|
EXPECT_NO_FATAL_FAILURE([] { FAIL() << "foo"; }()) << "my message";
|
||||||
}
|
}
|
||||||
ASSERT_EQ(2, gtest_failures.size());
|
ASSERT_EQ(2, gtest_failures.size());
|
||||||
EXPECT_EQ(TestPartResult::kNonFatalFailure,
|
EXPECT_EQ(TestPartResult::kFatalFailure,
|
||||||
gtest_failures.GetTestPartResult(0).type());
|
gtest_failures.GetTestPartResult(0).type());
|
||||||
EXPECT_EQ(TestPartResult::kNonFatalFailure,
|
EXPECT_EQ(TestPartResult::kNonFatalFailure,
|
||||||
gtest_failures.GetTestPartResult(1).type());
|
gtest_failures.GetTestPartResult(1).type());
|
||||||
@@ -6636,6 +6637,9 @@ TEST(ColoredOutputTest, UsesColorsWhenTermSupportsColors) {
|
|||||||
SetEnv("TERM", "xterm-color"); // TERM supports colors.
|
SetEnv("TERM", "xterm-color"); // TERM supports colors.
|
||||||
EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY.
|
EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY.
|
||||||
|
|
||||||
|
SetEnv("TERM", "xterm-kitty"); // TERM supports colors.
|
||||||
|
EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY.
|
||||||
|
|
||||||
SetEnv("TERM", "xterm-256color"); // TERM supports colors.
|
SetEnv("TERM", "xterm-256color"); // TERM supports colors.
|
||||||
EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY.
|
EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY.
|
||||||
|
|
||||||
@@ -7703,7 +7707,7 @@ auto* dynamic_test = testing::RegisterTest(
|
|||||||
__LINE__, []() -> DynamicUnitTestFixture* { return new DynamicTest; });
|
__LINE__, []() -> DynamicUnitTestFixture* { return new DynamicTest; });
|
||||||
|
|
||||||
TEST(RegisterTest, WasRegistered) {
|
TEST(RegisterTest, WasRegistered) {
|
||||||
auto* unittest = testing::UnitTest::GetInstance();
|
const auto& unittest = testing::UnitTest::GetInstance();
|
||||||
for (int i = 0; i < unittest->total_test_suite_count(); ++i) {
|
for (int i = 0; i < unittest->total_test_suite_count(); ++i) {
|
||||||
auto* tests = unittest->GetTestSuite(i);
|
auto* tests = unittest->GetTestSuite(i);
|
||||||
if (tests->name() != std::string("DynamicUnitTestFixture")) continue;
|
if (tests->name() != std::string("DynamicUnitTestFixture")) continue;
|
||||||
|
|||||||
@@ -39,5 +39,7 @@ class PropertyTwo : public testing::Test {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(PropertyTwo, TestSomeProperties) {
|
TEST_F(PropertyTwo, TestSomeProperties) {
|
||||||
RecordProperty("TestSomeProperty", 2);
|
// Validate we can write an unsigned size_t as a property
|
||||||
|
size_t prop_two = 2;
|
||||||
|
RecordProperty("TestSomeProperty", prop_two);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user