mirror of
https://github.com/google/googletest.git
synced 2025-12-06 16:57:00 +08:00
Compare commits
54 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b96fa13f5 | ||
|
|
085af2cc08 | ||
|
|
37678c92fb | ||
|
|
dedab73a68 | ||
|
|
6ec14dfd8c | ||
|
|
17d335d7c7 | ||
|
|
4fe3307fb2 | ||
|
|
b2b9072ecb | ||
|
|
e17e37a115 | ||
|
|
8dbd60f7d5 | ||
|
|
2ce9d8f2e8 | ||
|
|
279f847946 | ||
|
|
de1c609262 | ||
|
|
9706f75b8f | ||
|
|
50b8600c63 | ||
|
|
0934b7e112 | ||
|
|
4969d0ad54 | ||
|
|
9df216cc9d | ||
|
|
7917641ff9 | ||
|
|
eb2d85edd0 | ||
|
|
6986c2b575 | ||
|
|
a05c091507 | ||
|
|
244cec869d | ||
|
|
373af2e3df | ||
|
|
32f9f4c82a | ||
|
|
7e17b15f15 | ||
|
|
309dab8d4b | ||
|
|
3983f67e32 | ||
|
|
c67de11737 | ||
|
|
a45468c0fc | ||
|
|
f8ed0e687c | ||
|
|
35b75a2cba | ||
|
|
175c1b55cf | ||
|
|
1aeec48a1d | ||
|
|
0fe21ac6ef | ||
|
|
fd15f51d57 | ||
|
|
6230d316e1 | ||
|
|
28e9d1f267 | ||
|
|
7e2c425db2 | ||
|
|
e9092b12dc | ||
|
|
7427a6b5e3 | ||
|
|
7da55820cc | ||
|
|
3abc68be30 | ||
|
|
09ffd00153 | ||
|
|
6aa03e6774 | ||
|
|
16d4f8eff6 | ||
|
|
bac6a8fd8a | ||
|
|
fa8438ae6b | ||
|
|
571930618f | ||
|
|
9f79a9597a | ||
|
|
8b8ef3ff0d | ||
|
|
90a4152114 | ||
|
|
04ee1b4f2a | ||
|
|
005254dae2 |
10
BUILD.bazel
10
BUILD.bazel
@ -30,6 +30,8 @@
|
|||||||
#
|
#
|
||||||
# Bazel Build for Google C++ Testing Framework(Google Test)
|
# Bazel Build for Google C++ Testing Framework(Google Test)
|
||||||
|
|
||||||
|
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
|
||||||
|
|
||||||
package(default_visibility = ["//visibility:public"])
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
licenses(["notice"])
|
licenses(["notice"])
|
||||||
@ -151,10 +153,7 @@ cc_library(
|
|||||||
"@abseil-cpp//absl/flags:reflection",
|
"@abseil-cpp//absl/flags:reflection",
|
||||||
"@abseil-cpp//absl/flags:usage",
|
"@abseil-cpp//absl/flags:usage",
|
||||||
"@abseil-cpp//absl/strings",
|
"@abseil-cpp//absl/strings",
|
||||||
"@abseil-cpp//absl/types:any",
|
"@re2",
|
||||||
"@abseil-cpp//absl/types:optional",
|
|
||||||
"@abseil-cpp//absl/types:variant",
|
|
||||||
"@re2//:re2",
|
|
||||||
],
|
],
|
||||||
"//conditions:default": [],
|
"//conditions:default": [],
|
||||||
}) + select({
|
}) + select({
|
||||||
@ -164,7 +163,6 @@ cc_library(
|
|||||||
# Otherwise, builds targeting Fuchsia would fail to compile.
|
# Otherwise, builds targeting Fuchsia would fail to compile.
|
||||||
":fuchsia": [
|
":fuchsia": [
|
||||||
"@fuchsia_sdk//pkg/fdio",
|
"@fuchsia_sdk//pkg/fdio",
|
||||||
"@fuchsia_sdk//pkg/syslog",
|
|
||||||
"@fuchsia_sdk//pkg/zx",
|
"@fuchsia_sdk//pkg/zx",
|
||||||
],
|
],
|
||||||
"//conditions:default": [],
|
"//conditions:default": [],
|
||||||
@ -174,8 +172,8 @@ cc_library(
|
|||||||
# `gtest`, but testonly. See guidance on `gtest` for when to use this.
|
# `gtest`, but testonly. See guidance on `gtest` for when to use this.
|
||||||
alias(
|
alias(
|
||||||
name = "gtest_for_library",
|
name = "gtest_for_library",
|
||||||
actual = ":gtest",
|
|
||||||
testonly = True,
|
testonly = True,
|
||||||
|
actual = ":gtest",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Implements main() for tests using gtest. Prefer to depend on `gtest` as well
|
# Implements main() for tests using gtest. Prefer to depend on `gtest` as well
|
||||||
|
|||||||
@ -41,7 +41,7 @@ module(
|
|||||||
|
|
||||||
bazel_dep(
|
bazel_dep(
|
||||||
name = "abseil-cpp",
|
name = "abseil-cpp",
|
||||||
version = "20250127.1",
|
version = "20250814.0",
|
||||||
)
|
)
|
||||||
bazel_dep(
|
bazel_dep(
|
||||||
name = "platforms",
|
name = "platforms",
|
||||||
@ -52,6 +52,11 @@ bazel_dep(
|
|||||||
version = "2024-07-02.bcr.1",
|
version = "2024-07-02.bcr.1",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
bazel_dep(
|
||||||
|
name = "rules_cc",
|
||||||
|
version = "0.2.8"
|
||||||
|
)
|
||||||
|
|
||||||
bazel_dep(
|
bazel_dep(
|
||||||
name = "rules_python",
|
name = "rules_python",
|
||||||
version = "1.3.0",
|
version = "1.3.0",
|
||||||
|
|||||||
19
README.md
19
README.md
@ -2,30 +2,19 @@
|
|||||||
|
|
||||||
### Announcements
|
### Announcements
|
||||||
|
|
||||||
#### Live at Head
|
|
||||||
|
|
||||||
GoogleTest now follows the
|
|
||||||
[Abseil Live at Head philosophy](https://abseil.io/about/philosophy#upgrade-support).
|
|
||||||
We recommend
|
|
||||||
[updating to the latest commit in the `main` branch as often as possible](https://github.com/abseil/abseil-cpp/blob/master/FAQ.md#what-is-live-at-head-and-how-do-i-do-it).
|
|
||||||
We do publish occasional semantic versions, tagged with
|
|
||||||
`v${major}.${minor}.${patch}` (e.g. `v1.16.0`).
|
|
||||||
|
|
||||||
#### Documentation Updates
|
#### Documentation Updates
|
||||||
|
|
||||||
Our documentation is now live on GitHub Pages at
|
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.16.0
|
#### Release 1.17.0
|
||||||
|
|
||||||
[Release 1.16.0](https://github.com/google/googletest/releases/tag/v1.16.0) is
|
[Release 1.17.0](https://github.com/google/googletest/releases/tag/v1.17.0) is
|
||||||
now available.
|
now available.
|
||||||
|
|
||||||
The 1.16.x branch requires at least C++14.
|
The 1.17.x branch
|
||||||
|
[requires at least C++17](https://opensource.google/documentation/policies/cplusplus-support#c_language_standard).
|
||||||
The 1.16.x branch will be the last to support C++14. Future development will
|
|
||||||
[require at least C++17](https://opensource.google/documentation/policies/cplusplus-support#c_language_standard).
|
|
||||||
|
|
||||||
#### Continuous Integration
|
#### Continuous Integration
|
||||||
|
|
||||||
|
|||||||
12
WORKSPACE
12
WORKSPACE
@ -45,12 +45,6 @@ http_archive(
|
|||||||
load("@rules_python//python:repositories.bzl", "py_repositories")
|
load("@rules_python//python:repositories.bzl", "py_repositories")
|
||||||
py_repositories()
|
py_repositories()
|
||||||
|
|
||||||
http_archive(
|
|
||||||
name = "bazel_skylib",
|
|
||||||
sha256 = "cd55a062e763b9349921f0f5db8c3933288dc8ba4f76dd9416aac68acee3cb94",
|
|
||||||
urls = ["https://github.com/bazelbuild/bazel-skylib/releases/download/1.5.0/bazel-skylib-1.5.0.tar.gz"],
|
|
||||||
)
|
|
||||||
|
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "platforms",
|
name = "platforms",
|
||||||
urls = [
|
urls = [
|
||||||
@ -59,3 +53,9 @@ http_archive(
|
|||||||
],
|
],
|
||||||
sha256 = "29742e87275809b5e598dc2f04d86960cc7a55b3067d97221c9abbc9926bff0f",
|
sha256 = "29742e87275809b5e598dc2f04d86960cc7a55b3067d97221c9abbc9926bff0f",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
load("@bazel_features//:deps.bzl", "bazel_features_deps")
|
||||||
|
bazel_features_deps()
|
||||||
|
|
||||||
|
load("@rules_cc//cc:extensions.bzl", "compatibility_proxy_repo")
|
||||||
|
compatibility_proxy_repo()
|
||||||
|
|||||||
@ -31,15 +31,23 @@
|
|||||||
|
|
||||||
set -euox pipefail
|
set -euox pipefail
|
||||||
|
|
||||||
readonly LINUX_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20241218"
|
readonly LINUX_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20250430"
|
||||||
readonly LINUX_GCC_FLOOR_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-floor:20250205"
|
readonly LINUX_GCC_FLOOR_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-floor:20250430"
|
||||||
|
|
||||||
if [[ -z ${GTEST_ROOT:-} ]]; then
|
if [[ -z ${GTEST_ROOT:-} ]]; then
|
||||||
GTEST_ROOT="$(realpath $(dirname ${0})/..)"
|
GTEST_ROOT="$(realpath $(dirname ${0})/..)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Use Bazel Vendor mode to reduce reliance on external dependencies.
|
||||||
|
# See https://bazel.build/external/vendor and the Dockerfile for
|
||||||
|
# an explaination of how this works.
|
||||||
|
if [[ ${KOKORO_GFILE_DIR:-} ]] && [[ -f "${KOKORO_GFILE_DIR}/distdir/googletest_vendor.tar.gz" ]]; then
|
||||||
|
DOCKER_EXTRA_ARGS="--mount type=bind,source=${KOKORO_GFILE_DIR}/distdir,target=/distdir,readonly --env=BAZEL_VENDOR_ARCHIVE=/distdir/googletest_vendor.tar.gz ${DOCKER_EXTRA_ARGS:-}"
|
||||||
|
BAZEL_EXTRA_ARGS="--vendor_dir=/googletest_vendor ${BAZEL_EXTRA_ARGS:-}"
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ -z ${STD:-} ]]; then
|
if [[ -z ${STD:-} ]]; then
|
||||||
STD="c++17 c++20"
|
STD="c++17 c++20 c++23"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Test CMake + GCC
|
# Test CMake + GCC
|
||||||
@ -93,18 +101,21 @@ time docker run \
|
|||||||
--rm \
|
--rm \
|
||||||
--env="CC=/usr/local/bin/gcc" \
|
--env="CC=/usr/local/bin/gcc" \
|
||||||
--env="BAZEL_CXXOPTS=-std=c++17" \
|
--env="BAZEL_CXXOPTS=-std=c++17" \
|
||||||
|
${DOCKER_EXTRA_ARGS:-} \
|
||||||
${LINUX_GCC_FLOOR_CONTAINER} \
|
${LINUX_GCC_FLOOR_CONTAINER} \
|
||||||
|
/bin/bash --login -c "
|
||||||
/usr/local/bin/bazel test ... \
|
/usr/local/bin/bazel test ... \
|
||||||
--copt="-Wall" \
|
--copt=\"-Wall\" \
|
||||||
--copt="-Werror" \
|
--copt=\"-Werror\" \
|
||||||
--copt="-Wuninitialized" \
|
--copt=\"-Wuninitialized\" \
|
||||||
--copt="-Wundef" \
|
--copt=\"-Wundef\" \
|
||||||
--copt="-Wno-error=pragmas" \
|
--copt=\"-Wno-error=pragmas\" \
|
||||||
--enable_bzlmod=false \
|
--enable_bzlmod=false \
|
||||||
--features=external_include_paths \
|
--features=external_include_paths \
|
||||||
--keep_going \
|
--keep_going \
|
||||||
--show_timestamps \
|
--show_timestamps \
|
||||||
--test_output=errors
|
--test_output=errors \
|
||||||
|
${BAZEL_EXTRA_ARGS:-}"
|
||||||
|
|
||||||
# Test GCC
|
# Test GCC
|
||||||
for std in ${STD}; do
|
for std in ${STD}; do
|
||||||
@ -115,18 +126,21 @@ for std in ${STD}; do
|
|||||||
--rm \
|
--rm \
|
||||||
--env="CC=/usr/local/bin/gcc" \
|
--env="CC=/usr/local/bin/gcc" \
|
||||||
--env="BAZEL_CXXOPTS=-std=${std}" \
|
--env="BAZEL_CXXOPTS=-std=${std}" \
|
||||||
|
${DOCKER_EXTRA_ARGS:-} \
|
||||||
${LINUX_LATEST_CONTAINER} \
|
${LINUX_LATEST_CONTAINER} \
|
||||||
/usr/local/bin/bazel test ... \
|
/bin/bash --login -c "
|
||||||
--copt="-Wall" \
|
/usr/local/bin/bazel test ... \
|
||||||
--copt="-Werror" \
|
--copt=\"-Wall\" \
|
||||||
--copt="-Wuninitialized" \
|
--copt=\"-Werror\" \
|
||||||
--copt="-Wundef" \
|
--copt=\"-Wuninitialized\" \
|
||||||
--define="absl=${absl}" \
|
--copt=\"-Wundef\" \
|
||||||
--enable_bzlmod=true \
|
--define=\"absl=${absl}\" \
|
||||||
--features=external_include_paths \
|
--enable_bzlmod=true \
|
||||||
--keep_going \
|
--features=external_include_paths \
|
||||||
--show_timestamps \
|
--keep_going \
|
||||||
--test_output=errors
|
--show_timestamps \
|
||||||
|
--test_output=errors \
|
||||||
|
${BAZEL_EXTRA_ARGS:-}"
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
|
|
||||||
@ -139,19 +153,22 @@ for std in ${STD}; do
|
|||||||
--rm \
|
--rm \
|
||||||
--env="CC=/opt/llvm/clang/bin/clang" \
|
--env="CC=/opt/llvm/clang/bin/clang" \
|
||||||
--env="BAZEL_CXXOPTS=-std=${std}" \
|
--env="BAZEL_CXXOPTS=-std=${std}" \
|
||||||
|
${DOCKER_EXTRA_ARGS:-} \
|
||||||
${LINUX_LATEST_CONTAINER} \
|
${LINUX_LATEST_CONTAINER} \
|
||||||
/usr/local/bin/bazel test ... \
|
/bin/bash --login -c "
|
||||||
--copt="--gcc-toolchain=/usr/local" \
|
/usr/local/bin/bazel test ... \
|
||||||
--copt="-Wall" \
|
--copt=\"--gcc-toolchain=/usr/local\" \
|
||||||
--copt="-Werror" \
|
--copt=\"-Wall\" \
|
||||||
--copt="-Wuninitialized" \
|
--copt=\"-Werror\" \
|
||||||
--copt="-Wundef" \
|
--copt=\"-Wuninitialized\" \
|
||||||
--define="absl=${absl}" \
|
--copt=\"-Wundef\" \
|
||||||
--enable_bzlmod=true \
|
--define=\"absl=${absl}\" \
|
||||||
--features=external_include_paths \
|
--enable_bzlmod=true \
|
||||||
--keep_going \
|
--features=external_include_paths \
|
||||||
--linkopt="--gcc-toolchain=/usr/local" \
|
--keep_going \
|
||||||
--show_timestamps \
|
--linkopt=\"--gcc-toolchain=/usr/local\" \
|
||||||
--test_output=errors
|
--show_timestamps \
|
||||||
|
--test_output=errors \
|
||||||
|
${BAZEL_EXTRA_ARGS:-}"
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
|
|||||||
@ -56,7 +56,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-8.0.0-darwin-x86_64"
|
KOKORO_GFILE_BAZEL_BIN="bazel-8.2.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}
|
||||||
@ -64,6 +64,12 @@ else
|
|||||||
BAZEL_BIN="bazel"
|
BAZEL_BIN="bazel"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Use Bazel Vendor mode to reduce reliance on external dependencies.
|
||||||
|
if [[ ${KOKORO_GFILE_DIR:-} ]] && [[ -f "${KOKORO_GFILE_DIR}/distdir/googletest_vendor.tar.gz" ]]; then
|
||||||
|
tar -xf "${KOKORO_GFILE_DIR}/distdir/googletest_vendor.tar.gz" -C "${HOME}/"
|
||||||
|
BAZEL_EXTRA_ARGS="--vendor_dir=${HOME}/googletest_vendor ${BAZEL_EXTRA_ARGS:-}"
|
||||||
|
fi
|
||||||
|
|
||||||
cd ${GTEST_ROOT}
|
cd ${GTEST_ROOT}
|
||||||
for absl in 0 1; do
|
for absl in 0 1; do
|
||||||
${BAZEL_BIN} test ... \
|
${BAZEL_BIN} test ... \
|
||||||
@ -76,5 +82,6 @@ for absl in 0 1; do
|
|||||||
--features=external_include_paths \
|
--features=external_include_paths \
|
||||||
--keep_going \
|
--keep_going \
|
||||||
--show_timestamps \
|
--show_timestamps \
|
||||||
--test_output=errors
|
--test_output=errors \
|
||||||
|
${BAZEL_EXTRA_ARGS:-}
|
||||||
done
|
done
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
SETLOCAL ENABLEDELAYEDEXPANSION
|
SETLOCAL ENABLEDELAYEDEXPANSION
|
||||||
|
|
||||||
SET BAZEL_EXE=%KOKORO_GFILE_DIR%\bazel-8.0.0-windows-x86_64.exe
|
SET BAZEL_EXE=%KOKORO_GFILE_DIR%\bazel-8.2.1-windows-x86_64.exe
|
||||||
|
|
||||||
SET PATH=C:\Python34;%PATH%
|
SET PATH=C:\Python34;%PATH%
|
||||||
SET BAZEL_PYTHON=C:\python34\python.exe
|
SET BAZEL_PYTHON=C:\python34\python.exe
|
||||||
@ -48,6 +48,14 @@ RMDIR /S /Q %CMAKE_BUILD_PATH%
|
|||||||
:: --output_user_root=C:\tmp causes Bazel to use a shorter path.
|
:: --output_user_root=C:\tmp causes Bazel to use a shorter path.
|
||||||
SET BAZEL_VS=C:\Program Files\Microsoft Visual Studio\2022\Community
|
SET BAZEL_VS=C:\Program Files\Microsoft Visual Studio\2022\Community
|
||||||
|
|
||||||
|
:: Use Bazel Vendor mode to reduce reliance on external dependencies.
|
||||||
|
IF EXIST "%KOKORO_GFILE_DIR%\distdir\googletest_vendor.tar.gz" (
|
||||||
|
tar --force-local -xf "%KOKORO_GFILE_DIR%\distdir\googletest_vendor.tar.gz" -C c:
|
||||||
|
SET VENDOR_FLAG=--vendor_dir=c:\googletest_vendor
|
||||||
|
) ELSE (
|
||||||
|
SET VENDOR_FLAG=
|
||||||
|
)
|
||||||
|
|
||||||
:: C++17
|
:: C++17
|
||||||
%BAZEL_EXE% ^
|
%BAZEL_EXE% ^
|
||||||
--output_user_root=C:\tmp ^
|
--output_user_root=C:\tmp ^
|
||||||
@ -58,7 +66,8 @@ SET BAZEL_VS=C:\Program Files\Microsoft Visual Studio\2022\Community
|
|||||||
--enable_bzlmod=true ^
|
--enable_bzlmod=true ^
|
||||||
--keep_going ^
|
--keep_going ^
|
||||||
--test_output=errors ^
|
--test_output=errors ^
|
||||||
--test_tag_filters=-no_test_msvc2017
|
--test_tag_filters=-no_test_msvc2017 ^
|
||||||
|
%VENDOR_FLAG%
|
||||||
IF %errorlevel% neq 0 EXIT /B 1
|
IF %errorlevel% neq 0 EXIT /B 1
|
||||||
|
|
||||||
:: C++20
|
:: C++20
|
||||||
@ -71,5 +80,6 @@ IF %errorlevel% neq 0 EXIT /B 1
|
|||||||
--enable_bzlmod=true ^
|
--enable_bzlmod=true ^
|
||||||
--keep_going ^
|
--keep_going ^
|
||||||
--test_output=errors ^
|
--test_output=errors ^
|
||||||
--test_tag_filters=-no_test_msvc2017
|
--test_tag_filters=-no_test_msvc2017 ^
|
||||||
|
%VENDOR_FLAG%
|
||||||
IF %errorlevel% neq 0 EXIT /B 1
|
IF %errorlevel% neq 0 EXIT /B 1
|
||||||
|
|||||||
@ -7,15 +7,15 @@
|
|||||||
|
|
||||||
{% seo %}
|
{% seo %}
|
||||||
<link rel="stylesheet" href="{{ "/assets/css/style.css?v=" | append: site.github.build_revision | relative_url }}">
|
<link rel="stylesheet" href="{{ "/assets/css/style.css?v=" | append: site.github.build_revision | relative_url }}">
|
||||||
|
<!-- Google tag (gtag.js) -->
|
||||||
|
<script async src="https://www.googletagmanager.com/gtag/js?id=G-9PTP6FW1M5"></script>
|
||||||
<script>
|
<script>
|
||||||
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
|
window.dataLayer = window.dataLayer || [];
|
||||||
ga('create', 'UA-197576187-1', { 'storage': 'none' });
|
function gtag(){dataLayer.push(arguments);}
|
||||||
ga('set', 'referrer', document.referrer.split('?')[0]);
|
gtag('js', new Date());
|
||||||
ga('set', 'location', window.location.href.split('?')[0]);
|
|
||||||
ga('set', 'anonymizeIp', true);
|
gtag('config', 'G-9PTP6FW1M5');
|
||||||
ga('send', 'pageview');
|
|
||||||
</script>
|
</script>
|
||||||
<script async src='https://www.google-analytics.com/analytics.js'></script>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="sidebar">
|
<div class="sidebar">
|
||||||
|
|||||||
@ -349,7 +349,8 @@ void AbslStringify(Sink& sink, EnumWithStringify e) {
|
|||||||
{: .callout .note}
|
{: .callout .note}
|
||||||
Note: `AbslStringify()` utilizes a generic "sink" buffer to construct its
|
Note: `AbslStringify()` utilizes a generic "sink" buffer to construct its
|
||||||
string. For more information about supported operations on `AbslStringify()`'s
|
string. For more information about supported operations on `AbslStringify()`'s
|
||||||
sink, see go/abslstringify.
|
sink, see
|
||||||
|
[the `AbslStringify()` documentation](https://abseil.io/docs/cpp/guides/abslstringify).
|
||||||
|
|
||||||
`AbslStringify()` can also use `absl::StrFormat`'s catch-all `%v` type specifier
|
`AbslStringify()` can also use `absl::StrFormat`'s catch-all `%v` type specifier
|
||||||
within its own format strings to perform type deduction. `Point` above could be
|
within its own format strings to perform type deduction. `Point` above could be
|
||||||
@ -403,7 +404,8 @@ EXPECT_TRUE(IsCorrectPointIntVector(point_ints))
|
|||||||
```
|
```
|
||||||
|
|
||||||
For more details regarding `AbslStringify()` and its integration with other
|
For more details regarding `AbslStringify()` and its integration with other
|
||||||
libraries, see go/abslstringify.
|
libraries, see
|
||||||
|
[the documentation](https://abseil.io/docs/cpp/guides/abslstringify).
|
||||||
|
|
||||||
## Regular Expression Syntax
|
## Regular Expression Syntax
|
||||||
|
|
||||||
@ -1448,17 +1450,19 @@ are two cases to consider:
|
|||||||
To test them, we use the following special techniques:
|
To test them, we use the following special techniques:
|
||||||
|
|
||||||
* Both static functions and definitions/declarations in an unnamed namespace
|
* Both static functions and definitions/declarations in an unnamed namespace
|
||||||
are only visible within the same translation unit. To test them, you can
|
are only visible within the same translation unit. To test them, move the
|
||||||
`#include` the entire `.cc` file being tested in your `*_test.cc` file.
|
private code into the `foo::internal` namespace, where `foo` is the
|
||||||
(#including `.cc` files is not a good way to reuse code - you should not do
|
namespace your project normally uses, and put the private declarations in a
|
||||||
this in production code!)
|
`*-internal.h` file. Your production `.cc` files and your tests are allowed
|
||||||
|
to include this internal header, but your clients are not. This way, you can
|
||||||
|
fully test your internal implementation without leaking it to your clients.
|
||||||
|
|
||||||
However, a better approach is to move the private code into the
|
{: .callout .note}
|
||||||
`foo::internal` namespace, where `foo` is the namespace your project
|
NOTE: It is also technically *possible* to `#include` the entire `.cc` file
|
||||||
normally uses, and put the private declarations in a `*-internal.h` file.
|
being tested in your `*_test.cc` file to test static functions and
|
||||||
Your production `.cc` files and your tests are allowed to include this
|
definitions/declarations in an unnamed namespace. However, this technique is
|
||||||
internal header, but your clients are not. This way, you can fully test your
|
**not recommended** by this documentation and it is only presented here for the
|
||||||
internal implementation without leaking it to your clients.
|
sake of completeness.
|
||||||
|
|
||||||
* Private class members are only accessible from within the class or by
|
* Private class members are only accessible from within the class or by
|
||||||
friends. To access a class' private members, you can declare your test
|
friends. To access a class' private members, you can declare your test
|
||||||
@ -1471,10 +1475,7 @@ To test them, we use the following special techniques:
|
|||||||
|
|
||||||
Another way to test private members is to refactor them into an
|
Another way to test private members is to refactor them into an
|
||||||
implementation class, which is then declared in a `*-internal.h` file. Your
|
implementation class, which is then declared in a `*-internal.h` file. Your
|
||||||
clients aren't allowed to include this header but your tests can. Such is
|
clients aren't allowed to include this header but your tests can.
|
||||||
called the
|
|
||||||
[Pimpl](https://www.gamedev.net/articles/programming/general-and-gameplay-programming/the-c-pimpl-r1794/)
|
|
||||||
(Private Implementation) idiom.
|
|
||||||
|
|
||||||
Or, you can declare an individual test as a friend of your class by adding
|
Or, you can declare an individual test as a friend of your class by adding
|
||||||
this line in the class body:
|
this line in the class body:
|
||||||
@ -1943,6 +1944,21 @@ test case is linked in.
|
|||||||
Note that *any* test case linked in makes the program valid for the purpose of
|
Note that *any* test case linked in makes the program valid for the purpose of
|
||||||
this check. In particular, even a disabled test case suffices.
|
this check. In particular, even a disabled test case suffices.
|
||||||
|
|
||||||
|
### Enforcing Running At Least One Test Case
|
||||||
|
|
||||||
|
In addition to enforcing that tests are defined in the binary with
|
||||||
|
`--gtest_fail_if_no_test_linked`, it is also possible to enforce that a test
|
||||||
|
case was actually executed to ensure that resources are not consumed by tests
|
||||||
|
that do nothing.
|
||||||
|
|
||||||
|
To catch such optimization opportunities, run the test program with the
|
||||||
|
`--gtest_fail_if_no_test_selected` flag or set the
|
||||||
|
`GTEST_FAIL_IF_NO_TEST_SELECTED` environment variable to a value other than `0`.
|
||||||
|
|
||||||
|
A test is considered selected if it begins to run, even if it is later skipped
|
||||||
|
via `GTEST_SKIP`. Thus, `DISABLED` tests do not count as selected and neither do
|
||||||
|
tests that are not matched by `--gtest_filter`.
|
||||||
|
|
||||||
### Repeating the Tests
|
### Repeating the Tests
|
||||||
|
|
||||||
Once in a while you'll run into a test whose result is hit-or-miss. Perhaps it
|
Once in a while you'll run into a test whose result is hit-or-miss. Perhaps it
|
||||||
|
|||||||
@ -130,7 +130,7 @@ TEST(BarTest, DoesThis) {
|
|||||||
## Setting Default Actions {#OnCall}
|
## Setting Default Actions {#OnCall}
|
||||||
|
|
||||||
gMock has a **built-in default action** for any function that returns `void`,
|
gMock has a **built-in default action** for any function that returns `void`,
|
||||||
`bool`, a numeric value, or a pointer. In C++11, it will additionally returns
|
`bool`, a numeric value, or a pointer. In C++11, it additionally returns
|
||||||
the default-constructed value, if one exists for the given type.
|
the default-constructed value, if one exists for the given type.
|
||||||
|
|
||||||
To customize the default action for functions with return type `T`, use
|
To customize the default action for functions with return type `T`, use
|
||||||
|
|||||||
@ -900,15 +900,16 @@ using ::testing::Not;
|
|||||||
|
|
||||||
Matchers are function objects, and parametrized matchers can be composed just
|
Matchers are function objects, and parametrized matchers can be composed just
|
||||||
like any other function. However because their types can be long and rarely
|
like any other function. However because their types can be long and rarely
|
||||||
provide meaningful information, it can be easier to express them with C++14
|
provide meaningful information, it can be easier to express them with template
|
||||||
generic lambdas to avoid specifying types. For example,
|
parameters and `auto`. For example,
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
using ::testing::Contains;
|
using ::testing::Contains;
|
||||||
using ::testing::Property;
|
using ::testing::Property;
|
||||||
|
|
||||||
inline constexpr auto HasFoo = [](const auto& f) {
|
template <typename SubMatcher>
|
||||||
return Property("foo", &MyClass::foo, Contains(f));
|
inline constexpr auto HasFoo(const SubMatcher& sub_matcher) {
|
||||||
|
return Property("foo", &MyClass::foo, Contains(sub_matcher));
|
||||||
};
|
};
|
||||||
...
|
...
|
||||||
EXPECT_THAT(x, HasFoo("blah"));
|
EXPECT_THAT(x, HasFoo("blah"));
|
||||||
|
|||||||
@ -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++14.
|
* A compatible C++ compiler that supports at least C++17.
|
||||||
* [Bazel](https://bazel.build/) 7.0 or higher, the preferred build system used
|
* [Bazel](https://bazel.build/) 7.0 or higher, the preferred build system used
|
||||||
by the GoogleTest team.
|
by the GoogleTest team.
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ with the following content:
|
|||||||
|
|
||||||
# Choose the most recent version available at
|
# Choose the most recent version available at
|
||||||
# https://registry.bazel.build/modules/googletest
|
# https://registry.bazel.build/modules/googletest
|
||||||
bazel_dep(name = "googletest", version = "1.15.2")
|
bazel_dep(name = "googletest", version = "1.17.0")
|
||||||
```
|
```
|
||||||
|
|
||||||
Now you're ready to build C++ code that uses GoogleTest.
|
Now you're ready to build C++ code that uses GoogleTest.
|
||||||
@ -99,16 +99,16 @@ files, see the
|
|||||||
[Bazel C++ Tutorial](https://docs.bazel.build/versions/main/tutorial/cpp.html).
|
[Bazel C++ Tutorial](https://docs.bazel.build/versions/main/tutorial/cpp.html).
|
||||||
|
|
||||||
{: .callout .note}
|
{: .callout .note}
|
||||||
NOTE: In the example below, we assume Clang or GCC and set `--cxxopt=-std=c++14`
|
NOTE: In the example below, we assume Clang or GCC and set `--cxxopt=-std=c++17`
|
||||||
to ensure that GoogleTest is compiled as C++14 instead of the compiler's default
|
to ensure that GoogleTest is compiled as C++17 instead of the compiler's default
|
||||||
setting (which could be C++11). For MSVC, the equivalent would be
|
setting. For MSVC, the equivalent would be `--cxxopt=/std:c++17`. See
|
||||||
`--cxxopt=/std:c++14`. See [Supported Platforms](platforms.md) for more details
|
[Supported Platforms](platforms.md) for more details on supported language
|
||||||
on supported language versions.
|
versions.
|
||||||
|
|
||||||
Now you can build and run your test:
|
Now you can build and run your test:
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<strong>$ bazel test --cxxopt=-std=c++14 --test_output=all //:hello_test</strong>
|
<strong>$ bazel test --cxxopt=-std=c++17 --test_output=all //:hello_test</strong>
|
||||||
INFO: Analyzed target //:hello_test (26 packages loaded, 362 targets configured).
|
INFO: Analyzed target //:hello_test (26 packages loaded, 362 targets configured).
|
||||||
INFO: Found 1 test target...
|
INFO: Found 1 test target...
|
||||||
INFO: From Testing //:hello_test:
|
INFO: From Testing //:hello_test:
|
||||||
|
|||||||
@ -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++14.
|
* A compatible C++ compiler that supports at least C++17.
|
||||||
* [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,8 +52,8 @@ 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++14
|
# GoogleTest requires at least C++17
|
||||||
set(CMAKE_CXX_STANDARD 14)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
|
|||||||
@ -48,8 +48,8 @@ functor, or lambda.
|
|||||||
| `InvokeWithoutArgs(object_pointer, &class::method)` | Invoke the method on the object, which takes no arguments. |
|
| `InvokeWithoutArgs(object_pointer, &class::method)` | Invoke the method on the object, which takes no arguments. |
|
||||||
| `InvokeArgument<N>(arg1, arg2, ..., argk)` | Invoke the mock function's `N`-th (0-based) argument, which must be a function or a functor, with the `k` arguments. |
|
| `InvokeArgument<N>(arg1, arg2, ..., argk)` | Invoke the mock function's `N`-th (0-based) argument, which must be a function or a functor, with the `k` arguments. |
|
||||||
|
|
||||||
The return value of the invoked function is used as the return value of the
|
The return value of the invoked function (except `InvokeArgument`) is used as
|
||||||
action.
|
the return value of the action.
|
||||||
|
|
||||||
When defining a callable to be used with `Invoke*()`, you can declare any unused
|
When defining a callable to be used with `Invoke*()`, you can declare any unused
|
||||||
parameters as `Unused`:
|
parameters as `Unused`:
|
||||||
|
|||||||
@ -49,6 +49,7 @@ Matcher | Description
|
|||||||
| `NotNull()` | `argument` is a non-null pointer (raw or smart). |
|
| `NotNull()` | `argument` is a non-null pointer (raw or smart). |
|
||||||
| `Optional(m)` | `argument` is `optional<>` that contains a value matching `m`. (For testing whether an `optional<>` is set, check for equality with `nullopt`. You may need to use `Eq(nullopt)` if the inner type doesn't have `==`.)|
|
| `Optional(m)` | `argument` is `optional<>` that contains a value matching `m`. (For testing whether an `optional<>` is set, check for equality with `nullopt`. You may need to use `Eq(nullopt)` if the inner type doesn't have `==`.)|
|
||||||
| `VariantWith<T>(m)` | `argument` is `variant<>` that holds the alternative of type T with a value matching `m`. |
|
| `VariantWith<T>(m)` | `argument` is `variant<>` that holds the alternative of type T with a value matching `m`. |
|
||||||
|
| `AnyWith<T>(m)` | `argument` is `any<>` that holds a value of type T with a value matching `m`. |
|
||||||
| `Ref(variable)` | `argument` is a reference to `variable`. |
|
| `Ref(variable)` | `argument` is a reference to `variable`. |
|
||||||
| `TypedEq<type>(value)` | `argument` has type `type` and is equal to `value`. You may need to use this instead of `Eq(value)` when the mock function is overloaded. |
|
| `TypedEq<type>(value)` | `argument` has type `type` and is equal to `value`. You may need to use this instead of `Eq(value)` when the mock function is overloaded. |
|
||||||
|
|
||||||
@ -111,6 +112,33 @@ use the regular expression syntax defined
|
|||||||
[here](../advanced.md#regular-expression-syntax). All of these matchers, except
|
[here](../advanced.md#regular-expression-syntax). All of these matchers, except
|
||||||
`ContainsRegex()` and `MatchesRegex()` work for wide strings as well.
|
`ContainsRegex()` and `MatchesRegex()` work for wide strings as well.
|
||||||
|
|
||||||
|
## Exception Matchers
|
||||||
|
|
||||||
|
| Matcher | Description |
|
||||||
|
| :---------------------------------------- | :------------------------------- |
|
||||||
|
| `Throws<E>()` | The `argument` is a callable object that, when called, throws an exception of the expected type `E`. |
|
||||||
|
| `Throws<E>(m)` | The `argument` is a callable object that, when called, throws an exception of type `E` that satisfies the matcher `m`. |
|
||||||
|
| `ThrowsMessage<E>(m)` | The `argument` is a callable object that, when called, throws an exception of type `E` with a message that satisfies the matcher `m`. |
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
auto argument = [] { throw std::runtime_error("error msg"); };
|
||||||
|
|
||||||
|
// Checks if the lambda throws a `std::runtime_error`.
|
||||||
|
EXPECT_THAT(argument, Throws<std::runtime_error>());
|
||||||
|
|
||||||
|
// Checks if the lambda throws a `std::runtime_error` with a specific message
|
||||||
|
// that matches "error msg".
|
||||||
|
EXPECT_THAT(argument,
|
||||||
|
Throws<std::runtime_error>(Property(&std::runtime_error::what,
|
||||||
|
Eq("error msg"))));
|
||||||
|
|
||||||
|
// Checks if the lambda throws a `std::runtime_error` with a message that
|
||||||
|
// contains "msg".
|
||||||
|
EXPECT_THAT(argument, ThrowsMessage<std::runtime_error>(HasSubstr("msg")));
|
||||||
|
```
|
||||||
|
|
||||||
## Container Matchers
|
## Container Matchers
|
||||||
|
|
||||||
Most STL-style containers support `==`, so you can use `Eq(expected_container)`
|
Most STL-style containers support `==`, so you can use `Eq(expected_container)`
|
||||||
|
|||||||
@ -203,7 +203,7 @@ class MyParam {
|
|||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(MyInstantiation, MyTestSuite,
|
INSTANTIATE_TEST_SUITE_P(MyInstantiation, MyTestSuite,
|
||||||
ConvertGenerator(Combine(Values(1, 1.2), Bool()),
|
ConvertGenerator(Combine(Values(1, 1.2), Bool()),
|
||||||
[](const std::tuple<int i, bool>& t){
|
[](const std::tuple<int, bool>& t){
|
||||||
const auto [i, b] = t;
|
const auto [i, b] = t;
|
||||||
return MyParam(i, b);
|
return MyParam(i, b);
|
||||||
}));
|
}));
|
||||||
|
|||||||
@ -1796,11 +1796,24 @@ struct SetArrayArgumentAction {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <size_t k>
|
template <size_t k>
|
||||||
struct DeleteArgAction {
|
class DeleteArgAction {
|
||||||
|
public:
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
void operator()(const Args&... args) const {
|
void operator()(const Args&... args) const {
|
||||||
delete std::get<k>(std::tie(args...));
|
DoDelete(std::get<k>(std::tie(args...)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename T>
|
||||||
|
static void DoDelete(T* ptr) {
|
||||||
|
delete ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
[[deprecated(
|
||||||
|
"DeleteArg<N> used for a non-pointer argument, it was likely migrated "
|
||||||
|
"to a smart pointer type. This action should be removed.")]]
|
||||||
|
static void DoDelete(T&) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Ptr>
|
template <typename Ptr>
|
||||||
@ -1866,6 +1879,13 @@ struct RethrowAction {
|
|||||||
// EXPECT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin));
|
// EXPECT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin));
|
||||||
typedef internal::IgnoredValue Unused;
|
typedef internal::IgnoredValue Unused;
|
||||||
|
|
||||||
|
// Deprecated single-argument DoAll.
|
||||||
|
template <typename Action>
|
||||||
|
GTEST_INTERNAL_DEPRECATE_AND_INLINE("Avoid using DoAll() for single actions")
|
||||||
|
typename std::decay<Action>::type DoAll(Action&& action) {
|
||||||
|
return std::forward<Action>(action);
|
||||||
|
}
|
||||||
|
|
||||||
// Creates an action that does actions a1, a2, ..., sequentially in
|
// Creates an action that does actions a1, a2, ..., sequentially in
|
||||||
// each invocation. All but the last action will have a readonly view of the
|
// each invocation. All but the last action will have a readonly view of the
|
||||||
// arguments.
|
// arguments.
|
||||||
@ -2031,10 +2051,11 @@ PolymorphicAction<internal::SetErrnoAndReturnAction<T>> SetErrnoAndReturn(
|
|||||||
// Various overloads for Invoke().
|
// Various overloads for Invoke().
|
||||||
|
|
||||||
// Legacy function.
|
// Legacy function.
|
||||||
// Actions can now be implicitly constructed from callables. No need to create
|
|
||||||
// wrapper objects.
|
|
||||||
// This function exists for backwards compatibility.
|
// This function exists for backwards compatibility.
|
||||||
template <typename FunctionImpl>
|
template <typename FunctionImpl>
|
||||||
|
GTEST_INTERNAL_DEPRECATE_AND_INLINE(
|
||||||
|
"Actions can now be implicitly constructed from callables. No need to "
|
||||||
|
"create wrapper objects using Invoke().")
|
||||||
typename std::decay<FunctionImpl>::type Invoke(FunctionImpl&& function_impl) {
|
typename std::decay<FunctionImpl>::type Invoke(FunctionImpl&& function_impl) {
|
||||||
return std::forward<FunctionImpl>(function_impl);
|
return std::forward<FunctionImpl>(function_impl);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -258,7 +258,6 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <exception>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <ios>
|
#include <ios>
|
||||||
@ -268,12 +267,12 @@
|
|||||||
#include <ostream> // NOLINT
|
#include <ostream> // NOLINT
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "gmock/internal/gmock-internal-utils.h"
|
#include "gmock/internal/gmock-internal-utils.h"
|
||||||
#include "gmock/internal/gmock-port.h"
|
|
||||||
#include "gmock/internal/gmock-pp.h"
|
#include "gmock/internal/gmock-pp.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
@ -376,11 +375,16 @@ class MatcherCastImpl {
|
|||||||
|
|
||||||
// M can't be implicitly converted to Matcher<T>, so M isn't a polymorphic
|
// M can't be implicitly converted to Matcher<T>, so M isn't a polymorphic
|
||||||
// matcher. It's a value of a type implicitly convertible to T. Use direct
|
// matcher. It's a value of a type implicitly convertible to T. Use direct
|
||||||
// initialization to create a matcher.
|
// initialization or `ImplicitCastEqMatcher` to create a matcher.
|
||||||
static Matcher<T> CastImpl(const M& value,
|
static Matcher<T> CastImpl(const M& value,
|
||||||
std::false_type /* convertible_to_matcher */,
|
std::false_type /* convertible_to_matcher */,
|
||||||
std::true_type /* convertible_to_T */) {
|
std::true_type /* convertible_to_T */) {
|
||||||
return Matcher<T>(ImplicitCast_<T>(value));
|
using NoRefT = std::remove_cv_t<std::remove_reference_t<T>>;
|
||||||
|
if constexpr (std::is_same_v<M, NoRefT>) {
|
||||||
|
return Matcher<T>(value);
|
||||||
|
} else {
|
||||||
|
return ImplicitCastEqMatcher<NoRefT, std::decay_t<const M&>>(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// M can't be implicitly converted to either Matcher<T> or T. Attempt to use
|
// M can't be implicitly converted to either Matcher<T> or T. Attempt to use
|
||||||
@ -391,11 +395,11 @@ class MatcherCastImpl {
|
|||||||
// latter calls bool operator==(const Lhs& lhs, const Rhs& rhs) in the end
|
// latter calls bool operator==(const Lhs& lhs, const Rhs& rhs) in the end
|
||||||
// which might be undefined even when Rhs is implicitly convertible to Lhs
|
// which might be undefined even when Rhs is implicitly convertible to Lhs
|
||||||
// (e.g. std::pair<const int, int> vs. std::pair<int, int>).
|
// (e.g. std::pair<const int, int> vs. std::pair<int, int>).
|
||||||
//
|
|
||||||
// We don't define this method inline as we need the declaration of Eq().
|
|
||||||
static Matcher<T> CastImpl(const M& value,
|
static Matcher<T> CastImpl(const M& value,
|
||||||
std::false_type /* convertible_to_matcher */,
|
std::false_type /* convertible_to_matcher */,
|
||||||
std::false_type /* convertible_to_T */);
|
std::false_type /* convertible_to_T */) {
|
||||||
|
return Eq(value);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// This more specialized version is used when MatcherCast()'s argument
|
// This more specialized version is used when MatcherCast()'s argument
|
||||||
@ -1325,17 +1329,23 @@ class AllOfMatcherImpl : public MatcherInterface<const T&> {
|
|||||||
// However, if matcher doesn't provide one, this method uses matcher's
|
// However, if matcher doesn't provide one, this method uses matcher's
|
||||||
// description.
|
// description.
|
||||||
std::string all_match_result;
|
std::string all_match_result;
|
||||||
|
bool success = true;
|
||||||
for (const Matcher<T>& matcher : matchers_) {
|
for (const Matcher<T>& matcher : matchers_) {
|
||||||
StringMatchResultListener slistener;
|
StringMatchResultListener slistener;
|
||||||
// Return explanation for first failed matcher.
|
// Return explanation for first failed matcher.
|
||||||
if (!matcher.MatchAndExplain(x, &slistener)) {
|
if (!matcher.MatchAndExplain(x, &slistener)) {
|
||||||
const std::string explanation = slistener.str();
|
const std::string explanation = slistener.str();
|
||||||
|
if (!success) {
|
||||||
|
// Already had a failure.
|
||||||
|
*listener << ", and ";
|
||||||
|
}
|
||||||
if (!explanation.empty()) {
|
if (!explanation.empty()) {
|
||||||
*listener << explanation;
|
*listener << explanation;
|
||||||
} else {
|
} else {
|
||||||
*listener << "which doesn't match (" << Describe(matcher) << ")";
|
*listener << "which doesn't match (" << Describe(matcher) << ")";
|
||||||
}
|
}
|
||||||
return false;
|
success = false;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
// Keep track of explanations in case all matchers succeed.
|
// Keep track of explanations in case all matchers succeed.
|
||||||
std::string explanation = slistener.str();
|
std::string explanation = slistener.str();
|
||||||
@ -1352,8 +1362,10 @@ class AllOfMatcherImpl : public MatcherInterface<const T&> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*listener << all_match_result;
|
if (success) {
|
||||||
return true;
|
*listener << all_match_result;
|
||||||
|
}
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -3433,6 +3445,35 @@ auto UnpackStructImpl(const T& in, std::make_index_sequence<22>, char) {
|
|||||||
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u,
|
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u,
|
||||||
v);
|
v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
auto UnpackStructImpl(const T& in, std::make_index_sequence<23>, char) {
|
||||||
|
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v,
|
||||||
|
w] = in;
|
||||||
|
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u,
|
||||||
|
v, w);
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
auto UnpackStructImpl(const T& in, std::make_index_sequence<24>, char) {
|
||||||
|
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v,
|
||||||
|
w, x] = in;
|
||||||
|
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u,
|
||||||
|
v, w, x);
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
auto UnpackStructImpl(const T& in, std::make_index_sequence<25>, char) {
|
||||||
|
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v,
|
||||||
|
w, x, y] = in;
|
||||||
|
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u,
|
||||||
|
v, w, x, y);
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
auto UnpackStructImpl(const T& in, std::make_index_sequence<26>, char) {
|
||||||
|
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v,
|
||||||
|
w, x, y, z] = in;
|
||||||
|
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u,
|
||||||
|
v, w, x, y, z);
|
||||||
|
}
|
||||||
#endif // defined(__cpp_structured_bindings)
|
#endif // defined(__cpp_structured_bindings)
|
||||||
|
|
||||||
template <size_t I, typename T>
|
template <size_t I, typename T>
|
||||||
@ -4475,13 +4516,6 @@ inline Matcher<T> An() {
|
|||||||
return _;
|
return _;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename M>
|
|
||||||
Matcher<T> internal::MatcherCastImpl<T, M>::CastImpl(
|
|
||||||
const M& value, std::false_type /* convertible_to_matcher */,
|
|
||||||
std::false_type /* convertible_to_T */) {
|
|
||||||
return Eq(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates a polymorphic matcher that matches any NULL pointer.
|
// Creates a polymorphic matcher that matches any NULL pointer.
|
||||||
inline PolymorphicMatcher<internal::IsNullMatcher> IsNull() {
|
inline PolymorphicMatcher<internal::IsNullMatcher> IsNull() {
|
||||||
return MakePolymorphicMatcher(internal::IsNullMatcher());
|
return MakePolymorphicMatcher(internal::IsNullMatcher());
|
||||||
|
|||||||
@ -1292,10 +1292,10 @@ class MockSpec {
|
|||||||
: function_mocker_(function_mocker), matchers_(matchers) {}
|
: function_mocker_(function_mocker), matchers_(matchers) {}
|
||||||
|
|
||||||
// Adds a new default action spec to the function mocker and returns
|
// Adds a new default action spec to the function mocker and returns
|
||||||
// the newly created spec.
|
// the newly created spec. .WillByDefault() must be called on the returned
|
||||||
internal::OnCallSpec<F>& InternalDefaultActionSetAt(const char* file,
|
// object.
|
||||||
int line, const char* obj,
|
[[nodiscard]] internal::OnCallSpec<F>& InternalDefaultActionSetAt(
|
||||||
const char* call) {
|
const char* file, int line, const char* obj, const char* call) {
|
||||||
LogWithLocation(internal::kInfo, file, line,
|
LogWithLocation(internal::kInfo, file, line,
|
||||||
std::string("ON_CALL(") + obj + ", " + call + ") invoked");
|
std::string("ON_CALL(") + obj + ", " + call + ") invoked");
|
||||||
return function_mocker_->AddNewOnCallSpec(file, line, matchers_);
|
return function_mocker_->AddNewOnCallSpec(file, line, matchers_);
|
||||||
@ -1467,7 +1467,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
|||||||
// function have been satisfied. If not, it will report Google Test
|
// function have been satisfied. If not, it will report Google Test
|
||||||
// non-fatal failures for the violations.
|
// non-fatal failures for the violations.
|
||||||
~FunctionMocker() override GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
~FunctionMocker() override GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||||
MutexLock l(&g_gmock_mutex);
|
MutexLock l(g_gmock_mutex);
|
||||||
VerifyAndClearExpectationsLocked();
|
VerifyAndClearExpectationsLocked();
|
||||||
Mock::UnregisterLocked(this);
|
Mock::UnregisterLocked(this);
|
||||||
ClearDefaultActionsLocked();
|
ClearDefaultActionsLocked();
|
||||||
@ -1530,7 +1530,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
|||||||
UntypedOnCallSpecs specs_to_delete;
|
UntypedOnCallSpecs specs_to_delete;
|
||||||
untyped_on_call_specs_.swap(specs_to_delete);
|
untyped_on_call_specs_.swap(specs_to_delete);
|
||||||
|
|
||||||
g_gmock_mutex.Unlock();
|
g_gmock_mutex.unlock();
|
||||||
for (UntypedOnCallSpecs::const_iterator it = specs_to_delete.begin();
|
for (UntypedOnCallSpecs::const_iterator it = specs_to_delete.begin();
|
||||||
it != specs_to_delete.end(); ++it) {
|
it != specs_to_delete.end(); ++it) {
|
||||||
delete static_cast<const OnCallSpec<F>*>(*it);
|
delete static_cast<const OnCallSpec<F>*>(*it);
|
||||||
@ -1538,7 +1538,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
|||||||
|
|
||||||
// Lock the mutex again, since the caller expects it to be locked when we
|
// Lock the mutex again, since the caller expects it to be locked when we
|
||||||
// return.
|
// return.
|
||||||
g_gmock_mutex.Lock();
|
g_gmock_mutex.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the result of invoking this mock function with the given
|
// Returns the result of invoking this mock function with the given
|
||||||
@ -1646,7 +1646,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
|||||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||||
const ArgumentTuple& args =
|
const ArgumentTuple& args =
|
||||||
*static_cast<const ArgumentTuple*>(untyped_args);
|
*static_cast<const ArgumentTuple*>(untyped_args);
|
||||||
MutexLock l(&g_gmock_mutex);
|
MutexLock l(g_gmock_mutex);
|
||||||
TypedExpectation<F>* exp = this->FindMatchingExpectationLocked(args);
|
TypedExpectation<F>* exp = this->FindMatchingExpectationLocked(args);
|
||||||
if (exp == nullptr) { // A match wasn't found.
|
if (exp == nullptr) { // A match wasn't found.
|
||||||
this->FormatUnexpectedCallMessageLocked(args, what, why);
|
this->FormatUnexpectedCallMessageLocked(args, what, why);
|
||||||
|
|||||||
@ -298,7 +298,7 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message,
|
|||||||
//
|
//
|
||||||
class WithoutMatchers {
|
class WithoutMatchers {
|
||||||
private:
|
private:
|
||||||
WithoutMatchers() {}
|
WithoutMatchers() = default;
|
||||||
friend GTEST_API_ WithoutMatchers GetWithoutMatchers();
|
friend GTEST_API_ WithoutMatchers GetWithoutMatchers();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -156,7 +156,7 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message,
|
|||||||
if (!LogIsVisible(severity)) return;
|
if (!LogIsVisible(severity)) return;
|
||||||
|
|
||||||
// Ensures that logs from different threads don't interleave.
|
// Ensures that logs from different threads don't interleave.
|
||||||
MutexLock l(&g_log_mutex);
|
MutexLock l(g_log_mutex);
|
||||||
|
|
||||||
if (severity == kWarning) {
|
if (severity == kWarning) {
|
||||||
// Prints a GMOCK WARNING marker to make the warnings easily searchable.
|
// Prints a GMOCK WARNING marker to make the warnings easily searchable.
|
||||||
|
|||||||
@ -212,7 +212,7 @@ void ExpectationBase::CheckActionCountIfNotDone() const
|
|||||||
GTEST_LOCK_EXCLUDED_(mutex_) {
|
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||||
bool should_check = false;
|
bool should_check = false;
|
||||||
{
|
{
|
||||||
MutexLock l(&mutex_);
|
MutexLock l(mutex_);
|
||||||
if (!action_count_checked_) {
|
if (!action_count_checked_) {
|
||||||
action_count_checked_ = true;
|
action_count_checked_ = true;
|
||||||
should_check = true;
|
should_check = true;
|
||||||
@ -293,7 +293,7 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg) {
|
|||||||
Log(kWarning,
|
Log(kWarning,
|
||||||
msg +
|
msg +
|
||||||
"\nNOTE: You can safely ignore the above warning unless this "
|
"\nNOTE: You can safely ignore the above warning unless this "
|
||||||
"call should not happen. Do not suppress it by blindly adding "
|
"call should not happen. Do not suppress it by 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/main/docs/"
|
"https://github.com/google/googletest/blob/main/docs/"
|
||||||
@ -318,7 +318,7 @@ UntypedFunctionMockerBase::~UntypedFunctionMockerBase() = default;
|
|||||||
void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj)
|
void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj)
|
||||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||||
{
|
{
|
||||||
MutexLock l(&g_gmock_mutex);
|
MutexLock l(g_gmock_mutex);
|
||||||
mock_obj_ = mock_obj;
|
mock_obj_ = mock_obj;
|
||||||
}
|
}
|
||||||
Mock::Register(mock_obj, this);
|
Mock::Register(mock_obj, this);
|
||||||
@ -332,7 +332,7 @@ void UntypedFunctionMockerBase::SetOwnerAndName(const void* mock_obj,
|
|||||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||||
// We protect name_ under g_gmock_mutex in case this mock function
|
// We protect name_ under g_gmock_mutex in case this mock function
|
||||||
// is called from two threads concurrently.
|
// is called from two threads concurrently.
|
||||||
MutexLock l(&g_gmock_mutex);
|
MutexLock l(g_gmock_mutex);
|
||||||
mock_obj_ = mock_obj;
|
mock_obj_ = mock_obj;
|
||||||
name_ = name;
|
name_ = name;
|
||||||
}
|
}
|
||||||
@ -345,7 +345,7 @@ const void* UntypedFunctionMockerBase::MockObject() const
|
|||||||
{
|
{
|
||||||
// We protect mock_obj_ under g_gmock_mutex in case this mock
|
// We protect mock_obj_ under g_gmock_mutex in case this mock
|
||||||
// function is called from two threads concurrently.
|
// function is called from two threads concurrently.
|
||||||
MutexLock l(&g_gmock_mutex);
|
MutexLock l(g_gmock_mutex);
|
||||||
Assert(mock_obj_ != nullptr, __FILE__, __LINE__,
|
Assert(mock_obj_ != nullptr, __FILE__, __LINE__,
|
||||||
"MockObject() must not be called before RegisterOwner() or "
|
"MockObject() must not be called before RegisterOwner() or "
|
||||||
"SetOwnerAndName() has been called.");
|
"SetOwnerAndName() has been called.");
|
||||||
@ -362,7 +362,7 @@ const char* UntypedFunctionMockerBase::Name() const
|
|||||||
{
|
{
|
||||||
// We protect name_ under g_gmock_mutex in case this mock
|
// We protect name_ under g_gmock_mutex in case this mock
|
||||||
// function is called from two threads concurrently.
|
// function is called from two threads concurrently.
|
||||||
MutexLock l(&g_gmock_mutex);
|
MutexLock l(g_gmock_mutex);
|
||||||
Assert(name_ != nullptr, __FILE__, __LINE__,
|
Assert(name_ != nullptr, __FILE__, __LINE__,
|
||||||
"Name() must not be called before SetOwnerAndName() has "
|
"Name() must not be called before SetOwnerAndName() has "
|
||||||
"been called.");
|
"been called.");
|
||||||
@ -436,9 +436,9 @@ bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()
|
|||||||
UntypedExpectations expectations_to_delete;
|
UntypedExpectations expectations_to_delete;
|
||||||
untyped_expectations_.swap(expectations_to_delete);
|
untyped_expectations_.swap(expectations_to_delete);
|
||||||
|
|
||||||
g_gmock_mutex.Unlock();
|
g_gmock_mutex.unlock();
|
||||||
expectations_to_delete.clear();
|
expectations_to_delete.clear();
|
||||||
g_gmock_mutex.Lock();
|
g_gmock_mutex.lock();
|
||||||
|
|
||||||
return expectations_met;
|
return expectations_met;
|
||||||
}
|
}
|
||||||
@ -490,7 +490,7 @@ class MockObjectRegistry {
|
|||||||
// failure, unless the user explicitly asked us to ignore it.
|
// failure, unless the user explicitly asked us to ignore it.
|
||||||
~MockObjectRegistry() {
|
~MockObjectRegistry() {
|
||||||
if (!GMOCK_FLAG_GET(catch_leaked_mocks)) return;
|
if (!GMOCK_FLAG_GET(catch_leaked_mocks)) return;
|
||||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
internal::MutexLock l(internal::g_gmock_mutex);
|
||||||
|
|
||||||
int leaked_count = 0;
|
int leaked_count = 0;
|
||||||
for (StateMap::const_iterator it = states_.begin(); it != states_.end();
|
for (StateMap::const_iterator it = states_.begin(); it != states_.end();
|
||||||
@ -559,7 +559,7 @@ UninterestingCallReactionMap() {
|
|||||||
void SetReactionOnUninterestingCalls(uintptr_t mock_obj,
|
void SetReactionOnUninterestingCalls(uintptr_t mock_obj,
|
||||||
internal::CallReaction reaction)
|
internal::CallReaction reaction)
|
||||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
internal::MutexLock l(internal::g_gmock_mutex);
|
||||||
UninterestingCallReactionMap()[mock_obj] = reaction;
|
UninterestingCallReactionMap()[mock_obj] = reaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -590,7 +590,7 @@ void Mock::FailUninterestingCalls(uintptr_t mock_obj)
|
|||||||
// entry in the call-reaction table should be removed.
|
// entry in the call-reaction table should be removed.
|
||||||
void Mock::UnregisterCallReaction(uintptr_t mock_obj)
|
void Mock::UnregisterCallReaction(uintptr_t mock_obj)
|
||||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
internal::MutexLock l(internal::g_gmock_mutex);
|
||||||
UninterestingCallReactionMap().erase(static_cast<uintptr_t>(mock_obj));
|
UninterestingCallReactionMap().erase(static_cast<uintptr_t>(mock_obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -598,7 +598,7 @@ void Mock::UnregisterCallReaction(uintptr_t mock_obj)
|
|||||||
// made on the given mock object.
|
// made on the given mock object.
|
||||||
internal::CallReaction Mock::GetReactionOnUninterestingCalls(
|
internal::CallReaction Mock::GetReactionOnUninterestingCalls(
|
||||||
const void* mock_obj) GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
const void* mock_obj) GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
internal::MutexLock l(internal::g_gmock_mutex);
|
||||||
return (UninterestingCallReactionMap().count(
|
return (UninterestingCallReactionMap().count(
|
||||||
reinterpret_cast<uintptr_t>(mock_obj)) == 0)
|
reinterpret_cast<uintptr_t>(mock_obj)) == 0)
|
||||||
? internal::intToCallReaction(
|
? internal::intToCallReaction(
|
||||||
@ -611,7 +611,7 @@ internal::CallReaction Mock::GetReactionOnUninterestingCalls(
|
|||||||
// objects.
|
// objects.
|
||||||
void Mock::AllowLeak(const void* mock_obj)
|
void Mock::AllowLeak(const void* mock_obj)
|
||||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
internal::MutexLock l(internal::g_gmock_mutex);
|
||||||
g_mock_object_registry.states()[mock_obj].leakable = true;
|
g_mock_object_registry.states()[mock_obj].leakable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -620,7 +620,7 @@ void Mock::AllowLeak(const void* mock_obj)
|
|||||||
// Test non-fatal failures and returns false.
|
// Test non-fatal failures and returns false.
|
||||||
bool Mock::VerifyAndClearExpectations(void* mock_obj)
|
bool Mock::VerifyAndClearExpectations(void* mock_obj)
|
||||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
internal::MutexLock l(internal::g_gmock_mutex);
|
||||||
return VerifyAndClearExpectationsLocked(mock_obj);
|
return VerifyAndClearExpectationsLocked(mock_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -629,7 +629,7 @@ bool Mock::VerifyAndClearExpectations(void* mock_obj)
|
|||||||
// verification was successful.
|
// verification was successful.
|
||||||
bool Mock::VerifyAndClear(void* mock_obj)
|
bool Mock::VerifyAndClear(void* mock_obj)
|
||||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
internal::MutexLock l(internal::g_gmock_mutex);
|
||||||
ClearDefaultActionsLocked(mock_obj);
|
ClearDefaultActionsLocked(mock_obj);
|
||||||
return VerifyAndClearExpectationsLocked(mock_obj);
|
return VerifyAndClearExpectationsLocked(mock_obj);
|
||||||
}
|
}
|
||||||
@ -679,7 +679,7 @@ bool Mock::IsStrict(void* mock_obj)
|
|||||||
void Mock::Register(const void* mock_obj,
|
void Mock::Register(const void* mock_obj,
|
||||||
internal::UntypedFunctionMockerBase* mocker)
|
internal::UntypedFunctionMockerBase* mocker)
|
||||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
internal::MutexLock l(internal::g_gmock_mutex);
|
||||||
g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker);
|
g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -689,7 +689,7 @@ void Mock::Register(const void* mock_obj,
|
|||||||
void Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj,
|
void Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj,
|
||||||
const char* file, int line)
|
const char* file, int line)
|
||||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
internal::MutexLock l(internal::g_gmock_mutex);
|
||||||
MockObjectState& state = g_mock_object_registry.states()[mock_obj];
|
MockObjectState& state = g_mock_object_registry.states()[mock_obj];
|
||||||
if (state.first_used_file == nullptr) {
|
if (state.first_used_file == nullptr) {
|
||||||
state.first_used_file = file;
|
state.first_used_file = file;
|
||||||
|
|||||||
@ -30,6 +30,7 @@
|
|||||||
#
|
#
|
||||||
# Bazel Build for Google C++ Testing Framework(Google Test)-googlemock
|
# Bazel Build for Google C++ Testing Framework(Google Test)-googlemock
|
||||||
|
|
||||||
|
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test")
|
||||||
load("@rules_python//python:defs.bzl", "py_library", "py_test")
|
load("@rules_python//python:defs.bzl", "py_library", "py_test")
|
||||||
|
|
||||||
licenses(["notice"])
|
licenses(["notice"])
|
||||||
|
|||||||
@ -188,7 +188,7 @@ TEST(TypeTraits, IsInvocableRV) {
|
|||||||
struct C {
|
struct C {
|
||||||
int operator()() const { return 0; }
|
int operator()() const { return 0; }
|
||||||
void operator()(int) & {}
|
void operator()(int) & {}
|
||||||
std::string operator()(int) && { return ""; };
|
std::string operator()(int) && { return ""; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// The first overload is callable for const and non-const rvalues and lvalues.
|
// The first overload is callable for const and non-const rvalues and lvalues.
|
||||||
@ -1030,8 +1030,7 @@ void VoidFunc(bool /* flag */) {}
|
|||||||
|
|
||||||
TEST(DoDefaultDeathTest, DiesIfUsedInCompositeAction) {
|
TEST(DoDefaultDeathTest, DiesIfUsedInCompositeAction) {
|
||||||
MockClass mock;
|
MockClass mock;
|
||||||
EXPECT_CALL(mock, IntFunc(_))
|
EXPECT_CALL(mock, IntFunc(_)).WillRepeatedly(DoAll(VoidFunc, DoDefault()));
|
||||||
.WillRepeatedly(DoAll(Invoke(VoidFunc), DoDefault()));
|
|
||||||
|
|
||||||
// Ideally we should verify the error message as well. Sadly,
|
// Ideally we should verify the error message as well. Sadly,
|
||||||
// EXPECT_DEATH() can only capture stderr, while Google Mock's
|
// EXPECT_DEATH() can only capture stderr, while Google Mock's
|
||||||
@ -1282,7 +1281,7 @@ int ReturnOne() {
|
|||||||
|
|
||||||
TEST(IgnoreResultTest, MonomorphicAction) {
|
TEST(IgnoreResultTest, MonomorphicAction) {
|
||||||
g_done = false;
|
g_done = false;
|
||||||
Action<void()> a = IgnoreResult(Invoke(ReturnOne));
|
Action<void()> a = IgnoreResult(&ReturnOne);
|
||||||
a.Perform(std::make_tuple());
|
a.Perform(std::make_tuple());
|
||||||
EXPECT_TRUE(g_done);
|
EXPECT_TRUE(g_done);
|
||||||
}
|
}
|
||||||
@ -1297,7 +1296,7 @@ MyNonDefaultConstructible ReturnMyNonDefaultConstructible(double /* x */) {
|
|||||||
TEST(IgnoreResultTest, ActionReturningClass) {
|
TEST(IgnoreResultTest, ActionReturningClass) {
|
||||||
g_done = false;
|
g_done = false;
|
||||||
Action<void(int)> a =
|
Action<void(int)> a =
|
||||||
IgnoreResult(Invoke(ReturnMyNonDefaultConstructible)); // NOLINT
|
IgnoreResult(&ReturnMyNonDefaultConstructible); // NOLINT
|
||||||
a.Perform(std::make_tuple(2));
|
a.Perform(std::make_tuple(2));
|
||||||
EXPECT_TRUE(g_done);
|
EXPECT_TRUE(g_done);
|
||||||
}
|
}
|
||||||
@ -1477,12 +1476,15 @@ TEST(DoAll, SupportsTypeErasedActions) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A DoAll action should be convertible to a OnceAction, even when its component
|
// A multi-action DoAll action should be convertible to a OnceAction, even when
|
||||||
// sub-actions are user-provided types that define only an Action conversion
|
// its component sub-actions are user-provided types that define only an Action
|
||||||
// operator. If they supposed being called more than once then they also support
|
// conversion operator. If they supposed being called more than once then they
|
||||||
// being called at most once.
|
// also support being called at most once.
|
||||||
|
//
|
||||||
|
// Single-arg DoAll just returns its argument, so will prefer the Action<F>
|
||||||
|
// overload for WillOnce.
|
||||||
TEST(DoAll, ConvertibleToOnceActionWithUserProvidedActionConversion) {
|
TEST(DoAll, ConvertibleToOnceActionWithUserProvidedActionConversion) {
|
||||||
// Simplest case: only one sub-action.
|
// Final action.
|
||||||
struct CustomFinal final {
|
struct CustomFinal final {
|
||||||
operator Action<int()>() { // NOLINT
|
operator Action<int()>() { // NOLINT
|
||||||
return Return(17);
|
return Return(17);
|
||||||
@ -1493,17 +1495,7 @@ TEST(DoAll, ConvertibleToOnceActionWithUserProvidedActionConversion) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
{
|
// Sub-actions.
|
||||||
OnceAction<int()> action = DoAll(CustomFinal{});
|
|
||||||
EXPECT_EQ(17, std::move(action).Call());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
OnceAction<int(int, char)> action = DoAll(CustomFinal{});
|
|
||||||
EXPECT_EQ(19, std::move(action).Call(0, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
// It should also work with multiple sub-actions.
|
|
||||||
struct CustomInitial final {
|
struct CustomInitial final {
|
||||||
operator Action<void()>() { // NOLINT
|
operator Action<void()>() { // NOLINT
|
||||||
return [] {};
|
return [] {};
|
||||||
@ -1527,7 +1519,7 @@ TEST(DoAll, ConvertibleToOnceActionWithUserProvidedActionConversion) {
|
|||||||
|
|
||||||
// Tests using WithArgs and with an action that takes 1 argument.
|
// Tests using WithArgs and with an action that takes 1 argument.
|
||||||
TEST(WithArgsTest, OneArg) {
|
TEST(WithArgsTest, OneArg) {
|
||||||
Action<bool(double x, int n)> a = WithArgs<1>(Invoke(Unary)); // NOLINT
|
Action<bool(double x, int n)> a = WithArgs<1>(Unary);
|
||||||
EXPECT_TRUE(a.Perform(std::make_tuple(1.5, -1)));
|
EXPECT_TRUE(a.Perform(std::make_tuple(1.5, -1)));
|
||||||
EXPECT_FALSE(a.Perform(std::make_tuple(1.5, 1)));
|
EXPECT_FALSE(a.Perform(std::make_tuple(1.5, 1)));
|
||||||
}
|
}
|
||||||
@ -1535,7 +1527,7 @@ TEST(WithArgsTest, OneArg) {
|
|||||||
// Tests using WithArgs with an action that takes 2 arguments.
|
// Tests using WithArgs with an action that takes 2 arguments.
|
||||||
TEST(WithArgsTest, TwoArgs) {
|
TEST(WithArgsTest, TwoArgs) {
|
||||||
Action<const char*(const char* s, double x, short n)> a = // NOLINT
|
Action<const char*(const char* s, double x, short n)> a = // NOLINT
|
||||||
WithArgs<0, 2>(Invoke(Binary));
|
WithArgs<0, 2>(Binary);
|
||||||
const char s[] = "Hello";
|
const char s[] = "Hello";
|
||||||
EXPECT_EQ(s + 2, a.Perform(std::make_tuple(CharPtr(s), 0.5, Short(2))));
|
EXPECT_EQ(s + 2, a.Perform(std::make_tuple(CharPtr(s), 0.5, Short(2))));
|
||||||
}
|
}
|
||||||
@ -1551,7 +1543,7 @@ struct ConcatAll {
|
|||||||
// Tests using WithArgs with an action that takes 10 arguments.
|
// Tests using WithArgs with an action that takes 10 arguments.
|
||||||
TEST(WithArgsTest, TenArgs) {
|
TEST(WithArgsTest, TenArgs) {
|
||||||
Action<std::string(const char*, const char*, const char*, const char*)> a =
|
Action<std::string(const char*, const char*, const char*, const char*)> a =
|
||||||
WithArgs<0, 1, 2, 3, 2, 1, 0, 1, 2, 3>(Invoke(ConcatAll{}));
|
WithArgs<0, 1, 2, 3, 2, 1, 0, 1, 2, 3>(ConcatAll{});
|
||||||
EXPECT_EQ("0123210123",
|
EXPECT_EQ("0123210123",
|
||||||
a.Perform(std::make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
|
a.Perform(std::make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
|
||||||
CharPtr("3"))));
|
CharPtr("3"))));
|
||||||
@ -1576,21 +1568,21 @@ TEST(WithArgsTest, NonInvokeAction) {
|
|||||||
// Tests using WithArgs to pass all original arguments in the original order.
|
// Tests using WithArgs to pass all original arguments in the original order.
|
||||||
TEST(WithArgsTest, Identity) {
|
TEST(WithArgsTest, Identity) {
|
||||||
Action<int(int x, char y, short z)> a = // NOLINT
|
Action<int(int x, char y, short z)> a = // NOLINT
|
||||||
WithArgs<0, 1, 2>(Invoke(Ternary));
|
WithArgs<0, 1, 2>(Ternary);
|
||||||
EXPECT_EQ(123, a.Perform(std::make_tuple(100, Char(20), Short(3))));
|
EXPECT_EQ(123, a.Perform(std::make_tuple(100, Char(20), Short(3))));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests using WithArgs with repeated arguments.
|
// Tests using WithArgs with repeated arguments.
|
||||||
TEST(WithArgsTest, RepeatedArguments) {
|
TEST(WithArgsTest, RepeatedArguments) {
|
||||||
Action<int(bool, int m, int n)> a = // NOLINT
|
Action<int(bool, int m, int n)> a = // NOLINT
|
||||||
WithArgs<1, 1, 1, 1>(Invoke(SumOf4));
|
WithArgs<1, 1, 1, 1>(SumOf4);
|
||||||
EXPECT_EQ(4, a.Perform(std::make_tuple(false, 1, 10)));
|
EXPECT_EQ(4, a.Perform(std::make_tuple(false, 1, 10)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests using WithArgs with reversed argument order.
|
// Tests using WithArgs with reversed argument order.
|
||||||
TEST(WithArgsTest, ReversedArgumentOrder) {
|
TEST(WithArgsTest, ReversedArgumentOrder) {
|
||||||
Action<const char*(short n, const char* input)> a = // NOLINT
|
Action<const char*(short n, const char* input)> a = // NOLINT
|
||||||
WithArgs<1, 0>(Invoke(Binary));
|
WithArgs<1, 0>(Binary);
|
||||||
const char s[] = "Hello";
|
const char s[] = "Hello";
|
||||||
EXPECT_EQ(s + 2, a.Perform(std::make_tuple(Short(2), CharPtr(s))));
|
EXPECT_EQ(s + 2, a.Perform(std::make_tuple(Short(2), CharPtr(s))));
|
||||||
}
|
}
|
||||||
@ -1598,14 +1590,14 @@ TEST(WithArgsTest, ReversedArgumentOrder) {
|
|||||||
// Tests using WithArgs with compatible, but not identical, argument types.
|
// Tests using WithArgs with compatible, but not identical, argument types.
|
||||||
TEST(WithArgsTest, ArgsOfCompatibleTypes) {
|
TEST(WithArgsTest, ArgsOfCompatibleTypes) {
|
||||||
Action<long(short x, char y, double z, char c)> a = // NOLINT
|
Action<long(short x, char y, double z, char c)> a = // NOLINT
|
||||||
WithArgs<0, 1, 3>(Invoke(Ternary));
|
WithArgs<0, 1, 3>(Ternary);
|
||||||
EXPECT_EQ(123,
|
EXPECT_EQ(123,
|
||||||
a.Perform(std::make_tuple(Short(100), Char(20), 5.6, Char(3))));
|
a.Perform(std::make_tuple(Short(100), Char(20), 5.6, Char(3))));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests using WithArgs with an action that returns void.
|
// Tests using WithArgs with an action that returns void.
|
||||||
TEST(WithArgsTest, VoidAction) {
|
TEST(WithArgsTest, VoidAction) {
|
||||||
Action<void(double x, char c, int n)> a = WithArgs<2, 1>(Invoke(VoidBinary));
|
Action<void(double x, char c, int n)> a = WithArgs<2, 1>(VoidBinary);
|
||||||
g_done = false;
|
g_done = false;
|
||||||
a.Perform(std::make_tuple(1.5, 'a', 3));
|
a.Perform(std::make_tuple(1.5, 'a', 3));
|
||||||
EXPECT_TRUE(g_done);
|
EXPECT_TRUE(g_done);
|
||||||
@ -1830,7 +1822,7 @@ std::vector<std::unique_ptr<int>> VectorUniquePtrSource() {
|
|||||||
|
|
||||||
TEST(MockMethodTest, CanReturnMoveOnlyValue_Return) {
|
TEST(MockMethodTest, CanReturnMoveOnlyValue_Return) {
|
||||||
MockClass mock;
|
MockClass mock;
|
||||||
std::unique_ptr<int> i(new int(19));
|
std::unique_ptr<int> i = std::make_unique<int>(19);
|
||||||
EXPECT_CALL(mock, MakeUnique()).WillOnce(Return(ByMove(std::move(i))));
|
EXPECT_CALL(mock, MakeUnique()).WillOnce(Return(ByMove(std::move(i))));
|
||||||
EXPECT_CALL(mock, MakeVectorUnique())
|
EXPECT_CALL(mock, MakeVectorUnique())
|
||||||
.WillOnce(Return(ByMove(VectorUniquePtrSource())));
|
.WillOnce(Return(ByMove(VectorUniquePtrSource())));
|
||||||
@ -1853,7 +1845,7 @@ TEST(MockMethodTest, CanReturnMoveOnlyValue_Return) {
|
|||||||
TEST(MockMethodTest, CanReturnMoveOnlyValue_DoAllReturn) {
|
TEST(MockMethodTest, CanReturnMoveOnlyValue_DoAllReturn) {
|
||||||
testing::MockFunction<void()> mock_function;
|
testing::MockFunction<void()> mock_function;
|
||||||
MockClass mock;
|
MockClass mock;
|
||||||
std::unique_ptr<int> i(new int(19));
|
std::unique_ptr<int> i = std::make_unique<int>(19);
|
||||||
EXPECT_CALL(mock_function, Call());
|
EXPECT_CALL(mock_function, Call());
|
||||||
EXPECT_CALL(mock, MakeUnique())
|
EXPECT_CALL(mock, MakeUnique())
|
||||||
.WillOnce(DoAll(InvokeWithoutArgs(&mock_function,
|
.WillOnce(DoAll(InvokeWithoutArgs(&mock_function,
|
||||||
@ -1872,9 +1864,8 @@ TEST(MockMethodTest, CanReturnMoveOnlyValue_Invoke) {
|
|||||||
[] { return std::make_unique<int>(42); });
|
[] { return std::make_unique<int>(42); });
|
||||||
EXPECT_EQ(42, *mock.MakeUnique());
|
EXPECT_EQ(42, *mock.MakeUnique());
|
||||||
|
|
||||||
EXPECT_CALL(mock, MakeUnique()).WillRepeatedly(Invoke(UniquePtrSource));
|
EXPECT_CALL(mock, MakeUnique()).WillRepeatedly(UniquePtrSource);
|
||||||
EXPECT_CALL(mock, MakeVectorUnique())
|
EXPECT_CALL(mock, MakeVectorUnique()).WillRepeatedly(VectorUniquePtrSource);
|
||||||
.WillRepeatedly(Invoke(VectorUniquePtrSource));
|
|
||||||
std::unique_ptr<int> result1 = mock.MakeUnique();
|
std::unique_ptr<int> result1 = mock.MakeUnique();
|
||||||
EXPECT_EQ(19, *result1);
|
EXPECT_EQ(19, *result1);
|
||||||
std::unique_ptr<int> result2 = mock.MakeUnique();
|
std::unique_ptr<int> result2 = mock.MakeUnique();
|
||||||
@ -1896,7 +1887,7 @@ TEST(MockMethodTest, CanTakeMoveOnlyValue) {
|
|||||||
});
|
});
|
||||||
// DoAll() does not compile, since it would move from its arguments twice.
|
// DoAll() does not compile, since it would move from its arguments twice.
|
||||||
// EXPECT_CALL(mock, TakeUnique(_, _))
|
// EXPECT_CALL(mock, TakeUnique(_, _))
|
||||||
// .WillRepeatedly(DoAll(Invoke([](std::unique_ptr<int> j) {}),
|
// .WillRepeatedly(DoAll([](std::unique_ptr<int> j) {})),
|
||||||
// Return(1)));
|
// Return(1)));
|
||||||
EXPECT_CALL(mock, TakeUnique(testing::Pointee(7)))
|
EXPECT_CALL(mock, TakeUnique(testing::Pointee(7)))
|
||||||
.WillOnce(Return(-7))
|
.WillOnce(Return(-7))
|
||||||
|
|||||||
@ -91,7 +91,7 @@ class FooInterface {
|
|||||||
|
|
||||||
virtual bool TakesNonConstReference(int& n) = 0; // NOLINT
|
virtual bool TakesNonConstReference(int& n) = 0; // NOLINT
|
||||||
virtual std::string TakesConstReference(const int& n) = 0;
|
virtual std::string TakesConstReference(const int& n) = 0;
|
||||||
virtual bool TakesConst(const int x) = 0;
|
virtual bool TakesConst(int x) = 0;
|
||||||
|
|
||||||
virtual int OverloadedOnArgumentNumber() = 0;
|
virtual int OverloadedOnArgumentNumber() = 0;
|
||||||
virtual int OverloadedOnArgumentNumber(int n) = 0;
|
virtual int OverloadedOnArgumentNumber(int n) = 0;
|
||||||
|
|||||||
@ -545,7 +545,7 @@ TEST(ExpectCallTest, DoesNotLogWhenVerbosityIsError) {
|
|||||||
|
|
||||||
void OnCallLogger() {
|
void OnCallLogger() {
|
||||||
DummyMock mock;
|
DummyMock mock;
|
||||||
ON_CALL(mock, TestMethod());
|
(void)ON_CALL(mock, TestMethod());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verifies that ON_CALL logs if the --gmock_verbose flag is set to "info".
|
// Verifies that ON_CALL logs if the --gmock_verbose flag is set to "info".
|
||||||
@ -568,7 +568,7 @@ TEST(OnCallTest, DoesNotLogWhenVerbosityIsError) {
|
|||||||
|
|
||||||
void OnCallAnyArgumentLogger() {
|
void OnCallAnyArgumentLogger() {
|
||||||
DummyMock mock;
|
DummyMock mock;
|
||||||
ON_CALL(mock, TestMethodArg(_));
|
(void)ON_CALL(mock, TestMethodArg(_));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verifies that ON_CALL prints provided _ argument.
|
// Verifies that ON_CALL prints provided _ argument.
|
||||||
|
|||||||
@ -770,7 +770,8 @@ TEST_P(AllOfTestP, ExplainsResult) {
|
|||||||
// Failed match. The first matcher, which failed, needs to
|
// Failed match. The first matcher, which failed, needs to
|
||||||
// explain.
|
// explain.
|
||||||
m = AllOf(GreaterThan(10), GreaterThan(20));
|
m = AllOf(GreaterThan(10), GreaterThan(20));
|
||||||
EXPECT_EQ("which is 5 less than 10", Explain(m, 5));
|
EXPECT_EQ("which is 5 less than 10, and which is 15 less than 20",
|
||||||
|
Explain(m, 5));
|
||||||
|
|
||||||
// Failed match. The second matcher, which failed, needs to
|
// Failed match. The second matcher, which failed, needs to
|
||||||
// explain. Since it doesn't given an explanation, the matcher text is
|
// explain. Since it doesn't given an explanation, the matcher text is
|
||||||
@ -1625,7 +1626,7 @@ TEST_F(DoubleNearTest, NanSensitiveDoubleNearCanMatchNaN) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(NotTest, WorksOnMoveOnlyType) {
|
TEST(NotTest, WorksOnMoveOnlyType) {
|
||||||
std::unique_ptr<int> p(new int(3));
|
std::unique_ptr<int> p = std::make_unique<int>(3);
|
||||||
EXPECT_THAT(p, Pointee(Eq(3)));
|
EXPECT_THAT(p, Pointee(Eq(3)));
|
||||||
EXPECT_THAT(p, Not(Pointee(Eq(2))));
|
EXPECT_THAT(p, Not(Pointee(Eq(2))));
|
||||||
}
|
}
|
||||||
@ -1681,13 +1682,13 @@ TEST(AnyOfTest, DoesNotCallAnyOfUnqualified) {
|
|||||||
} // namespace adl_test
|
} // namespace adl_test
|
||||||
|
|
||||||
TEST(AllOfTest, WorksOnMoveOnlyType) {
|
TEST(AllOfTest, WorksOnMoveOnlyType) {
|
||||||
std::unique_ptr<int> p(new int(3));
|
std::unique_ptr<int> p = std::make_unique<int>(3);
|
||||||
EXPECT_THAT(p, AllOf(Pointee(Eq(3)), Pointee(Gt(0)), Pointee(Lt(5))));
|
EXPECT_THAT(p, AllOf(Pointee(Eq(3)), Pointee(Gt(0)), Pointee(Lt(5))));
|
||||||
EXPECT_THAT(p, Not(AllOf(Pointee(Eq(3)), Pointee(Gt(0)), Pointee(Lt(3)))));
|
EXPECT_THAT(p, Not(AllOf(Pointee(Eq(3)), Pointee(Gt(0)), Pointee(Lt(3)))));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(AnyOfTest, WorksOnMoveOnlyType) {
|
TEST(AnyOfTest, WorksOnMoveOnlyType) {
|
||||||
std::unique_ptr<int> p(new int(3));
|
std::unique_ptr<int> p = std::make_unique<int>(3);
|
||||||
EXPECT_THAT(p, AnyOf(Pointee(Eq(5)), Pointee(Lt(0)), Pointee(Lt(5))));
|
EXPECT_THAT(p, AnyOf(Pointee(Eq(5)), Pointee(Lt(0)), Pointee(Lt(5))));
|
||||||
EXPECT_THAT(p, Not(AnyOf(Pointee(Eq(5)), Pointee(Lt(0)), Pointee(Gt(5)))));
|
EXPECT_THAT(p, Not(AnyOf(Pointee(Eq(5)), Pointee(Lt(0)), Pointee(Gt(5)))));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -622,15 +622,42 @@ struct IntReferenceWrapper {
|
|||||||
const int* value;
|
const int* value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Compared the contained values
|
||||||
bool operator==(const IntReferenceWrapper& a, const IntReferenceWrapper& b) {
|
bool operator==(const IntReferenceWrapper& a, const IntReferenceWrapper& b) {
|
||||||
return a.value == b.value;
|
return *a.value == *b.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MatcherCastTest, ValueIsNotCopied) {
|
TEST(MatcherCastTest, ValueIsCopied) {
|
||||||
int n = 42;
|
{
|
||||||
Matcher<IntReferenceWrapper> m = MatcherCast<IntReferenceWrapper>(n);
|
// When an IntReferenceWrapper is passed.
|
||||||
// Verify that the matcher holds a reference to n, not to its temporary copy.
|
int n = 42;
|
||||||
EXPECT_TRUE(m.Matches(n));
|
Matcher<IntReferenceWrapper> m =
|
||||||
|
MatcherCast<IntReferenceWrapper>(IntReferenceWrapper(n));
|
||||||
|
{
|
||||||
|
int value = 42;
|
||||||
|
EXPECT_TRUE(m.Matches(value));
|
||||||
|
value = 10;
|
||||||
|
EXPECT_FALSE(m.Matches(value));
|
||||||
|
// This changes the stored reference.
|
||||||
|
n = 10;
|
||||||
|
EXPECT_TRUE(m.Matches(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// When an int is passed.
|
||||||
|
int n = 42;
|
||||||
|
Matcher<IntReferenceWrapper> m = MatcherCast<IntReferenceWrapper>(n);
|
||||||
|
{
|
||||||
|
int value = 42;
|
||||||
|
EXPECT_TRUE(m.Matches(value));
|
||||||
|
value = 10;
|
||||||
|
EXPECT_FALSE(m.Matches(value));
|
||||||
|
// This does not change the stored int.
|
||||||
|
n = 10;
|
||||||
|
EXPECT_FALSE(m.Matches(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Base {
|
class Base {
|
||||||
@ -2362,22 +2389,19 @@ PolymorphicMatcher<DivisibleByImpl> DivisibleBy(int n) {
|
|||||||
return MakePolymorphicMatcher(DivisibleByImpl(n));
|
return MakePolymorphicMatcher(DivisibleByImpl(n));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that when AllOf() fails, only the first failing matcher is
|
// Tests that when AllOf() fails, all failing matchers are asked to explain why.
|
||||||
// asked to explain why.
|
|
||||||
TEST(ExplainMatchResultTest, AllOf_False_False) {
|
TEST(ExplainMatchResultTest, AllOf_False_False) {
|
||||||
const Matcher<int> m = AllOf(DivisibleBy(4), DivisibleBy(3));
|
const Matcher<int> m = AllOf(DivisibleBy(4), DivisibleBy(3));
|
||||||
EXPECT_EQ("which is 1 modulo 4", Explain(m, 5));
|
EXPECT_EQ("which is 1 modulo 4, and which is 2 modulo 3", Explain(m, 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that when AllOf() fails, only the first failing matcher is
|
// Tests that when AllOf() fails, all failing matchers are asked to explain why.
|
||||||
// asked to explain why.
|
|
||||||
TEST(ExplainMatchResultTest, AllOf_False_True) {
|
TEST(ExplainMatchResultTest, AllOf_False_True) {
|
||||||
const Matcher<int> m = AllOf(DivisibleBy(4), DivisibleBy(3));
|
const Matcher<int> m = AllOf(DivisibleBy(4), DivisibleBy(3));
|
||||||
EXPECT_EQ("which is 2 modulo 4", Explain(m, 6));
|
EXPECT_EQ("which is 2 modulo 4", Explain(m, 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that when AllOf() fails, only the first failing matcher is
|
// Tests that when AllOf() fails, all failing matchers are asked to explain why.
|
||||||
// asked to explain why.
|
|
||||||
TEST(ExplainMatchResultTest, AllOf_True_False) {
|
TEST(ExplainMatchResultTest, AllOf_True_False) {
|
||||||
const Matcher<int> m = AllOf(Ge(1), DivisibleBy(3));
|
const Matcher<int> m = AllOf(Ge(1), DivisibleBy(3));
|
||||||
EXPECT_EQ("which is 2 modulo 3", Explain(m, 5));
|
EXPECT_EQ("which is 2 modulo 3", Explain(m, 5));
|
||||||
|
|||||||
@ -217,7 +217,7 @@ TEST(PointeeTest, ReferenceToNonConstRawPointer) {
|
|||||||
TEST(PointeeTest, SmartPointer) {
|
TEST(PointeeTest, SmartPointer) {
|
||||||
const Matcher<std::unique_ptr<int>> m = Pointee(Ge(0));
|
const Matcher<std::unique_ptr<int>> m = Pointee(Ge(0));
|
||||||
|
|
||||||
std::unique_ptr<int> n(new int(1));
|
std::unique_ptr<int> n = std::make_unique<int>(1);
|
||||||
EXPECT_TRUE(m.Matches(n));
|
EXPECT_TRUE(m.Matches(n));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,7 +254,7 @@ TEST(PointerTest, RawPointerToConst) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(PointerTest, SmartPointer) {
|
TEST(PointerTest, SmartPointer) {
|
||||||
std::unique_ptr<int> n(new int(10));
|
std::unique_ptr<int> n = std::make_unique<int>(10);
|
||||||
int* raw_n = n.get();
|
int* raw_n = n.get();
|
||||||
const Matcher<std::unique_ptr<int>> m = Pointer(Eq(raw_n));
|
const Matcher<std::unique_ptr<int>> m = Pointer(Eq(raw_n));
|
||||||
|
|
||||||
@ -2796,7 +2796,7 @@ TEST(UnorderedPointwiseTest, WorksWithMoveOnly) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(PointeeTest, WorksOnMoveOnlyType) {
|
TEST(PointeeTest, WorksOnMoveOnlyType) {
|
||||||
std::unique_ptr<int> p(new int(3));
|
std::unique_ptr<int> p = std::make_unique<int>(3);
|
||||||
EXPECT_THAT(p, Pointee(Eq(3)));
|
EXPECT_THAT(p, Pointee(Eq(3)));
|
||||||
EXPECT_THAT(p, Not(Pointee(Eq(2))));
|
EXPECT_THAT(p, Not(Pointee(Eq(2))));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -79,7 +79,7 @@ TEST(AddressTest, Const) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(AddressTest, MatcherDoesntCopy) {
|
TEST(AddressTest, MatcherDoesntCopy) {
|
||||||
std::unique_ptr<int> n(new int(1));
|
std::unique_ptr<int> n = std::make_unique<int>(1);
|
||||||
const Matcher<std::unique_ptr<int>> m = Address(Eq(&n));
|
const Matcher<std::unique_ptr<int>> m = Address(Eq(&n));
|
||||||
|
|
||||||
EXPECT_TRUE(m.Matches(n));
|
EXPECT_TRUE(m.Matches(n));
|
||||||
@ -202,7 +202,7 @@ TEST(IsTrueTest, IsTrueIsFalse) {
|
|||||||
EXPECT_THAT(nullptr, Not(IsTrue()));
|
EXPECT_THAT(nullptr, Not(IsTrue()));
|
||||||
EXPECT_THAT(nullptr, IsFalse());
|
EXPECT_THAT(nullptr, IsFalse());
|
||||||
std::unique_ptr<int> null_unique;
|
std::unique_ptr<int> null_unique;
|
||||||
std::unique_ptr<int> nonnull_unique(new int(0));
|
std::unique_ptr<int> nonnull_unique = std::make_unique<int>(0);
|
||||||
EXPECT_THAT(null_unique, Not(IsTrue()));
|
EXPECT_THAT(null_unique, Not(IsTrue()));
|
||||||
EXPECT_THAT(null_unique, IsFalse());
|
EXPECT_THAT(null_unique, IsFalse());
|
||||||
EXPECT_THAT(nonnull_unique, IsTrue());
|
EXPECT_THAT(nonnull_unique, IsTrue());
|
||||||
@ -1665,7 +1665,7 @@ MATCHER(IsNotNull, "") { return arg != nullptr; }
|
|||||||
// Verifies that a matcher defined using MATCHER() can work on
|
// Verifies that a matcher defined using MATCHER() can work on
|
||||||
// move-only types.
|
// move-only types.
|
||||||
TEST(MatcherMacroTest, WorksOnMoveOnlyType) {
|
TEST(MatcherMacroTest, WorksOnMoveOnlyType) {
|
||||||
std::unique_ptr<int> p(new int(3));
|
std::unique_ptr<int> p = std::make_unique<int>(3);
|
||||||
EXPECT_THAT(p, IsNotNull());
|
EXPECT_THAT(p, IsNotNull());
|
||||||
EXPECT_THAT(std::unique_ptr<int>(), Not(IsNotNull()));
|
EXPECT_THAT(std::unique_ptr<int>(), Not(IsNotNull()));
|
||||||
}
|
}
|
||||||
@ -1675,7 +1675,7 @@ MATCHER_P(UniquePointee, pointee, "") { return *arg == pointee; }
|
|||||||
// Verifies that a matcher defined using MATCHER_P*() can work on
|
// Verifies that a matcher defined using MATCHER_P*() can work on
|
||||||
// move-only types.
|
// move-only types.
|
||||||
TEST(MatcherPMacroTest, WorksOnMoveOnlyType) {
|
TEST(MatcherPMacroTest, WorksOnMoveOnlyType) {
|
||||||
std::unique_ptr<int> p(new int(3));
|
std::unique_ptr<int> p = std::make_unique<int>(3);
|
||||||
EXPECT_THAT(p, UniquePointee(3));
|
EXPECT_THAT(p, UniquePointee(3));
|
||||||
EXPECT_THAT(p, Not(UniquePointee(2)));
|
EXPECT_THAT(p, Not(UniquePointee(2)));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -202,45 +202,45 @@ class Foo {
|
|||||||
|
|
||||||
// Tests using Invoke() with a nullary function.
|
// Tests using Invoke() with a nullary function.
|
||||||
TEST(InvokeTest, Nullary) {
|
TEST(InvokeTest, Nullary) {
|
||||||
Action<int()> a = Invoke(Nullary); // NOLINT
|
Action<int()> a = &Nullary;
|
||||||
EXPECT_EQ(1, a.Perform(std::make_tuple()));
|
EXPECT_EQ(1, a.Perform(std::make_tuple()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests using Invoke() with a unary function.
|
// Tests using Invoke() with a unary function.
|
||||||
TEST(InvokeTest, Unary) {
|
TEST(InvokeTest, Unary) {
|
||||||
Action<bool(int)> a = Invoke(Unary); // NOLINT
|
Action<bool(int)> a = &Unary;
|
||||||
EXPECT_FALSE(a.Perform(std::make_tuple(1)));
|
EXPECT_FALSE(a.Perform(std::make_tuple(1)));
|
||||||
EXPECT_TRUE(a.Perform(std::make_tuple(-1)));
|
EXPECT_TRUE(a.Perform(std::make_tuple(-1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests using Invoke() with a binary function.
|
// Tests using Invoke() with a binary function.
|
||||||
TEST(InvokeTest, Binary) {
|
TEST(InvokeTest, Binary) {
|
||||||
Action<const char*(const char*, short)> a = Invoke(Binary); // NOLINT
|
Action<const char*(const char*, short)> a = &Binary; // NOLINT
|
||||||
const char* p = "Hello";
|
const char* p = "Hello";
|
||||||
EXPECT_EQ(p + 2, a.Perform(std::make_tuple(p, Short(2))));
|
EXPECT_EQ(p + 2, a.Perform(std::make_tuple(p, Short(2))));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests using Invoke() with a ternary function.
|
// Tests using Invoke() with a ternary function.
|
||||||
TEST(InvokeTest, Ternary) {
|
TEST(InvokeTest, Ternary) {
|
||||||
Action<int(int, char, short)> a = Invoke(Ternary); // NOLINT
|
Action<int(int, char, short)> a = &Ternary; // NOLINT
|
||||||
EXPECT_EQ(6, a.Perform(std::make_tuple(1, '\2', Short(3))));
|
EXPECT_EQ(6, a.Perform(std::make_tuple(1, '\2', Short(3))));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests using Invoke() with a 4-argument function.
|
// Tests using Invoke() with a 4-argument function.
|
||||||
TEST(InvokeTest, FunctionThatTakes4Arguments) {
|
TEST(InvokeTest, FunctionThatTakes4Arguments) {
|
||||||
Action<int(int, int, int, int)> a = Invoke(SumOf4); // NOLINT
|
Action<int(int, int, int, int)> a = &SumOf4;
|
||||||
EXPECT_EQ(1234, a.Perform(std::make_tuple(1000, 200, 30, 4)));
|
EXPECT_EQ(1234, a.Perform(std::make_tuple(1000, 200, 30, 4)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests using Invoke() with a 5-argument function.
|
// Tests using Invoke() with a 5-argument function.
|
||||||
TEST(InvokeTest, FunctionThatTakes5Arguments) {
|
TEST(InvokeTest, FunctionThatTakes5Arguments) {
|
||||||
Action<int(int, int, int, int, int)> a = Invoke(SumOf5); // NOLINT
|
Action<int(int, int, int, int, int)> a = &SumOf5;
|
||||||
EXPECT_EQ(12345, a.Perform(std::make_tuple(10000, 2000, 300, 40, 5)));
|
EXPECT_EQ(12345, a.Perform(std::make_tuple(10000, 2000, 300, 40, 5)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests using Invoke() with a 6-argument function.
|
// Tests using Invoke() with a 6-argument function.
|
||||||
TEST(InvokeTest, FunctionThatTakes6Arguments) {
|
TEST(InvokeTest, FunctionThatTakes6Arguments) {
|
||||||
Action<int(int, int, int, int, int, int)> a = Invoke(SumOf6); // NOLINT
|
Action<int(int, int, int, int, int, int)> a = &SumOf6;
|
||||||
EXPECT_EQ(123456,
|
EXPECT_EQ(123456,
|
||||||
a.Perform(std::make_tuple(100000, 20000, 3000, 400, 50, 6)));
|
a.Perform(std::make_tuple(100000, 20000, 3000, 400, 50, 6)));
|
||||||
}
|
}
|
||||||
@ -253,7 +253,7 @@ inline const char* CharPtr(const char* s) { return s; }
|
|||||||
TEST(InvokeTest, FunctionThatTakes7Arguments) {
|
TEST(InvokeTest, FunctionThatTakes7Arguments) {
|
||||||
Action<std::string(const char*, const char*, const char*, const char*,
|
Action<std::string(const char*, const char*, const char*, const char*,
|
||||||
const char*, const char*, const char*)>
|
const char*, const char*, const char*)>
|
||||||
a = Invoke(Concat7);
|
a = &Concat7;
|
||||||
EXPECT_EQ("1234567",
|
EXPECT_EQ("1234567",
|
||||||
a.Perform(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
a.Perform(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
||||||
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
||||||
@ -264,7 +264,7 @@ TEST(InvokeTest, FunctionThatTakes7Arguments) {
|
|||||||
TEST(InvokeTest, FunctionThatTakes8Arguments) {
|
TEST(InvokeTest, FunctionThatTakes8Arguments) {
|
||||||
Action<std::string(const char*, const char*, const char*, const char*,
|
Action<std::string(const char*, const char*, const char*, const char*,
|
||||||
const char*, const char*, const char*, const char*)>
|
const char*, const char*, const char*, const char*)>
|
||||||
a = Invoke(Concat8);
|
a = &Concat8;
|
||||||
EXPECT_EQ("12345678",
|
EXPECT_EQ("12345678",
|
||||||
a.Perform(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
a.Perform(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
||||||
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
||||||
@ -276,7 +276,7 @@ TEST(InvokeTest, FunctionThatTakes9Arguments) {
|
|||||||
Action<std::string(const char*, const char*, const char*, const char*,
|
Action<std::string(const char*, const char*, const char*, const char*,
|
||||||
const char*, const char*, const char*, const char*,
|
const char*, const char*, const char*, const char*,
|
||||||
const char*)>
|
const char*)>
|
||||||
a = Invoke(Concat9);
|
a = &Concat9;
|
||||||
EXPECT_EQ("123456789", a.Perform(std::make_tuple(
|
EXPECT_EQ("123456789", a.Perform(std::make_tuple(
|
||||||
CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
||||||
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
||||||
@ -288,7 +288,7 @@ TEST(InvokeTest, FunctionThatTakes10Arguments) {
|
|||||||
Action<std::string(const char*, const char*, const char*, const char*,
|
Action<std::string(const char*, const char*, const char*, const char*,
|
||||||
const char*, const char*, const char*, const char*,
|
const char*, const char*, const char*, const char*,
|
||||||
const char*, const char*)>
|
const char*, const char*)>
|
||||||
a = Invoke(Concat10);
|
a = &Concat10;
|
||||||
EXPECT_EQ("1234567890",
|
EXPECT_EQ("1234567890",
|
||||||
a.Perform(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
a.Perform(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
||||||
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
||||||
@ -298,12 +298,12 @@ TEST(InvokeTest, FunctionThatTakes10Arguments) {
|
|||||||
|
|
||||||
// Tests using Invoke() with functions with parameters declared as Unused.
|
// Tests using Invoke() with functions with parameters declared as Unused.
|
||||||
TEST(InvokeTest, FunctionWithUnusedParameters) {
|
TEST(InvokeTest, FunctionWithUnusedParameters) {
|
||||||
Action<int(int, int, double, const std::string&)> a1 = Invoke(SumOfFirst2);
|
Action<int(int, int, double, const std::string&)> a1 = &SumOfFirst2;
|
||||||
std::tuple<int, int, double, std::string> dummy =
|
std::tuple<int, int, double, std::string> dummy =
|
||||||
std::make_tuple(10, 2, 5.6, std::string("hi"));
|
std::make_tuple(10, 2, 5.6, std::string("hi"));
|
||||||
EXPECT_EQ(12, a1.Perform(dummy));
|
EXPECT_EQ(12, a1.Perform(dummy));
|
||||||
|
|
||||||
Action<int(int, int, bool, int*)> a2 = Invoke(SumOfFirst2);
|
Action<int(int, int, bool, int*)> a2 = &SumOfFirst2;
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
23, a2.Perform(std::make_tuple(20, 3, true, static_cast<int*>(nullptr))));
|
23, a2.Perform(std::make_tuple(20, 3, true, static_cast<int*>(nullptr))));
|
||||||
}
|
}
|
||||||
@ -320,13 +320,13 @@ TEST(InvokeTest, MethodWithUnusedParameters) {
|
|||||||
|
|
||||||
// Tests using Invoke() with a functor.
|
// Tests using Invoke() with a functor.
|
||||||
TEST(InvokeTest, Functor) {
|
TEST(InvokeTest, Functor) {
|
||||||
Action<long(long, int)> a = Invoke(plus<long>()); // NOLINT
|
Action<long(long, int)> a = plus<long>(); // NOLINT
|
||||||
EXPECT_EQ(3L, a.Perform(std::make_tuple(1, 2)));
|
EXPECT_EQ(3L, a.Perform(std::make_tuple(1, 2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests using Invoke(f) as an action of a compatible type.
|
// Tests using Invoke(f) as an action of a compatible type.
|
||||||
TEST(InvokeTest, FunctionWithCompatibleType) {
|
TEST(InvokeTest, FunctionWithCompatibleType) {
|
||||||
Action<long(int, short, char, bool)> a = Invoke(SumOf4); // NOLINT
|
Action<long(int, short, char, bool)> a = &SumOf4; // NOLINT
|
||||||
EXPECT_EQ(4321, a.Perform(std::make_tuple(4000, Short(300), Char(20), true)));
|
EXPECT_EQ(4321, a.Perform(std::make_tuple(4000, Short(300), Char(20), true)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,13 +447,13 @@ TEST(InvokeMethodTest, MethodWithCompatibleType) {
|
|||||||
|
|
||||||
// Tests using WithoutArgs with an action that takes no argument.
|
// Tests using WithoutArgs with an action that takes no argument.
|
||||||
TEST(WithoutArgsTest, NoArg) {
|
TEST(WithoutArgsTest, NoArg) {
|
||||||
Action<int(int n)> a = WithoutArgs(Invoke(Nullary)); // NOLINT
|
Action<int(int n)> a = WithoutArgs(&Nullary); // NOLINT
|
||||||
EXPECT_EQ(1, a.Perform(std::make_tuple(2)));
|
EXPECT_EQ(1, a.Perform(std::make_tuple(2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests using WithArg with an action that takes 1 argument.
|
// Tests using WithArg with an action that takes 1 argument.
|
||||||
TEST(WithArgTest, OneArg) {
|
TEST(WithArgTest, OneArg) {
|
||||||
Action<bool(double x, int n)> b = WithArg<1>(Invoke(Unary)); // NOLINT
|
Action<bool(double x, int n)> b = WithArg<1>(&Unary); // NOLINT
|
||||||
EXPECT_TRUE(b.Perform(std::make_tuple(1.5, -1)));
|
EXPECT_TRUE(b.Perform(std::make_tuple(1.5, -1)));
|
||||||
EXPECT_FALSE(b.Perform(std::make_tuple(1.5, 1)));
|
EXPECT_FALSE(b.Perform(std::make_tuple(1.5, 1)));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -160,7 +160,7 @@ class MockCC : public CC {
|
|||||||
// Tests that a method with expanded name compiles.
|
// Tests that a method with expanded name compiles.
|
||||||
TEST(OnCallSyntaxTest, CompilesWithMethodNameExpandedFromMacro) {
|
TEST(OnCallSyntaxTest, CompilesWithMethodNameExpandedFromMacro) {
|
||||||
MockCC cc;
|
MockCC cc;
|
||||||
ON_CALL(cc, Method());
|
(void)ON_CALL(cc, Method());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that the method with expanded name not only compiles but runs
|
// Tests that the method with expanded name not only compiles but runs
|
||||||
@ -193,7 +193,7 @@ TEST(OnCallSyntaxTest, EvaluatesFirstArgumentOnce) {
|
|||||||
MockA a;
|
MockA a;
|
||||||
MockA* pa = &a;
|
MockA* pa = &a;
|
||||||
|
|
||||||
ON_CALL(*pa++, DoA(_));
|
(void)ON_CALL(*pa++, DoA(_));
|
||||||
EXPECT_EQ(&a + 1, pa);
|
EXPECT_EQ(&a + 1, pa);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,7 +201,7 @@ TEST(OnCallSyntaxTest, EvaluatesSecondArgumentOnce) {
|
|||||||
MockA a;
|
MockA a;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
|
||||||
ON_CALL(a, DoA(n++));
|
(void)ON_CALL(a, DoA(n++));
|
||||||
EXPECT_EQ(1, n);
|
EXPECT_EQ(1, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,7 +232,7 @@ TEST(OnCallSyntaxTest, WillByDefaultIsMandatory) {
|
|||||||
|
|
||||||
EXPECT_DEATH_IF_SUPPORTED(
|
EXPECT_DEATH_IF_SUPPORTED(
|
||||||
{
|
{
|
||||||
ON_CALL(a, DoA(5));
|
(void)ON_CALL(a, DoA(5));
|
||||||
a.DoA(5);
|
a.DoA(5);
|
||||||
},
|
},
|
||||||
"");
|
"");
|
||||||
@ -2045,7 +2045,7 @@ class GMockVerboseFlagTest : public VerboseFlagPreservingFixture {
|
|||||||
NaggyMock<MockA> a;
|
NaggyMock<MockA> a;
|
||||||
const std::string note =
|
const std::string note =
|
||||||
"NOTE: You can safely ignore the above warning unless this "
|
"NOTE: You can safely ignore the above warning unless this "
|
||||||
"call should not happen. Do not suppress it by blindly adding "
|
"call should not happen. Do not suppress it by 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/main/docs/"
|
"https://github.com/google/googletest/blob/main/docs/"
|
||||||
|
|||||||
@ -79,14 +79,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/main/docs/gmock_cook_book.md#knowing-when-to-expect-useoncall for details.
|
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md#knowing-when-to-expect-useoncall for details.
|
||||||
[ OK ] GMockOutputTest.UninterestingCall
|
[ 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/main/docs/gmock_cook_book.md#knowing-when-to-expect-useoncall for details.
|
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md#knowing-when-to-expect-useoncall for details.
|
||||||
[ OK ] GMockOutputTest.UninterestingCallToVoidFunction
|
[ OK ] GMockOutputTest.UninterestingCallToVoidFunction
|
||||||
[ RUN ] GMockOutputTest.RetiredExpectation
|
[ RUN ] GMockOutputTest.RetiredExpectation
|
||||||
unknown file: Failure
|
unknown file: Failure
|
||||||
@ -283,14 +283,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/main/docs/gmock_cook_book.md#knowing-when-to-expect-useoncall for details.
|
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md#knowing-when-to-expect-useoncall for details.
|
||||||
|
|
||||||
GMOCK WARNING:
|
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/main/docs/gmock_cook_book.md#knowing-when-to-expect-useoncall for details.
|
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md#knowing-when-to-expect-useoncall for details.
|
||||||
[ OK ] GMockOutputTest.UninterestingCallWithDefaultAction
|
[ OK ] GMockOutputTest.UninterestingCallWithDefaultAction
|
||||||
[ RUN ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction
|
[ RUN ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction
|
||||||
|
|
||||||
|
|||||||
@ -132,9 +132,6 @@ if(GTEST_HAS_ABSL)
|
|||||||
absl::flags_reflection
|
absl::flags_reflection
|
||||||
absl::flags_usage
|
absl::flags_usage
|
||||||
absl::strings
|
absl::strings
|
||||||
absl::any
|
|
||||||
absl::optional
|
|
||||||
absl::variant
|
|
||||||
re2::re2
|
re2::re2
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@ -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 v1.16.0
|
git clone https://github.com/google/googletest.git -b v1.17.0
|
||||||
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
|
||||||
@ -124,9 +124,9 @@ match the project in which it is included.
|
|||||||
|
|
||||||
#### C++ Standard Version
|
#### C++ Standard Version
|
||||||
|
|
||||||
An environment that supports C++14 is required in order to successfully build
|
An environment that supports C++17 is required in order to successfully build
|
||||||
GoogleTest. One way to ensure this is to specify the standard in the top-level
|
GoogleTest. One way to ensure this is to specify the standard in the top-level
|
||||||
project, for example by using the `set(CMAKE_CXX_STANDARD 14)` command along
|
project, for example by using the `set(CMAKE_CXX_STANDARD 17)` command along
|
||||||
with `set(CMAKE_CXX_STANDARD_REQUIRED ON)`. If this is not feasible, for example
|
with `set(CMAKE_CXX_STANDARD_REQUIRED ON)`. If this is not feasible, for example
|
||||||
in a C project using GoogleTest for validation, then it can be specified by
|
in a C project using GoogleTest for validation, then it can be specified by
|
||||||
adding it to the options for cmake via the`-DCMAKE_CXX_FLAGS` option.
|
adding it to the options for cmake via the`-DCMAKE_CXX_FLAGS` option.
|
||||||
@ -145,9 +145,9 @@ We list the most frequently used macros below. For a complete list, see file
|
|||||||
### Multi-threaded Tests
|
### Multi-threaded Tests
|
||||||
|
|
||||||
GoogleTest is thread-safe where the pthread library is available. After
|
GoogleTest is thread-safe where the pthread library is available. After
|
||||||
`#include <gtest/gtest.h>`, you can check the
|
`#include <gtest/gtest.h>`, you can check the `GTEST_IS_THREADSAFE` macro to see
|
||||||
`GTEST_IS_THREADSAFE` macro to see whether this is the case (yes if the macro is
|
whether this is the case (yes if the macro is `#defined` to 1, no if it's
|
||||||
`#defined` to 1, no if it's undefined.).
|
undefined.).
|
||||||
|
|
||||||
If GoogleTest doesn't correctly detect whether pthread is available in your
|
If GoogleTest doesn't correctly detect whether pthread is available in your
|
||||||
environment, you can force it with
|
environment, you can force it with
|
||||||
|
|||||||
@ -296,12 +296,12 @@ class MatcherBase : private MatcherDescriberInterface {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
MatcherBase(MatcherBase&& other)
|
MatcherBase(MatcherBase&& other) noexcept
|
||||||
: vtable_(other.vtable_), buffer_(other.buffer_) {
|
: vtable_(other.vtable_), buffer_(other.buffer_) {
|
||||||
other.vtable_ = nullptr;
|
other.vtable_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MatcherBase& operator=(MatcherBase&& other) {
|
MatcherBase& operator=(MatcherBase&& other) noexcept {
|
||||||
if (this == &other) return *this;
|
if (this == &other) return *this;
|
||||||
Destroy();
|
Destroy();
|
||||||
vtable_ = other.vtable_;
|
vtable_ = other.vtable_;
|
||||||
@ -773,6 +773,35 @@ class GeMatcher
|
|||||||
static const char* NegatedDesc() { return "isn't >="; }
|
static const char* NegatedDesc() { return "isn't >="; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Same as `EqMatcher<Rhs>`, except that the `rhs` is stored as `StoredRhs` and
|
||||||
|
// must be implicitly convertible to `Rhs`.
|
||||||
|
template <typename Rhs, typename StoredRhs>
|
||||||
|
class ImplicitCastEqMatcher {
|
||||||
|
public:
|
||||||
|
explicit ImplicitCastEqMatcher(const StoredRhs& rhs) : stored_rhs_(rhs) {}
|
||||||
|
|
||||||
|
using is_gtest_matcher = void;
|
||||||
|
|
||||||
|
template <typename Lhs>
|
||||||
|
bool MatchAndExplain(const Lhs& lhs, std::ostream*) const {
|
||||||
|
return lhs == rhs();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DescribeTo(std::ostream* os) const {
|
||||||
|
*os << "is equal to ";
|
||||||
|
UniversalPrint(rhs(), os);
|
||||||
|
}
|
||||||
|
void DescribeNegationTo(std::ostream* os) const {
|
||||||
|
*os << "isn't equal to ";
|
||||||
|
UniversalPrint(rhs(), os);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Rhs rhs() const { return ImplicitCast_<Rhs>(stored_rhs_); }
|
||||||
|
|
||||||
|
StoredRhs stored_rhs_;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T, typename = typename std::enable_if<
|
template <typename T, typename = typename std::enable_if<
|
||||||
std::is_constructible<std::string, T>::value>::type>
|
std::is_constructible<std::string, T>::value>::type>
|
||||||
using StringLike = T;
|
using StringLike = T;
|
||||||
|
|||||||
@ -104,15 +104,19 @@
|
|||||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
||||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
||||||
|
|
||||||
|
#include <any>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
#include <ostream> // NOLINT
|
#include <ostream> // NOLINT
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#ifdef GTEST_HAS_ABSL
|
#ifdef GTEST_HAS_ABSL
|
||||||
@ -245,8 +249,8 @@ struct StreamPrinter {
|
|||||||
// ADL (possibly involving implicit conversions).
|
// ADL (possibly involving implicit conversions).
|
||||||
// (Use SFINAE via return type, because it seems GCC < 12 doesn't handle name
|
// (Use SFINAE via return type, because it seems GCC < 12 doesn't handle name
|
||||||
// lookup properly when we do it in the template parameter list.)
|
// lookup properly when we do it in the template parameter list.)
|
||||||
static auto PrintValue(const T& value,
|
static auto PrintValue(const T& value, ::std::ostream* os)
|
||||||
::std::ostream* os) -> decltype((void)(*os << value)) {
|
-> decltype((void)(*os << value)) {
|
||||||
// Call streaming operator found by ADL, possibly with implicit conversions
|
// Call streaming operator found by ADL, possibly with implicit conversions
|
||||||
// of the arguments.
|
// of the arguments.
|
||||||
*os << value;
|
*os << value;
|
||||||
@ -521,11 +525,15 @@ GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os);
|
|||||||
|
|
||||||
GTEST_API_ void PrintTo(char32_t c, ::std::ostream* os);
|
GTEST_API_ void PrintTo(char32_t c, ::std::ostream* os);
|
||||||
inline void PrintTo(char16_t c, ::std::ostream* os) {
|
inline void PrintTo(char16_t c, ::std::ostream* os) {
|
||||||
PrintTo(ImplicitCast_<char32_t>(c), os);
|
// TODO(b/418738869): Incorrect for values not representing valid codepoints.
|
||||||
|
// Also see https://github.com/google/googletest/issues/4762.
|
||||||
|
PrintTo(static_cast<char32_t>(c), os);
|
||||||
}
|
}
|
||||||
#ifdef __cpp_lib_char8_t
|
#ifdef __cpp_lib_char8_t
|
||||||
inline void PrintTo(char8_t c, ::std::ostream* os) {
|
inline void PrintTo(char8_t c, ::std::ostream* os) {
|
||||||
PrintTo(ImplicitCast_<char32_t>(c), os);
|
// TODO(b/418738869): Incorrect for values not representing valid codepoints.
|
||||||
|
// Also see https://github.com/google/googletest/issues/4762.
|
||||||
|
PrintTo(static_cast<char32_t>(c), os);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -695,44 +703,63 @@ void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overloads for ::std::string.
|
// Overloads for ::std::string and ::std::string_view
|
||||||
GTEST_API_ void PrintStringTo(const ::std::string& s, ::std::ostream* os);
|
GTEST_API_ void PrintStringTo(::std::string_view s, ::std::ostream* os);
|
||||||
inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
|
inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
|
||||||
PrintStringTo(s, os);
|
PrintStringTo(s, os);
|
||||||
}
|
}
|
||||||
|
inline void PrintTo(::std::string_view s, ::std::ostream* os) {
|
||||||
|
PrintStringTo(s, os);
|
||||||
|
}
|
||||||
|
|
||||||
// Overloads for ::std::u8string
|
// Overloads for ::std::u8string and ::std::u8string_view
|
||||||
#ifdef __cpp_lib_char8_t
|
#ifdef __cpp_lib_char8_t
|
||||||
GTEST_API_ void PrintU8StringTo(const ::std::u8string& s, ::std::ostream* os);
|
GTEST_API_ void PrintU8StringTo(::std::u8string_view 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);
|
||||||
}
|
}
|
||||||
|
inline void PrintTo(::std::u8string_view s, ::std::ostream* os) {
|
||||||
|
PrintU8StringTo(s, os);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Overloads for ::std::u16string
|
// Overloads for ::std::u16string and ::std::u16string_view
|
||||||
GTEST_API_ void PrintU16StringTo(const ::std::u16string& s, ::std::ostream* os);
|
GTEST_API_ void PrintU16StringTo(::std::u16string_view s, ::std::ostream* os);
|
||||||
inline void PrintTo(const ::std::u16string& s, ::std::ostream* os) {
|
inline void PrintTo(const ::std::u16string& s, ::std::ostream* os) {
|
||||||
PrintU16StringTo(s, os);
|
PrintU16StringTo(s, os);
|
||||||
}
|
}
|
||||||
|
inline void PrintTo(::std::u16string_view s, ::std::ostream* os) {
|
||||||
|
PrintU16StringTo(s, os);
|
||||||
|
}
|
||||||
|
|
||||||
// Overloads for ::std::u32string
|
// Overloads for ::std::u32string and ::std::u32string_view
|
||||||
GTEST_API_ void PrintU32StringTo(const ::std::u32string& s, ::std::ostream* os);
|
GTEST_API_ void PrintU32StringTo(::std::u32string_view s, ::std::ostream* os);
|
||||||
inline void PrintTo(const ::std::u32string& s, ::std::ostream* os) {
|
inline void PrintTo(const ::std::u32string& s, ::std::ostream* os) {
|
||||||
PrintU32StringTo(s, os);
|
PrintU32StringTo(s, os);
|
||||||
}
|
}
|
||||||
|
inline void PrintTo(::std::u32string_view s, ::std::ostream* os) {
|
||||||
|
PrintU32StringTo(s, os);
|
||||||
|
}
|
||||||
|
|
||||||
// Overloads for ::std::wstring.
|
// Overloads for ::std::wstring and ::std::wstring_view
|
||||||
#if GTEST_HAS_STD_WSTRING
|
#if GTEST_HAS_STD_WSTRING
|
||||||
GTEST_API_ void PrintWideStringTo(const ::std::wstring& s, ::std::ostream* os);
|
GTEST_API_ void PrintWideStringTo(::std::wstring_view s, ::std::ostream* os);
|
||||||
inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
|
inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
|
||||||
PrintWideStringTo(s, os);
|
PrintWideStringTo(s, os);
|
||||||
}
|
}
|
||||||
|
inline void PrintTo(::std::wstring_view s, ::std::ostream* os) {
|
||||||
|
PrintWideStringTo(s, os);
|
||||||
|
}
|
||||||
#endif // GTEST_HAS_STD_WSTRING
|
#endif // GTEST_HAS_STD_WSTRING
|
||||||
|
|
||||||
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||||
// Overload for internal::StringView.
|
// Overload for internal::StringView. Needed for build configurations where
|
||||||
|
// internal::StringView is an alias for absl::string_view, but absl::string_view
|
||||||
|
// is a distinct type from std::string_view.
|
||||||
|
template <int&... ExplicitArgumentBarrier, typename T = internal::StringView,
|
||||||
|
std::enable_if_t<!std::is_same_v<T, ::std::string_view>, int> = 0>
|
||||||
inline void PrintTo(internal::StringView sp, ::std::ostream* os) {
|
inline void PrintTo(internal::StringView sp, ::std::ostream* os) {
|
||||||
PrintTo(::std::string(sp), os);
|
PrintStringTo(sp, os);
|
||||||
}
|
}
|
||||||
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
||||||
|
|
||||||
@ -890,14 +917,11 @@ class UniversalPrinter {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
class UniversalPrinter<const T> : public UniversalPrinter<T> {};
|
class UniversalPrinter<const T> : public UniversalPrinter<T> {};
|
||||||
|
|
||||||
#if GTEST_INTERNAL_HAS_ANY
|
// Printer for std::any
|
||||||
|
|
||||||
// Printer for std::any / absl::any
|
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class UniversalPrinter<Any> {
|
class UniversalPrinter<std::any> {
|
||||||
public:
|
public:
|
||||||
static void Print(const Any& value, ::std::ostream* os) {
|
static void Print(const std::any& value, ::std::ostream* os) {
|
||||||
if (value.has_value()) {
|
if (value.has_value()) {
|
||||||
*os << "value of type " << GetTypeName(value);
|
*os << "value of type " << GetTypeName(value);
|
||||||
} else {
|
} else {
|
||||||
@ -906,7 +930,7 @@ class UniversalPrinter<Any> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::string GetTypeName(const Any& value) {
|
static std::string GetTypeName(const std::any& value) {
|
||||||
#if GTEST_HAS_RTTI
|
#if GTEST_HAS_RTTI
|
||||||
return internal::GetTypeName(value.type());
|
return internal::GetTypeName(value.type());
|
||||||
#else
|
#else
|
||||||
@ -916,16 +940,11 @@ class UniversalPrinter<Any> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GTEST_INTERNAL_HAS_ANY
|
// Printer for std::optional
|
||||||
|
|
||||||
#if GTEST_INTERNAL_HAS_OPTIONAL
|
|
||||||
|
|
||||||
// Printer for std::optional / absl::optional
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class UniversalPrinter<Optional<T>> {
|
class UniversalPrinter<std::optional<T>> {
|
||||||
public:
|
public:
|
||||||
static void Print(const Optional<T>& value, ::std::ostream* os) {
|
static void Print(const std::optional<T>& value, ::std::ostream* os) {
|
||||||
*os << '(';
|
*os << '(';
|
||||||
if (!value) {
|
if (!value) {
|
||||||
*os << "nullopt";
|
*os << "nullopt";
|
||||||
@ -937,29 +956,18 @@ class UniversalPrinter<Optional<T>> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class UniversalPrinter<decltype(Nullopt())> {
|
class UniversalPrinter<std::nullopt_t> {
|
||||||
public:
|
public:
|
||||||
static void Print(decltype(Nullopt()), ::std::ostream* os) {
|
static void Print(std::nullopt_t, ::std::ostream* os) { *os << "(nullopt)"; }
|
||||||
*os << "(nullopt)";
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GTEST_INTERNAL_HAS_OPTIONAL
|
// Printer for std::variant
|
||||||
|
|
||||||
#if GTEST_INTERNAL_HAS_VARIANT
|
|
||||||
|
|
||||||
// Printer for std::variant / absl::variant
|
|
||||||
|
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
class UniversalPrinter<Variant<T...>> {
|
class UniversalPrinter<std::variant<T...>> {
|
||||||
public:
|
public:
|
||||||
static void Print(const Variant<T...>& value, ::std::ostream* os) {
|
static void Print(const std::variant<T...>& value, ::std::ostream* os) {
|
||||||
*os << '(';
|
*os << '(';
|
||||||
#ifdef GTEST_HAS_ABSL
|
|
||||||
absl::visit(Visitor{os, value.index()}, value);
|
|
||||||
#else
|
|
||||||
std::visit(Visitor{os, value.index()}, value);
|
std::visit(Visitor{os, value.index()}, value);
|
||||||
#endif // GTEST_HAS_ABSL
|
|
||||||
*os << ')';
|
*os << ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -976,8 +984,6 @@ class UniversalPrinter<Variant<T...>> {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GTEST_INTERNAL_HAS_VARIANT
|
|
||||||
|
|
||||||
// UniversalPrintArray(begin, len, os) prints an array of 'len'
|
// UniversalPrintArray(begin, len, os) prints an array of 'len'
|
||||||
// elements, starting at address 'begin'.
|
// elements, starting at address 'begin'.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|||||||
@ -48,15 +48,15 @@ template <typename T>
|
|||||||
class FooTest : public testing::Test {
|
class FooTest : public testing::Test {
|
||||||
public:
|
public:
|
||||||
...
|
...
|
||||||
typedef std::list<T> List;
|
using List = ::std::list<T>;
|
||||||
static T shared_;
|
static T shared_;
|
||||||
T value_;
|
T value_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Next, associate a list of types with the test suite, which will be
|
// Next, associate a list of types with the test suite, which will be
|
||||||
// repeated for each type in the list. The typedef is necessary for
|
// repeated for each type in the list. The using-declaration is necessary for
|
||||||
// the macro to parse correctly.
|
// the macro to parse correctly.
|
||||||
typedef testing::Types<char, int, unsigned int> MyTypes;
|
using MyTypes = ::testing::Types<char, int, unsigned int>;
|
||||||
TYPED_TEST_SUITE(FooTest, MyTypes);
|
TYPED_TEST_SUITE(FooTest, MyTypes);
|
||||||
|
|
||||||
// If the type list contains only one type, you can write that type
|
// If the type list contains only one type, you can write that type
|
||||||
@ -157,7 +157,7 @@ REGISTER_TYPED_TEST_SUITE_P(FooTest,
|
|||||||
// argument to the INSTANTIATE_* macro is a prefix that will be added
|
// argument to the INSTANTIATE_* macro is a prefix that will be added
|
||||||
// to the actual test suite name. Remember to pick unique prefixes for
|
// to the actual test suite name. Remember to pick unique prefixes for
|
||||||
// different instances.
|
// different instances.
|
||||||
typedef testing::Types<char, int, unsigned int> MyTypes;
|
using MyTypes = ::testing::Types<char, int, unsigned int>;
|
||||||
INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
|
INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
|
||||||
|
|
||||||
// If the type list contains only one type, you can write that type
|
// If the type list contains only one type, you can write that type
|
||||||
|
|||||||
@ -1610,6 +1610,8 @@ GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1,
|
|||||||
double val1, double val2,
|
double val1, double val2,
|
||||||
double abs_error);
|
double abs_error);
|
||||||
|
|
||||||
|
using GoogleTest_NotSupported_OnFunctionReturningNonVoid = void;
|
||||||
|
|
||||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
// A class that enables one to stream messages to assertion macros
|
// A class that enables one to stream messages to assertion macros
|
||||||
class GTEST_API_ AssertHelper {
|
class GTEST_API_ AssertHelper {
|
||||||
@ -1621,7 +1623,8 @@ class GTEST_API_ AssertHelper {
|
|||||||
|
|
||||||
// Message assignment is a semantic trick to enable assertion
|
// Message assignment is a semantic trick to enable assertion
|
||||||
// streaming; see the GTEST_MESSAGE_ macro below.
|
// streaming; see the GTEST_MESSAGE_ macro below.
|
||||||
void operator=(const Message& message) const;
|
GoogleTest_NotSupported_OnFunctionReturningNonVoid operator=(
|
||||||
|
const Message& message) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// We put our data in a struct so that the size of the AssertHelper class can
|
// We put our data in a struct so that the size of the AssertHelper class can
|
||||||
@ -1693,7 +1696,7 @@ class WithParamInterface {
|
|||||||
|
|
||||||
// The current parameter value. Is also available in the test fixture's
|
// The current parameter value. Is also available in the test fixture's
|
||||||
// constructor.
|
// constructor.
|
||||||
static const ParamType& GetParam() {
|
[[nodiscard]] static const ParamType& GetParam() {
|
||||||
GTEST_CHECK_(parameter_ != nullptr)
|
GTEST_CHECK_(parameter_ != nullptr)
|
||||||
<< "GetParam() can only be called inside a value-parameterized test "
|
<< "GetParam() can only be called inside a value-parameterized test "
|
||||||
<< "-- did you intend to write TEST_P instead of TEST_F?";
|
<< "-- did you intend to write TEST_P instead of TEST_F?";
|
||||||
|
|||||||
@ -198,21 +198,8 @@
|
|||||||
// suppressed (constant conditional).
|
// suppressed (constant conditional).
|
||||||
// GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127
|
// GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127
|
||||||
// is suppressed.
|
// is suppressed.
|
||||||
// GTEST_INTERNAL_HAS_ANY - for enabling UniversalPrinter<std::any> or
|
|
||||||
// UniversalPrinter<absl::any> specializations.
|
|
||||||
// Always defined to 0 or 1.
|
|
||||||
// GTEST_INTERNAL_HAS_OPTIONAL - for enabling UniversalPrinter<std::optional>
|
|
||||||
// or
|
|
||||||
// UniversalPrinter<absl::optional>
|
|
||||||
// specializations. Always defined to 0 or 1.
|
|
||||||
// GTEST_INTERNAL_HAS_STD_SPAN - for enabling UniversalPrinter<std::span>
|
// GTEST_INTERNAL_HAS_STD_SPAN - for enabling UniversalPrinter<std::span>
|
||||||
// specializations. Always defined to 0 or 1
|
// specializations. Always defined to 0 or 1
|
||||||
// GTEST_INTERNAL_HAS_STRING_VIEW - for enabling Matcher<std::string_view> or
|
|
||||||
// Matcher<absl::string_view>
|
|
||||||
// specializations. Always defined to 0 or 1.
|
|
||||||
// GTEST_INTERNAL_HAS_VARIANT - for enabling UniversalPrinter<std::variant> or
|
|
||||||
// UniversalPrinter<absl::variant>
|
|
||||||
// specializations. Always defined to 0 or 1.
|
|
||||||
// GTEST_USE_OWN_FLAGFILE_FLAG_ - Always defined to 0 or 1.
|
// GTEST_USE_OWN_FLAGFILE_FLAG_ - Always defined to 0 or 1.
|
||||||
// GTEST_HAS_CXXABI_H_ - Always defined to 0 or 1.
|
// GTEST_HAS_CXXABI_H_ - Always defined to 0 or 1.
|
||||||
// GTEST_CAN_STREAM_RESULTS_ - Always defined to 0 or 1.
|
// GTEST_CAN_STREAM_RESULTS_ - Always defined to 0 or 1.
|
||||||
@ -1398,9 +1385,9 @@ class GTEST_API_ Mutex {
|
|||||||
Mutex();
|
Mutex();
|
||||||
~Mutex();
|
~Mutex();
|
||||||
|
|
||||||
void Lock();
|
void lock();
|
||||||
|
|
||||||
void Unlock();
|
void unlock();
|
||||||
|
|
||||||
// Does nothing if the current thread holds the mutex. Otherwise, crashes
|
// Does nothing if the current thread holds the mutex. Otherwise, crashes
|
||||||
// with high probability.
|
// with high probability.
|
||||||
@ -1437,12 +1424,11 @@ class GTEST_API_ Mutex {
|
|||||||
// "MutexLock l(&mu)". Hence the typedef trick below.
|
// "MutexLock l(&mu)". Hence the typedef trick below.
|
||||||
class GTestMutexLock {
|
class GTestMutexLock {
|
||||||
public:
|
public:
|
||||||
explicit GTestMutexLock(Mutex* mutex) : mutex_(mutex) { mutex_->Lock(); }
|
explicit GTestMutexLock(Mutex& mutex) : mutex_(mutex) { mutex_.lock(); }
|
||||||
|
~GTestMutexLock() { mutex_.unlock(); }
|
||||||
~GTestMutexLock() { mutex_->Unlock(); }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Mutex* const mutex_;
|
Mutex& mutex_;
|
||||||
|
|
||||||
GTestMutexLock(const GTestMutexLock&) = delete;
|
GTestMutexLock(const GTestMutexLock&) = delete;
|
||||||
GTestMutexLock& operator=(const GTestMutexLock&) = delete;
|
GTestMutexLock& operator=(const GTestMutexLock&) = delete;
|
||||||
@ -1654,14 +1640,14 @@ class ThreadLocal : public ThreadLocalBase {
|
|||||||
class MutexBase {
|
class MutexBase {
|
||||||
public:
|
public:
|
||||||
// Acquires this mutex.
|
// Acquires this mutex.
|
||||||
void Lock() {
|
void lock() {
|
||||||
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_));
|
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_));
|
||||||
owner_ = pthread_self();
|
owner_ = pthread_self();
|
||||||
has_owner_ = true;
|
has_owner_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Releases this mutex.
|
// Releases this mutex.
|
||||||
void Unlock() {
|
void unlock() {
|
||||||
// Since the lock is being released the owner_ field should no longer be
|
// Since the lock is being released the owner_ field should no longer be
|
||||||
// considered valid. We don't protect writing to has_owner_ here, as it's
|
// considered valid. We don't protect writing to has_owner_ here, as it's
|
||||||
// the caller's responsibility to ensure that the current thread holds the
|
// the caller's responsibility to ensure that the current thread holds the
|
||||||
@ -1729,12 +1715,11 @@ class Mutex : public MutexBase {
|
|||||||
// "MutexLock l(&mu)". Hence the typedef trick below.
|
// "MutexLock l(&mu)". Hence the typedef trick below.
|
||||||
class GTestMutexLock {
|
class GTestMutexLock {
|
||||||
public:
|
public:
|
||||||
explicit GTestMutexLock(MutexBase* mutex) : mutex_(mutex) { mutex_->Lock(); }
|
explicit GTestMutexLock(MutexBase& mutex) : mutex_(mutex) { mutex_.lock(); }
|
||||||
|
~GTestMutexLock() { mutex_.unlock(); }
|
||||||
~GTestMutexLock() { mutex_->Unlock(); }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MutexBase* const mutex_;
|
MutexBase& mutex_;
|
||||||
|
|
||||||
GTestMutexLock(const GTestMutexLock&) = delete;
|
GTestMutexLock(const GTestMutexLock&) = delete;
|
||||||
GTestMutexLock& operator=(const GTestMutexLock&) = delete;
|
GTestMutexLock& operator=(const GTestMutexLock&) = delete;
|
||||||
@ -1877,8 +1862,8 @@ class GTEST_API_ ThreadLocal {
|
|||||||
class Mutex {
|
class Mutex {
|
||||||
public:
|
public:
|
||||||
Mutex() {}
|
Mutex() {}
|
||||||
void Lock() {}
|
void lock() {}
|
||||||
void Unlock() {}
|
void unlock() {}
|
||||||
void AssertHeld() const {}
|
void AssertHeld() const {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1894,7 +1879,7 @@ class Mutex {
|
|||||||
// "MutexLock l(&mu)". Hence the typedef trick below.
|
// "MutexLock l(&mu)". Hence the typedef trick below.
|
||||||
class GTestMutexLock {
|
class GTestMutexLock {
|
||||||
public:
|
public:
|
||||||
explicit GTestMutexLock(Mutex*) {} // NOLINT
|
explicit GTestMutexLock(Mutex&) {} // NOLINT
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef GTestMutexLock MutexLock;
|
typedef GTestMutexLock MutexLock;
|
||||||
@ -2335,71 +2320,11 @@ const char* StringFromGTestEnv(const char* flag, const char* default_val);
|
|||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
|
||||||
#ifdef GTEST_HAS_ABSL
|
#if GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(clang::annotate)
|
||||||
// Always use absl::any for UniversalPrinter<> specializations if googletest
|
#define GTEST_INTERNAL_DEPRECATE_AND_INLINE(msg) \
|
||||||
// is built with absl support.
|
[[deprecated(msg), clang::annotate("inline-me")]]
|
||||||
#define GTEST_INTERNAL_HAS_ANY 1
|
|
||||||
#include "absl/types/any.h"
|
|
||||||
namespace testing {
|
|
||||||
namespace internal {
|
|
||||||
using Any = ::absl::any;
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace testing
|
|
||||||
#else
|
#else
|
||||||
#if defined(__cpp_lib_any) || (GTEST_INTERNAL_HAS_INCLUDE(<any>) && \
|
#define GTEST_INTERNAL_DEPRECATE_AND_INLINE(msg) [[deprecated(msg)]]
|
||||||
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L && \
|
|
||||||
(!defined(_MSC_VER) || GTEST_HAS_RTTI))
|
|
||||||
// Otherwise for C++17 and higher use std::any for UniversalPrinter<>
|
|
||||||
// specializations.
|
|
||||||
#define GTEST_INTERNAL_HAS_ANY 1
|
|
||||||
#include <any>
|
|
||||||
namespace testing {
|
|
||||||
namespace internal {
|
|
||||||
using Any = ::std::any;
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace testing
|
|
||||||
// The case where absl is configured NOT to alias std::any is not
|
|
||||||
// supported.
|
|
||||||
#endif // __cpp_lib_any
|
|
||||||
#endif // GTEST_HAS_ABSL
|
|
||||||
|
|
||||||
#ifndef GTEST_INTERNAL_HAS_ANY
|
|
||||||
#define GTEST_INTERNAL_HAS_ANY 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GTEST_HAS_ABSL
|
|
||||||
// Always use absl::optional for UniversalPrinter<> specializations if
|
|
||||||
// googletest is built with absl support.
|
|
||||||
#define GTEST_INTERNAL_HAS_OPTIONAL 1
|
|
||||||
#include "absl/types/optional.h"
|
|
||||||
namespace testing {
|
|
||||||
namespace internal {
|
|
||||||
template <typename T>
|
|
||||||
using Optional = ::absl::optional<T>;
|
|
||||||
inline ::absl::nullopt_t Nullopt() { return ::absl::nullopt; }
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace testing
|
|
||||||
#else
|
|
||||||
#if defined(__cpp_lib_optional) || (GTEST_INTERNAL_HAS_INCLUDE(<optional>) && \
|
|
||||||
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L)
|
|
||||||
// Otherwise for C++17 and higher use std::optional for UniversalPrinter<>
|
|
||||||
// specializations.
|
|
||||||
#define GTEST_INTERNAL_HAS_OPTIONAL 1
|
|
||||||
#include <optional>
|
|
||||||
namespace testing {
|
|
||||||
namespace internal {
|
|
||||||
template <typename T>
|
|
||||||
using Optional = ::std::optional<T>;
|
|
||||||
inline ::std::nullopt_t Nullopt() { return ::std::nullopt; }
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace testing
|
|
||||||
// The case where absl is configured NOT to alias std::optional is not
|
|
||||||
// supported.
|
|
||||||
#endif // __cpp_lib_optional
|
|
||||||
#endif // GTEST_HAS_ABSL
|
|
||||||
|
|
||||||
#ifndef GTEST_INTERNAL_HAS_OPTIONAL
|
|
||||||
#define GTEST_INTERNAL_HAS_OPTIONAL 0
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__cpp_lib_span) || (GTEST_INTERNAL_HAS_INCLUDE(<span>) && \
|
#if defined(__cpp_lib_span) || (GTEST_INTERNAL_HAS_INCLUDE(<span>) && \
|
||||||
@ -2443,38 +2368,6 @@ using StringView = ::std::string_view;
|
|||||||
#define GTEST_INTERNAL_HAS_STRING_VIEW 0
|
#define GTEST_INTERNAL_HAS_STRING_VIEW 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef GTEST_HAS_ABSL
|
|
||||||
// Always use absl::variant for UniversalPrinter<> specializations if googletest
|
|
||||||
// is built with absl support.
|
|
||||||
#define GTEST_INTERNAL_HAS_VARIANT 1
|
|
||||||
#include "absl/types/variant.h"
|
|
||||||
namespace testing {
|
|
||||||
namespace internal {
|
|
||||||
template <typename... T>
|
|
||||||
using Variant = ::absl::variant<T...>;
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace testing
|
|
||||||
#else
|
|
||||||
#if defined(__cpp_lib_variant) || (GTEST_INTERNAL_HAS_INCLUDE(<variant>) && \
|
|
||||||
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L)
|
|
||||||
// Otherwise for C++17 and higher use std::variant for UniversalPrinter<>
|
|
||||||
// specializations.
|
|
||||||
#define GTEST_INTERNAL_HAS_VARIANT 1
|
|
||||||
#include <variant>
|
|
||||||
namespace testing {
|
|
||||||
namespace internal {
|
|
||||||
template <typename... T>
|
|
||||||
using Variant = ::std::variant<T...>;
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace testing
|
|
||||||
// The case where absl is configured NOT to alias std::variant is not supported.
|
|
||||||
#endif // __cpp_lib_variant
|
|
||||||
#endif // GTEST_HAS_ABSL
|
|
||||||
|
|
||||||
#ifndef GTEST_INTERNAL_HAS_VARIANT
|
|
||||||
#define GTEST_INTERNAL_HAS_VARIANT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (defined(__cpp_lib_three_way_comparison) || \
|
#if (defined(__cpp_lib_three_way_comparison) || \
|
||||||
(GTEST_INTERNAL_HAS_INCLUDE(<compare>) && \
|
(GTEST_INTERNAL_HAS_INCLUDE(<compare>) && \
|
||||||
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201907L))
|
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201907L))
|
||||||
|
|||||||
@ -320,13 +320,13 @@ Mutex::~Mutex() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mutex::Lock() {
|
void Mutex::lock() {
|
||||||
ThreadSafeLazyInit();
|
ThreadSafeLazyInit();
|
||||||
::EnterCriticalSection(critical_section_);
|
::EnterCriticalSection(critical_section_);
|
||||||
owner_thread_id_ = ::GetCurrentThreadId();
|
owner_thread_id_ = ::GetCurrentThreadId();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mutex::Unlock() {
|
void Mutex::unlock() {
|
||||||
ThreadSafeLazyInit();
|
ThreadSafeLazyInit();
|
||||||
// We don't protect writing to owner_thread_id_ here, as it's the
|
// We don't protect writing to owner_thread_id_ here, as it's the
|
||||||
// caller's responsibility to ensure that the current thread holds the
|
// caller's responsibility to ensure that the current thread holds the
|
||||||
@ -499,7 +499,7 @@ class ThreadLocalRegistryImpl {
|
|||||||
MemoryIsNotDeallocated memory_is_not_deallocated;
|
MemoryIsNotDeallocated memory_is_not_deallocated;
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
DWORD current_thread = ::GetCurrentThreadId();
|
DWORD current_thread = ::GetCurrentThreadId();
|
||||||
MutexLock lock(&mutex_);
|
MutexLock lock(mutex_);
|
||||||
ThreadIdToThreadLocals* const thread_to_thread_locals =
|
ThreadIdToThreadLocals* const thread_to_thread_locals =
|
||||||
GetThreadLocalsMapLocked();
|
GetThreadLocalsMapLocked();
|
||||||
ThreadIdToThreadLocals::iterator thread_local_pos =
|
ThreadIdToThreadLocals::iterator thread_local_pos =
|
||||||
@ -532,7 +532,7 @@ class ThreadLocalRegistryImpl {
|
|||||||
// Clean up the ThreadLocalValues data structure while holding the lock, but
|
// Clean up the ThreadLocalValues data structure while holding the lock, but
|
||||||
// defer the destruction of the ThreadLocalValueHolderBases.
|
// defer the destruction of the ThreadLocalValueHolderBases.
|
||||||
{
|
{
|
||||||
MutexLock lock(&mutex_);
|
MutexLock lock(mutex_);
|
||||||
ThreadIdToThreadLocals* const thread_to_thread_locals =
|
ThreadIdToThreadLocals* const thread_to_thread_locals =
|
||||||
GetThreadLocalsMapLocked();
|
GetThreadLocalsMapLocked();
|
||||||
for (ThreadIdToThreadLocals::iterator it =
|
for (ThreadIdToThreadLocals::iterator it =
|
||||||
@ -559,7 +559,7 @@ class ThreadLocalRegistryImpl {
|
|||||||
// Clean up the ThreadIdToThreadLocals data structure while holding the
|
// Clean up the ThreadIdToThreadLocals data structure while holding the
|
||||||
// lock, but defer the destruction of the ThreadLocalValueHolderBases.
|
// lock, but defer the destruction of the ThreadLocalValueHolderBases.
|
||||||
{
|
{
|
||||||
MutexLock lock(&mutex_);
|
MutexLock lock(mutex_);
|
||||||
ThreadIdToThreadLocals* const thread_to_thread_locals =
|
ThreadIdToThreadLocals* const thread_to_thread_locals =
|
||||||
GetThreadLocalsMapLocked();
|
GetThreadLocalsMapLocked();
|
||||||
ThreadIdToThreadLocals::iterator thread_local_pos =
|
ThreadIdToThreadLocals::iterator thread_local_pos =
|
||||||
|
|||||||
@ -50,7 +50,7 @@
|
|||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <ios>
|
#include <ios>
|
||||||
#include <ostream> // NOLINT
|
#include <ostream> // NOLINT
|
||||||
#include <string>
|
#include <string_view>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include "gtest/internal/gtest-port.h"
|
#include "gtest/internal/gtest-port.h"
|
||||||
@ -333,14 +333,14 @@ void PrintTo(__int128_t v, ::std::ostream* os) {
|
|||||||
|
|
||||||
// Prints the given array of characters to the ostream. CharType must be either
|
// Prints the given array of characters to the ostream. CharType must be either
|
||||||
// char, char8_t, char16_t, char32_t, or wchar_t.
|
// char, char8_t, char16_t, char32_t, or wchar_t.
|
||||||
// The array starts at begin, the length is len, it may include '\0' characters
|
// The array starts at begin (which may be nullptr) and contains len characters.
|
||||||
// and may not be NUL-terminated.
|
// The array may include '\0' characters and may not be NUL-terminated.
|
||||||
template <typename CharType>
|
template <typename CharType>
|
||||||
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
||||||
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
|
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
|
||||||
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static CharFormat
|
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static CharFormat
|
||||||
PrintCharsAsStringTo(const CharType* begin, size_t len, ostream* os) {
|
PrintCharsAsStringTo(const CharType* begin, size_t len, ostream* os) {
|
||||||
const char* const quote_prefix = GetCharWidthPrefix(*begin);
|
const char* const quote_prefix = GetCharWidthPrefix(CharType());
|
||||||
*os << quote_prefix << "\"";
|
*os << quote_prefix << "\"";
|
||||||
bool is_previous_hex = false;
|
bool is_previous_hex = false;
|
||||||
CharFormat print_format = kAsIs;
|
CharFormat print_format = kAsIs;
|
||||||
@ -516,13 +516,13 @@ bool IsValidUTF8(const char* str, size_t length) {
|
|||||||
void ConditionalPrintAsText(const char* str, size_t length, ostream* os) {
|
void ConditionalPrintAsText(const char* str, size_t length, ostream* os) {
|
||||||
if (!ContainsUnprintableControlCodes(str, length) &&
|
if (!ContainsUnprintableControlCodes(str, length) &&
|
||||||
IsValidUTF8(str, length)) {
|
IsValidUTF8(str, length)) {
|
||||||
*os << "\n As Text: \"" << str << "\"";
|
*os << "\n As Text: \"" << ::std::string_view(str, length) << "\"";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
void PrintStringTo(const ::std::string& s, ostream* os) {
|
void PrintStringTo(::std::string_view s, ostream* os) {
|
||||||
if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) {
|
if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) {
|
||||||
if (GTEST_FLAG_GET(print_utf8)) {
|
if (GTEST_FLAG_GET(print_utf8)) {
|
||||||
ConditionalPrintAsText(s.data(), s.size(), os);
|
ConditionalPrintAsText(s.data(), s.size(), os);
|
||||||
@ -531,21 +531,21 @@ void PrintStringTo(const ::std::string& s, ostream* os) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cpp_lib_char8_t
|
#ifdef __cpp_lib_char8_t
|
||||||
void PrintU8StringTo(const ::std::u8string& s, ostream* os) {
|
void PrintU8StringTo(::std::u8string_view s, ostream* os) {
|
||||||
PrintCharsAsStringTo(s.data(), s.size(), os);
|
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void PrintU16StringTo(const ::std::u16string& s, ostream* os) {
|
void PrintU16StringTo(::std::u16string_view s, ostream* os) {
|
||||||
PrintCharsAsStringTo(s.data(), s.size(), os);
|
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintU32StringTo(const ::std::u32string& s, ostream* os) {
|
void PrintU32StringTo(::std::u32string_view s, ostream* os) {
|
||||||
PrintCharsAsStringTo(s.data(), s.size(), os);
|
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GTEST_HAS_STD_WSTRING
|
#if GTEST_HAS_STD_WSTRING
|
||||||
void PrintWideStringTo(const ::std::wstring& s, ostream* os) {
|
void PrintWideStringTo(::std::wstring_view s, ostream* os) {
|
||||||
PrintCharsAsStringTo(s.data(), s.size(), os);
|
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||||
}
|
}
|
||||||
#endif // GTEST_HAS_STD_WSTRING
|
#endif // GTEST_HAS_STD_WSTRING
|
||||||
|
|||||||
@ -269,6 +269,13 @@ GTEST_DEFINE_bool_(
|
|||||||
"True if and only if the test should fail if no test case (including "
|
"True if and only if the test should fail if no test case (including "
|
||||||
"disabled test cases) is linked.");
|
"disabled test cases) is linked.");
|
||||||
|
|
||||||
|
GTEST_DEFINE_bool_(
|
||||||
|
fail_if_no_test_selected,
|
||||||
|
testing::internal::BoolFromGTestEnv("fail_if_no_test_selected", false),
|
||||||
|
"True if and only if the test should fail if no test case is selected to "
|
||||||
|
"run. A test case is selected to run if it is not disabled and is matched "
|
||||||
|
"by the filter flag so that it starts executing.");
|
||||||
|
|
||||||
GTEST_DEFINE_bool_(
|
GTEST_DEFINE_bool_(
|
||||||
also_run_disabled_tests,
|
also_run_disabled_tests,
|
||||||
testing::internal::BoolFromGTestEnv("also_run_disabled_tests", false),
|
testing::internal::BoolFromGTestEnv("also_run_disabled_tests", false),
|
||||||
@ -706,7 +713,7 @@ std::string UnitTestOptions::GetAbsolutePathToOutputFile() {
|
|||||||
const char* const gtest_output_flag = s.c_str();
|
const char* const gtest_output_flag = s.c_str();
|
||||||
|
|
||||||
std::string format = GetOutputFormat();
|
std::string format = GetOutputFormat();
|
||||||
if (format.empty()) format = std::string(kDefaultOutputFormat);
|
if (format.empty()) format = kDefaultOutputFormat;
|
||||||
|
|
||||||
const char* const colon = strchr(gtest_output_flag, ':');
|
const char* const colon = strchr(gtest_output_flag, ':');
|
||||||
if (colon == nullptr)
|
if (colon == nullptr)
|
||||||
@ -1079,14 +1086,14 @@ void DefaultPerThreadTestPartResultReporter::ReportTestPartResult(
|
|||||||
// Returns the global test part result reporter.
|
// Returns the global test part result reporter.
|
||||||
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_reporter_;
|
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_reporter_ = reporter;
|
global_test_part_result_reporter_ = reporter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1488,17 +1495,17 @@ class Hunk {
|
|||||||
// Print a unified diff header for one hunk.
|
// Print a unified diff header for one hunk.
|
||||||
// The format is
|
// The format is
|
||||||
// "@@ -<left_start>,<left_length> +<right_start>,<right_length> @@"
|
// "@@ -<left_start>,<left_length> +<right_start>,<right_length> @@"
|
||||||
// where the left/right parts are omitted if unnecessary.
|
// where the left/right lengths are omitted if unnecessary.
|
||||||
void PrintHeader(std::ostream* ss) const {
|
void PrintHeader(std::ostream* ss) const {
|
||||||
*ss << "@@ ";
|
size_t left_length = removes_ + common_;
|
||||||
if (removes_) {
|
size_t right_length = adds_ + common_;
|
||||||
*ss << "-" << left_start_ << "," << (removes_ + common_);
|
*ss << "@@ " << "-" << left_start_;
|
||||||
|
if (left_length != 1) {
|
||||||
|
*ss << "," << left_length;
|
||||||
}
|
}
|
||||||
if (removes_ && adds_) {
|
*ss << " " << "+" << right_start_;
|
||||||
*ss << " ";
|
if (right_length != 1) {
|
||||||
}
|
*ss << "," << right_length;
|
||||||
if (adds_) {
|
|
||||||
*ss << "+" << right_start_ << "," << (adds_ + common_);
|
|
||||||
}
|
}
|
||||||
*ss << " @@\n";
|
*ss << " @@\n";
|
||||||
}
|
}
|
||||||
@ -2340,7 +2347,7 @@ void TestResult::RecordProperty(const std::string& xml_element,
|
|||||||
if (!ValidateTestProperty(xml_element, test_property)) {
|
if (!ValidateTestProperty(xml_element, test_property)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
internal::MutexLock lock(&test_properties_mutex_);
|
internal::MutexLock lock(test_properties_mutex_);
|
||||||
const std::vector<TestProperty>::iterator property_with_matching_key =
|
const std::vector<TestProperty>::iterator property_with_matching_key =
|
||||||
std::find_if(test_properties_.begin(), test_properties_.end(),
|
std::find_if(test_properties_.begin(), test_properties_.end(),
|
||||||
internal::TestPropertyKeyIs(test_property.key()));
|
internal::TestPropertyKeyIs(test_property.key()));
|
||||||
@ -3298,6 +3305,7 @@ bool ShouldUseColor(bool stdout_is_tty) {
|
|||||||
const bool term_supports_color =
|
const bool term_supports_color =
|
||||||
term != nullptr && (String::CStringEquals(term, "xterm") ||
|
term != nullptr && (String::CStringEquals(term, "xterm") ||
|
||||||
String::CStringEquals(term, "xterm-color") ||
|
String::CStringEquals(term, "xterm-color") ||
|
||||||
|
String::CStringEquals(term, "xterm-ghostty") ||
|
||||||
String::CStringEquals(term, "xterm-kitty") ||
|
String::CStringEquals(term, "xterm-kitty") ||
|
||||||
String::CStringEquals(term, "alacritty") ||
|
String::CStringEquals(term, "alacritty") ||
|
||||||
String::CStringEquals(term, "screen") ||
|
String::CStringEquals(term, "screen") ||
|
||||||
@ -4347,8 +4355,8 @@ void XmlUnitTestResultPrinter::OutputXmlTestResult(::std::ostream* stream,
|
|||||||
internal::FormatCompilerIndependentFileLocation(part.file_name(),
|
internal::FormatCompilerIndependentFileLocation(part.file_name(),
|
||||||
part.line_number());
|
part.line_number());
|
||||||
const std::string summary = location + "\n" + part.summary();
|
const std::string summary = location + "\n" + part.summary();
|
||||||
*stream << " <skipped message=\""
|
*stream << " <skipped message=\"" << EscapeXmlAttribute(summary)
|
||||||
<< EscapeXmlAttribute(summary.c_str()) << "\">";
|
<< "\">";
|
||||||
const std::string detail = location + "\n" + part.message();
|
const std::string detail = location + "\n" + part.message();
|
||||||
OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str());
|
OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str());
|
||||||
*stream << "</skipped>\n";
|
*stream << "</skipped>\n";
|
||||||
@ -5080,7 +5088,7 @@ std::string OsStackTraceGetter::CurrentStackTrace(int max_depth, int skip_count)
|
|||||||
|
|
||||||
void* caller_frame = nullptr;
|
void* caller_frame = nullptr;
|
||||||
{
|
{
|
||||||
MutexLock lock(&mutex_);
|
MutexLock lock(mutex_);
|
||||||
caller_frame = caller_frame_;
|
caller_frame = caller_frame_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5119,7 +5127,7 @@ void OsStackTraceGetter::UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_) {
|
|||||||
caller_frame = nullptr;
|
caller_frame = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MutexLock lock(&mutex_);
|
MutexLock lock(mutex_);
|
||||||
caller_frame_ = caller_frame;
|
caller_frame_ = caller_frame;
|
||||||
#endif // GTEST_HAS_ABSL
|
#endif // GTEST_HAS_ABSL
|
||||||
}
|
}
|
||||||
@ -5382,13 +5390,13 @@ void UnitTest::UponLeavingGTest() {
|
|||||||
|
|
||||||
// Sets the TestSuite object for the test that's currently running.
|
// Sets the TestSuite object for the test that's currently running.
|
||||||
void UnitTest::set_current_test_suite(TestSuite* a_current_test_suite) {
|
void UnitTest::set_current_test_suite(TestSuite* a_current_test_suite) {
|
||||||
internal::MutexLock lock(&mutex_);
|
internal::MutexLock lock(mutex_);
|
||||||
impl_->set_current_test_suite(a_current_test_suite);
|
impl_->set_current_test_suite(a_current_test_suite);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets the TestInfo object for the test that's currently running.
|
// Sets the TestInfo object for the test that's currently running.
|
||||||
void UnitTest::set_current_test_info(TestInfo* a_current_test_info) {
|
void UnitTest::set_current_test_info(TestInfo* a_current_test_info) {
|
||||||
internal::MutexLock lock(&mutex_);
|
internal::MutexLock lock(mutex_);
|
||||||
impl_->set_current_test_info(a_current_test_info);
|
impl_->set_current_test_info(a_current_test_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5427,7 +5435,7 @@ void UnitTest::AddTestPartResult(TestPartResult::Type result_type,
|
|||||||
Message msg;
|
Message msg;
|
||||||
msg << message;
|
msg << message;
|
||||||
|
|
||||||
internal::MutexLock lock(&mutex_);
|
internal::MutexLock lock(mutex_);
|
||||||
if (!impl_->gtest_trace_stack().empty()) {
|
if (!impl_->gtest_trace_stack().empty()) {
|
||||||
msg << "\n" << GTEST_NAME_ << " trace:";
|
msg << "\n" << GTEST_NAME_ << " trace:";
|
||||||
|
|
||||||
@ -5610,7 +5618,7 @@ const char* UnitTest::original_working_dir() const {
|
|||||||
// or NULL if no test is running.
|
// or NULL if no test is running.
|
||||||
const TestSuite* UnitTest::current_test_suite() const
|
const TestSuite* UnitTest::current_test_suite() const
|
||||||
GTEST_LOCK_EXCLUDED_(mutex_) {
|
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||||
internal::MutexLock lock(&mutex_);
|
internal::MutexLock lock(mutex_);
|
||||||
return impl_->current_test_suite();
|
return impl_->current_test_suite();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5618,7 +5626,7 @@ const TestSuite* UnitTest::current_test_suite() const
|
|||||||
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
const TestCase* UnitTest::current_test_case() const
|
const TestCase* UnitTest::current_test_case() const
|
||||||
GTEST_LOCK_EXCLUDED_(mutex_) {
|
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||||
internal::MutexLock lock(&mutex_);
|
internal::MutexLock lock(mutex_);
|
||||||
return impl_->current_test_suite();
|
return impl_->current_test_suite();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -5627,7 +5635,7 @@ const TestCase* UnitTest::current_test_case() const
|
|||||||
// or NULL if no test is running.
|
// or NULL if no test is running.
|
||||||
const TestInfo* UnitTest::current_test_info() const
|
const TestInfo* UnitTest::current_test_info() const
|
||||||
GTEST_LOCK_EXCLUDED_(mutex_) {
|
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||||
internal::MutexLock lock(&mutex_);
|
internal::MutexLock lock(mutex_);
|
||||||
return impl_->current_test_info();
|
return impl_->current_test_info();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5651,13 +5659,13 @@ UnitTest::~UnitTest() { delete impl_; }
|
|||||||
// Google Test trace stack.
|
// Google Test trace stack.
|
||||||
void UnitTest::PushGTestTrace(const internal::TraceInfo& trace)
|
void UnitTest::PushGTestTrace(const internal::TraceInfo& trace)
|
||||||
GTEST_LOCK_EXCLUDED_(mutex_) {
|
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||||
internal::MutexLock lock(&mutex_);
|
internal::MutexLock lock(mutex_);
|
||||||
impl_->gtest_trace_stack().push_back(trace);
|
impl_->gtest_trace_stack().push_back(trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pops a trace from the per-thread Google Test trace stack.
|
// Pops a trace from the per-thread Google Test trace stack.
|
||||||
void UnitTest::PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_) {
|
void UnitTest::PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||||
internal::MutexLock lock(&mutex_);
|
internal::MutexLock lock(mutex_);
|
||||||
impl_->gtest_trace_stack().pop_back();
|
impl_->gtest_trace_stack().pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6079,6 +6087,20 @@ bool UnitTestImpl::RunAllTests() {
|
|||||||
TearDownEnvironment);
|
TearDownEnvironment);
|
||||||
repeater->OnEnvironmentsTearDownEnd(*parent_);
|
repeater->OnEnvironmentsTearDownEnd(*parent_);
|
||||||
}
|
}
|
||||||
|
} else if (GTEST_FLAG_GET(fail_if_no_test_selected)) {
|
||||||
|
// If there were no tests to run, bail if we were requested to be
|
||||||
|
// strict.
|
||||||
|
constexpr char kNoTestsSelectedMessage[] =
|
||||||
|
"No tests ran. Check that tests exist and are not disabled or "
|
||||||
|
"filtered out.\n\n"
|
||||||
|
"For sharded runs, this error indicates an empty shard. This can "
|
||||||
|
"happen if you have more shards than tests, or if --gtest_filter "
|
||||||
|
"leaves a shard with no tests.\n\n"
|
||||||
|
"To permit empty shards (e.g., when debugging with a filter), "
|
||||||
|
"specify \n"
|
||||||
|
"--gtest_fail_if_no_test_selected=false.";
|
||||||
|
ColoredPrintf(GTestColor::kRed, "%s\n", kNoTestsSelectedMessage);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
elapsed_time_ = timer.Elapsed();
|
elapsed_time_ = timer.Elapsed();
|
||||||
@ -6763,6 +6785,7 @@ static bool ParseGoogleTestFlag(const char* const arg) {
|
|||||||
GTEST_INTERNAL_PARSE_FLAG(death_test_use_fork);
|
GTEST_INTERNAL_PARSE_FLAG(death_test_use_fork);
|
||||||
GTEST_INTERNAL_PARSE_FLAG(fail_fast);
|
GTEST_INTERNAL_PARSE_FLAG(fail_fast);
|
||||||
GTEST_INTERNAL_PARSE_FLAG(fail_if_no_test_linked);
|
GTEST_INTERNAL_PARSE_FLAG(fail_if_no_test_linked);
|
||||||
|
GTEST_INTERNAL_PARSE_FLAG(fail_if_no_test_selected);
|
||||||
GTEST_INTERNAL_PARSE_FLAG(filter);
|
GTEST_INTERNAL_PARSE_FLAG(filter);
|
||||||
GTEST_INTERNAL_PARSE_FLAG(internal_run_death_test);
|
GTEST_INTERNAL_PARSE_FLAG(internal_run_death_test);
|
||||||
GTEST_INTERNAL_PARSE_FLAG(list_tests);
|
GTEST_INTERNAL_PARSE_FLAG(list_tests);
|
||||||
|
|||||||
@ -30,6 +30,7 @@
|
|||||||
#
|
#
|
||||||
# Bazel BUILD for The Google C++ Testing Framework (Google Test)
|
# Bazel BUILD for The Google C++ Testing Framework (Google Test)
|
||||||
|
|
||||||
|
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test")
|
||||||
load("@rules_python//python:defs.bzl", "py_library", "py_test")
|
load("@rules_python//python:defs.bzl", "py_library", "py_test")
|
||||||
|
|
||||||
licenses(["notice"])
|
licenses(["notice"])
|
||||||
|
|||||||
@ -79,6 +79,7 @@ class GTestColorTest(gtest_test_utils.TestCase):
|
|||||||
self.assertTrue(UsesColor('cygwin', None, None))
|
self.assertTrue(UsesColor('cygwin', None, None))
|
||||||
self.assertTrue(UsesColor('xterm', None, None))
|
self.assertTrue(UsesColor('xterm', None, None))
|
||||||
self.assertTrue(UsesColor('xterm-color', None, None))
|
self.assertTrue(UsesColor('xterm-color', None, None))
|
||||||
|
self.assertTrue(UsesColor('xterm-ghostty', None, None))
|
||||||
self.assertTrue(UsesColor('xterm-kitty', None, None))
|
self.assertTrue(UsesColor('xterm-kitty', None, None))
|
||||||
self.assertTrue(UsesColor('alacritty', None, None))
|
self.assertTrue(UsesColor('alacritty', None, None))
|
||||||
self.assertTrue(UsesColor('xterm-256color', None, None))
|
self.assertTrue(UsesColor('xterm-256color', None, None))
|
||||||
|
|||||||
@ -291,7 +291,7 @@ TEST(ExitStatusPredicateTest, KilledBySignal) {
|
|||||||
const int status_kill = KilledExitStatus(SIGKILL);
|
const int status_kill = KilledExitStatus(SIGKILL);
|
||||||
const testing::KilledBySignal pred_segv(SIGSEGV);
|
const testing::KilledBySignal pred_segv(SIGSEGV);
|
||||||
const testing::KilledBySignal pred_kill(SIGKILL);
|
const testing::KilledBySignal pred_kill(SIGKILL);
|
||||||
#if !(defined(GTEST_OS_LINUX_ANDROID) && __ANDROID_API__ <= 21)
|
#if !(defined(GTEST_OS_LINUX_ANDROID) && __ANDROID_API__ <= 23)
|
||||||
EXPECT_PRED1(pred_segv, status_segv);
|
EXPECT_PRED1(pred_segv, status_segv);
|
||||||
#endif
|
#endif
|
||||||
EXPECT_PRED1(pred_kill, status_kill);
|
EXPECT_PRED1(pred_kill, status_kill);
|
||||||
|
|||||||
@ -80,11 +80,7 @@ class GTestFailIfNoTestLinkedTest(gtest_test_utils.TestCase):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
warning_file_contents = open(warning_file, "r").read()
|
warning_file_contents = open(warning_file, "r").read()
|
||||||
self.assertEqual(
|
self.assertIn("does NOT link", warning_file_contents)
|
||||||
warning_file_contents,
|
|
||||||
"This test program does NOT link in any test case. Please make sure"
|
|
||||||
" this is intended.\n",
|
|
||||||
)
|
|
||||||
|
|
||||||
def testFailsIfNoTestLinkedAndFlagSpecified(self):
|
def testFailsIfNoTestLinkedAndFlagSpecified(self):
|
||||||
"""Tests the behavior of no test linked and flag specified."""
|
"""Tests the behavior of no test linked and flag specified."""
|
||||||
|
|||||||
91
googletest/test/googletest-fail-if-no-test-selected-test.py
Normal file
91
googletest/test/googletest-fail-if-no-test-selected-test.py
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#!/usr/bin/env python3 # pylint: disable=g-interpreter-mismatch
|
||||||
|
#
|
||||||
|
# Copyright 2025, Google Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are
|
||||||
|
# met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above
|
||||||
|
# copyright notice, this list of conditions and the following disclaimer
|
||||||
|
# in the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
# * Neither the name of Google Inc. nor the names of its
|
||||||
|
# contributors may be used to endorse or promote products derived from
|
||||||
|
# this software without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
"""Tests for Google Test's --gtest_fail_if_no_test_selected flag."""
|
||||||
|
|
||||||
|
from googletest.test import gtest_test_utils
|
||||||
|
|
||||||
|
|
||||||
|
# The command line flag for enabling the fail-if-no-test-selected behavior.
|
||||||
|
FAIL_IF_NO_TEST_SELECTED_FLAG = "gtest_fail_if_no_test_selected"
|
||||||
|
|
||||||
|
# The environment variable for the test output warnings file.
|
||||||
|
TEST_WARNINGS_OUTPUT_FILE = "TEST_WARNINGS_OUTPUT_FILE"
|
||||||
|
|
||||||
|
|
||||||
|
class GTestFailIfNoTestSelectedTest(gtest_test_utils.TestCase):
|
||||||
|
"""Tests the --gtest_fail_if_no_test_selected flag."""
|
||||||
|
|
||||||
|
def Run(self, program_name, flags=None, env=None):
|
||||||
|
"""Run the given program with the given flag.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
program_name: Name of the program to run.
|
||||||
|
flags: The command line flags to pass to the program, or None.
|
||||||
|
env: Dictionary with environment to pass to the subprocess.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
True if the program exits with code 0, false otherwise.
|
||||||
|
"""
|
||||||
|
|
||||||
|
exe_path = gtest_test_utils.GetTestExecutablePath(program_name)
|
||||||
|
args = [exe_path]
|
||||||
|
if flags is not None:
|
||||||
|
args.extend(flags)
|
||||||
|
process = gtest_test_utils.Subprocess(args, capture_stderr=False, env=env)
|
||||||
|
return process.exited and process.exit_code == 0
|
||||||
|
|
||||||
|
def testSucceedsWhenFlagIsNotSetAndOnlyDisabledTestsPresent(self):
|
||||||
|
"""Tests that no test selected results in success without the flag set."""
|
||||||
|
self.assertTrue(
|
||||||
|
self.Run("googletest-fail-if-no-test-linked-test-with-disabled-test_"),
|
||||||
|
)
|
||||||
|
|
||||||
|
def testFailsWhenFlagIsSetAndOnlyDisabledTestsPresent(self):
|
||||||
|
"""Tests that no test selected results in failure with the flag set."""
|
||||||
|
self.assertFalse(
|
||||||
|
self.Run(
|
||||||
|
"googletest-fail-if-no-test-linked-test-with-disabled-test_",
|
||||||
|
flags=[f"--{FAIL_IF_NO_TEST_SELECTED_FLAG}"],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
def testSucceedsWhenFlagIsSetAndEnabledTestsPresent(self):
|
||||||
|
"""Tests that a test running still succeeds when the flag is set."""
|
||||||
|
self.assertTrue(
|
||||||
|
self.Run(
|
||||||
|
"googletest-fail-if-no-test-linked-test-with-enabled-test_",
|
||||||
|
flags=[f"--{FAIL_IF_NO_TEST_SELECTED_FLAG}"],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
gtest_test_utils.Main()
|
||||||
@ -62,7 +62,7 @@ Expected equality of these values:
|
|||||||
Which is: "\"Line\0 1\"\nLine 2"
|
Which is: "\"Line\0 1\"\nLine 2"
|
||||||
"Line 2"
|
"Line 2"
|
||||||
With diff:
|
With diff:
|
||||||
@@ -1,2 @@
|
@@ -1,2 +1 @@
|
||||||
-\"Line\0 1\"
|
-\"Line\0 1\"
|
||||||
Line 2
|
Line 2
|
||||||
|
|
||||||
|
|||||||
@ -696,7 +696,7 @@ class TestGenerationEnvironment : public ::testing::Environment {
|
|||||||
msg << "TestsExpandedAndRun/" << i;
|
msg << "TestsExpandedAndRun/" << i;
|
||||||
if (UnitTestOptions::FilterMatchesTest(
|
if (UnitTestOptions::FilterMatchesTest(
|
||||||
"TestExpansionModule/MultipleTestGenerationTest",
|
"TestExpansionModule/MultipleTestGenerationTest",
|
||||||
msg.GetString().c_str())) {
|
msg.GetString())) {
|
||||||
perform_check = true;
|
perform_check = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1174,7 +1174,7 @@ TEST_P(ParameterizedDerivedTest, SeesSequence) {
|
|||||||
class ParameterizedDeathTest : public ::testing::TestWithParam<int> {};
|
class ParameterizedDeathTest : public ::testing::TestWithParam<int> {};
|
||||||
|
|
||||||
TEST_F(ParameterizedDeathTest, GetParamDiesFromTestF) {
|
TEST_F(ParameterizedDeathTest, GetParamDiesFromTestF) {
|
||||||
EXPECT_DEATH_IF_SUPPORTED(GetParam(), ".* value-parameterized test .*");
|
EXPECT_DEATH_IF_SUPPORTED((void)GetParam(), ".* value-parameterized test .*");
|
||||||
}
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(RangeZeroToFive, ParameterizedDerivedTest,
|
INSTANTIATE_TEST_SUITE_P(RangeZeroToFive, ParameterizedDerivedTest,
|
||||||
|
|||||||
@ -288,8 +288,8 @@ TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFileAndLine) {
|
|||||||
defined(GTEST_OS_OPENBSD) || defined(GTEST_OS_GNU_HURD)
|
defined(GTEST_OS_OPENBSD) || defined(GTEST_OS_GNU_HURD)
|
||||||
void* ThreadFunc(void* data) {
|
void* ThreadFunc(void* data) {
|
||||||
internal::Mutex* mutex = static_cast<internal::Mutex*>(data);
|
internal::Mutex* mutex = static_cast<internal::Mutex*>(data);
|
||||||
mutex->Lock();
|
mutex->lock();
|
||||||
mutex->Unlock();
|
mutex->unlock();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,7 +308,7 @@ TEST(GetThreadCountTest, ReturnsCorrectValue) {
|
|||||||
|
|
||||||
internal::Mutex mutex;
|
internal::Mutex mutex;
|
||||||
{
|
{
|
||||||
internal::MutexLock lock(&mutex);
|
internal::MutexLock lock(mutex);
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
ASSERT_EQ(0, pthread_attr_init(&attr));
|
ASSERT_EQ(0, pthread_attr_init(&attr));
|
||||||
ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
|
ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
|
||||||
@ -1028,7 +1028,9 @@ TEST(MutexDeathTest, AssertHeldShouldAssertWhenNotLocked) {
|
|||||||
EXPECT_DEATH_IF_SUPPORTED(
|
EXPECT_DEATH_IF_SUPPORTED(
|
||||||
{
|
{
|
||||||
Mutex m;
|
Mutex m;
|
||||||
{ MutexLock lock(&m); }
|
{
|
||||||
|
MutexLock lock(m);
|
||||||
|
}
|
||||||
m.AssertHeld();
|
m.AssertHeld();
|
||||||
},
|
},
|
||||||
"thread .*hold");
|
"thread .*hold");
|
||||||
@ -1036,13 +1038,13 @@ TEST(MutexDeathTest, AssertHeldShouldAssertWhenNotLocked) {
|
|||||||
|
|
||||||
TEST(MutexTest, AssertHeldShouldNotAssertWhenLocked) {
|
TEST(MutexTest, AssertHeldShouldNotAssertWhenLocked) {
|
||||||
Mutex m;
|
Mutex m;
|
||||||
MutexLock lock(&m);
|
MutexLock lock(m);
|
||||||
m.AssertHeld();
|
m.AssertHeld();
|
||||||
}
|
}
|
||||||
|
|
||||||
class AtomicCounterWithMutex {
|
class AtomicCounterWithMutex {
|
||||||
public:
|
public:
|
||||||
explicit AtomicCounterWithMutex(Mutex* mutex)
|
explicit AtomicCounterWithMutex(Mutex& mutex)
|
||||||
: value_(0), mutex_(mutex), random_(42) {}
|
: value_(0), mutex_(mutex), random_(42) {}
|
||||||
|
|
||||||
void Increment() {
|
void Increment() {
|
||||||
@ -1083,7 +1085,7 @@ class AtomicCounterWithMutex {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
volatile int value_;
|
volatile int value_;
|
||||||
Mutex* const mutex_; // Protects value_.
|
Mutex& mutex_; // Protects value_.
|
||||||
Random random_;
|
Random random_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1094,7 +1096,7 @@ void CountingThreadFunc(pair<AtomicCounterWithMutex*, int> param) {
|
|||||||
// Tests that the mutex only lets one thread at a time to lock it.
|
// Tests that the mutex only lets one thread at a time to lock it.
|
||||||
TEST(MutexTest, OnlyOneThreadCanLockAtATime) {
|
TEST(MutexTest, OnlyOneThreadCanLockAtATime) {
|
||||||
Mutex mutex;
|
Mutex mutex;
|
||||||
AtomicCounterWithMutex locked_counter(&mutex);
|
AtomicCounterWithMutex locked_counter(mutex);
|
||||||
|
|
||||||
typedef ThreadWithParam<pair<AtomicCounterWithMutex*, int> > ThreadType;
|
typedef ThreadWithParam<pair<AtomicCounterWithMutex*, int> > ThreadType;
|
||||||
const int kCycleCount = 20;
|
const int kCycleCount = 20;
|
||||||
|
|||||||
@ -32,6 +32,7 @@
|
|||||||
// This file tests the universal value printer.
|
// This file tests the universal value printer.
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <any>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@ -42,14 +43,17 @@
|
|||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "gtest/gtest-printers.h"
|
#include "gtest/gtest-printers.h"
|
||||||
@ -62,7 +66,7 @@
|
|||||||
|
|
||||||
#if GTEST_INTERNAL_HAS_STD_SPAN
|
#if GTEST_INTERNAL_HAS_STD_SPAN
|
||||||
#include <span> // NOLINT
|
#include <span> // NOLINT
|
||||||
#endif // GTEST_INTERNAL_HAS_STD_SPAN
|
#endif // GTEST_INTERNAL_HAS_STD_SPAN
|
||||||
|
|
||||||
#if GTEST_INTERNAL_HAS_COMPARE_LIB
|
#if GTEST_INTERNAL_HAS_COMPARE_LIB
|
||||||
#include <compare> // NOLINT
|
#include <compare> // NOLINT
|
||||||
@ -796,7 +800,7 @@ struct Foo {
|
|||||||
TEST(PrintPointerTest, MemberVariablePointer) {
|
TEST(PrintPointerTest, MemberVariablePointer) {
|
||||||
EXPECT_TRUE(HasPrefix(Print(&Foo::value),
|
EXPECT_TRUE(HasPrefix(Print(&Foo::value),
|
||||||
Print(sizeof(&Foo::value)) + "-byte object "));
|
Print(sizeof(&Foo::value)) + "-byte object "));
|
||||||
int Foo::*p = NULL; // NOLINT
|
int Foo::* p = NULL; // NOLINT
|
||||||
EXPECT_TRUE(HasPrefix(Print(p), Print(sizeof(p)) + "-byte object "));
|
EXPECT_TRUE(HasPrefix(Print(p), Print(sizeof(p)) + "-byte object "));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -923,7 +927,7 @@ TEST(PrintArrayTest, BigArray) {
|
|||||||
PrintArrayHelper(a));
|
PrintArrayHelper(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests printing ::string and ::std::string.
|
// Tests printing ::std::string and ::string_view.
|
||||||
|
|
||||||
// ::std::string.
|
// ::std::string.
|
||||||
TEST(PrintStringTest, StringInStdNamespace) {
|
TEST(PrintStringTest, StringInStdNamespace) {
|
||||||
@ -933,6 +937,13 @@ TEST(PrintStringTest, StringInStdNamespace) {
|
|||||||
Print(str));
|
Print(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(PrintStringTest, StringViewInStdNamespace) {
|
||||||
|
const char s[] = "'\"?\\\a\b\f\n\0\r\t\v\x7F\xFF a";
|
||||||
|
const ::std::string_view str(s, sizeof(s));
|
||||||
|
EXPECT_EQ("\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"",
|
||||||
|
Print(str));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(PrintStringTest, StringAmbiguousHex) {
|
TEST(PrintStringTest, StringAmbiguousHex) {
|
||||||
// "\x6BANANA" is ambiguous, it can be interpreted as starting with either of:
|
// "\x6BANANA" is ambiguous, it can be interpreted as starting with either of:
|
||||||
// '\x6', '\x6B', or '\x6BA'.
|
// '\x6', '\x6B', or '\x6BA'.
|
||||||
@ -950,7 +961,7 @@ TEST(PrintStringTest, StringAmbiguousHex) {
|
|||||||
EXPECT_EQ("\"!\\x5-!\"", Print(::std::string("!\x5-!")));
|
EXPECT_EQ("\"!\\x5-!\"", Print(::std::string("!\x5-!")));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests printing ::std::wstring.
|
// Tests printing ::std::wstring and ::std::wstring_view.
|
||||||
#if GTEST_HAS_STD_WSTRING
|
#if GTEST_HAS_STD_WSTRING
|
||||||
// ::std::wstring.
|
// ::std::wstring.
|
||||||
TEST(PrintWideStringTest, StringInStdNamespace) {
|
TEST(PrintWideStringTest, StringInStdNamespace) {
|
||||||
@ -962,6 +973,15 @@ TEST(PrintWideStringTest, StringInStdNamespace) {
|
|||||||
Print(str));
|
Print(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(PrintWideStringTest, StringViewInStdNamespace) {
|
||||||
|
const wchar_t s[] = L"'\"?\\\a\b\f\n\0\r\t\v\xD3\x576\x8D3\xC74D a";
|
||||||
|
const ::std::wstring_view str(s, sizeof(s) / sizeof(wchar_t));
|
||||||
|
EXPECT_EQ(
|
||||||
|
"L\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v"
|
||||||
|
"\\xD3\\x576\\x8D3\\xC74D a\\0\"",
|
||||||
|
Print(str));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(PrintWideStringTest, StringAmbiguousHex) {
|
TEST(PrintWideStringTest, StringAmbiguousHex) {
|
||||||
// same for wide strings.
|
// same for wide strings.
|
||||||
EXPECT_EQ("L\"0\\x12\" L\"3\"", Print(::std::wstring(L"0\x12"
|
EXPECT_EQ("L\"0\\x12\" L\"3\"", Print(::std::wstring(L"0\x12"
|
||||||
@ -980,6 +1000,12 @@ TEST(PrintStringTest, U8String) {
|
|||||||
EXPECT_EQ(str, str); // Verify EXPECT_EQ compiles with this type.
|
EXPECT_EQ(str, str); // Verify EXPECT_EQ compiles with this type.
|
||||||
EXPECT_EQ("u8\"Hello, \\xE4\\xB8\\x96\\xE7\\x95\\x8C\"", Print(str));
|
EXPECT_EQ("u8\"Hello, \\xE4\\xB8\\x96\\xE7\\x95\\x8C\"", Print(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(PrintStringTest, U8StringView) {
|
||||||
|
std::u8string_view str = u8"Hello, 世界";
|
||||||
|
EXPECT_EQ(str, str); // Verify EXPECT_EQ compiles with this type.
|
||||||
|
EXPECT_EQ("u8\"Hello, \\xE4\\xB8\\x96\\xE7\\x95\\x8C\"", Print(str));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TEST(PrintStringTest, U16String) {
|
TEST(PrintStringTest, U16String) {
|
||||||
@ -988,12 +1014,24 @@ TEST(PrintStringTest, U16String) {
|
|||||||
EXPECT_EQ("u\"Hello, \\x4E16\\x754C\"", Print(str));
|
EXPECT_EQ("u\"Hello, \\x4E16\\x754C\"", Print(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(PrintStringTest, U16StringView) {
|
||||||
|
std::u16string_view str = u"Hello, 世界";
|
||||||
|
EXPECT_EQ(str, str); // Verify EXPECT_EQ compiles with this type.
|
||||||
|
EXPECT_EQ("u\"Hello, \\x4E16\\x754C\"", Print(str));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(PrintStringTest, U32String) {
|
TEST(PrintStringTest, U32String) {
|
||||||
std::u32string str = U"Hello, 🗺️";
|
std::u32string str = U"Hello, 🗺️";
|
||||||
EXPECT_EQ(str, str); // Verify EXPECT_EQ compiles with this type
|
EXPECT_EQ(str, str); // Verify EXPECT_EQ compiles with this type
|
||||||
EXPECT_EQ("U\"Hello, \\x1F5FA\\xFE0F\"", Print(str));
|
EXPECT_EQ("U\"Hello, \\x1F5FA\\xFE0F\"", Print(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(PrintStringTest, U32StringView) {
|
||||||
|
std::u32string_view str = U"Hello, 🗺️";
|
||||||
|
EXPECT_EQ(str, str); // Verify EXPECT_EQ compiles with this type
|
||||||
|
EXPECT_EQ("U\"Hello, \\x1F5FA\\xFE0F\"", Print(str));
|
||||||
|
}
|
||||||
|
|
||||||
// Tests printing types that support generic streaming (i.e. streaming
|
// Tests printing types that support generic streaming (i.e. streaming
|
||||||
// to std::basic_ostream<Char, CharTraits> for any valid Char and
|
// to std::basic_ostream<Char, CharTraits> for any valid Char and
|
||||||
// CharTraits types).
|
// CharTraits types).
|
||||||
@ -1453,7 +1491,7 @@ TEST(PrintReferenceTest, HandlesMemberFunctionPointer) {
|
|||||||
// Tests that the universal printer prints a member variable pointer
|
// Tests that the universal printer prints a member variable pointer
|
||||||
// passed by reference.
|
// passed by reference.
|
||||||
TEST(PrintReferenceTest, HandlesMemberVariablePointer) {
|
TEST(PrintReferenceTest, HandlesMemberVariablePointer) {
|
||||||
int Foo::*p = &Foo::value; // NOLINT
|
int Foo::* p = &Foo::value; // NOLINT
|
||||||
EXPECT_TRUE(HasPrefix(PrintByRef(p), "@" + PrintPointer(&p) + " " +
|
EXPECT_TRUE(HasPrefix(PrintByRef(p), "@" + PrintPointer(&p) + " " +
|
||||||
Print(sizeof(p)) + "-byte object "));
|
Print(sizeof(p)) + "-byte object "));
|
||||||
}
|
}
|
||||||
@ -1661,7 +1699,7 @@ TEST(PrintToStringTest, ContainsNonLatin) {
|
|||||||
EXPECT_PRINT_TO_STRING_(non_ascii_str,
|
EXPECT_PRINT_TO_STRING_(non_ascii_str,
|
||||||
"\"\\xEC\\x98\\xA4\\xEC\\xA0\\x84 4:30\"\n"
|
"\"\\xEC\\x98\\xA4\\xEC\\xA0\\x84 4:30\"\n"
|
||||||
" As Text: \"오전 4:30\"");
|
" As Text: \"오전 4:30\"");
|
||||||
non_ascii_str = ::std::string("From ä — ẑ");
|
non_ascii_str = "From ä — ẑ";
|
||||||
EXPECT_PRINT_TO_STRING_(non_ascii_str,
|
EXPECT_PRINT_TO_STRING_(non_ascii_str,
|
||||||
"\"From \\xC3\\xA4 \\xE2\\x80\\x94 \\xE1\\xBA\\x91\""
|
"\"From \\xC3\\xA4 \\xE2\\x80\\x94 \\xE1\\xBA\\x91\""
|
||||||
"\n As Text: \"From ä — ẑ\"");
|
"\n As Text: \"From ä — ẑ\"");
|
||||||
@ -1891,6 +1929,22 @@ TEST(UniversalPrintTest, SmartPointers) {
|
|||||||
PrintToString(std::shared_ptr<void>(p.get(), [](void*) {})));
|
PrintToString(std::shared_ptr<void>(p.get(), [](void*) {})));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(UniversalPrintTest, StringViewNonZeroTerminated) {
|
||||||
|
// Craft a non-ASCII UTF-8 input (to trigger a special path in
|
||||||
|
// `ConditionalPrintAsText`). Use array notation instead of the string
|
||||||
|
// literal syntax, to avoid placing a terminating 0 at the end of the input.
|
||||||
|
const char s[] = {'\357', '\243', '\242', 'X'};
|
||||||
|
// Only include the first 3 bytes in the `string_view` and leave the last one
|
||||||
|
// ('X') outside. This way, if the code tries to use `str.data()` with
|
||||||
|
// `strlen` instead of `str.size()`, it will include 'X' and cause a visible
|
||||||
|
// difference (in addition to ASAN tests detecting a buffer overflow due to
|
||||||
|
// the missing 0 at the end).
|
||||||
|
const ::std::string_view str(s, 3);
|
||||||
|
::std::stringstream ss;
|
||||||
|
UniversalPrint(str, &ss);
|
||||||
|
EXPECT_EQ("\"\\xEF\\xA3\\xA2\"\n As Text: \"\xEF\xA3\xA2\"", ss.str());
|
||||||
|
}
|
||||||
|
|
||||||
TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsEmptyTuple) {
|
TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsEmptyTuple) {
|
||||||
Strings result = UniversalTersePrintTupleFieldsToStrings(::std::make_tuple());
|
Strings result = UniversalTersePrintTupleFieldsToStrings(::std::make_tuple());
|
||||||
EXPECT_EQ(0u, result.size());
|
EXPECT_EQ(0u, result.size());
|
||||||
@ -1920,7 +1974,6 @@ TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTersely) {
|
|||||||
EXPECT_EQ("\"a\"", result[1]);
|
EXPECT_EQ("\"a\"", result[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GTEST_INTERNAL_HAS_ANY
|
|
||||||
class PrintAnyTest : public ::testing::Test {
|
class PrintAnyTest : public ::testing::Test {
|
||||||
protected:
|
protected:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -1934,12 +1987,12 @@ class PrintAnyTest : public ::testing::Test {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(PrintAnyTest, Empty) {
|
TEST_F(PrintAnyTest, Empty) {
|
||||||
internal::Any any;
|
std::any any;
|
||||||
EXPECT_EQ("no value", PrintToString(any));
|
EXPECT_EQ("no value", PrintToString(any));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(PrintAnyTest, NonEmpty) {
|
TEST_F(PrintAnyTest, NonEmpty) {
|
||||||
internal::Any any;
|
std::any any;
|
||||||
constexpr int val1 = 10;
|
constexpr int val1 = 10;
|
||||||
const std::string val2 = "content";
|
const std::string val2 = "content";
|
||||||
|
|
||||||
@ -1950,27 +2003,23 @@ TEST_F(PrintAnyTest, NonEmpty) {
|
|||||||
EXPECT_EQ("value of type " + ExpectedTypeName<std::string>(),
|
EXPECT_EQ("value of type " + ExpectedTypeName<std::string>(),
|
||||||
PrintToString(any));
|
PrintToString(any));
|
||||||
}
|
}
|
||||||
#endif // GTEST_INTERNAL_HAS_ANY
|
|
||||||
|
|
||||||
#if GTEST_INTERNAL_HAS_OPTIONAL
|
|
||||||
TEST(PrintOptionalTest, Basic) {
|
TEST(PrintOptionalTest, Basic) {
|
||||||
EXPECT_EQ("(nullopt)", PrintToString(internal::Nullopt()));
|
EXPECT_EQ("(nullopt)", PrintToString(std::nullopt));
|
||||||
internal::Optional<int> value;
|
std::optional<int> value;
|
||||||
EXPECT_EQ("(nullopt)", PrintToString(value));
|
EXPECT_EQ("(nullopt)", PrintToString(value));
|
||||||
value = {7};
|
value = {7};
|
||||||
EXPECT_EQ("(7)", PrintToString(value));
|
EXPECT_EQ("(7)", PrintToString(value));
|
||||||
EXPECT_EQ("(1.1)", PrintToString(internal::Optional<double>{1.1}));
|
EXPECT_EQ("(1.1)", PrintToString(std::optional<double>{1.1}));
|
||||||
EXPECT_EQ("(\"A\")", PrintToString(internal::Optional<std::string>{"A"}));
|
EXPECT_EQ("(\"A\")", PrintToString(std::optional<std::string>{"A"}));
|
||||||
}
|
}
|
||||||
#endif // GTEST_INTERNAL_HAS_OPTIONAL
|
|
||||||
|
|
||||||
#if GTEST_INTERNAL_HAS_VARIANT
|
|
||||||
struct NonPrintable {
|
struct NonPrintable {
|
||||||
unsigned char contents = 17;
|
unsigned char contents = 17;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(PrintOneofTest, Basic) {
|
TEST(PrintOneofTest, Basic) {
|
||||||
using Type = internal::Variant<int, StreamableInGlobal, NonPrintable>;
|
using Type = std::variant<int, StreamableInGlobal, NonPrintable>;
|
||||||
EXPECT_EQ("('int(index = 0)' with value 7)", PrintToString(Type(7)));
|
EXPECT_EQ("('int(index = 0)' with value 7)", PrintToString(Type(7)));
|
||||||
EXPECT_EQ("('StreamableInGlobal(index = 1)' with value StreamableInGlobal)",
|
EXPECT_EQ("('StreamableInGlobal(index = 1)' with value StreamableInGlobal)",
|
||||||
PrintToString(Type(StreamableInGlobal{})));
|
PrintToString(Type(StreamableInGlobal{})));
|
||||||
@ -1979,7 +2028,6 @@ TEST(PrintOneofTest, Basic) {
|
|||||||
"1-byte object <11>)",
|
"1-byte object <11>)",
|
||||||
PrintToString(Type(NonPrintable{})));
|
PrintToString(Type(NonPrintable{})));
|
||||||
}
|
}
|
||||||
#endif // GTEST_INTERNAL_HAS_VARIANT
|
|
||||||
|
|
||||||
#if GTEST_INTERNAL_HAS_COMPARE_LIB
|
#if GTEST_INTERNAL_HAS_COMPARE_LIB
|
||||||
TEST(PrintOrderingTest, Basic) {
|
TEST(PrintOrderingTest, Basic) {
|
||||||
|
|||||||
@ -95,9 +95,9 @@ void ManyAsserts(int id) {
|
|||||||
|
|
||||||
// RecordProperty() should interact safely with other threads as well.
|
// RecordProperty() should interact safely with other threads as well.
|
||||||
// The shared_key forces property updates.
|
// The shared_key forces property updates.
|
||||||
Test::RecordProperty(IdToKey(id, "string").c_str(), IdToString(id).c_str());
|
Test::RecordProperty(IdToKey(id, "string"), IdToString(id));
|
||||||
Test::RecordProperty(IdToKey(id, "int").c_str(), id);
|
Test::RecordProperty(IdToKey(id, "int").c_str(), id);
|
||||||
Test::RecordProperty("shared_key", IdToString(id).c_str());
|
Test::RecordProperty("shared_key", IdToString(id));
|
||||||
|
|
||||||
// This assertion should fail kThreadCount times per thread. It
|
// This assertion should fail kThreadCount times per thread. It
|
||||||
// is for testing whether Google Test can handle failed assertions in a
|
// is for testing whether Google Test can handle failed assertions in a
|
||||||
|
|||||||
@ -2649,8 +2649,8 @@ TEST(IsSubstringTest, GeneratesCorrectMessageForCString) {
|
|||||||
// Tests that IsSubstring returns the correct result when the input
|
// Tests that IsSubstring returns the correct result when the input
|
||||||
// argument type is ::std::string.
|
// argument type is ::std::string.
|
||||||
TEST(IsSubstringTest, ReturnsCorrectResultsForStdString) {
|
TEST(IsSubstringTest, ReturnsCorrectResultsForStdString) {
|
||||||
EXPECT_TRUE(IsSubstring("", "", std::string("hello"), "ahellob"));
|
EXPECT_TRUE(IsSubstring("", "", "hello", "ahellob"));
|
||||||
EXPECT_FALSE(IsSubstring("", "", "hello", std::string("world")));
|
EXPECT_FALSE(IsSubstring("", "", "hello", "world"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GTEST_HAS_STD_WSTRING
|
#if GTEST_HAS_STD_WSTRING
|
||||||
@ -2707,8 +2707,8 @@ TEST(IsNotSubstringTest, GeneratesCorrectMessageForWideCString) {
|
|||||||
// Tests that IsNotSubstring returns the correct result when the input
|
// Tests that IsNotSubstring returns the correct result when the input
|
||||||
// argument type is ::std::string.
|
// argument type is ::std::string.
|
||||||
TEST(IsNotSubstringTest, ReturnsCorrectResultsForStdString) {
|
TEST(IsNotSubstringTest, ReturnsCorrectResultsForStdString) {
|
||||||
EXPECT_FALSE(IsNotSubstring("", "", std::string("hello"), "ahellob"));
|
EXPECT_FALSE(IsNotSubstring("", "", "hello", "ahellob"));
|
||||||
EXPECT_TRUE(IsNotSubstring("", "", "hello", std::string("world")));
|
EXPECT_TRUE(IsNotSubstring("", "", "hello", "world"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that IsNotSubstring() generates the correct message when the input
|
// Tests that IsNotSubstring() generates the correct message when the input
|
||||||
@ -2719,8 +2719,7 @@ TEST(IsNotSubstringTest, GeneratesCorrectMessageForStdString) {
|
|||||||
" Actual: \"needle\"\n"
|
" Actual: \"needle\"\n"
|
||||||
"Expected: not a substring of haystack_expr\n"
|
"Expected: not a substring of haystack_expr\n"
|
||||||
"Which is: \"two needles\"",
|
"Which is: \"two needles\"",
|
||||||
IsNotSubstring("needle_expr", "haystack_expr", ::std::string("needle"),
|
IsNotSubstring("needle_expr", "haystack_expr", "needle", "two needles")
|
||||||
"two needles")
|
|
||||||
.failure_message());
|
.failure_message());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3579,13 +3578,13 @@ TEST(EditDistance, TestSuites) {
|
|||||||
{__LINE__, "A", "A", " ", ""},
|
{__LINE__, "A", "A", " ", ""},
|
||||||
{__LINE__, "ABCDE", "ABCDE", " ", ""},
|
{__LINE__, "ABCDE", "ABCDE", " ", ""},
|
||||||
// Simple adds.
|
// Simple adds.
|
||||||
{__LINE__, "X", "XA", " +", "@@ +1,2 @@\n X\n+A\n"},
|
{__LINE__, "X", "XA", " +", "@@ -1 +1,2 @@\n X\n+A\n"},
|
||||||
{__LINE__, "X", "XABCD", " ++++", "@@ +1,5 @@\n X\n+A\n+B\n+C\n+D\n"},
|
{__LINE__, "X", "XABCD", " ++++", "@@ -1 +1,5 @@\n X\n+A\n+B\n+C\n+D\n"},
|
||||||
// Simple removes.
|
// Simple removes.
|
||||||
{__LINE__, "XA", "X", " -", "@@ -1,2 @@\n X\n-A\n"},
|
{__LINE__, "XA", "X", " -", "@@ -1,2 +1 @@\n X\n-A\n"},
|
||||||
{__LINE__, "XABCD", "X", " ----", "@@ -1,5 @@\n X\n-A\n-B\n-C\n-D\n"},
|
{__LINE__, "XABCD", "X", " ----", "@@ -1,5 +1 @@\n X\n-A\n-B\n-C\n-D\n"},
|
||||||
// Simple replaces.
|
// Simple replaces.
|
||||||
{__LINE__, "A", "a", "/", "@@ -1,1 +1,1 @@\n-A\n+a\n"},
|
{__LINE__, "A", "a", "/", "@@ -1 +1 @@\n-A\n+a\n"},
|
||||||
{__LINE__, "ABCD", "abcd", "////",
|
{__LINE__, "ABCD", "abcd", "////",
|
||||||
"@@ -1,4 +1,4 @@\n-A\n-B\n-C\n-D\n+a\n+b\n+c\n+d\n"},
|
"@@ -1,4 +1,4 @@\n-A\n-B\n-C\n-D\n+a\n+b\n+c\n+d\n"},
|
||||||
// Path finding.
|
// Path finding.
|
||||||
@ -3655,8 +3654,7 @@ TEST(AssertionTest, EqFailure) {
|
|||||||
msg4.c_str());
|
msg4.c_str());
|
||||||
|
|
||||||
const std::string msg5(
|
const std::string msg5(
|
||||||
EqFailure("foo", "bar", std::string("\"x\""), std::string("\"y\""), true)
|
EqFailure("foo", "bar", "\"x\"", "\"y\"", true).failure_message());
|
||||||
.failure_message());
|
|
||||||
EXPECT_STREQ(
|
EXPECT_STREQ(
|
||||||
"Expected equality of these values:\n"
|
"Expected equality of these values:\n"
|
||||||
" foo\n"
|
" foo\n"
|
||||||
@ -6717,6 +6715,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-ghostty"); // TERM supports colors.
|
||||||
|
EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY.
|
||||||
|
|
||||||
SetEnv("TERM", "xterm-kitty"); // TERM supports colors.
|
SetEnv("TERM", "xterm-kitty"); // TERM supports colors.
|
||||||
EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY.
|
EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY.
|
||||||
|
|
||||||
|
|||||||
@ -17,9 +17,25 @@ def googletest_deps():
|
|||||||
if not native.existing_rule("abseil-cpp"):
|
if not native.existing_rule("abseil-cpp"):
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "abseil-cpp",
|
name = "abseil-cpp",
|
||||||
sha256 = "b396401fd29e2e679cace77867481d388c807671dc2acc602a0259eeb79b7811",
|
sha256 = "9b2b72d4e8367c0b843fa2bcfa2b08debbe3cee34f7aaa27de55a6cbb3e843db",
|
||||||
strip_prefix = "abseil-cpp-20250127.1",
|
strip_prefix = "abseil-cpp-20250814.0",
|
||||||
urls = ["https://github.com/abseil/abseil-cpp/releases/download/20250127.1/abseil-cpp-20250127.1.tar.gz"],
|
urls = ["https://github.com/abseil/abseil-cpp/releases/download/20250814.0/abseil-cpp-20250814.0.tar.gz"],
|
||||||
|
)
|
||||||
|
|
||||||
|
if not native.existing_rule("bazel_features"):
|
||||||
|
http_archive(
|
||||||
|
name = "bazel_features",
|
||||||
|
sha256 = "9390b391a68d3b24aef7966bce8556d28003fe3f022a5008efc7807e8acaaf1a",
|
||||||
|
strip_prefix = "bazel_features-1.36.0",
|
||||||
|
url = "https://github.com/bazel-contrib/bazel_features/releases/download/v1.36.0/bazel_features-v1.36.0.tar.gz",
|
||||||
|
)
|
||||||
|
|
||||||
|
if not native.existing_rule("rules_cc"):
|
||||||
|
http_archive(
|
||||||
|
name = "rules_cc",
|
||||||
|
sha256 = "207ea073dd20a705f9e8bc5ac02f5203e9621fc672774bb1a0935aefab7aebfa",
|
||||||
|
strip_prefix = "rules_cc-0.2.8",
|
||||||
|
url = "https://github.com/bazelbuild/rules_cc/releases/download/0.2.8/rules_cc-0.2.8.tar.gz",
|
||||||
)
|
)
|
||||||
|
|
||||||
if not native.existing_rule("fuchsia_sdk"):
|
if not native.existing_rule("fuchsia_sdk"):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user