mirror of
https://github.com/google/googletest.git
synced 2025-12-07 01:06:50 +08:00
Compare commits
54 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b96fa13f5 | ||
|
|
085af2cc08 | ||
|
|
37678c92fb | ||
|
|
dedab73a68 | ||
|
|
6ec14dfd8c | ||
|
|
17d335d7c7 | ||
|
|
4fe3307fb2 | ||
|
|
b2b9072ecb | ||
|
|
e17e37a115 | ||
|
|
8dbd60f7d5 | ||
|
|
2ce9d8f2e8 | ||
|
|
279f847946 | ||
|
|
de1c609262 | ||
|
|
9706f75b8f | ||
|
|
50b8600c63 | ||
|
|
0934b7e112 | ||
|
|
4969d0ad54 | ||
|
|
9df216cc9d | ||
|
|
7917641ff9 | ||
|
|
eb2d85edd0 | ||
|
|
6986c2b575 | ||
|
|
a05c091507 | ||
|
|
244cec869d | ||
|
|
373af2e3df | ||
|
|
32f9f4c82a | ||
|
|
7e17b15f15 | ||
|
|
309dab8d4b | ||
|
|
3983f67e32 | ||
|
|
c67de11737 | ||
|
|
a45468c0fc | ||
|
|
f8ed0e687c | ||
|
|
35b75a2cba | ||
|
|
175c1b55cf | ||
|
|
1aeec48a1d | ||
|
|
0fe21ac6ef | ||
|
|
fd15f51d57 | ||
|
|
6230d316e1 | ||
|
|
28e9d1f267 | ||
|
|
7e2c425db2 | ||
|
|
e9092b12dc | ||
|
|
7427a6b5e3 | ||
|
|
7da55820cc | ||
|
|
3abc68be30 | ||
|
|
09ffd00153 | ||
|
|
6aa03e6774 | ||
|
|
16d4f8eff6 | ||
|
|
bac6a8fd8a | ||
|
|
fa8438ae6b | ||
|
|
571930618f | ||
|
|
9f79a9597a | ||
|
|
8b8ef3ff0d | ||
|
|
90a4152114 | ||
|
|
04ee1b4f2a | ||
|
|
005254dae2 |
10
BUILD.bazel
10
BUILD.bazel
@ -30,6 +30,8 @@
|
||||
#
|
||||
# Bazel Build for Google C++ Testing Framework(Google Test)
|
||||
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
@ -151,10 +153,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 +163,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 +172,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
|
||||
|
||||
@ -41,7 +41,7 @@ module(
|
||||
|
||||
bazel_dep(
|
||||
name = "abseil-cpp",
|
||||
version = "20250127.1",
|
||||
version = "20250814.0",
|
||||
)
|
||||
bazel_dep(
|
||||
name = "platforms",
|
||||
@ -52,6 +52,11 @@ bazel_dep(
|
||||
version = "2024-07-02.bcr.1",
|
||||
)
|
||||
|
||||
bazel_dep(
|
||||
name = "rules_cc",
|
||||
version = "0.2.8"
|
||||
)
|
||||
|
||||
bazel_dep(
|
||||
name = "rules_python",
|
||||
version = "1.3.0",
|
||||
|
||||
19
README.md
19
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
|
||||
|
||||
|
||||
12
WORKSPACE
12
WORKSPACE
@ -45,12 +45,6 @@ http_archive(
|
||||
load("@rules_python//python:repositories.bzl", "py_repositories")
|
||||
py_repositories()
|
||||
|
||||
http_archive(
|
||||
name = "bazel_skylib",
|
||||
sha256 = "cd55a062e763b9349921f0f5db8c3933288dc8ba4f76dd9416aac68acee3cb94",
|
||||
urls = ["https://github.com/bazelbuild/bazel-skylib/releases/download/1.5.0/bazel-skylib-1.5.0.tar.gz"],
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "platforms",
|
||||
urls = [
|
||||
@ -59,3 +53,9 @@ http_archive(
|
||||
],
|
||||
sha256 = "29742e87275809b5e598dc2f04d86960cc7a55b3067d97221c9abbc9926bff0f",
|
||||
)
|
||||
|
||||
load("@bazel_features//:deps.bzl", "bazel_features_deps")
|
||||
bazel_features_deps()
|
||||
|
||||
load("@rules_cc//cc:extensions.bzl", "compatibility_proxy_repo")
|
||||
compatibility_proxy_repo()
|
||||
|
||||
@ -31,15 +31,23 @@
|
||||
|
||||
set -euox pipefail
|
||||
|
||||
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} \
|
||||
/bin/bash --login -c "
|
||||
/usr/local/bin/bazel test ... \
|
||||
--copt="-Wall" \
|
||||
--copt="-Werror" \
|
||||
--copt="-Wuninitialized" \
|
||||
--copt="-Wundef" \
|
||||
--define="absl=${absl}" \
|
||||
--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
|
||||
--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} \
|
||||
/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}" \
|
||||
--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" \
|
||||
--linkopt=\"--gcc-toolchain=/usr/local\" \
|
||||
--show_timestamps \
|
||||
--test_output=errors
|
||||
--test_output=errors \
|
||||
${BAZEL_EXTRA_ARGS:-}"
|
||||
done
|
||||
done
|
||||
|
||||
@ -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 "${HOME}/"
|
||||
BAZEL_EXTRA_ARGS="--vendor_dir=${HOME}/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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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">
|
||||
|
||||
@ -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!)
|
||||
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.
|
||||
|
||||
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.
|
||||
{: .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
|
||||
|
||||
@ -130,7 +130,7 @@ TEST(BarTest, DoesThis) {
|
||||
## Setting Default Actions {#OnCall}
|
||||
|
||||
gMock has a **built-in default action** for any function that returns `void`,
|
||||
`bool`, a numeric value, or a pointer. In C++11, it will additionally returns
|
||||
`bool`, a numeric value, or a pointer. In C++11, it additionally returns
|
||||
the default-constructed value, if one exists for the given type.
|
||||
|
||||
To customize the default action for functions with return type `T`, use
|
||||
|
||||
@ -900,15 +900,16 @@ using ::testing::Not;
|
||||
|
||||
Matchers are function objects, and parametrized matchers can be composed just
|
||||
like any other function. However because their types can be long and rarely
|
||||
provide meaningful information, it can be easier to express them with C++14
|
||||
generic lambdas to avoid specifying types. For example,
|
||||
provide meaningful information, it can be easier to express them with template
|
||||
parameters and `auto`. For example,
|
||||
|
||||
```cpp
|
||||
using ::testing::Contains;
|
||||
using ::testing::Property;
|
||||
|
||||
inline constexpr auto HasFoo = [](const auto& f) {
|
||||
return Property("foo", &MyClass::foo, Contains(f));
|
||||
template <typename SubMatcher>
|
||||
inline constexpr auto HasFoo(const SubMatcher& sub_matcher) {
|
||||
return Property("foo", &MyClass::foo, Contains(sub_matcher));
|
||||
};
|
||||
...
|
||||
EXPECT_THAT(x, HasFoo("blah"));
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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`:
|
||||
|
||||
@ -49,6 +49,7 @@ Matcher | Description
|
||||
| `NotNull()` | `argument` is a non-null pointer (raw or smart). |
|
||||
| `Optional(m)` | `argument` is `optional<>` that contains a value matching `m`. (For testing whether an `optional<>` is set, check for equality with `nullopt`. You may need to use `Eq(nullopt)` if the inner type doesn't have `==`.)|
|
||||
| `VariantWith<T>(m)` | `argument` is `variant<>` that holds the alternative of type T with a value matching `m`. |
|
||||
| `AnyWith<T>(m)` | `argument` is `any<>` that holds a value of type T with a value matching `m`. |
|
||||
| `Ref(variable)` | `argument` is a reference to `variable`. |
|
||||
| `TypedEq<type>(value)` | `argument` has type `type` and is equal to `value`. You may need to use this instead of `Eq(value)` when the mock function is overloaded. |
|
||||
|
||||
@ -111,6 +112,33 @@ use the regular expression syntax defined
|
||||
[here](../advanced.md#regular-expression-syntax). All of these matchers, except
|
||||
`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)`
|
||||
|
||||
@ -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);
|
||||
}));
|
||||
|
||||
@ -1796,11 +1796,24 @@ struct SetArrayArgumentAction {
|
||||
};
|
||||
|
||||
template <size_t k>
|
||||
struct DeleteArgAction {
|
||||
class DeleteArgAction {
|
||||
public:
|
||||
template <typename... Args>
|
||||
void operator()(const Args&... args) const {
|
||||
delete std::get<k>(std::tie(args...));
|
||||
DoDelete(std::get<k>(std::tie(args...)));
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
static void DoDelete(T* ptr) {
|
||||
delete ptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
[[deprecated(
|
||||
"DeleteArg<N> used for a non-pointer argument, it was likely migrated "
|
||||
"to a smart pointer type. This action should be removed.")]]
|
||||
static void DoDelete(T&) {}
|
||||
};
|
||||
|
||||
template <typename Ptr>
|
||||
@ -1866,6 +1879,13 @@ struct RethrowAction {
|
||||
// EXPECT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin));
|
||||
typedef internal::IgnoredValue Unused;
|
||||
|
||||
// Deprecated single-argument DoAll.
|
||||
template <typename Action>
|
||||
GTEST_INTERNAL_DEPRECATE_AND_INLINE("Avoid using DoAll() for single actions")
|
||||
typename std::decay<Action>::type DoAll(Action&& action) {
|
||||
return std::forward<Action>(action);
|
||||
}
|
||||
|
||||
// Creates an action that does actions a1, a2, ..., sequentially in
|
||||
// each invocation. All but the last action will have a readonly view of the
|
||||
// arguments.
|
||||
@ -2031,10 +2051,11 @@ PolymorphicAction<internal::SetErrnoAndReturnAction<T>> SetErrnoAndReturn(
|
||||
// Various overloads for Invoke().
|
||||
|
||||
// Legacy function.
|
||||
// Actions can now be implicitly constructed from callables. No need to create
|
||||
// wrapper objects.
|
||||
// This function exists for backwards compatibility.
|
||||
template <typename FunctionImpl>
|
||||
GTEST_INTERNAL_DEPRECATE_AND_INLINE(
|
||||
"Actions can now be implicitly constructed from callables. No need to "
|
||||
"create wrapper objects using Invoke().")
|
||||
typename std::decay<FunctionImpl>::type Invoke(FunctionImpl&& function_impl) {
|
||||
return std::forward<FunctionImpl>(function_impl);
|
||||
}
|
||||
|
||||
@ -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
|
||||
@ -1325,17 +1329,23 @@ class AllOfMatcherImpl : public MatcherInterface<const T&> {
|
||||
// However, if matcher doesn't provide one, this method uses matcher's
|
||||
// description.
|
||||
std::string all_match_result;
|
||||
bool success = true;
|
||||
for (const Matcher<T>& matcher : matchers_) {
|
||||
StringMatchResultListener slistener;
|
||||
// Return explanation for first failed matcher.
|
||||
if (!matcher.MatchAndExplain(x, &slistener)) {
|
||||
const std::string explanation = slistener.str();
|
||||
if (!success) {
|
||||
// Already had a failure.
|
||||
*listener << ", and ";
|
||||
}
|
||||
if (!explanation.empty()) {
|
||||
*listener << explanation;
|
||||
} else {
|
||||
*listener << "which doesn't match (" << Describe(matcher) << ")";
|
||||
}
|
||||
return false;
|
||||
success = false;
|
||||
continue;
|
||||
}
|
||||
// Keep track of explanations in case all matchers succeed.
|
||||
std::string explanation = slistener.str();
|
||||
@ -1352,8 +1362,10 @@ class AllOfMatcherImpl : public MatcherInterface<const T&> {
|
||||
}
|
||||
}
|
||||
|
||||
if (success) {
|
||||
*listener << all_match_result;
|
||||
return true;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -3433,6 +3445,35 @@ auto UnpackStructImpl(const T& in, std::make_index_sequence<22>, char) {
|
||||
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u,
|
||||
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>
|
||||
@ -4475,13 +4516,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());
|
||||
|
||||
@ -1292,10 +1292,10 @@ class MockSpec {
|
||||
: function_mocker_(function_mocker), matchers_(matchers) {}
|
||||
|
||||
// Adds a new default action spec to the function mocker and returns
|
||||
// the newly created spec.
|
||||
internal::OnCallSpec<F>& InternalDefaultActionSetAt(const char* file,
|
||||
int line, const char* obj,
|
||||
const char* call) {
|
||||
// the newly created spec. .WillByDefault() must be called on the returned
|
||||
// object.
|
||||
[[nodiscard]] internal::OnCallSpec<F>& InternalDefaultActionSetAt(
|
||||
const char* file, int line, const char* obj, const char* call) {
|
||||
LogWithLocation(internal::kInfo, file, line,
|
||||
std::string("ON_CALL(") + obj + ", " + call + ") invoked");
|
||||
return function_mocker_->AddNewOnCallSpec(file, line, matchers_);
|
||||
@ -1467,7 +1467,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
||||
// function have been satisfied. If not, it will report Google Test
|
||||
// non-fatal failures for the violations.
|
||||
~FunctionMocker() override GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
MutexLock l(g_gmock_mutex);
|
||||
VerifyAndClearExpectationsLocked();
|
||||
Mock::UnregisterLocked(this);
|
||||
ClearDefaultActionsLocked();
|
||||
@ -1530,7 +1530,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
||||
UntypedOnCallSpecs specs_to_delete;
|
||||
untyped_on_call_specs_.swap(specs_to_delete);
|
||||
|
||||
g_gmock_mutex.Unlock();
|
||||
g_gmock_mutex.unlock();
|
||||
for (UntypedOnCallSpecs::const_iterator it = specs_to_delete.begin();
|
||||
it != specs_to_delete.end(); ++it) {
|
||||
delete static_cast<const OnCallSpec<F>*>(*it);
|
||||
@ -1538,7 +1538,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
||||
|
||||
// Lock the mutex again, since the caller expects it to be locked when we
|
||||
// return.
|
||||
g_gmock_mutex.Lock();
|
||||
g_gmock_mutex.lock();
|
||||
}
|
||||
|
||||
// Returns the result of invoking this mock function with the given
|
||||
@ -1646,7 +1646,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
const ArgumentTuple& args =
|
||||
*static_cast<const ArgumentTuple*>(untyped_args);
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
MutexLock l(g_gmock_mutex);
|
||||
TypedExpectation<F>* exp = this->FindMatchingExpectationLocked(args);
|
||||
if (exp == nullptr) { // A match wasn't found.
|
||||
this->FormatUnexpectedCallMessageLocked(args, what, why);
|
||||
|
||||
@ -298,7 +298,7 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message,
|
||||
//
|
||||
class WithoutMatchers {
|
||||
private:
|
||||
WithoutMatchers() {}
|
||||
WithoutMatchers() = default;
|
||||
friend GTEST_API_ WithoutMatchers GetWithoutMatchers();
|
||||
};
|
||||
|
||||
|
||||
@ -156,7 +156,7 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message,
|
||||
if (!LogIsVisible(severity)) return;
|
||||
|
||||
// Ensures that logs from different threads don't interleave.
|
||||
MutexLock l(&g_log_mutex);
|
||||
MutexLock l(g_log_mutex);
|
||||
|
||||
if (severity == kWarning) {
|
||||
// Prints a GMOCK WARNING marker to make the warnings easily searchable.
|
||||
|
||||
@ -212,7 +212,7 @@ void ExpectationBase::CheckActionCountIfNotDone() const
|
||||
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||
bool should_check = false;
|
||||
{
|
||||
MutexLock l(&mutex_);
|
||||
MutexLock l(mutex_);
|
||||
if (!action_count_checked_) {
|
||||
action_count_checked_ = true;
|
||||
should_check = true;
|
||||
@ -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/"
|
||||
@ -318,7 +318,7 @@ UntypedFunctionMockerBase::~UntypedFunctionMockerBase() = default;
|
||||
void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
{
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
MutexLock l(g_gmock_mutex);
|
||||
mock_obj_ = mock_obj;
|
||||
}
|
||||
Mock::Register(mock_obj, this);
|
||||
@ -332,7 +332,7 @@ void UntypedFunctionMockerBase::SetOwnerAndName(const void* mock_obj,
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
// We protect name_ under g_gmock_mutex in case this mock function
|
||||
// is called from two threads concurrently.
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
MutexLock l(g_gmock_mutex);
|
||||
mock_obj_ = mock_obj;
|
||||
name_ = name;
|
||||
}
|
||||
@ -345,7 +345,7 @@ const void* UntypedFunctionMockerBase::MockObject() const
|
||||
{
|
||||
// We protect mock_obj_ under g_gmock_mutex in case this mock
|
||||
// function is called from two threads concurrently.
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
MutexLock l(g_gmock_mutex);
|
||||
Assert(mock_obj_ != nullptr, __FILE__, __LINE__,
|
||||
"MockObject() must not be called before RegisterOwner() or "
|
||||
"SetOwnerAndName() has been called.");
|
||||
@ -362,7 +362,7 @@ const char* UntypedFunctionMockerBase::Name() const
|
||||
{
|
||||
// We protect name_ under g_gmock_mutex in case this mock
|
||||
// function is called from two threads concurrently.
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
MutexLock l(g_gmock_mutex);
|
||||
Assert(name_ != nullptr, __FILE__, __LINE__,
|
||||
"Name() must not be called before SetOwnerAndName() has "
|
||||
"been called.");
|
||||
@ -436,9 +436,9 @@ bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()
|
||||
UntypedExpectations expectations_to_delete;
|
||||
untyped_expectations_.swap(expectations_to_delete);
|
||||
|
||||
g_gmock_mutex.Unlock();
|
||||
g_gmock_mutex.unlock();
|
||||
expectations_to_delete.clear();
|
||||
g_gmock_mutex.Lock();
|
||||
g_gmock_mutex.lock();
|
||||
|
||||
return expectations_met;
|
||||
}
|
||||
@ -490,7 +490,7 @@ class MockObjectRegistry {
|
||||
// failure, unless the user explicitly asked us to ignore it.
|
||||
~MockObjectRegistry() {
|
||||
if (!GMOCK_FLAG_GET(catch_leaked_mocks)) return;
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
internal::MutexLock l(internal::g_gmock_mutex);
|
||||
|
||||
int leaked_count = 0;
|
||||
for (StateMap::const_iterator it = states_.begin(); it != states_.end();
|
||||
@ -559,7 +559,7 @@ UninterestingCallReactionMap() {
|
||||
void SetReactionOnUninterestingCalls(uintptr_t mock_obj,
|
||||
internal::CallReaction reaction)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
internal::MutexLock l(internal::g_gmock_mutex);
|
||||
UninterestingCallReactionMap()[mock_obj] = reaction;
|
||||
}
|
||||
|
||||
@ -590,7 +590,7 @@ void Mock::FailUninterestingCalls(uintptr_t mock_obj)
|
||||
// entry in the call-reaction table should be removed.
|
||||
void Mock::UnregisterCallReaction(uintptr_t mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
internal::MutexLock l(internal::g_gmock_mutex);
|
||||
UninterestingCallReactionMap().erase(static_cast<uintptr_t>(mock_obj));
|
||||
}
|
||||
|
||||
@ -598,7 +598,7 @@ void Mock::UnregisterCallReaction(uintptr_t mock_obj)
|
||||
// made on the given mock object.
|
||||
internal::CallReaction Mock::GetReactionOnUninterestingCalls(
|
||||
const void* mock_obj) GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
internal::MutexLock l(internal::g_gmock_mutex);
|
||||
return (UninterestingCallReactionMap().count(
|
||||
reinterpret_cast<uintptr_t>(mock_obj)) == 0)
|
||||
? internal::intToCallReaction(
|
||||
@ -611,7 +611,7 @@ internal::CallReaction Mock::GetReactionOnUninterestingCalls(
|
||||
// objects.
|
||||
void Mock::AllowLeak(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
internal::MutexLock l(internal::g_gmock_mutex);
|
||||
g_mock_object_registry.states()[mock_obj].leakable = true;
|
||||
}
|
||||
|
||||
@ -620,7 +620,7 @@ void Mock::AllowLeak(const void* mock_obj)
|
||||
// Test non-fatal failures and returns false.
|
||||
bool Mock::VerifyAndClearExpectations(void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
internal::MutexLock l(internal::g_gmock_mutex);
|
||||
return VerifyAndClearExpectationsLocked(mock_obj);
|
||||
}
|
||||
|
||||
@ -629,7 +629,7 @@ bool Mock::VerifyAndClearExpectations(void* mock_obj)
|
||||
// verification was successful.
|
||||
bool Mock::VerifyAndClear(void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
internal::MutexLock l(internal::g_gmock_mutex);
|
||||
ClearDefaultActionsLocked(mock_obj);
|
||||
return VerifyAndClearExpectationsLocked(mock_obj);
|
||||
}
|
||||
@ -679,7 +679,7 @@ bool Mock::IsStrict(void* mock_obj)
|
||||
void Mock::Register(const void* mock_obj,
|
||||
internal::UntypedFunctionMockerBase* mocker)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
internal::MutexLock l(internal::g_gmock_mutex);
|
||||
g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker);
|
||||
}
|
||||
|
||||
@ -689,7 +689,7 @@ void Mock::Register(const void* mock_obj,
|
||||
void Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj,
|
||||
const char* file, int line)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
internal::MutexLock l(internal::g_gmock_mutex);
|
||||
MockObjectState& state = g_mock_object_registry.states()[mock_obj];
|
||||
if (state.first_used_file == nullptr) {
|
||||
state.first_used_file = file;
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
#
|
||||
# Bazel Build for Google C++ Testing Framework(Google Test)-googlemock
|
||||
|
||||
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test")
|
||||
load("@rules_python//python:defs.bzl", "py_library", "py_test")
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
@ -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);
|
||||
@ -1830,7 +1822,7 @@ std::vector<std::unique_ptr<int>> VectorUniquePtrSource() {
|
||||
|
||||
TEST(MockMethodTest, CanReturnMoveOnlyValue_Return) {
|
||||
MockClass mock;
|
||||
std::unique_ptr<int> i(new int(19));
|
||||
std::unique_ptr<int> i = std::make_unique<int>(19);
|
||||
EXPECT_CALL(mock, MakeUnique()).WillOnce(Return(ByMove(std::move(i))));
|
||||
EXPECT_CALL(mock, MakeVectorUnique())
|
||||
.WillOnce(Return(ByMove(VectorUniquePtrSource())));
|
||||
@ -1853,7 +1845,7 @@ TEST(MockMethodTest, CanReturnMoveOnlyValue_Return) {
|
||||
TEST(MockMethodTest, CanReturnMoveOnlyValue_DoAllReturn) {
|
||||
testing::MockFunction<void()> mock_function;
|
||||
MockClass mock;
|
||||
std::unique_ptr<int> i(new int(19));
|
||||
std::unique_ptr<int> i = std::make_unique<int>(19);
|
||||
EXPECT_CALL(mock_function, Call());
|
||||
EXPECT_CALL(mock, MakeUnique())
|
||||
.WillOnce(DoAll(InvokeWithoutArgs(&mock_function,
|
||||
@ -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))
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -545,7 +545,7 @@ TEST(ExpectCallTest, DoesNotLogWhenVerbosityIsError) {
|
||||
|
||||
void OnCallLogger() {
|
||||
DummyMock mock;
|
||||
ON_CALL(mock, TestMethod());
|
||||
(void)ON_CALL(mock, TestMethod());
|
||||
}
|
||||
|
||||
// Verifies that ON_CALL logs if the --gmock_verbose flag is set to "info".
|
||||
@ -568,7 +568,7 @@ TEST(OnCallTest, DoesNotLogWhenVerbosityIsError) {
|
||||
|
||||
void OnCallAnyArgumentLogger() {
|
||||
DummyMock mock;
|
||||
ON_CALL(mock, TestMethodArg(_));
|
||||
(void)ON_CALL(mock, TestMethodArg(_));
|
||||
}
|
||||
|
||||
// Verifies that ON_CALL prints provided _ argument.
|
||||
|
||||
@ -770,7 +770,8 @@ TEST_P(AllOfTestP, ExplainsResult) {
|
||||
// Failed match. The first matcher, which failed, needs to
|
||||
// explain.
|
||||
m = AllOf(GreaterThan(10), GreaterThan(20));
|
||||
EXPECT_EQ("which is 5 less than 10", Explain(m, 5));
|
||||
EXPECT_EQ("which is 5 less than 10, and which is 15 less than 20",
|
||||
Explain(m, 5));
|
||||
|
||||
// Failed match. The second matcher, which failed, needs to
|
||||
// explain. Since it doesn't given an explanation, the matcher text is
|
||||
@ -1625,7 +1626,7 @@ TEST_F(DoubleNearTest, NanSensitiveDoubleNearCanMatchNaN) {
|
||||
}
|
||||
|
||||
TEST(NotTest, WorksOnMoveOnlyType) {
|
||||
std::unique_ptr<int> p(new int(3));
|
||||
std::unique_ptr<int> p = std::make_unique<int>(3);
|
||||
EXPECT_THAT(p, Pointee(Eq(3)));
|
||||
EXPECT_THAT(p, Not(Pointee(Eq(2))));
|
||||
}
|
||||
@ -1681,13 +1682,13 @@ TEST(AnyOfTest, DoesNotCallAnyOfUnqualified) {
|
||||
} // namespace adl_test
|
||||
|
||||
TEST(AllOfTest, WorksOnMoveOnlyType) {
|
||||
std::unique_ptr<int> p(new int(3));
|
||||
std::unique_ptr<int> p = std::make_unique<int>(3);
|
||||
EXPECT_THAT(p, AllOf(Pointee(Eq(3)), Pointee(Gt(0)), Pointee(Lt(5))));
|
||||
EXPECT_THAT(p, Not(AllOf(Pointee(Eq(3)), Pointee(Gt(0)), Pointee(Lt(3)))));
|
||||
}
|
||||
|
||||
TEST(AnyOfTest, WorksOnMoveOnlyType) {
|
||||
std::unique_ptr<int> p(new int(3));
|
||||
std::unique_ptr<int> p = std::make_unique<int>(3);
|
||||
EXPECT_THAT(p, AnyOf(Pointee(Eq(5)), Pointee(Lt(0)), Pointee(Lt(5))));
|
||||
EXPECT_THAT(p, Not(AnyOf(Pointee(Eq(5)), Pointee(Lt(0)), Pointee(Gt(5)))));
|
||||
}
|
||||
|
||||
@ -622,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) {
|
||||
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);
|
||||
// Verify that the matcher holds a reference to n, not to its temporary copy.
|
||||
EXPECT_TRUE(m.Matches(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 {
|
||||
@ -2362,22 +2389,19 @@ PolymorphicMatcher<DivisibleByImpl> DivisibleBy(int n) {
|
||||
return MakePolymorphicMatcher(DivisibleByImpl(n));
|
||||
}
|
||||
|
||||
// Tests that when AllOf() fails, only the first failing matcher is
|
||||
// asked to explain why.
|
||||
// Tests that when AllOf() fails, all failing matchers are asked to explain why.
|
||||
TEST(ExplainMatchResultTest, AllOf_False_False) {
|
||||
const Matcher<int> m = AllOf(DivisibleBy(4), DivisibleBy(3));
|
||||
EXPECT_EQ("which is 1 modulo 4", Explain(m, 5));
|
||||
EXPECT_EQ("which is 1 modulo 4, and which is 2 modulo 3", Explain(m, 5));
|
||||
}
|
||||
|
||||
// Tests that when AllOf() fails, only the first failing matcher is
|
||||
// asked to explain why.
|
||||
// Tests that when AllOf() fails, all failing matchers are asked to explain why.
|
||||
TEST(ExplainMatchResultTest, AllOf_False_True) {
|
||||
const Matcher<int> m = AllOf(DivisibleBy(4), DivisibleBy(3));
|
||||
EXPECT_EQ("which is 2 modulo 4", Explain(m, 6));
|
||||
}
|
||||
|
||||
// Tests that when AllOf() fails, only the first failing matcher is
|
||||
// asked to explain why.
|
||||
// Tests that when AllOf() fails, all failing matchers are asked to explain why.
|
||||
TEST(ExplainMatchResultTest, AllOf_True_False) {
|
||||
const Matcher<int> m = AllOf(Ge(1), DivisibleBy(3));
|
||||
EXPECT_EQ("which is 2 modulo 3", Explain(m, 5));
|
||||
|
||||
@ -217,7 +217,7 @@ TEST(PointeeTest, ReferenceToNonConstRawPointer) {
|
||||
TEST(PointeeTest, SmartPointer) {
|
||||
const Matcher<std::unique_ptr<int>> m = Pointee(Ge(0));
|
||||
|
||||
std::unique_ptr<int> n(new int(1));
|
||||
std::unique_ptr<int> n = std::make_unique<int>(1);
|
||||
EXPECT_TRUE(m.Matches(n));
|
||||
}
|
||||
|
||||
@ -254,7 +254,7 @@ TEST(PointerTest, RawPointerToConst) {
|
||||
}
|
||||
|
||||
TEST(PointerTest, SmartPointer) {
|
||||
std::unique_ptr<int> n(new int(10));
|
||||
std::unique_ptr<int> n = std::make_unique<int>(10);
|
||||
int* raw_n = n.get();
|
||||
const Matcher<std::unique_ptr<int>> m = Pointer(Eq(raw_n));
|
||||
|
||||
@ -2796,7 +2796,7 @@ TEST(UnorderedPointwiseTest, WorksWithMoveOnly) {
|
||||
}
|
||||
|
||||
TEST(PointeeTest, WorksOnMoveOnlyType) {
|
||||
std::unique_ptr<int> p(new int(3));
|
||||
std::unique_ptr<int> p = std::make_unique<int>(3);
|
||||
EXPECT_THAT(p, Pointee(Eq(3)));
|
||||
EXPECT_THAT(p, Not(Pointee(Eq(2))));
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ TEST(AddressTest, Const) {
|
||||
}
|
||||
|
||||
TEST(AddressTest, MatcherDoesntCopy) {
|
||||
std::unique_ptr<int> n(new int(1));
|
||||
std::unique_ptr<int> n = std::make_unique<int>(1);
|
||||
const Matcher<std::unique_ptr<int>> m = Address(Eq(&n));
|
||||
|
||||
EXPECT_TRUE(m.Matches(n));
|
||||
@ -202,7 +202,7 @@ TEST(IsTrueTest, IsTrueIsFalse) {
|
||||
EXPECT_THAT(nullptr, Not(IsTrue()));
|
||||
EXPECT_THAT(nullptr, IsFalse());
|
||||
std::unique_ptr<int> null_unique;
|
||||
std::unique_ptr<int> nonnull_unique(new int(0));
|
||||
std::unique_ptr<int> nonnull_unique = std::make_unique<int>(0);
|
||||
EXPECT_THAT(null_unique, Not(IsTrue()));
|
||||
EXPECT_THAT(null_unique, IsFalse());
|
||||
EXPECT_THAT(nonnull_unique, IsTrue());
|
||||
@ -1665,7 +1665,7 @@ MATCHER(IsNotNull, "") { return arg != nullptr; }
|
||||
// Verifies that a matcher defined using MATCHER() can work on
|
||||
// move-only types.
|
||||
TEST(MatcherMacroTest, WorksOnMoveOnlyType) {
|
||||
std::unique_ptr<int> p(new int(3));
|
||||
std::unique_ptr<int> p = std::make_unique<int>(3);
|
||||
EXPECT_THAT(p, IsNotNull());
|
||||
EXPECT_THAT(std::unique_ptr<int>(), Not(IsNotNull()));
|
||||
}
|
||||
@ -1675,7 +1675,7 @@ MATCHER_P(UniquePointee, pointee, "") { return *arg == pointee; }
|
||||
// Verifies that a matcher defined using MATCHER_P*() can work on
|
||||
// move-only types.
|
||||
TEST(MatcherPMacroTest, WorksOnMoveOnlyType) {
|
||||
std::unique_ptr<int> p(new int(3));
|
||||
std::unique_ptr<int> p = std::make_unique<int>(3);
|
||||
EXPECT_THAT(p, UniquePointee(3));
|
||||
EXPECT_THAT(p, Not(UniquePointee(2)));
|
||||
}
|
||||
|
||||
@ -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)));
|
||||
}
|
||||
|
||||
@ -160,7 +160,7 @@ class MockCC : public CC {
|
||||
// Tests that a method with expanded name compiles.
|
||||
TEST(OnCallSyntaxTest, CompilesWithMethodNameExpandedFromMacro) {
|
||||
MockCC cc;
|
||||
ON_CALL(cc, Method());
|
||||
(void)ON_CALL(cc, Method());
|
||||
}
|
||||
|
||||
// Tests that the method with expanded name not only compiles but runs
|
||||
@ -193,7 +193,7 @@ TEST(OnCallSyntaxTest, EvaluatesFirstArgumentOnce) {
|
||||
MockA a;
|
||||
MockA* pa = &a;
|
||||
|
||||
ON_CALL(*pa++, DoA(_));
|
||||
(void)ON_CALL(*pa++, DoA(_));
|
||||
EXPECT_EQ(&a + 1, pa);
|
||||
}
|
||||
|
||||
@ -201,7 +201,7 @@ TEST(OnCallSyntaxTest, EvaluatesSecondArgumentOnce) {
|
||||
MockA a;
|
||||
int n = 0;
|
||||
|
||||
ON_CALL(a, DoA(n++));
|
||||
(void)ON_CALL(a, DoA(n++));
|
||||
EXPECT_EQ(1, n);
|
||||
}
|
||||
|
||||
@ -232,7 +232,7 @@ TEST(OnCallSyntaxTest, WillByDefaultIsMandatory) {
|
||||
|
||||
EXPECT_DEATH_IF_SUPPORTED(
|
||||
{
|
||||
ON_CALL(a, DoA(5));
|
||||
(void)ON_CALL(a, DoA(5));
|
||||
a.DoA(5);
|
||||
},
|
||||
"");
|
||||
@ -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/"
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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
|
||||
|
||||
@ -296,12 +296,12 @@ class MatcherBase : private MatcherDescriberInterface {
|
||||
return *this;
|
||||
}
|
||||
|
||||
MatcherBase(MatcherBase&& other)
|
||||
MatcherBase(MatcherBase&& other) noexcept
|
||||
: vtable_(other.vtable_), buffer_(other.buffer_) {
|
||||
other.vtable_ = nullptr;
|
||||
}
|
||||
|
||||
MatcherBase& operator=(MatcherBase&& other) {
|
||||
MatcherBase& operator=(MatcherBase&& other) noexcept {
|
||||
if (this == &other) return *this;
|
||||
Destroy();
|
||||
vtable_ = other.vtable_;
|
||||
@ -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;
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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?";
|
||||
|
||||
@ -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.
|
||||
@ -1398,9 +1385,9 @@ class GTEST_API_ Mutex {
|
||||
Mutex();
|
||||
~Mutex();
|
||||
|
||||
void Lock();
|
||||
void lock();
|
||||
|
||||
void Unlock();
|
||||
void unlock();
|
||||
|
||||
// Does nothing if the current thread holds the mutex. Otherwise, crashes
|
||||
// with high probability.
|
||||
@ -1437,12 +1424,11 @@ class GTEST_API_ Mutex {
|
||||
// "MutexLock l(&mu)". Hence the typedef trick below.
|
||||
class GTestMutexLock {
|
||||
public:
|
||||
explicit GTestMutexLock(Mutex* mutex) : mutex_(mutex) { mutex_->Lock(); }
|
||||
|
||||
~GTestMutexLock() { mutex_->Unlock(); }
|
||||
explicit GTestMutexLock(Mutex& mutex) : mutex_(mutex) { mutex_.lock(); }
|
||||
~GTestMutexLock() { mutex_.unlock(); }
|
||||
|
||||
private:
|
||||
Mutex* const mutex_;
|
||||
Mutex& mutex_;
|
||||
|
||||
GTestMutexLock(const GTestMutexLock&) = delete;
|
||||
GTestMutexLock& operator=(const GTestMutexLock&) = delete;
|
||||
@ -1654,14 +1640,14 @@ class ThreadLocal : public ThreadLocalBase {
|
||||
class MutexBase {
|
||||
public:
|
||||
// Acquires this mutex.
|
||||
void Lock() {
|
||||
void lock() {
|
||||
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_));
|
||||
owner_ = pthread_self();
|
||||
has_owner_ = true;
|
||||
}
|
||||
|
||||
// Releases this mutex.
|
||||
void Unlock() {
|
||||
void unlock() {
|
||||
// Since the lock is being released the owner_ field should no longer be
|
||||
// considered valid. We don't protect writing to has_owner_ here, as it's
|
||||
// the caller's responsibility to ensure that the current thread holds the
|
||||
@ -1729,12 +1715,11 @@ class Mutex : public MutexBase {
|
||||
// "MutexLock l(&mu)". Hence the typedef trick below.
|
||||
class GTestMutexLock {
|
||||
public:
|
||||
explicit GTestMutexLock(MutexBase* mutex) : mutex_(mutex) { mutex_->Lock(); }
|
||||
|
||||
~GTestMutexLock() { mutex_->Unlock(); }
|
||||
explicit GTestMutexLock(MutexBase& mutex) : mutex_(mutex) { mutex_.lock(); }
|
||||
~GTestMutexLock() { mutex_.unlock(); }
|
||||
|
||||
private:
|
||||
MutexBase* const mutex_;
|
||||
MutexBase& mutex_;
|
||||
|
||||
GTestMutexLock(const GTestMutexLock&) = delete;
|
||||
GTestMutexLock& operator=(const GTestMutexLock&) = delete;
|
||||
@ -1877,8 +1862,8 @@ class GTEST_API_ ThreadLocal {
|
||||
class Mutex {
|
||||
public:
|
||||
Mutex() {}
|
||||
void Lock() {}
|
||||
void Unlock() {}
|
||||
void lock() {}
|
||||
void unlock() {}
|
||||
void AssertHeld() const {}
|
||||
};
|
||||
|
||||
@ -1894,7 +1879,7 @@ class Mutex {
|
||||
// "MutexLock l(&mu)". Hence the typedef trick below.
|
||||
class GTestMutexLock {
|
||||
public:
|
||||
explicit GTestMutexLock(Mutex*) {} // NOLINT
|
||||
explicit GTestMutexLock(Mutex&) {} // NOLINT
|
||||
};
|
||||
|
||||
typedef GTestMutexLock MutexLock;
|
||||
@ -2335,71 +2320,11 @@ 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
|
||||
#if GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(clang::annotate)
|
||||
#define GTEST_INTERNAL_DEPRECATE_AND_INLINE(msg) \
|
||||
[[deprecated(msg), clang::annotate("inline-me")]]
|
||||
#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
|
||||
#define GTEST_INTERNAL_DEPRECATE_AND_INLINE(msg) [[deprecated(msg)]]
|
||||
#endif
|
||||
|
||||
#if defined(__cpp_lib_span) || (GTEST_INTERNAL_HAS_INCLUDE(<span>) && \
|
||||
@ -2443,38 +2368,6 @@ using StringView = ::std::string_view;
|
||||
#define GTEST_INTERNAL_HAS_STRING_VIEW 0
|
||||
#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))
|
||||
|
||||
@ -320,13 +320,13 @@ Mutex::~Mutex() {
|
||||
}
|
||||
}
|
||||
|
||||
void Mutex::Lock() {
|
||||
void Mutex::lock() {
|
||||
ThreadSafeLazyInit();
|
||||
::EnterCriticalSection(critical_section_);
|
||||
owner_thread_id_ = ::GetCurrentThreadId();
|
||||
}
|
||||
|
||||
void Mutex::Unlock() {
|
||||
void Mutex::unlock() {
|
||||
ThreadSafeLazyInit();
|
||||
// We don't protect writing to owner_thread_id_ here, as it's the
|
||||
// caller's responsibility to ensure that the current thread holds the
|
||||
@ -499,7 +499,7 @@ class ThreadLocalRegistryImpl {
|
||||
MemoryIsNotDeallocated memory_is_not_deallocated;
|
||||
#endif // _MSC_VER
|
||||
DWORD current_thread = ::GetCurrentThreadId();
|
||||
MutexLock lock(&mutex_);
|
||||
MutexLock lock(mutex_);
|
||||
ThreadIdToThreadLocals* const thread_to_thread_locals =
|
||||
GetThreadLocalsMapLocked();
|
||||
ThreadIdToThreadLocals::iterator thread_local_pos =
|
||||
@ -532,7 +532,7 @@ class ThreadLocalRegistryImpl {
|
||||
// Clean up the ThreadLocalValues data structure while holding the lock, but
|
||||
// defer the destruction of the ThreadLocalValueHolderBases.
|
||||
{
|
||||
MutexLock lock(&mutex_);
|
||||
MutexLock lock(mutex_);
|
||||
ThreadIdToThreadLocals* const thread_to_thread_locals =
|
||||
GetThreadLocalsMapLocked();
|
||||
for (ThreadIdToThreadLocals::iterator it =
|
||||
@ -559,7 +559,7 @@ class ThreadLocalRegistryImpl {
|
||||
// Clean up the ThreadIdToThreadLocals data structure while holding the
|
||||
// lock, but defer the destruction of the ThreadLocalValueHolderBases.
|
||||
{
|
||||
MutexLock lock(&mutex_);
|
||||
MutexLock lock(mutex_);
|
||||
ThreadIdToThreadLocals* const thread_to_thread_locals =
|
||||
GetThreadLocalsMapLocked();
|
||||
ThreadIdToThreadLocals::iterator thread_local_pos =
|
||||
|
||||
@ -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
|
||||
|
||||
@ -269,6 +269,13 @@ GTEST_DEFINE_bool_(
|
||||
"True if and only if the test should fail if no test case (including "
|
||||
"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),
|
||||
@ -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)
|
||||
@ -1079,14 +1086,14 @@ void DefaultPerThreadTestPartResultReporter::ReportTestPartResult(
|
||||
// Returns the global test part result reporter.
|
||||
TestPartResultReporterInterface*
|
||||
UnitTestImpl::GetGlobalTestPartResultReporter() {
|
||||
internal::MutexLock lock(&global_test_part_result_reporter_mutex_);
|
||||
internal::MutexLock lock(global_test_part_result_reporter_mutex_);
|
||||
return global_test_part_result_reporter_;
|
||||
}
|
||||
|
||||
// Sets the global test part result reporter.
|
||||
void UnitTestImpl::SetGlobalTestPartResultReporter(
|
||||
TestPartResultReporterInterface* reporter) {
|
||||
internal::MutexLock lock(&global_test_part_result_reporter_mutex_);
|
||||
internal::MutexLock lock(global_test_part_result_reporter_mutex_);
|
||||
global_test_part_result_reporter_ = reporter;
|
||||
}
|
||||
|
||||
@ -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";
|
||||
}
|
||||
@ -2340,7 +2347,7 @@ void TestResult::RecordProperty(const std::string& xml_element,
|
||||
if (!ValidateTestProperty(xml_element, test_property)) {
|
||||
return;
|
||||
}
|
||||
internal::MutexLock lock(&test_properties_mutex_);
|
||||
internal::MutexLock lock(test_properties_mutex_);
|
||||
const std::vector<TestProperty>::iterator property_with_matching_key =
|
||||
std::find_if(test_properties_.begin(), test_properties_.end(),
|
||||
internal::TestPropertyKeyIs(test_property.key()));
|
||||
@ -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";
|
||||
@ -5080,7 +5088,7 @@ std::string OsStackTraceGetter::CurrentStackTrace(int max_depth, int skip_count)
|
||||
|
||||
void* caller_frame = nullptr;
|
||||
{
|
||||
MutexLock lock(&mutex_);
|
||||
MutexLock lock(mutex_);
|
||||
caller_frame = caller_frame_;
|
||||
}
|
||||
|
||||
@ -5119,7 +5127,7 @@ void OsStackTraceGetter::UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||
caller_frame = nullptr;
|
||||
}
|
||||
|
||||
MutexLock lock(&mutex_);
|
||||
MutexLock lock(mutex_);
|
||||
caller_frame_ = caller_frame;
|
||||
#endif // GTEST_HAS_ABSL
|
||||
}
|
||||
@ -5382,13 +5390,13 @@ void UnitTest::UponLeavingGTest() {
|
||||
|
||||
// Sets the TestSuite object for the test that's currently running.
|
||||
void UnitTest::set_current_test_suite(TestSuite* a_current_test_suite) {
|
||||
internal::MutexLock lock(&mutex_);
|
||||
internal::MutexLock lock(mutex_);
|
||||
impl_->set_current_test_suite(a_current_test_suite);
|
||||
}
|
||||
|
||||
// Sets the TestInfo object for the test that's currently running.
|
||||
void UnitTest::set_current_test_info(TestInfo* a_current_test_info) {
|
||||
internal::MutexLock lock(&mutex_);
|
||||
internal::MutexLock lock(mutex_);
|
||||
impl_->set_current_test_info(a_current_test_info);
|
||||
}
|
||||
|
||||
@ -5427,7 +5435,7 @@ void UnitTest::AddTestPartResult(TestPartResult::Type result_type,
|
||||
Message msg;
|
||||
msg << message;
|
||||
|
||||
internal::MutexLock lock(&mutex_);
|
||||
internal::MutexLock lock(mutex_);
|
||||
if (!impl_->gtest_trace_stack().empty()) {
|
||||
msg << "\n" << GTEST_NAME_ << " trace:";
|
||||
|
||||
@ -5610,7 +5618,7 @@ const char* UnitTest::original_working_dir() const {
|
||||
// or NULL if no test is running.
|
||||
const TestSuite* UnitTest::current_test_suite() const
|
||||
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||
internal::MutexLock lock(&mutex_);
|
||||
internal::MutexLock lock(mutex_);
|
||||
return impl_->current_test_suite();
|
||||
}
|
||||
|
||||
@ -5618,7 +5626,7 @@ const TestSuite* UnitTest::current_test_suite() const
|
||||
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
const TestCase* UnitTest::current_test_case() const
|
||||
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||
internal::MutexLock lock(&mutex_);
|
||||
internal::MutexLock lock(mutex_);
|
||||
return impl_->current_test_suite();
|
||||
}
|
||||
#endif
|
||||
@ -5627,7 +5635,7 @@ const TestCase* UnitTest::current_test_case() const
|
||||
// or NULL if no test is running.
|
||||
const TestInfo* UnitTest::current_test_info() const
|
||||
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||
internal::MutexLock lock(&mutex_);
|
||||
internal::MutexLock lock(mutex_);
|
||||
return impl_->current_test_info();
|
||||
}
|
||||
|
||||
@ -5651,13 +5659,13 @@ UnitTest::~UnitTest() { delete impl_; }
|
||||
// Google Test trace stack.
|
||||
void UnitTest::PushGTestTrace(const internal::TraceInfo& trace)
|
||||
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||
internal::MutexLock lock(&mutex_);
|
||||
internal::MutexLock lock(mutex_);
|
||||
impl_->gtest_trace_stack().push_back(trace);
|
||||
}
|
||||
|
||||
// Pops a trace from the per-thread Google Test trace stack.
|
||||
void UnitTest::PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||
internal::MutexLock lock(&mutex_);
|
||||
internal::MutexLock lock(mutex_);
|
||||
impl_->gtest_trace_stack().pop_back();
|
||||
}
|
||||
|
||||
@ -6079,6 +6087,20 @@ 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 ran. Check that tests exist and are not disabled or "
|
||||
"filtered out.\n\n"
|
||||
"For sharded runs, this error indicates an empty shard. This can "
|
||||
"happen if you have more shards than tests, or if --gtest_filter "
|
||||
"leaves a shard with no tests.\n\n"
|
||||
"To permit empty shards (e.g., when debugging with a filter), "
|
||||
"specify \n"
|
||||
"--gtest_fail_if_no_test_selected=false.";
|
||||
ColoredPrintf(GTestColor::kRed, "%s\n", kNoTestsSelectedMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
elapsed_time_ = timer.Elapsed();
|
||||
@ -6763,6 +6785,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);
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
#
|
||||
# Bazel BUILD for The Google C++ Testing Framework (Google Test)
|
||||
|
||||
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test")
|
||||
load("@rules_python//python:defs.bzl", "py_library", "py_test")
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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."""
|
||||
|
||||
91
googletest/test/googletest-fail-if-no-test-selected-test.py
Normal file
91
googletest/test/googletest-fail-if-no-test-selected-test.py
Normal file
@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env python3 # pylint: disable=g-interpreter-mismatch
|
||||
#
|
||||
# Copyright 2025, Google Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
"""Tests for Google Test's --gtest_fail_if_no_test_selected flag."""
|
||||
|
||||
from googletest.test import gtest_test_utils
|
||||
|
||||
|
||||
# The command line flag for enabling the fail-if-no-test-selected behavior.
|
||||
FAIL_IF_NO_TEST_SELECTED_FLAG = "gtest_fail_if_no_test_selected"
|
||||
|
||||
# The environment variable for the test output warnings file.
|
||||
TEST_WARNINGS_OUTPUT_FILE = "TEST_WARNINGS_OUTPUT_FILE"
|
||||
|
||||
|
||||
class GTestFailIfNoTestSelectedTest(gtest_test_utils.TestCase):
|
||||
"""Tests the --gtest_fail_if_no_test_selected flag."""
|
||||
|
||||
def Run(self, program_name, flags=None, env=None):
|
||||
"""Run the given program with the given flag.
|
||||
|
||||
Args:
|
||||
program_name: Name of the program to run.
|
||||
flags: The command line flags to pass to the program, or None.
|
||||
env: Dictionary with environment to pass to the subprocess.
|
||||
|
||||
Returns:
|
||||
True if the program exits with code 0, false otherwise.
|
||||
"""
|
||||
|
||||
exe_path = gtest_test_utils.GetTestExecutablePath(program_name)
|
||||
args = [exe_path]
|
||||
if flags is not None:
|
||||
args.extend(flags)
|
||||
process = gtest_test_utils.Subprocess(args, capture_stderr=False, env=env)
|
||||
return process.exited and process.exit_code == 0
|
||||
|
||||
def testSucceedsWhenFlagIsNotSetAndOnlyDisabledTestsPresent(self):
|
||||
"""Tests that no test selected results in success without the flag set."""
|
||||
self.assertTrue(
|
||||
self.Run("googletest-fail-if-no-test-linked-test-with-disabled-test_"),
|
||||
)
|
||||
|
||||
def testFailsWhenFlagIsSetAndOnlyDisabledTestsPresent(self):
|
||||
"""Tests that no test selected results in failure with the flag set."""
|
||||
self.assertFalse(
|
||||
self.Run(
|
||||
"googletest-fail-if-no-test-linked-test-with-disabled-test_",
|
||||
flags=[f"--{FAIL_IF_NO_TEST_SELECTED_FLAG}"],
|
||||
),
|
||||
)
|
||||
|
||||
def testSucceedsWhenFlagIsSetAndEnabledTestsPresent(self):
|
||||
"""Tests that a test running still succeeds when the flag is set."""
|
||||
self.assertTrue(
|
||||
self.Run(
|
||||
"googletest-fail-if-no-test-linked-test-with-enabled-test_",
|
||||
flags=[f"--{FAIL_IF_NO_TEST_SELECTED_FLAG}"],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
gtest_test_utils.Main()
|
||||
@ -62,7 +62,7 @@ Expected equality of these values:
|
||||
Which is: "\"Line\0 1\"\nLine 2"
|
||||
"Line 2"
|
||||
With diff:
|
||||
@@ -1,2 @@
|
||||
@@ -1,2 +1 @@
|
||||
-\"Line\0 1\"
|
||||
Line 2
|
||||
|
||||
|
||||
@ -696,7 +696,7 @@ class TestGenerationEnvironment : public ::testing::Environment {
|
||||
msg << "TestsExpandedAndRun/" << i;
|
||||
if (UnitTestOptions::FilterMatchesTest(
|
||||
"TestExpansionModule/MultipleTestGenerationTest",
|
||||
msg.GetString().c_str())) {
|
||||
msg.GetString())) {
|
||||
perform_check = true;
|
||||
}
|
||||
}
|
||||
@ -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,
|
||||
|
||||
@ -288,8 +288,8 @@ TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFileAndLine) {
|
||||
defined(GTEST_OS_OPENBSD) || defined(GTEST_OS_GNU_HURD)
|
||||
void* ThreadFunc(void* data) {
|
||||
internal::Mutex* mutex = static_cast<internal::Mutex*>(data);
|
||||
mutex->Lock();
|
||||
mutex->Unlock();
|
||||
mutex->lock();
|
||||
mutex->unlock();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -308,7 +308,7 @@ TEST(GetThreadCountTest, ReturnsCorrectValue) {
|
||||
|
||||
internal::Mutex mutex;
|
||||
{
|
||||
internal::MutexLock lock(&mutex);
|
||||
internal::MutexLock lock(mutex);
|
||||
pthread_attr_t attr;
|
||||
ASSERT_EQ(0, pthread_attr_init(&attr));
|
||||
ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
|
||||
@ -1028,7 +1028,9 @@ TEST(MutexDeathTest, AssertHeldShouldAssertWhenNotLocked) {
|
||||
EXPECT_DEATH_IF_SUPPORTED(
|
||||
{
|
||||
Mutex m;
|
||||
{ MutexLock lock(&m); }
|
||||
{
|
||||
MutexLock lock(m);
|
||||
}
|
||||
m.AssertHeld();
|
||||
},
|
||||
"thread .*hold");
|
||||
@ -1036,13 +1038,13 @@ TEST(MutexDeathTest, AssertHeldShouldAssertWhenNotLocked) {
|
||||
|
||||
TEST(MutexTest, AssertHeldShouldNotAssertWhenLocked) {
|
||||
Mutex m;
|
||||
MutexLock lock(&m);
|
||||
MutexLock lock(m);
|
||||
m.AssertHeld();
|
||||
}
|
||||
|
||||
class AtomicCounterWithMutex {
|
||||
public:
|
||||
explicit AtomicCounterWithMutex(Mutex* mutex)
|
||||
explicit AtomicCounterWithMutex(Mutex& mutex)
|
||||
: value_(0), mutex_(mutex), random_(42) {}
|
||||
|
||||
void Increment() {
|
||||
@ -1083,7 +1085,7 @@ class AtomicCounterWithMutex {
|
||||
|
||||
private:
|
||||
volatile int value_;
|
||||
Mutex* const mutex_; // Protects value_.
|
||||
Mutex& mutex_; // Protects value_.
|
||||
Random random_;
|
||||
};
|
||||
|
||||
@ -1094,7 +1096,7 @@ void CountingThreadFunc(pair<AtomicCounterWithMutex*, int> param) {
|
||||
// Tests that the mutex only lets one thread at a time to lock it.
|
||||
TEST(MutexTest, OnlyOneThreadCanLockAtATime) {
|
||||
Mutex mutex;
|
||||
AtomicCounterWithMutex locked_counter(&mutex);
|
||||
AtomicCounterWithMutex locked_counter(mutex);
|
||||
|
||||
typedef ThreadWithParam<pair<AtomicCounterWithMutex*, int> > ThreadType;
|
||||
const int kCycleCount = 20;
|
||||
|
||||
@ -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"
|
||||
@ -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).
|
||||
@ -1661,7 +1699,7 @@ TEST(PrintToStringTest, ContainsNonLatin) {
|
||||
EXPECT_PRINT_TO_STRING_(non_ascii_str,
|
||||
"\"\\xEC\\x98\\xA4\\xEC\\xA0\\x84 4:30\"\n"
|
||||
" As Text: \"오전 4:30\"");
|
||||
non_ascii_str = ::std::string("From ä — ẑ");
|
||||
non_ascii_str = "From ä — ẑ";
|
||||
EXPECT_PRINT_TO_STRING_(non_ascii_str,
|
||||
"\"From \\xC3\\xA4 \\xE2\\x80\\x94 \\xE1\\xBA\\x91\""
|
||||
"\n As Text: \"From ä — ẑ\"");
|
||||
@ -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) {
|
||||
|
||||
@ -95,9 +95,9 @@ void ManyAsserts(int id) {
|
||||
|
||||
// RecordProperty() should interact safely with other threads as well.
|
||||
// The shared_key forces property updates.
|
||||
Test::RecordProperty(IdToKey(id, "string").c_str(), IdToString(id).c_str());
|
||||
Test::RecordProperty(IdToKey(id, "string"), IdToString(id));
|
||||
Test::RecordProperty(IdToKey(id, "int").c_str(), id);
|
||||
Test::RecordProperty("shared_key", IdToString(id).c_str());
|
||||
Test::RecordProperty("shared_key", IdToString(id));
|
||||
|
||||
// This assertion should fail kThreadCount times per thread. It
|
||||
// is for testing whether Google Test can handle failed assertions in a
|
||||
|
||||
@ -2649,8 +2649,8 @@ TEST(IsSubstringTest, GeneratesCorrectMessageForCString) {
|
||||
// Tests that IsSubstring returns the correct result when the input
|
||||
// argument type is ::std::string.
|
||||
TEST(IsSubstringTest, ReturnsCorrectResultsForStdString) {
|
||||
EXPECT_TRUE(IsSubstring("", "", std::string("hello"), "ahellob"));
|
||||
EXPECT_FALSE(IsSubstring("", "", "hello", std::string("world")));
|
||||
EXPECT_TRUE(IsSubstring("", "", "hello", "ahellob"));
|
||||
EXPECT_FALSE(IsSubstring("", "", "hello", "world"));
|
||||
}
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
@ -2707,8 +2707,8 @@ TEST(IsNotSubstringTest, GeneratesCorrectMessageForWideCString) {
|
||||
// Tests that IsNotSubstring returns the correct result when the input
|
||||
// argument type is ::std::string.
|
||||
TEST(IsNotSubstringTest, ReturnsCorrectResultsForStdString) {
|
||||
EXPECT_FALSE(IsNotSubstring("", "", std::string("hello"), "ahellob"));
|
||||
EXPECT_TRUE(IsNotSubstring("", "", "hello", std::string("world")));
|
||||
EXPECT_FALSE(IsNotSubstring("", "", "hello", "ahellob"));
|
||||
EXPECT_TRUE(IsNotSubstring("", "", "hello", "world"));
|
||||
}
|
||||
|
||||
// Tests that IsNotSubstring() generates the correct message when the input
|
||||
@ -2719,8 +2719,7 @@ TEST(IsNotSubstringTest, GeneratesCorrectMessageForStdString) {
|
||||
" Actual: \"needle\"\n"
|
||||
"Expected: not a substring of haystack_expr\n"
|
||||
"Which is: \"two needles\"",
|
||||
IsNotSubstring("needle_expr", "haystack_expr", ::std::string("needle"),
|
||||
"two needles")
|
||||
IsNotSubstring("needle_expr", "haystack_expr", "needle", "two needles")
|
||||
.failure_message());
|
||||
}
|
||||
|
||||
@ -3579,13 +3578,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.
|
||||
@ -3655,8 +3654,7 @@ TEST(AssertionTest, EqFailure) {
|
||||
msg4.c_str());
|
||||
|
||||
const std::string msg5(
|
||||
EqFailure("foo", "bar", std::string("\"x\""), std::string("\"y\""), true)
|
||||
.failure_message());
|
||||
EqFailure("foo", "bar", "\"x\"", "\"y\"", true).failure_message());
|
||||
EXPECT_STREQ(
|
||||
"Expected equality of these values:\n"
|
||||
" foo\n"
|
||||
@ -6717,6 +6715,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.
|
||||
|
||||
|
||||
@ -17,9 +17,25 @@ def googletest_deps():
|
||||
if not native.existing_rule("abseil-cpp"):
|
||||
http_archive(
|
||||
name = "abseil-cpp",
|
||||
sha256 = "b396401fd29e2e679cace77867481d388c807671dc2acc602a0259eeb79b7811",
|
||||
strip_prefix = "abseil-cpp-20250127.1",
|
||||
urls = ["https://github.com/abseil/abseil-cpp/releases/download/20250127.1/abseil-cpp-20250127.1.tar.gz"],
|
||||
sha256 = "9b2b72d4e8367c0b843fa2bcfa2b08debbe3cee34f7aaa27de55a6cbb3e843db",
|
||||
strip_prefix = "abseil-cpp-20250814.0",
|
||||
urls = ["https://github.com/abseil/abseil-cpp/releases/download/20250814.0/abseil-cpp-20250814.0.tar.gz"],
|
||||
)
|
||||
|
||||
if not native.existing_rule("bazel_features"):
|
||||
http_archive(
|
||||
name = "bazel_features",
|
||||
sha256 = "9390b391a68d3b24aef7966bce8556d28003fe3f022a5008efc7807e8acaaf1a",
|
||||
strip_prefix = "bazel_features-1.36.0",
|
||||
url = "https://github.com/bazel-contrib/bazel_features/releases/download/v1.36.0/bazel_features-v1.36.0.tar.gz",
|
||||
)
|
||||
|
||||
if not native.existing_rule("rules_cc"):
|
||||
http_archive(
|
||||
name = "rules_cc",
|
||||
sha256 = "207ea073dd20a705f9e8bc5ac02f5203e9621fc672774bb1a0935aefab7aebfa",
|
||||
strip_prefix = "rules_cc-0.2.8",
|
||||
url = "https://github.com/bazelbuild/rules_cc/releases/download/0.2.8/rules_cc-0.2.8.tar.gz",
|
||||
)
|
||||
|
||||
if not native.existing_rule("fuchsia_sdk"):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user