summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--BUILD.bazel8
-rw-r--r--MODULE.bazel8
-rw-r--r--README.md19
-rw-r--r--WORKSPACE12
-rw-r--r--ci/linux-presubmit.sh83
-rw-r--r--ci/macos-presubmit.sh11
-rw-r--r--ci/windows-presubmit.bat16
-rw-r--r--docs/_layouts/default.html14
-rw-r--r--docs/advanced.md50
-rw-r--r--docs/quickstart-bazel.md16
-rw-r--r--docs/quickstart-cmake.md6
-rw-r--r--docs/reference/actions.md4
-rw-r--r--docs/reference/matchers.md27
-rw-r--r--docs/reference/testing.md2
-rw-r--r--googlemock/include/gmock/gmock-actions.h8
-rw-r--r--googlemock/include/gmock/gmock-matchers.h76
-rw-r--r--googlemock/include/gmock/internal/gmock-port.h13
-rw-r--r--googlemock/src/gmock-spec-builders.cc2
-rw-r--r--googlemock/test/gmock-actions_test.cc57
-rw-r--r--googlemock/test/gmock-function-mocker_test.cc2
-rw-r--r--googlemock/test/gmock-matchers-comparisons_test.cc108
-rw-r--r--googlemock/test/gmock-more-actions_test.cc34
-rw-r--r--googlemock/test/gmock-spec-builders_test.cc2
-rw-r--r--googlemock/test/gmock_output_test_golden.txt8
-rw-r--r--googletest/CMakeLists.txt3
-rw-r--r--googletest/README.md12
-rw-r--r--googletest/include/gtest/gtest-matchers.h29
-rw-r--r--googletest/include/gtest/gtest-printers.h104
-rw-r--r--googletest/include/gtest/gtest-typed-test.h8
-rw-r--r--googletest/include/gtest/gtest.h7
-rw-r--r--googletest/include/gtest/internal/gtest-internal.h34
-rw-r--r--googletest/include/gtest/internal/gtest-port.h124
-rw-r--r--googletest/src/gtest-printers.cc20
-rw-r--r--googletest/src/gtest.cc45
-rwxr-xr-xgoogletest/test/googletest-color-test.py1
-rw-r--r--googletest/test/googletest-death-test-test.cc2
-rwxr-xr-xgoogletest/test/googletest-fail-if-no-test-linked-test.py6
-rw-r--r--googletest/test/googletest-fail-if-no-test-selected-test.py91
-rw-r--r--googletest/test/googletest-output-test-golden-lin.txt2
-rw-r--r--googletest/test/googletest-param-test-test.cc2
-rw-r--r--googletest/test/googletest-printers-test.cc84
-rw-r--r--googletest/test/gtest_unittest.cc13
-rw-r--r--googletest_deps.bzl6
43 files changed, 736 insertions, 443 deletions
diff --git a/BUILD.bazel b/BUILD.bazel
index 5350145..3ca5735 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -151,10 +151,7 @@ cc_library(
"@abseil-cpp//absl/flags:reflection",
"@abseil-cpp//absl/flags:usage",
"@abseil-cpp//absl/strings",
- "@abseil-cpp//absl/types:any",
- "@abseil-cpp//absl/types:optional",
- "@abseil-cpp//absl/types:variant",
- "@re2//:re2",
+ "@re2",
],
"//conditions:default": [],
}) + select({
@@ -164,7 +161,6 @@ cc_library(
# Otherwise, builds targeting Fuchsia would fail to compile.
":fuchsia": [
"@fuchsia_sdk//pkg/fdio",
- "@fuchsia_sdk//pkg/syslog",
"@fuchsia_sdk//pkg/zx",
],
"//conditions:default": [],
@@ -174,8 +170,8 @@ cc_library(
# `gtest`, but testonly. See guidance on `gtest` for when to use this.
alias(
name = "gtest_for_library",
- actual = ":gtest",
testonly = True,
+ actual = ":gtest",
)
# Implements main() for tests using gtest. Prefer to depend on `gtest` as well
diff --git a/MODULE.bazel b/MODULE.bazel
index 66eee54..c2fb850 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -41,20 +41,20 @@ module(
bazel_dep(
name = "abseil-cpp",
- version = "20250127.0",
+ version = "20250512.0",
)
bazel_dep(
name = "platforms",
- version = "0.0.10",
+ version = "0.0.11",
)
bazel_dep(
name = "re2",
- version = "2024-07-02",
+ version = "2024-07-02.bcr.1",
)
bazel_dep(
name = "rules_python",
- version = "1.1.0",
+ version = "1.3.0",
dev_dependency = True,
)
diff --git a/README.md b/README.md
index 2a2a722..1584c79 100644
--- a/README.md
+++ b/README.md
@@ -2,30 +2,19 @@
### 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
Our documentation is now live on GitHub Pages at
https://google.github.io/googletest/. We recommend browsing the documentation on
GitHub Pages rather than directly in the repository.
-#### Release 1.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.
-The 1.16.x branch requires at least C++14.
-
-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).
+The 1.17.x branch
+[requires at least C++17](https://opensource.google/documentation/policies/cplusplus-support#c_language_standard).
#### Continuous Integration
diff --git a/WORKSPACE b/WORKSPACE
index 4c76102..0ae5dee 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -37,9 +37,9 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "rules_python",
- sha256 = "9c6e26911a79fbf510a8f06d8eedb40f412023cf7fa6d1461def27116bff022c",
- strip_prefix = "rules_python-1.1.0",
- url = "https://github.com/bazelbuild/rules_python/releases/download/1.1.0/rules_python-1.1.0.tar.gz",
+ sha256 = "2cc26bbd53854ceb76dd42a834b1002cd4ba7f8df35440cf03482e045affc244",
+ strip_prefix = "rules_python-1.3.0",
+ url = "https://github.com/bazelbuild/rules_python/releases/download/1.3.0/rules_python-1.3.0.tar.gz",
)
# https://github.com/bazelbuild/rules_python/releases/tag/1.1.0
load("@rules_python//python:repositories.bzl", "py_repositories")
@@ -54,8 +54,8 @@ http_archive(
http_archive(
name = "platforms",
urls = [
- "https://mirror.bazel.build/github.com/bazelbuild/platforms/releases/download/0.0.10/platforms-0.0.10.tar.gz",
- "https://github.com/bazelbuild/platforms/releases/download/0.0.10/platforms-0.0.10.tar.gz",
+ "https://mirror.bazel.build/github.com/bazelbuild/platforms/releases/download/0.0.11/platforms-0.0.11.tar.gz",
+ "https://github.com/bazelbuild/platforms/releases/download/0.0.11/platforms-0.0.11.tar.gz",
],
- sha256 = "218efe8ee736d26a3572663b374a253c012b716d8af0c07e842e82f238a0a7ee",
+ sha256 = "29742e87275809b5e598dc2f04d86960cc7a55b3067d97221c9abbc9926bff0f",
)
diff --git a/ci/linux-presubmit.sh b/ci/linux-presubmit.sh
index 6491e79..c4ad579 100644
--- a/ci/linux-presubmit.sh
+++ b/ci/linux-presubmit.sh
@@ -31,15 +31,23 @@
set -euox pipefail
-readonly LINUX_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20241218"
-readonly LINUX_GCC_FLOOR_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-floor:20250205"
+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:20250430"
if [[ -z ${GTEST_ROOT:-} ]]; then
GTEST_ROOT="$(realpath $(dirname ${0})/..)"
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
- STD="c++17 c++20"
+ STD="c++17 c++20 c++23"
fi
# Test CMake + GCC
@@ -93,18 +101,21 @@ time docker run \
--rm \
--env="CC=/usr/local/bin/gcc" \
--env="BAZEL_CXXOPTS=-std=c++17" \
+ ${DOCKER_EXTRA_ARGS:-} \
${LINUX_GCC_FLOOR_CONTAINER} \
+ /bin/bash --login -c "
/usr/local/bin/bazel test ... \
- --copt="-Wall" \
- --copt="-Werror" \
- --copt="-Wuninitialized" \
- --copt="-Wundef" \
- --copt="-Wno-error=pragmas" \
+ --copt=\"-Wall\" \
+ --copt=\"-Werror\" \
+ --copt=\"-Wuninitialized\" \
+ --copt=\"-Wundef\" \
+ --copt=\"-Wno-error=pragmas\" \
--enable_bzlmod=false \
--features=external_include_paths \
--keep_going \
--show_timestamps \
- --test_output=errors
+ --test_output=errors \
+ ${BAZEL_EXTRA_ARGS:-}"
# Test GCC
for std in ${STD}; do
@@ -115,18 +126,21 @@ for std in ${STD}; do
--rm \
--env="CC=/usr/local/bin/gcc" \
--env="BAZEL_CXXOPTS=-std=${std}" \
+ ${DOCKER_EXTRA_ARGS:-} \
${LINUX_LATEST_CONTAINER} \
- /usr/local/bin/bazel test ... \
- --copt="-Wall" \
- --copt="-Werror" \
- --copt="-Wuninitialized" \
- --copt="-Wundef" \
- --define="absl=${absl}" \
- --enable_bzlmod=true \
- --features=external_include_paths \
- --keep_going \
- --show_timestamps \
- --test_output=errors
+ /bin/bash --login -c "
+ /usr/local/bin/bazel test ... \
+ --copt=\"-Wall\" \
+ --copt=\"-Werror\" \
+ --copt=\"-Wuninitialized\" \
+ --copt=\"-Wundef\" \
+ --define=\"absl=${absl}\" \
+ --enable_bzlmod=true \
+ --features=external_include_paths \
+ --keep_going \
+ --show_timestamps \
+ --test_output=errors \
+ ${BAZEL_EXTRA_ARGS:-}"
done
done
@@ -139,19 +153,22 @@ for std in ${STD}; do
--rm \
--env="CC=/opt/llvm/clang/bin/clang" \
--env="BAZEL_CXXOPTS=-std=${std}" \
+ ${DOCKER_EXTRA_ARGS:-} \
${LINUX_LATEST_CONTAINER} \
- /usr/local/bin/bazel test ... \
- --copt="--gcc-toolchain=/usr/local" \
- --copt="-Wall" \
- --copt="-Werror" \
- --copt="-Wuninitialized" \
- --copt="-Wundef" \
- --define="absl=${absl}" \
- --enable_bzlmod=true \
- --features=external_include_paths \
- --keep_going \
- --linkopt="--gcc-toolchain=/usr/local" \
- --show_timestamps \
- --test_output=errors
+ /bin/bash --login -c "
+ /usr/local/bin/bazel test ... \
+ --copt=\"--gcc-toolchain=/usr/local\" \
+ --copt=\"-Wall\" \
+ --copt=\"-Werror\" \
+ --copt=\"-Wuninitialized\" \
+ --copt=\"-Wundef\" \
+ --define=\"absl=${absl}\" \
+ --enable_bzlmod=true \
+ --features=external_include_paths \
+ --keep_going \
+ --linkopt=\"--gcc-toolchain=/usr/local\" \
+ --show_timestamps \
+ --test_output=errors \
+ ${BAZEL_EXTRA_ARGS:-}"
done
done
diff --git a/ci/macos-presubmit.sh b/ci/macos-presubmit.sh
index 5370ed6..63cf814 100644
--- a/ci/macos-presubmit.sh
+++ b/ci/macos-presubmit.sh
@@ -56,7 +56,7 @@ done
# Test the Bazel build
# 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
BAZEL_BIN="${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN}"
chmod +x ${BAZEL_BIN}
@@ -64,6 +64,12 @@ else
BAZEL_BIN="bazel"
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 "${TMP}/"
+ BAZEL_EXTRA_ARGS="--vendor_dir=\"${TMP}/googletest_vendor\" ${BAZEL_EXTRA_ARGS:-}"
+fi
+
cd ${GTEST_ROOT}
for absl in 0 1; do
${BAZEL_BIN} test ... \
@@ -76,5 +82,6 @@ for absl in 0 1; do
--features=external_include_paths \
--keep_going \
--show_timestamps \
- --test_output=errors
+ --test_output=errors \
+ ${BAZEL_EXTRA_ARGS:-}
done
diff --git a/ci/windows-presubmit.bat b/ci/windows-presubmit.bat
index e2664c5..267e2e9 100644
--- a/ci/windows-presubmit.bat
+++ b/ci/windows-presubmit.bat
@@ -1,6 +1,6 @@
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 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.
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
%BAZEL_EXE% ^
--output_user_root=C:\tmp ^
@@ -58,7 +66,8 @@ SET BAZEL_VS=C:\Program Files\Microsoft Visual Studio\2022\Community
--enable_bzlmod=true ^
--keep_going ^
--test_output=errors ^
- --test_tag_filters=-no_test_msvc2017
+ --test_tag_filters=-no_test_msvc2017 ^
+ %VENDOR_FLAG%
IF %errorlevel% neq 0 EXIT /B 1
:: C++20
@@ -71,5 +80,6 @@ IF %errorlevel% neq 0 EXIT /B 1
--enable_bzlmod=true ^
--keep_going ^
--test_output=errors ^
- --test_tag_filters=-no_test_msvc2017
+ --test_tag_filters=-no_test_msvc2017 ^
+ %VENDOR_FLAG%
IF %errorlevel% neq 0 EXIT /B 1
diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html
index c7f331b..f0ae474 100644
--- a/docs/_layouts/default.html
+++ b/docs/_layouts/default.html
@@ -7,15 +7,15 @@
{% seo %}
<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>
- window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
- ga('create', 'UA-197576187-1', { 'storage': 'none' });
- ga('set', 'referrer', document.referrer.split('?')[0]);
- ga('set', 'location', window.location.href.split('?')[0]);
- ga('set', 'anonymizeIp', true);
- ga('send', 'pageview');
+ window.dataLayer = window.dataLayer || [];
+ function gtag(){dataLayer.push(arguments);}
+ gtag('js', new Date());
+
+ gtag('config', 'G-9PTP6FW1M5');
</script>
- <script async src='https://www.google-analytics.com/analytics.js'></script>
</head>
<body>
<div class="sidebar">
diff --git a/docs/advanced.md b/docs/advanced.md
index 9b1220a..d703a7b 100644
--- a/docs/advanced.md
+++ b/docs/advanced.md
@@ -349,7 +349,8 @@ void AbslStringify(Sink& sink, EnumWithStringify e) {
{: .callout .note}
Note: `AbslStringify()` utilizes a generic "sink" buffer to construct its
string. For more information about supported operations on `AbslStringify()`'s
-sink, see go/abslstringify.
+sink, see
+[the `AbslStringify()` documentation](https://abseil.io/docs/cpp/guides/abslstringify).
`AbslStringify()` can also use `absl::StrFormat`'s catch-all `%v` type specifier
within its own format strings to perform type deduction. `Point` above could be
@@ -403,7 +404,8 @@ EXPECT_TRUE(IsCorrectPointIntVector(point_ints))
```
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
@@ -1448,17 +1450,19 @@ are two cases to consider:
To test them, we use the following special techniques:
* Both static functions and definitions/declarations in an unnamed namespace
- are only visible within the same translation unit. To test them, you can
- `#include` the entire `.cc` file being tested in your `*_test.cc` file.
- (#including `.cc` files is not a good way to reuse code - you should not do
- this in production code!)
-
- However, a better approach is to move the private code into the
- `foo::internal` namespace, where `foo` is the namespace your project
- normally uses, and put the private declarations in a `*-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.
+ are only visible within the same translation unit. To test them, move the
+ private code into the `foo::internal` namespace, where `foo` is the
+ namespace your project normally uses, and put the private declarations in a
+ `*-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.
+
+{: .callout .note}
+NOTE: It is also technically *possible* to `#include` the entire `.cc` file
+being tested in your `*_test.cc` file to test static functions and
+definitions/declarations in an unnamed namespace. However, this technique is
+**not recommended** by this documentation and it is only presented here for the
+sake of completeness.
* Private class members are only accessible from within the class or by
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
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
- called the
- [Pimpl](https://www.gamedev.net/articles/programming/general-and-gameplay-programming/the-c-pimpl-r1794/)
- (Private Implementation) idiom.
+ clients aren't allowed to include this header but your tests can.
Or, you can declare an individual test as a friend of your class by adding
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
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
Once in a while you'll run into a test whose result is hit-or-miss. Perhaps it
diff --git a/docs/quickstart-bazel.md b/docs/quickstart-bazel.md
index 5750f02..04fa829 100644
--- a/docs/quickstart-bazel.md
+++ b/docs/quickstart-bazel.md
@@ -9,7 +9,7 @@ we recommend this tutorial as a starting point.
To complete this tutorial, you'll need:
* A compatible operating system (e.g. Linux, macOS, Windows).
-* A compatible C++ compiler that supports at least C++14.
+* A compatible C++ compiler that supports at least C++17.
* [Bazel](https://bazel.build/) 7.0 or higher, the preferred build system used
by the GoogleTest team.
@@ -48,7 +48,7 @@ with the following content:
# Choose the most recent version available at
# 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.
@@ -99,16 +99,16 @@ files, see the
[Bazel C++ Tutorial](https://docs.bazel.build/versions/main/tutorial/cpp.html).
{: .callout .note}
-NOTE: In the example below, we assume Clang or GCC and set `--cxxopt=-std=c++14`
-to ensure that GoogleTest is compiled as C++14 instead of the compiler's default
-setting (which could be C++11). For MSVC, the equivalent would be
-`--cxxopt=/std:c++14`. See [Supported Platforms](platforms.md) for more details
-on supported language versions.
+NOTE: In the example below, we assume Clang or GCC and set `--cxxopt=-std=c++17`
+to ensure that GoogleTest is compiled as C++17 instead of the compiler's default
+setting. For MSVC, the equivalent would be `--cxxopt=/std:c++17`. See
+[Supported Platforms](platforms.md) for more details on supported language
+versions.
Now you can build and run your test:
<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: Found 1 test target...
INFO: From Testing //:hello_test:
diff --git a/docs/quickstart-cmake.md b/docs/quickstart-cmake.md
index 4e422b7..bcdb1b5 100644
--- a/docs/quickstart-cmake.md
+++ b/docs/quickstart-cmake.md
@@ -10,7 +10,7 @@ this tutorial as a starting point. If your project uses Bazel, see the
To complete this tutorial, you'll need:
* A compatible operating system (e.g. Linux, macOS, Windows).
-* A compatible C++ compiler that supports at least C++14.
+* A compatible C++ compiler that supports at least C++17.
* [CMake](https://cmake.org/) and a compatible build tool for building the
project.
* 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)
project(my_project)
-# GoogleTest requires at least C++14
-set(CMAKE_CXX_STANDARD 14)
+# GoogleTest requires at least C++17
+set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
include(FetchContent)
diff --git a/docs/reference/actions.md b/docs/reference/actions.md
index 0ebdc1e..2ca3a9f 100644
--- a/docs/reference/actions.md
+++ b/docs/reference/actions.md
@@ -48,8 +48,8 @@ functor, or lambda.
| `InvokeWithoutArgs(object_pointer, &class::method)` | Invoke the method on the object, which takes no arguments. |
| `InvokeArgument<N>(arg1, arg2, ..., argk)` | Invoke the mock function's `N`-th (0-based) argument, which must be a function or a functor, with the `k` arguments. |
-The return value of the invoked function is used as the return value of the
-action.
+The return value of the invoked function (except `InvokeArgument`) is used as
+the return value of the action.
When defining a callable to be used with `Invoke*()`, you can declare any unused
parameters as `Unused`:
diff --git a/docs/reference/matchers.md b/docs/reference/matchers.md
index 8ff9e0b..8b3d140 100644
--- a/docs/reference/matchers.md
+++ b/docs/reference/matchers.md
@@ -111,6 +111,33 @@ use the regular expression syntax defined
[here](../advanced.md#regular-expression-syntax). All of these matchers, except
`ContainsRegex()` and `MatchesRegex()` work for wide strings as well.
+## 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
Most STL-style containers support `==`, so you can use `Eq(expected_container)`
diff --git a/docs/reference/testing.md b/docs/reference/testing.md
index d7dc5cf..ea43721 100644
--- a/docs/reference/testing.md
+++ b/docs/reference/testing.md
@@ -203,7 +203,7 @@ class MyParam {
INSTANTIATE_TEST_SUITE_P(MyInstantiation, MyTestSuite,
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;
return MyParam(i, b);
}));
diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h
index 5fe50e3..2746edd 100644
--- a/googlemock/include/gmock/gmock-actions.h
+++ b/googlemock/include/gmock/gmock-actions.h
@@ -1866,6 +1866,13 @@ struct RethrowAction {
// EXPECT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin));
typedef internal::IgnoredValue Unused;
+// Deprecated single-argument DoAll.
+template <typename Action>
+GMOCK_DEPRECATE_AND_INLINE()
+typename std::decay<Action>::type DoAll(Action&& action) {
+ return std::forward<Action>(action);
+}
+
// Creates an action that does actions a1, a2, ..., sequentially in
// each invocation. All but the last action will have a readonly view of the
// arguments.
@@ -2035,6 +2042,7 @@ PolymorphicAction<internal::SetErrnoAndReturnAction<T>> SetErrnoAndReturn(
// wrapper objects.
// This function exists for backwards compatibility.
template <typename FunctionImpl>
+GMOCK_DEPRECATE_AND_INLINE()
typename std::decay<FunctionImpl>::type Invoke(FunctionImpl&& function_impl) {
return std::forward<FunctionImpl>(function_impl);
}
diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h
index 402dd69..236d3e5 100644
--- a/googlemock/include/gmock/gmock-matchers.h
+++ b/googlemock/include/gmock/gmock-matchers.h
@@ -258,7 +258,6 @@
#include <algorithm>
#include <cmath>
#include <cstddef>
-#include <exception>
#include <functional>
#include <initializer_list>
#include <ios>
@@ -268,12 +267,12 @@
#include <ostream> // NOLINT
#include <sstream>
#include <string>
+#include <tuple>
#include <type_traits>
#include <utility>
#include <vector>
#include "gmock/internal/gmock-internal-utils.h"
-#include "gmock/internal/gmock-port.h"
#include "gmock/internal/gmock-pp.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
// 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,
std::false_type /* convertible_to_matcher */,
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
@@ -391,11 +395,11 @@ class MatcherCastImpl {
// 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
// (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,
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
@@ -1312,6 +1316,15 @@ class AllOfMatcherImpl : public MatcherInterface<const T&> {
bool MatchAndExplain(const T& x,
MatchResultListener* listener) const override {
+ if (!listener->IsInterested()) {
+ // Fast path to avoid unnecessary formatting.
+ for (const Matcher<T>& matcher : matchers_) {
+ if (!matcher.Matches(x)) {
+ return false;
+ }
+ }
+ return true;
+ }
// This method uses matcher's explanation when explaining the result.
// However, if matcher doesn't provide one, this method uses matcher's
// description.
@@ -1431,6 +1444,15 @@ class AnyOfMatcherImpl : public MatcherInterface<const T&> {
bool MatchAndExplain(const T& x,
MatchResultListener* listener) const override {
+ if (!listener->IsInterested()) {
+ // Fast path to avoid unnecessary formatting of match explanations.
+ for (const Matcher<T>& matcher : matchers_) {
+ if (matcher.Matches(x)) {
+ return true;
+ }
+ }
+ return false;
+ }
// This method uses matcher's explanation when explaining the result.
// However, if matcher doesn't provide one, this method uses matcher's
// description.
@@ -3415,6 +3437,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,
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)
template <size_t I, typename T>
@@ -4118,6 +4169,10 @@ class OptionalMatcher {
return false;
}
const ValueType& value = *optional;
+ if (!listener->IsInterested()) {
+ // Fast path to avoid unnecessary generation of match explanation.
+ return value_matcher_.Matches(value);
+ }
StringMatchResultListener value_listener;
const bool match = value_matcher_.MatchAndExplain(value, &value_listener);
*listener << "whose value " << PrintToString(value)
@@ -4453,13 +4508,6 @@ inline Matcher<T> An() {
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.
inline PolymorphicMatcher<internal::IsNullMatcher> IsNull() {
return MakePolymorphicMatcher(internal::IsNullMatcher());
diff --git a/googlemock/include/gmock/internal/gmock-port.h b/googlemock/include/gmock/internal/gmock-port.h
index 42d36d2..c23b69d 100644
--- a/googlemock/include/gmock/internal/gmock-port.h
+++ b/googlemock/include/gmock/internal/gmock-port.h
@@ -57,10 +57,19 @@
#include "gmock/internal/custom/gmock-port.h"
#include "gtest/internal/gtest-port.h"
-#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
+#if defined(GTEST_HAS_ABSL)
+#include "absl/base/macros.h"
+
+#define GMOCK_DEPRECATE_AND_INLINE() ABSL_DEPRECATE_AND_INLINE()
+
+#if !defined(GTEST_NO_ABSL_FLAGS)
#include "absl/flags/declare.h"
#include "absl/flags/flag.h"
-#endif
+#endif // !defined(GTEST_NO_ABSL_FLAGS)
+
+#else // defined(GTEST_HAS_ABSL)
+#define GMOCK_DEPRECATE_AND_INLINE()
+#endif // defined(GTEST_HAS_ABSL)
// For MS Visual C++, check the compiler version. At least VS 2015 is
// required to compile Google Mock.
diff --git a/googlemock/src/gmock-spec-builders.cc b/googlemock/src/gmock-spec-builders.cc
index ffdf03d..b681fee 100644
--- a/googlemock/src/gmock-spec-builders.cc
+++ b/googlemock/src/gmock-spec-builders.cc
@@ -293,7 +293,7 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg) {
Log(kWarning,
msg +
"\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. "
"See "
"https://github.com/google/googletest/blob/main/docs/"
diff --git a/googlemock/test/gmock-actions_test.cc b/googlemock/test/gmock-actions_test.cc
index 46b0e91..9751705 100644
--- a/googlemock/test/gmock-actions_test.cc
+++ b/googlemock/test/gmock-actions_test.cc
@@ -188,7 +188,7 @@ TEST(TypeTraits, IsInvocableRV) {
struct C {
int operator()() const { return 0; }
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.
@@ -1030,8 +1030,7 @@ void VoidFunc(bool /* flag */) {}
TEST(DoDefaultDeathTest, DiesIfUsedInCompositeAction) {
MockClass mock;
- EXPECT_CALL(mock, IntFunc(_))
- .WillRepeatedly(DoAll(Invoke(VoidFunc), DoDefault()));
+ EXPECT_CALL(mock, IntFunc(_)).WillRepeatedly(DoAll(VoidFunc, DoDefault()));
// Ideally we should verify the error message as well. Sadly,
// EXPECT_DEATH() can only capture stderr, while Google Mock's
@@ -1282,7 +1281,7 @@ int ReturnOne() {
TEST(IgnoreResultTest, MonomorphicAction) {
g_done = false;
- Action<void()> a = IgnoreResult(Invoke(ReturnOne));
+ Action<void()> a = IgnoreResult(&ReturnOne);
a.Perform(std::make_tuple());
EXPECT_TRUE(g_done);
}
@@ -1297,7 +1296,7 @@ MyNonDefaultConstructible ReturnMyNonDefaultConstructible(double /* x */) {
TEST(IgnoreResultTest, ActionReturningClass) {
g_done = false;
Action<void(int)> a =
- IgnoreResult(Invoke(ReturnMyNonDefaultConstructible)); // NOLINT
+ IgnoreResult(&ReturnMyNonDefaultConstructible); // NOLINT
a.Perform(std::make_tuple(2));
EXPECT_TRUE(g_done);
}
@@ -1477,12 +1476,15 @@ TEST(DoAll, SupportsTypeErasedActions) {
}
}
-// A DoAll action should be convertible to a OnceAction, even when its component
-// sub-actions are user-provided types that define only an Action conversion
-// operator. If they supposed being called more than once then they also support
-// being called at most once.
+// A multi-action DoAll action should be convertible to a OnceAction, even when
+// its component sub-actions are user-provided types that define only an Action
+// conversion operator. If they supposed being called more than once then they
+// 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) {
- // Simplest case: only one sub-action.
+ // Final action.
struct CustomFinal final {
operator Action<int()>() { // NOLINT
return Return(17);
@@ -1493,17 +1495,7 @@ TEST(DoAll, ConvertibleToOnceActionWithUserProvidedActionConversion) {
}
};
- {
- 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.
+ // Sub-actions.
struct CustomInitial final {
operator Action<void()>() { // NOLINT
return [] {};
@@ -1527,7 +1519,7 @@ TEST(DoAll, ConvertibleToOnceActionWithUserProvidedActionConversion) {
// Tests using WithArgs and with an action that takes 1 argument.
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_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.
TEST(WithArgsTest, TwoArgs) {
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";
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.
TEST(WithArgsTest, TenArgs) {
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",
a.Perform(std::make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
CharPtr("3"))));
@@ -1576,21 +1568,21 @@ TEST(WithArgsTest, NonInvokeAction) {
// Tests using WithArgs to pass all original arguments in the original order.
TEST(WithArgsTest, Identity) {
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))));
}
// Tests using WithArgs with repeated arguments.
TEST(WithArgsTest, RepeatedArguments) {
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)));
}
// Tests using WithArgs with reversed argument order.
TEST(WithArgsTest, ReversedArgumentOrder) {
Action<const char*(short n, const char* input)> a = // NOLINT
- WithArgs<1, 0>(Invoke(Binary));
+ WithArgs<1, 0>(Binary);
const char s[] = "Hello";
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.
TEST(WithArgsTest, ArgsOfCompatibleTypes) {
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,
a.Perform(std::make_tuple(Short(100), Char(20), 5.6, Char(3))));
}
// Tests using WithArgs with an action that returns void.
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;
a.Perform(std::make_tuple(1.5, 'a', 3));
EXPECT_TRUE(g_done);
@@ -1872,9 +1864,8 @@ TEST(MockMethodTest, CanReturnMoveOnlyValue_Invoke) {
[] { return std::make_unique<int>(42); });
EXPECT_EQ(42, *mock.MakeUnique());
- EXPECT_CALL(mock, MakeUnique()).WillRepeatedly(Invoke(UniquePtrSource));
- EXPECT_CALL(mock, MakeVectorUnique())
- .WillRepeatedly(Invoke(VectorUniquePtrSource));
+ EXPECT_CALL(mock, MakeUnique()).WillRepeatedly(UniquePtrSource);
+ EXPECT_CALL(mock, MakeVectorUnique()).WillRepeatedly(VectorUniquePtrSource);
std::unique_ptr<int> result1 = mock.MakeUnique();
EXPECT_EQ(19, *result1);
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.
// EXPECT_CALL(mock, TakeUnique(_, _))
- // .WillRepeatedly(DoAll(Invoke([](std::unique_ptr<int> j) {}),
+ // .WillRepeatedly(DoAll([](std::unique_ptr<int> j) {})),
// Return(1)));
EXPECT_CALL(mock, TakeUnique(testing::Pointee(7)))
.WillOnce(Return(-7))
diff --git a/googlemock/test/gmock-function-mocker_test.cc b/googlemock/test/gmock-function-mocker_test.cc
index cdac79b..c3719f9 100644
--- a/googlemock/test/gmock-function-mocker_test.cc
+++ b/googlemock/test/gmock-function-mocker_test.cc
@@ -91,7 +91,7 @@ class FooInterface {
virtual bool TakesNonConstReference(int& n) = 0; // NOLINT
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(int n) = 0;
diff --git a/googlemock/test/gmock-matchers-comparisons_test.cc b/googlemock/test/gmock-matchers-comparisons_test.cc
index a331aec..413c2bb 100644
--- a/googlemock/test/gmock-matchers-comparisons_test.cc
+++ b/googlemock/test/gmock-matchers-comparisons_test.cc
@@ -33,6 +33,7 @@
#include <functional>
#include <memory>
+#include <optional>
#include <string>
#include <tuple>
#include <vector>
@@ -621,15 +622,42 @@ struct IntReferenceWrapper {
const int* value;
};
+// Compared the contained values
bool operator==(const IntReferenceWrapper& a, const IntReferenceWrapper& b) {
- return a.value == b.value;
+ return *a.value == *b.value;
}
-TEST(MatcherCastTest, ValueIsNotCopied) {
- int n = 42;
- Matcher<IntReferenceWrapper> m = MatcherCast<IntReferenceWrapper>(n);
- // Verify that the matcher holds a reference to n, not to its temporary copy.
- EXPECT_TRUE(m.Matches(n));
+TEST(MatcherCastTest, ValueIsCopied) {
+ {
+ // When an IntReferenceWrapper is passed.
+ int n = 42;
+ 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 {
@@ -2396,6 +2424,74 @@ TEST(ExplainMatchResultTest, AllOf_True_True_2) {
EXPECT_EQ("is >= 2, and is <= 3", Explain(m, 2));
}
+// A matcher that records whether the listener was interested.
+template <typename T>
+class CountingMatcher : public MatcherInterface<T> {
+ public:
+ explicit CountingMatcher(const Matcher<T>& base_matcher,
+ std::vector<bool>* listener_interested)
+ : base_matcher_(base_matcher),
+ listener_interested_(listener_interested) {}
+
+ bool MatchAndExplain(T x, MatchResultListener* listener) const override {
+ listener_interested_->push_back(listener->IsInterested());
+ return base_matcher_.MatchAndExplain(x, listener);
+ }
+
+ void DescribeTo(ostream* os) const override { base_matcher_.DescribeTo(os); }
+
+ private:
+ Matcher<T> base_matcher_;
+ std::vector<bool>* listener_interested_;
+};
+
+TEST(AllOfTest, DoesNotFormatChildMatchersWhenNotInterested) {
+ std::vector<bool> listener_interested;
+ Matcher<int> matcher =
+ MakeMatcher(new CountingMatcher<int>(Eq(1), &listener_interested));
+ EXPECT_TRUE(matcher.Matches(1));
+ EXPECT_THAT(listener_interested, ElementsAre(false));
+ listener_interested.clear();
+ Matcher<int> all_of_matcher = AllOf(matcher, matcher);
+ EXPECT_TRUE(all_of_matcher.Matches(1));
+ EXPECT_THAT(listener_interested, ElementsAre(false, false));
+ listener_interested.clear();
+ EXPECT_FALSE(all_of_matcher.Matches(0));
+ EXPECT_THAT(listener_interested, ElementsAre(false));
+}
+
+TEST(AnyOfTest, DoesNotFormatChildMatchersWhenNotInterested) {
+ std::vector<bool> listener_interested;
+ Matcher<int> matcher =
+ MakeMatcher(new CountingMatcher<int>(Eq(1), &listener_interested));
+ EXPECT_TRUE(matcher.Matches(1));
+ EXPECT_THAT(listener_interested, ElementsAre(false));
+ listener_interested.clear();
+ Matcher<int> any_of_matcher = AnyOf(matcher, matcher);
+ EXPECT_TRUE(any_of_matcher.Matches(1));
+ EXPECT_THAT(listener_interested, ElementsAre(false));
+ listener_interested.clear();
+ EXPECT_FALSE(any_of_matcher.Matches(0));
+ EXPECT_THAT(listener_interested, ElementsAre(false, false));
+}
+
+TEST(OptionalTest, DoesNotFormatChildMatcherWhenNotInterested) {
+ std::vector<bool> listener_interested;
+ Matcher<int> matcher =
+ MakeMatcher(new CountingMatcher<int>(Eq(1), &listener_interested));
+ EXPECT_TRUE(matcher.Matches(1));
+ EXPECT_THAT(listener_interested, ElementsAre(false));
+ listener_interested.clear();
+ Matcher<std::optional<int>> optional_matcher = Optional(matcher);
+ EXPECT_FALSE(optional_matcher.Matches(std::nullopt));
+ EXPECT_THAT(listener_interested, ElementsAre());
+ EXPECT_TRUE(optional_matcher.Matches(1));
+ EXPECT_THAT(listener_interested, ElementsAre(false));
+ listener_interested.clear();
+ EXPECT_FALSE(matcher.Matches(0));
+ EXPECT_THAT(listener_interested, ElementsAre(false));
+}
+
INSTANTIATE_GTEST_MATCHER_TEST_P(ExplainmatcherResultTest);
TEST_P(ExplainmatcherResultTestP, MonomorphicMatcher) {
diff --git a/googlemock/test/gmock-more-actions_test.cc b/googlemock/test/gmock-more-actions_test.cc
index 5b8b566..7c44eb0 100644
--- a/googlemock/test/gmock-more-actions_test.cc
+++ b/googlemock/test/gmock-more-actions_test.cc
@@ -202,45 +202,45 @@ class Foo {
// Tests using Invoke() with a nullary function.
TEST(InvokeTest, Nullary) {
- Action<int()> a = Invoke(Nullary); // NOLINT
+ Action<int()> a = &Nullary;
EXPECT_EQ(1, a.Perform(std::make_tuple()));
}
// Tests using Invoke() with a unary function.
TEST(InvokeTest, Unary) {
- Action<bool(int)> a = Invoke(Unary); // NOLINT
+ Action<bool(int)> a = &Unary;
EXPECT_FALSE(a.Perform(std::make_tuple(1)));
EXPECT_TRUE(a.Perform(std::make_tuple(-1)));
}
// Tests using Invoke() with a binary function.
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";
EXPECT_EQ(p + 2, a.Perform(std::make_tuple(p, Short(2))));
}
// Tests using Invoke() with a ternary function.
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))));
}
// Tests using Invoke() with a 4-argument function.
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)));
}
// Tests using Invoke() with a 5-argument function.
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)));
}
// Tests using Invoke() with a 6-argument function.
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,
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) {
Action<std::string(const char*, const char*, const char*, const char*,
const char*, const char*, const char*)>
- a = Invoke(Concat7);
+ a = &Concat7;
EXPECT_EQ("1234567",
a.Perform(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
CharPtr("4"), CharPtr("5"), CharPtr("6"),
@@ -264,7 +264,7 @@ TEST(InvokeTest, FunctionThatTakes7Arguments) {
TEST(InvokeTest, FunctionThatTakes8Arguments) {
Action<std::string(const char*, const char*, const char*, const char*,
const char*, const char*, const char*, const char*)>
- a = Invoke(Concat8);
+ a = &Concat8;
EXPECT_EQ("12345678",
a.Perform(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
CharPtr("4"), CharPtr("5"), CharPtr("6"),
@@ -276,7 +276,7 @@ TEST(InvokeTest, FunctionThatTakes9Arguments) {
Action<std::string(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(
CharPtr("1"), CharPtr("2"), CharPtr("3"),
CharPtr("4"), CharPtr("5"), CharPtr("6"),
@@ -288,7 +288,7 @@ TEST(InvokeTest, FunctionThatTakes10Arguments) {
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(Concat10);
+ a = &Concat10;
EXPECT_EQ("1234567890",
a.Perform(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
CharPtr("4"), CharPtr("5"), CharPtr("6"),
@@ -298,12 +298,12 @@ TEST(InvokeTest, FunctionThatTakes10Arguments) {
// Tests using Invoke() with functions with parameters declared as Unused.
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::make_tuple(10, 2, 5.6, std::string("hi"));
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(
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.
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)));
}
// Tests using Invoke(f) as an action of a compatible type.
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)));
}
@@ -447,13 +447,13 @@ TEST(InvokeMethodTest, MethodWithCompatibleType) {
// Tests using WithoutArgs with an action that takes no argument.
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)));
}
// Tests using WithArg with an action that takes 1 argument.
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_FALSE(b.Perform(std::make_tuple(1.5, 1)));
}
diff --git a/googlemock/test/gmock-spec-builders_test.cc b/googlemock/test/gmock-spec-builders_test.cc
index 9e68aa0..90f00c2 100644
--- a/googlemock/test/gmock-spec-builders_test.cc
+++ b/googlemock/test/gmock-spec-builders_test.cc
@@ -2045,7 +2045,7 @@ class GMockVerboseFlagTest : public VerboseFlagPreservingFixture {
NaggyMock<MockA> a;
const std::string note =
"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. "
"See "
"https://github.com/google/googletest/blob/main/docs/"
diff --git a/googlemock/test/gmock_output_test_golden.txt b/googlemock/test/gmock_output_test_golden.txt
index ca88af0..4b47f33 100644
--- a/googlemock/test/gmock_output_test_golden.txt
+++ b/googlemock/test/gmock_output_test_golden.txt
@@ -79,14 +79,14 @@ GMOCK WARNING:
Uninteresting mock function call - returning default value.
Function call: Bar2(0, 1)
Returns: false
-NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md#knowing-when-to-expect-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
[ RUN ] GMockOutputTest.UninterestingCallToVoidFunction
GMOCK WARNING:
Uninteresting mock function call - returning directly.
Function call: Bar3(0, 1)
-NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md#knowing-when-to-expect-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
[ RUN ] GMockOutputTest.RetiredExpectation
unknown file: Failure
@@ -283,14 +283,14 @@ Uninteresting mock function call - taking default action specified at:
FILE:#:
Function call: Bar2(2, 2)
Returns: true
-NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md#knowing-when-to-expect-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:
Uninteresting mock function call - taking default action specified at:
FILE:#:
Function call: Bar2(1, 1)
Returns: false
-NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md#knowing-when-to-expect-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
[ RUN ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction
diff --git a/googletest/CMakeLists.txt b/googletest/CMakeLists.txt
index dce6a7c..2e53889 100644
--- a/googletest/CMakeLists.txt
+++ b/googletest/CMakeLists.txt
@@ -132,9 +132,6 @@ if(GTEST_HAS_ABSL)
absl::flags_reflection
absl::flags_usage
absl::strings
- absl::any
- absl::optional
- absl::variant
re2::re2
)
endif()
diff --git a/googletest/README.md b/googletest/README.md
index 5de23c5..26e48d1 100644
--- a/googletest/README.md
+++ b/googletest/README.md
@@ -25,7 +25,7 @@ When building GoogleTest as a standalone project, the typical workflow starts
with
```
-git clone https://github.com/google/googletest.git -b v1.16.0
+git clone https://github.com/google/googletest.git -b v1.17.0
cd googletest # Main directory of the cloned repository.
mkdir build # Create a directory to hold the build output.
cd build
@@ -124,9 +124,9 @@ match the project in which it is included.
#### 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
-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
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.
@@ -145,9 +145,9 @@ We list the most frequently used macros below. For a complete list, see file
### Multi-threaded Tests
GoogleTest is thread-safe where the pthread library is available. After
-`#include <gtest/gtest.h>`, you can check the
-`GTEST_IS_THREADSAFE` macro to see whether this is the case (yes if the macro is
-`#defined` to 1, no if it's undefined.).
+`#include <gtest/gtest.h>`, you can check the `GTEST_IS_THREADSAFE` macro to see
+whether this is the case (yes if the macro is `#defined` to 1, no if it's
+undefined.).
If GoogleTest doesn't correctly detect whether pthread is available in your
environment, you can force it with
diff --git a/googletest/include/gtest/gtest-matchers.h b/googletest/include/gtest/gtest-matchers.h
index 78160f0..93643db 100644
--- a/googletest/include/gtest/gtest-matchers.h
+++ b/googletest/include/gtest/gtest-matchers.h
@@ -773,6 +773,35 @@ class GeMatcher
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<
std::is_constructible<std::string, T>::value>::type>
using StringLike = T;
diff --git a/googletest/include/gtest/gtest-printers.h b/googletest/include/gtest/gtest-printers.h
index 198a769..048c32d 100644
--- a/googletest/include/gtest/gtest-printers.h
+++ b/googletest/include/gtest/gtest-printers.h
@@ -104,15 +104,19 @@
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
+#include <any>
#include <functional>
#include <memory>
+#include <optional>
#include <ostream> // NOLINT
#include <sstream>
#include <string>
+#include <string_view>
#include <tuple>
#include <type_traits>
#include <typeinfo>
#include <utility>
+#include <variant>
#include <vector>
#ifdef GTEST_HAS_ABSL
@@ -245,8 +249,8 @@ struct StreamPrinter {
// ADL (possibly involving implicit conversions).
// (Use SFINAE via return type, because it seems GCC < 12 doesn't handle name
// lookup properly when we do it in the template parameter list.)
- static auto PrintValue(const T& value,
- ::std::ostream* os) -> decltype((void)(*os << value)) {
+ static auto PrintValue(const T& value, ::std::ostream* os)
+ -> decltype((void)(*os << value)) {
// Call streaming operator found by ADL, possibly with implicit conversions
// of the arguments.
*os << value;
@@ -521,11 +525,15 @@ GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os);
GTEST_API_ void PrintTo(char32_t c, ::std::ostream* os);
inline void PrintTo(char16_t c, ::std::ostream* os) {
- PrintTo(ImplicitCast_<char32_t>(c), os);
+ // 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
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
@@ -695,44 +703,63 @@ void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {
}
}
-// Overloads for ::std::string.
-GTEST_API_ void PrintStringTo(const ::std::string& s, ::std::ostream* os);
+// Overloads for ::std::string and ::std::string_view
+GTEST_API_ void PrintStringTo(::std::string_view s, ::std::ostream* os);
inline void PrintTo(const ::std::string& s, ::std::ostream* 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
-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) {
PrintU8StringTo(s, os);
}
+inline void PrintTo(::std::u8string_view s, ::std::ostream* os) {
+ PrintU8StringTo(s, os);
+}
#endif
-// Overloads for ::std::u16string
-GTEST_API_ void PrintU16StringTo(const ::std::u16string& s, ::std::ostream* os);
+// Overloads for ::std::u16string and ::std::u16string_view
+GTEST_API_ void PrintU16StringTo(::std::u16string_view s, ::std::ostream* os);
inline void PrintTo(const ::std::u16string& s, ::std::ostream* os) {
PrintU16StringTo(s, os);
}
+inline void PrintTo(::std::u16string_view s, ::std::ostream* os) {
+ PrintU16StringTo(s, os);
+}
-// Overloads for ::std::u32string
-GTEST_API_ void PrintU32StringTo(const ::std::u32string& s, ::std::ostream* os);
+// Overloads for ::std::u32string and ::std::u32string_view
+GTEST_API_ void PrintU32StringTo(::std::u32string_view s, ::std::ostream* os);
inline void PrintTo(const ::std::u32string& s, ::std::ostream* 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
-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) {
PrintWideStringTo(s, os);
}
+inline void PrintTo(::std::wstring_view s, ::std::ostream* os) {
+ PrintWideStringTo(s, os);
+}
#endif // GTEST_HAS_STD_WSTRING
#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) {
- PrintTo(::std::string(sp), os);
+ PrintStringTo(sp, os);
}
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
@@ -890,14 +917,11 @@ class UniversalPrinter {
template <typename T>
class UniversalPrinter<const T> : public UniversalPrinter<T> {};
-#if GTEST_INTERNAL_HAS_ANY
-
-// Printer for std::any / absl::any
-
+// Printer for std::any
template <>
-class UniversalPrinter<Any> {
+class UniversalPrinter<std::any> {
public:
- static void Print(const Any& value, ::std::ostream* os) {
+ static void Print(const std::any& value, ::std::ostream* os) {
if (value.has_value()) {
*os << "value of type " << GetTypeName(value);
} else {
@@ -906,7 +930,7 @@ class UniversalPrinter<Any> {
}
private:
- static std::string GetTypeName(const Any& value) {
+ static std::string GetTypeName(const std::any& value) {
#if GTEST_HAS_RTTI
return internal::GetTypeName(value.type());
#else
@@ -916,16 +940,11 @@ class UniversalPrinter<Any> {
}
};
-#endif // GTEST_INTERNAL_HAS_ANY
-
-#if GTEST_INTERNAL_HAS_OPTIONAL
-
-// Printer for std::optional / absl::optional
-
+// Printer for std::optional
template <typename T>
-class UniversalPrinter<Optional<T>> {
+class UniversalPrinter<std::optional<T>> {
public:
- static void Print(const Optional<T>& value, ::std::ostream* os) {
+ static void Print(const std::optional<T>& value, ::std::ostream* os) {
*os << '(';
if (!value) {
*os << "nullopt";
@@ -937,29 +956,18 @@ class UniversalPrinter<Optional<T>> {
};
template <>
-class UniversalPrinter<decltype(Nullopt())> {
+class UniversalPrinter<std::nullopt_t> {
public:
- static void Print(decltype(Nullopt()), ::std::ostream* os) {
- *os << "(nullopt)";
- }
+ static void Print(std::nullopt_t, ::std::ostream* os) { *os << "(nullopt)"; }
};
-#endif // GTEST_INTERNAL_HAS_OPTIONAL
-
-#if GTEST_INTERNAL_HAS_VARIANT
-
-// Printer for std::variant / absl::variant
-
+// Printer for std::variant
template <typename... T>
-class UniversalPrinter<Variant<T...>> {
+class UniversalPrinter<std::variant<T...>> {
public:
- static void Print(const Variant<T...>& value, ::std::ostream* os) {
+ static void Print(const std::variant<T...>& value, ::std::ostream* os) {
*os << '(';
-#ifdef GTEST_HAS_ABSL
- absl::visit(Visitor{os, value.index()}, value);
-#else
std::visit(Visitor{os, value.index()}, value);
-#endif // GTEST_HAS_ABSL
*os << ')';
}
@@ -976,8 +984,6 @@ class UniversalPrinter<Variant<T...>> {
};
};
-#endif // GTEST_INTERNAL_HAS_VARIANT
-
// UniversalPrintArray(begin, len, os) prints an array of 'len'
// elements, starting at address 'begin'.
template <typename T>
diff --git a/googletest/include/gtest/gtest-typed-test.h b/googletest/include/gtest/gtest-typed-test.h
index 442e00b..ae24f94 100644
--- a/googletest/include/gtest/gtest-typed-test.h
+++ b/googletest/include/gtest/gtest-typed-test.h
@@ -48,15 +48,15 @@ template <typename T>
class FooTest : public testing::Test {
public:
...
- typedef std::list<T> List;
+ using List = ::std::list<T>;
static T shared_;
T value_;
};
// 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.
-typedef testing::Types<char, int, unsigned int> MyTypes;
+using MyTypes = ::testing::Types<char, int, unsigned int>;
TYPED_TEST_SUITE(FooTest, MyTypes);
// 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
// to the actual test suite name. Remember to pick unique prefixes for
// 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);
// If the type list contains only one type, you can write that type
diff --git a/googletest/include/gtest/gtest.h b/googletest/include/gtest/gtest.h
index 7be0caa..69994ee 100644
--- a/googletest/include/gtest/gtest.h
+++ b/googletest/include/gtest/gtest.h
@@ -1610,6 +1610,8 @@ GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1,
double val1, double val2,
double abs_error);
+using GoogleTest_NotSupported_OnFunctionReturningNonVoid = void;
+
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
// A class that enables one to stream messages to assertion macros
class GTEST_API_ AssertHelper {
@@ -1621,7 +1623,8 @@ class GTEST_API_ AssertHelper {
// Message assignment is a semantic trick to enable assertion
// streaming; see the GTEST_MESSAGE_ macro below.
- void operator=(const Message& message) const;
+ GoogleTest_NotSupported_OnFunctionReturningNonVoid operator=(
+ const Message& message) const;
private:
// 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
// constructor.
- static const ParamType& GetParam() {
+ [[nodiscard]] static const ParamType& GetParam() {
GTEST_CHECK_(parameter_ != nullptr)
<< "GetParam() can only be called inside a value-parameterized test "
<< "-- did you intend to write TEST_P instead of TEST_F?";
diff --git a/googletest/include/gtest/internal/gtest-internal.h b/googletest/include/gtest/internal/gtest-internal.h
index 9ee0eca..808d89b 100644
--- a/googletest/include/gtest/internal/gtest-internal.h
+++ b/googletest/include/gtest/internal/gtest-internal.h
@@ -290,17 +290,17 @@ class FloatingPoint {
// around may change its bits, although the new value is guaranteed
// to be also a NAN. Therefore, don't expect this constructor to
// preserve the bits in x when x is a NAN.
- explicit FloatingPoint(const RawType& x) { u_.value_ = x; }
+ explicit FloatingPoint(RawType x) { memcpy(&bits_, &x, sizeof(x)); }
// Static methods
// Reinterprets a bit pattern as a floating-point number.
//
// This function is needed to test the AlmostEquals() method.
- static RawType ReinterpretBits(const Bits bits) {
- FloatingPoint fp(0);
- fp.u_.bits_ = bits;
- return fp.u_.value_;
+ static RawType ReinterpretBits(Bits bits) {
+ RawType fp;
+ memcpy(&fp, &bits, sizeof(fp));
+ return fp;
}
// Returns the floating-point number that represent positive infinity.
@@ -309,16 +309,16 @@ class FloatingPoint {
// Non-static methods
// Returns the bits that represents this number.
- const Bits& bits() const { return u_.bits_; }
+ const Bits& bits() const { return bits_; }
// Returns the exponent bits of this number.
- Bits exponent_bits() const { return kExponentBitMask & u_.bits_; }
+ Bits exponent_bits() const { return kExponentBitMask & bits_; }
// Returns the fraction bits of this number.
- Bits fraction_bits() const { return kFractionBitMask & u_.bits_; }
+ Bits fraction_bits() const { return kFractionBitMask & bits_; }
// Returns the sign bit of this number.
- Bits sign_bit() const { return kSignBitMask & u_.bits_; }
+ Bits sign_bit() const { return kSignBitMask & bits_; }
// Returns true if and only if this is NAN (not a number).
bool is_nan() const {
@@ -338,17 +338,10 @@ class FloatingPoint {
// a NAN must return false.
if (is_nan() || rhs.is_nan()) return false;
- return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) <=
- kMaxUlps;
+ return DistanceBetweenSignAndMagnitudeNumbers(bits_, rhs.bits_) <= kMaxUlps;
}
private:
- // The data type used to store the actual floating-point number.
- union FloatingPointUnion {
- RawType value_; // The raw floating-point number.
- Bits bits_; // The bits that represent the number.
- };
-
// Converts an integer from the sign-and-magnitude representation to
// the biased representation. More precisely, let N be 2 to the
// power of (kBitCount - 1), an integer x is represented by the
@@ -364,7 +357,7 @@ class FloatingPoint {
//
// Read https://en.wikipedia.org/wiki/Signed_number_representations
// for more details on signed number representations.
- static Bits SignAndMagnitudeToBiased(const Bits& sam) {
+ static Bits SignAndMagnitudeToBiased(Bits sam) {
if (kSignBitMask & sam) {
// sam represents a negative number.
return ~sam + 1;
@@ -376,14 +369,13 @@ class FloatingPoint {
// Given two numbers in the sign-and-magnitude representation,
// returns the distance between them as an unsigned number.
- static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits& sam1,
- const Bits& sam2) {
+ static Bits DistanceBetweenSignAndMagnitudeNumbers(Bits sam1, Bits sam2) {
const Bits biased1 = SignAndMagnitudeToBiased(sam1);
const Bits biased2 = SignAndMagnitudeToBiased(sam2);
return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
}
- FloatingPointUnion u_;
+ Bits bits_; // The bits that represent the number.
};
// Typedefs the instances of the FloatingPoint template class that we
diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h
index 4cfc16c..06a5a8e 100644
--- a/googletest/include/gtest/internal/gtest-port.h
+++ b/googletest/include/gtest/internal/gtest-port.h
@@ -198,21 +198,8 @@
// suppressed (constant conditional).
// GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127
// 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>
// 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_HAS_CXXABI_H_ - Always defined to 0 or 1.
// GTEST_CAN_STREAM_RESULTS_ - Always defined to 0 or 1.
@@ -282,10 +269,14 @@
// Detect C++ feature test macros as gracefully as possible.
// MSVC >= 19.15, Clang >= 3.4.1, and GCC >= 4.1.2 support feature test macros.
-#if GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L && \
- (!defined(__has_include) || GTEST_INTERNAL_HAS_INCLUDE(<version>))
-#include <version> // C++20 and later
-#elif (!defined(__has_include) || GTEST_INTERNAL_HAS_INCLUDE(<ciso646>))
+//
+// GCC15 warns that <ciso646> is deprecated in C++17 and suggests using
+// <version> instead, even though <version> is not available in C++17 mode prior
+// to GCC9.
+#if GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L || \
+ GTEST_INTERNAL_HAS_INCLUDE(<version>)
+#include <version> // C++20 or <version> support.
+#else
#include <ciso646> // Pre-C++20
#endif
@@ -2331,73 +2322,6 @@ const char* StringFromGTestEnv(const char* flag, const char* default_val);
} // namespace internal
} // namespace testing
-#ifdef GTEST_HAS_ABSL
-// Always use absl::any for UniversalPrinter<> specializations if googletest
-// is built with absl support.
-#define GTEST_INTERNAL_HAS_ANY 1
-#include "absl/types/any.h"
-namespace testing {
-namespace internal {
-using Any = ::absl::any;
-} // namespace internal
-} // namespace testing
-#else
-#if defined(__cpp_lib_any) || (GTEST_INTERNAL_HAS_INCLUDE(<any>) && \
- 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
-
#if defined(__cpp_lib_span) || (GTEST_INTERNAL_HAS_INCLUDE(<span>) && \
GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L)
#define GTEST_INTERNAL_HAS_STD_SPAN 1
@@ -2439,38 +2363,6 @@ using StringView = ::std::string_view;
#define GTEST_INTERNAL_HAS_STRING_VIEW 0
#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) || \
(GTEST_INTERNAL_HAS_INCLUDE(<compare>) && \
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201907L))
diff --git a/googletest/src/gtest-printers.cc b/googletest/src/gtest-printers.cc
index e3acecb..f655730 100644
--- a/googletest/src/gtest-printers.cc
+++ b/googletest/src/gtest-printers.cc
@@ -50,7 +50,7 @@
#include <iomanip>
#include <ios>
#include <ostream> // NOLINT
-#include <string>
+#include <string_view>
#include <type_traits>
#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
// char, char8_t, char16_t, char32_t, or wchar_t.
-// The array starts at begin, the length is len, it may include '\0' characters
-// and may not be NUL-terminated.
+// The array starts at begin (which may be nullptr) and contains len characters.
+// The array may include '\0' characters and may not be NUL-terminated.
template <typename CharType>
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static CharFormat
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 << "\"";
bool is_previous_hex = false;
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) {
if (!ContainsUnprintableControlCodes(str, length) &&
IsValidUTF8(str, length)) {
- *os << "\n As Text: \"" << str << "\"";
+ *os << "\n As Text: \"" << ::std::string_view(str, length) << "\"";
}
}
} // 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 (GTEST_FLAG_GET(print_utf8)) {
ConditionalPrintAsText(s.data(), s.size(), os);
@@ -531,21 +531,21 @@ void PrintStringTo(const ::std::string& s, ostream* os) {
}
#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);
}
#endif
-void PrintU16StringTo(const ::std::u16string& s, ostream* os) {
+void PrintU16StringTo(::std::u16string_view s, ostream* 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);
}
#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);
}
#endif // GTEST_HAS_STD_WSTRING
diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc
index 09af151..cd218c9 100644
--- a/googletest/src/gtest.cc
+++ b/googletest/src/gtest.cc
@@ -270,6 +270,13 @@ GTEST_DEFINE_bool_(
"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_(
also_run_disabled_tests,
testing::internal::BoolFromGTestEnv("also_run_disabled_tests", false),
"Run disabled tests too, in addition to the tests normally being run.");
@@ -706,7 +713,7 @@ std::string UnitTestOptions::GetAbsolutePathToOutputFile() {
const char* const gtest_output_flag = s.c_str();
std::string format = GetOutputFormat();
- if (format.empty()) format = std::string(kDefaultOutputFormat);
+ if (format.empty()) format = kDefaultOutputFormat;
const char* const colon = strchr(gtest_output_flag, ':');
if (colon == nullptr)
@@ -1488,17 +1495,17 @@ class Hunk {
// Print a unified diff header for one hunk.
// The format is
// "@@ -<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 {
- *ss << "@@ ";
- if (removes_) {
- *ss << "-" << left_start_ << "," << (removes_ + common_);
+ size_t left_length = removes_ + common_;
+ size_t right_length = adds_ + common_;
+ *ss << "@@ " << "-" << left_start_;
+ if (left_length != 1) {
+ *ss << "," << left_length;
}
- if (removes_ && adds_) {
- *ss << " ";
- }
- if (adds_) {
- *ss << "+" << right_start_ << "," << (adds_ + common_);
+ *ss << " " << "+" << right_start_;
+ if (right_length != 1) {
+ *ss << "," << right_length;
}
*ss << " @@\n";
}
@@ -3298,6 +3305,7 @@ bool ShouldUseColor(bool stdout_is_tty) {
const bool term_supports_color =
term != nullptr && (String::CStringEquals(term, "xterm") ||
String::CStringEquals(term, "xterm-color") ||
+ String::CStringEquals(term, "xterm-ghostty") ||
String::CStringEquals(term, "xterm-kitty") ||
String::CStringEquals(term, "alacritty") ||
String::CStringEquals(term, "screen") ||
@@ -4347,8 +4355,8 @@ void XmlUnitTestResultPrinter::OutputXmlTestResult(::std::ostream* stream,
internal::FormatCompilerIndependentFileLocation(part.file_name(),
part.line_number());
const std::string summary = location + "\n" + part.summary();
- *stream << " <skipped message=\""
- << EscapeXmlAttribute(summary.c_str()) << "\">";
+ *stream << " <skipped message=\"" << EscapeXmlAttribute(summary)
+ << "\">";
const std::string detail = location + "\n" + part.message();
OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str());
*stream << "</skipped>\n";
@@ -6079,6 +6087,18 @@ bool UnitTestImpl::RunAllTests() {
TearDownEnvironment);
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 were selected to run. Please make sure at least one test "
+ "exists and is not disabled! If the test is sharded, you may have "
+ "defined more shards than test cases, which is wasteful. If you also "
+ "defined --gtest_filter, that filter is taken into account, so "
+ "shards with no matching test cases will hit this error. Either "
+ "disable sharding, set --gtest_fail_if_no_test_selected=false, or "
+ "remove the filter to resolve this error.";
+ ColoredPrintf(GTestColor::kRed, "%s\n", kNoTestsSelectedMessage);
+ return false;
}
elapsed_time_ = timer.Elapsed();
@@ -6763,6 +6783,7 @@ static bool ParseGoogleTestFlag(const char* const arg) {
GTEST_INTERNAL_PARSE_FLAG(death_test_use_fork);
GTEST_INTERNAL_PARSE_FLAG(fail_fast);
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(internal_run_death_test);
GTEST_INTERNAL_PARSE_FLAG(list_tests);
diff --git a/googletest/test/googletest-color-test.py b/googletest/test/googletest-color-test.py
index 8968cf1..76ca8e0 100755
--- a/googletest/test/googletest-color-test.py
+++ b/googletest/test/googletest-color-test.py
@@ -79,6 +79,7 @@ class GTestColorTest(gtest_test_utils.TestCase):
self.assertTrue(UsesColor('cygwin', None, None))
self.assertTrue(UsesColor('xterm', 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('alacritty', None, None))
self.assertTrue(UsesColor('xterm-256color', None, None))
diff --git a/googletest/test/googletest-death-test-test.cc b/googletest/test/googletest-death-test-test.cc
index 44b8046..8770315 100644
--- a/googletest/test/googletest-death-test-test.cc
+++ b/googletest/test/googletest-death-test-test.cc
@@ -291,7 +291,7 @@ TEST(ExitStatusPredicateTest, KilledBySignal) {
const int status_kill = KilledExitStatus(SIGKILL);
const testing::KilledBySignal pred_segv(SIGSEGV);
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);
#endif
EXPECT_PRED1(pred_kill, status_kill);
diff --git a/googletest/test/googletest-fail-if-no-test-linked-test.py b/googletest/test/googletest-fail-if-no-test-linked-test.py
index f5854ba..e62bfb2 100755
--- a/googletest/test/googletest-fail-if-no-test-linked-test.py
+++ b/googletest/test/googletest-fail-if-no-test-linked-test.py
@@ -80,11 +80,7 @@ class GTestFailIfNoTestLinkedTest(gtest_test_utils.TestCase):
)
)
warning_file_contents = open(warning_file, "r").read()
- self.assertEqual(
- warning_file_contents,
- "This test program does NOT link in any test case. Please make sure"
- " this is intended.\n",
- )
+ self.assertIn("does NOT link", warning_file_contents)
def testFailsIfNoTestLinkedAndFlagSpecified(self):
"""Tests the behavior of no test linked and flag specified."""
diff --git a/googletest/test/googletest-fail-if-no-test-selected-test.py b/googletest/test/googletest-fail-if-no-test-selected-test.py
new file mode 100644
index 0000000..03a324c
--- /dev/null
+++ b/googletest/test/googletest-fail-if-no-test-selected-test.py
@@ -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()
diff --git a/googletest/test/googletest-output-test-golden-lin.txt b/googletest/test/googletest-output-test-golden-lin.txt
index 533eb8c..57f7d1a 100644
--- a/googletest/test/googletest-output-test-golden-lin.txt
+++ b/googletest/test/googletest-output-test-golden-lin.txt
@@ -62,7 +62,7 @@ Expected equality of these values:
Which is: "\"Line\0 1\"\nLine 2"
"Line 2"
With diff:
-@@ -1,2 @@
+@@ -1,2 +1 @@
-\"Line\0 1\"
Line 2
diff --git a/googletest/test/googletest-param-test-test.cc b/googletest/test/googletest-param-test-test.cc
index bc13060..fab977e 100644
--- a/googletest/test/googletest-param-test-test.cc
+++ b/googletest/test/googletest-param-test-test.cc
@@ -1174,7 +1174,7 @@ TEST_P(ParameterizedDerivedTest, SeesSequence) {
class ParameterizedDeathTest : public ::testing::TestWithParam<int> {};
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,
diff --git a/googletest/test/googletest-printers-test.cc b/googletest/test/googletest-printers-test.cc
index 52b2c49..c5d9756 100644
--- a/googletest/test/googletest-printers-test.cc
+++ b/googletest/test/googletest-printers-test.cc
@@ -32,6 +32,7 @@
// This file tests the universal value printer.
#include <algorithm>
+#include <any>
#include <cctype>
#include <cstdint>
#include <cstring>
@@ -42,14 +43,17 @@
#include <list>
#include <map>
#include <memory>
+#include <optional>
#include <ostream>
#include <set>
#include <sstream>
#include <string>
+#include <string_view>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
+#include <variant>
#include <vector>
#include "gtest/gtest-printers.h"
@@ -62,7 +66,7 @@
#if GTEST_INTERNAL_HAS_STD_SPAN
#include <span> // NOLINT
-#endif // GTEST_INTERNAL_HAS_STD_SPAN
+#endif // GTEST_INTERNAL_HAS_STD_SPAN
#if GTEST_INTERNAL_HAS_COMPARE_LIB
#include <compare> // NOLINT
@@ -796,7 +800,7 @@ struct Foo {
TEST(PrintPointerTest, MemberVariablePointer) {
EXPECT_TRUE(HasPrefix(Print(&Foo::value),
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 "));
}
@@ -923,7 +927,7 @@ TEST(PrintArrayTest, BigArray) {
PrintArrayHelper(a));
}
-// Tests printing ::string and ::std::string.
+// Tests printing ::std::string and ::string_view.
// ::std::string.
TEST(PrintStringTest, StringInStdNamespace) {
@@ -933,6 +937,13 @@ TEST(PrintStringTest, StringInStdNamespace) {
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) {
// "\x6BANANA" is ambiguous, it can be interpreted as starting with either of:
// '\x6', '\x6B', or '\x6BA'.
@@ -950,7 +961,7 @@ TEST(PrintStringTest, StringAmbiguousHex) {
EXPECT_EQ("\"!\\x5-!\"", Print(::std::string("!\x5-!")));
}
-// Tests printing ::std::wstring.
+// Tests printing ::std::wstring and ::std::wstring_view.
#if GTEST_HAS_STD_WSTRING
// ::std::wstring.
TEST(PrintWideStringTest, StringInStdNamespace) {
@@ -962,6 +973,15 @@ TEST(PrintWideStringTest, StringInStdNamespace) {
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) {
// same for wide strings.
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("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
TEST(PrintStringTest, U16String) {
@@ -988,12 +1014,24 @@ TEST(PrintStringTest, U16String) {
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) {
std::u32string str = U"Hello, 🗺️";
EXPECT_EQ(str, str); // Verify EXPECT_EQ compiles with this type
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
// to std::basic_ostream<Char, CharTraits> for any valid Char and
// CharTraits types).
@@ -1453,7 +1491,7 @@ TEST(PrintReferenceTest, HandlesMemberFunctionPointer) {
// Tests that the universal printer prints a member variable pointer
// passed by reference.
TEST(PrintReferenceTest, HandlesMemberVariablePointer) {
- int Foo::*p = &Foo::value; // NOLINT
+ int Foo::* p = &Foo::value; // NOLINT
EXPECT_TRUE(HasPrefix(PrintByRef(p), "@" + PrintPointer(&p) + " " +
Print(sizeof(p)) + "-byte object "));
}
@@ -1891,6 +1929,22 @@ TEST(UniversalPrintTest, SmartPointers) {
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) {
Strings result = UniversalTersePrintTupleFieldsToStrings(::std::make_tuple());
EXPECT_EQ(0u, result.size());
@@ -1920,7 +1974,6 @@ TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTersely) {
EXPECT_EQ("\"a\"", result[1]);
}
-#if GTEST_INTERNAL_HAS_ANY
class PrintAnyTest : public ::testing::Test {
protected:
template <typename T>
@@ -1934,12 +1987,12 @@ class PrintAnyTest : public ::testing::Test {
};
TEST_F(PrintAnyTest, Empty) {
- internal::Any any;
+ std::any any;
EXPECT_EQ("no value", PrintToString(any));
}
TEST_F(PrintAnyTest, NonEmpty) {
- internal::Any any;
+ std::any any;
constexpr int val1 = 10;
const std::string val2 = "content";
@@ -1950,27 +2003,23 @@ TEST_F(PrintAnyTest, NonEmpty) {
EXPECT_EQ("value of type " + ExpectedTypeName<std::string>(),
PrintToString(any));
}
-#endif // GTEST_INTERNAL_HAS_ANY
-#if GTEST_INTERNAL_HAS_OPTIONAL
TEST(PrintOptionalTest, Basic) {
- EXPECT_EQ("(nullopt)", PrintToString(internal::Nullopt()));
- internal::Optional<int> value;
+ EXPECT_EQ("(nullopt)", PrintToString(std::nullopt));
+ std::optional<int> value;
EXPECT_EQ("(nullopt)", PrintToString(value));
value = {7};
EXPECT_EQ("(7)", PrintToString(value));
- EXPECT_EQ("(1.1)", PrintToString(internal::Optional<double>{1.1}));
- EXPECT_EQ("(\"A\")", PrintToString(internal::Optional<std::string>{"A"}));
+ EXPECT_EQ("(1.1)", PrintToString(std::optional<double>{1.1}));
+ EXPECT_EQ("(\"A\")", PrintToString(std::optional<std::string>{"A"}));
}
-#endif // GTEST_INTERNAL_HAS_OPTIONAL
-#if GTEST_INTERNAL_HAS_VARIANT
struct NonPrintable {
unsigned char contents = 17;
};
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("('StreamableInGlobal(index = 1)' with value StreamableInGlobal)",
PrintToString(Type(StreamableInGlobal{})));
@@ -1979,7 +2028,6 @@ TEST(PrintOneofTest, Basic) {
"1-byte object <11>)",
PrintToString(Type(NonPrintable{})));
}
-#endif // GTEST_INTERNAL_HAS_VARIANT
#if GTEST_INTERNAL_HAS_COMPARE_LIB
TEST(PrintOrderingTest, Basic) {
diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc
index 559d34c..a31b7ba 100644
--- a/googletest/test/gtest_unittest.cc
+++ b/googletest/test/gtest_unittest.cc
@@ -3579,13 +3579,13 @@ TEST(EditDistance, TestSuites) {
{__LINE__, "A", "A", " ", ""},
{__LINE__, "ABCDE", "ABCDE", " ", ""},
// Simple adds.
- {__LINE__, "X", "XA", " +", "@@ +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", "XA", " +", "@@ -1 +1,2 @@\n X\n+A\n"},
+ {__LINE__, "X", "XABCD", " ++++", "@@ -1 +1,5 @@\n X\n+A\n+B\n+C\n+D\n"},
// Simple removes.
- {__LINE__, "XA", "X", " -", "@@ -1,2 @@\n X\n-A\n"},
- {__LINE__, "XABCD", "X", " ----", "@@ -1,5 @@\n X\n-A\n-B\n-C\n-D\n"},
+ {__LINE__, "XA", "X", " -", "@@ -1,2 +1 @@\n X\n-A\n"},
+ {__LINE__, "XABCD", "X", " ----", "@@ -1,5 +1 @@\n X\n-A\n-B\n-C\n-D\n"},
// 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", "////",
"@@ -1,4 +1,4 @@\n-A\n-B\n-C\n-D\n+a\n+b\n+c\n+d\n"},
// Path finding.
@@ -6717,6 +6717,9 @@ TEST(ColoredOutputTest, UsesColorsWhenTermSupportsColors) {
SetEnv("TERM", "xterm-color"); // TERM supports colors.
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.
EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY.
diff --git a/googletest_deps.bzl b/googletest_deps.bzl
index d3dd03e..9eb7270 100644
--- a/googletest_deps.bzl
+++ b/googletest_deps.bzl
@@ -17,9 +17,9 @@ def googletest_deps():
if not native.existing_rule("abseil-cpp"):
http_archive(
name = "abseil-cpp",
- sha256 = "16242f394245627e508ec6bb296b433c90f8d914f73b9c026fddb905e27276e8",
- strip_prefix = "abseil-cpp-20250127.0",
- urls = ["https://github.com/abseil/abseil-cpp/releases/download/20250127.0/abseil-cpp-20250127.0.tar.gz"],
+ sha256 = "7262daa7c1711406248c10f41026d685e88223bc92817d16fb93c19adb57f669",
+ strip_prefix = "abseil-cpp-20250512.0",
+ urls = ["https://github.com/abseil/abseil-cpp/releases/download/20250512.0/abseil-cpp-20250512.0.tar.gz"],
)
if not native.existing_rule("fuchsia_sdk"):