Merge branch 'google:main' into master

This commit is contained in:
Anthony Graca 2022-10-19 20:30:36 -07:00 committed by GitHub
commit 1f32636560
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 685 additions and 222 deletions

View File

@ -12,32 +12,32 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Tests - name: Tests
run: bazel test --test_output=errors //... run: bazel test --cxxopt=-std=c++14 --features=external_include_paths --test_output=errors ...
MacOs: macOS:
runs-on: macos-latest runs-on: macos-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Tests - name: Tests
run: bazel test --test_output=errors //... run: bazel test --cxxopt=-std=c++14 --features=external_include_paths --test_output=errors ...
Windows: Windows:
runs-on: windows-latest runs-on: windows-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Tests - name: Tests
run: bazel test --test_output=errors //... run: bazel test --cxxopt=/std:c++14 --features=external_include_paths --test_output=errors ...

View File

@ -30,6 +30,7 @@ include(GNUInstallDirs)
#Note that googlemock target already builds googletest #Note that googlemock target already builds googletest
option(BUILD_GMOCK "Builds the googlemock subproject" ON) option(BUILD_GMOCK "Builds the googlemock subproject" ON)
option(INSTALL_GTEST "Enable installation of googletest. (Projects embedding googletest may want to turn this OFF.)" ON) option(INSTALL_GTEST "Enable installation of googletest. (Projects embedding googletest may want to turn this OFF.)" ON)
option(GTEST_HAS_ABSL "Use Abseil and RE2. Requires Abseil and RE2 to be separately added to the build." OFF)
if(BUILD_GMOCK) if(BUILD_GMOCK)
add_subdirectory( googlemock ) add_subdirectory( googlemock )

View File

@ -80,8 +80,8 @@ fairly rigid coding style, as defined by the
[google-styleguide](https://github.com/google/styleguide) project. All patches [google-styleguide](https://github.com/google/styleguide) project. All patches
will be expected to conform to the style outlined will be expected to conform to the style outlined
[here](https://google.github.io/styleguide/cppguide.html). Use [here](https://google.github.io/styleguide/cppguide.html). Use
[.clang-format](https://github.com/google/googletest/blob/master/.clang-format) [.clang-format](https://github.com/google/googletest/blob/main/.clang-format) to
to check your formatting. check your formatting.
## Requirements for Contributors ## Requirements for Contributors

View File

@ -59,39 +59,12 @@ More information about building GoogleTest can be found at
## Supported Platforms ## Supported Platforms
GoogleTest requires a codebase and compiler compliant with the C++14 standard or GoogleTest follows Google's
newer. [Foundational C++ Support Policy](https://opensource.google/documentation/policies/cplusplus-support).
See
The GoogleTest code is officially supported on the following platforms. [this table](https://github.com/google/oss-policies-info/blob/main/foundational-cxx-support-matrix.md)
Operating systems or tools not listed below are community-supported. For for a list of currently supported versions compilers, platforms, and build
community-supported platforms, patches that do not complicate the code may be tools.
considered.
If you notice any problems on your platform, please file an issue on the
[GoogleTest GitHub Issue Tracker](https://github.com/google/googletest/issues).
Pull requests containing fixes are welcome!
### Operating Systems
* Linux
* macOS
* Windows
### Compilers
* gcc 5.0+
* clang 5.0+
* MSVC 2015+
**macOS users:** Xcode 9.3+ provides clang 5.0+.
### Build Systems
* [Bazel](https://bazel.build/)
* [CMake](https://cmake.org/)
**Note:** Bazel is the build system used by the team internally and in tests.
CMake is supported on a best-effort basis and by the community.
## Who Is Using GoogleTest? ## Who Is Using GoogleTest?
@ -138,7 +111,7 @@ that generates stub code for GoogleTest.
## Contributing Changes ## Contributing Changes
Please read Please read
[`CONTRIBUTING.md`](https://github.com/google/googletest/blob/master/CONTRIBUTING.md) [`CONTRIBUTING.md`](https://github.com/google/googletest/blob/main/CONTRIBUTING.md)
for details on how to contribute to this project. for details on how to contribute to this project.
Happy testing! Happy testing!

View File

@ -20,20 +20,25 @@ http_archive(
http_archive( http_archive(
name = "rules_python", name = "rules_python",
sha256 = "0b460f17771258341528753b1679335b629d1d25e3af28eda47d009c103a6e15", sha256 = "8c8fe44ef0a9afc256d1e75ad5f448bb59b81aba149b8958f02f7b3a98f5d9b4",
strip_prefix = "rules_python-aef17ad72919d184e5edb7abf61509eb78e57eda", strip_prefix = "rules_python-0.13.0",
urls = ["https://github.com/bazelbuild/rules_python/archive/aef17ad72919d184e5edb7abf61509eb78e57eda.zip"], # 2022-06-21T23:44:47Z url = "https://github.com/bazelbuild/rules_python/archive/refs/tags/0.13.0.tar.gz",
) )
http_archive( http_archive(
name = "bazel_skylib", name = "bazel_skylib",
urls = ["https://github.com/bazelbuild/bazel-skylib/releases/download/1.2.1/bazel-skylib-1.2.1.tar.gz"], urls = [
sha256 = "f7be3474d42aae265405a592bb7da8e171919d74c16f082a5457840f06054728", "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.3.0/bazel-skylib-1.3.0.tar.gz",
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.3.0/bazel-skylib-1.3.0.tar.gz",
],
sha256 = "74d544d96f4a5bb630d465ca8bbcfe231e3594e5aae57e1edbf17a6eb3ca2506",
) )
http_archive( http_archive(
name = "platforms", name = "platforms",
sha256 = "a879ea428c6d56ab0ec18224f976515948822451473a80d06c2e50af0bbe5121", urls = [
strip_prefix = "platforms-da5541f26b7de1dc8e04c075c99df5351742a4a2", "https://mirror.bazel.build/github.com/bazelbuild/platforms/releases/download/0.0.6/platforms-0.0.6.tar.gz",
urls = ["https://github.com/bazelbuild/platforms/archive/da5541f26b7de1dc8e04c075c99df5351742a4a2.zip"], # 2022-05-27 "https://github.com/bazelbuild/platforms/releases/download/0.0.6/platforms-0.0.6.tar.gz",
],
sha256 = "5308fc1d8865406a49427ba24a9ab53087f17f5266a7aabbfc28823f3916e1ca",
) )

View File

@ -80,6 +80,7 @@ time docker run \
--copt="-Wuninitialized" \ --copt="-Wuninitialized" \
--copt="-Wno-error=pragmas" \ --copt="-Wno-error=pragmas" \
--distdir="/bazel-distdir" \ --distdir="/bazel-distdir" \
--features=external_include_paths \
--keep_going \ --keep_going \
--show_timestamps \ --show_timestamps \
--test_output=errors --test_output=errors
@ -100,6 +101,7 @@ for std in ${STD}; do
--copt="-Wuninitialized" \ --copt="-Wuninitialized" \
--define="absl=${absl}" \ --define="absl=${absl}" \
--distdir="/bazel-distdir" \ --distdir="/bazel-distdir" \
--features=external_include_paths \
--keep_going \ --keep_going \
--show_timestamps \ --show_timestamps \
--test_output=errors --test_output=errors
@ -123,6 +125,7 @@ for std in ${STD}; do
--copt="-Wuninitialized" \ --copt="-Wuninitialized" \
--define="absl=${absl}" \ --define="absl=${absl}" \
--distdir="/bazel-distdir" \ --distdir="/bazel-distdir" \
--features=external_include_paths \
--keep_going \ --keep_going \
--linkopt="--gcc-toolchain=/usr/local" \ --linkopt="--gcc-toolchain=/usr/local" \
--show_timestamps \ --show_timestamps \

View File

@ -68,6 +68,7 @@ for absl in 0 1; do
--copt="-Werror" \ --copt="-Werror" \
--cxxopt="-std=c++14" \ --cxxopt="-std=c++14" \
--define="absl=${absl}" \ --define="absl=${absl}" \
--features=external_include_paths \
--keep_going \ --keep_going \
--show_timestamps \ --show_timestamps \
--test_output=errors --test_output=errors

56
ci/windows-presubmit.bat Normal file
View File

@ -0,0 +1,56 @@
SETLOCAL ENABLEDELAYEDEXPANSION
SET BAZEL_EXE=%KOKORO_GFILE_DIR%\bazel-5.1.1-windows-x86_64.exe
SET PATH=C:\Python37;%PATH%
SET BAZEL_PYTHON=C:\python37\python.exe
SET BAZEL_SH=C:\tools\msys64\usr\bin\bash.exe
SET CMAKE_BIN="C:\Program Files\CMake\bin\cmake.exe"
SET CTEST_BIN="C:\Program Files\CMake\bin\ctest.exe"
SET CTEST_OUTPUT_ON_FAILURE=1
IF EXIST git\googletest (
CD git\googletest
) ELSE IF EXIST github\googletest (
CD github\googletest
)
IF %errorlevel% neq 0 EXIT /B 1
:: ----------------------------------------------------------------------------
:: CMake Visual Studio 15 2017 Win64
MKDIR cmake_msvc2017
CD cmake_msvc2017
%CMAKE_BIN% .. ^
-G "Visual Studio 15 2017 Win64" ^
-DPYTHON_EXECUTABLE:FILEPATH=c:\python37\python.exe ^
-DPYTHON_INCLUDE_DIR:PATH=c:\python37\include ^
-DPYTHON_LIBRARY:FILEPATH=c:\python37\lib\site-packages\pip ^
-Dgtest_build_samples=ON ^
-Dgtest_build_tests=ON ^
-Dgmock_build_tests=ON
IF %errorlevel% neq 0 EXIT /B 1
%CMAKE_BIN% --build . --target ALL_BUILD --config Debug -- -maxcpucount
IF %errorlevel% neq 0 EXIT /B 1
%CTEST_BIN% -C Debug --timeout 600
IF %errorlevel% neq 0 EXIT /B 1
CD ..
RMDIR /S /Q cmake_msvc2017
:: ----------------------------------------------------------------------------
:: Bazel Visual Studio 15 2017 Win64
SET BAZEL_VC=C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC
%BAZEL_EXE% test ... ^
--compilation_mode=dbg ^
--copt=/std:c++14 ^
--copt=/WX ^
--features=external_include_paths ^
--keep_going ^
--test_output=errors ^
--test_tag_filters=-no_test_msvc2017
IF %errorlevel% neq 0 EXIT /B 1

View File

@ -48,7 +48,7 @@
<div class="footer"> <div class="footer">
GoogleTest &middot; GoogleTest &middot;
<a href="https://github.com/google/googletest">GitHub Repository</a> &middot; <a href="https://github.com/google/googletest">GitHub Repository</a> &middot;
<a href="https://github.com/google/googletest/blob/master/LICENSE">License</a> &middot; <a href="https://github.com/google/googletest/blob/main/LICENSE">License</a> &middot;
<a href="https://policies.google.com/privacy">Privacy Policy</a> <a href="https://policies.google.com/privacy">Privacy Policy</a>
</div> </div>
</div> </div>

View File

@ -487,7 +487,7 @@ When built with Bazel and using Abseil, googletest uses the
systems (Linux, Cygwin, Mac), googletest uses the systems (Linux, Cygwin, Mac), googletest uses the
[POSIX extended regular expression](http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.html#tag_09_04) [POSIX extended regular expression](http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.html#tag_09_04)
syntax. To learn about POSIX syntax, you may want to read this syntax. To learn about POSIX syntax, you may want to read this
[Wikipedia entry](http://en.wikipedia.org/wiki/Regular_expression#POSIX_Extended_Regular_Expressions). [Wikipedia entry](http://en.wikipedia.org/wiki/Regular_expression#POSIX_extended).
On Windows, googletest uses its own simple regular expression implementation. It On Windows, googletest uses its own simple regular expression implementation. It
lacks many features. For example, we don't support union (`"x|y"`), grouping lacks many features. For example, we don't support union (`"x|y"`), grouping
@ -1142,8 +1142,8 @@ GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FooTest);
You can see [sample7_unittest.cc] and [sample8_unittest.cc] for more examples. You can see [sample7_unittest.cc] and [sample8_unittest.cc] for more examples.
[sample7_unittest.cc]: https://github.com/google/googletest/blob/master/googletest/samples/sample7_unittest.cc "Parameterized Test example" [sample7_unittest.cc]: https://github.com/google/googletest/blob/main/googletest/samples/sample7_unittest.cc "Parameterized Test example"
[sample8_unittest.cc]: https://github.com/google/googletest/blob/master/googletest/samples/sample8_unittest.cc "Parameterized Test example with multiple parameters" [sample8_unittest.cc]: https://github.com/google/googletest/blob/main/googletest/samples/sample8_unittest.cc "Parameterized Test example with multiple parameters"
### Creating Value-Parameterized Abstract Tests ### Creating Value-Parameterized Abstract Tests
@ -1294,7 +1294,7 @@ TYPED_TEST(FooTest, HasPropertyA) { ... }
You can see [sample6_unittest.cc] for a complete example. You can see [sample6_unittest.cc] for a complete example.
[sample6_unittest.cc]: https://github.com/google/googletest/blob/master/googletest/samples/sample6_unittest.cc "Typed Test example" [sample6_unittest.cc]: https://github.com/google/googletest/blob/main/googletest/samples/sample6_unittest.cc "Typed Test example"
## Type-Parameterized Tests ## Type-Parameterized Tests
@ -1733,7 +1733,7 @@ You can do so by adding one line:
Now, sit back and enjoy a completely different output from your tests. For more Now, sit back and enjoy a completely different output from your tests. For more
details, see [sample9_unittest.cc]. details, see [sample9_unittest.cc].
[sample9_unittest.cc]: https://github.com/google/googletest/blob/master/googletest/samples/sample9_unittest.cc "Event listener example" [sample9_unittest.cc]: https://github.com/google/googletest/blob/main/googletest/samples/sample9_unittest.cc "Event listener example"
You may append more than one listener to the list. When an `On*Start()` or You may append more than one listener to the list. When an `On*Start()` or
`OnTestPartResult()` event is fired, the listeners will receive it in the order `OnTestPartResult()` event is fired, the listeners will receive it in the order
@ -1760,7 +1760,7 @@ by the former.
See [sample10_unittest.cc] for an example of a failure-raising listener. See [sample10_unittest.cc] for an example of a failure-raising listener.
[sample10_unittest.cc]: https://github.com/google/googletest/blob/master/googletest/samples/sample10_unittest.cc "Failure-raising listener example" [sample10_unittest.cc]: https://github.com/google/googletest/blob/main/googletest/samples/sample10_unittest.cc "Failure-raising listener example"
## Running Test Programs: Advanced Options ## Running Test Programs: Advanced Options

View File

@ -267,7 +267,7 @@ If necessary, you can continue to derive test fixtures from a derived fixture.
GoogleTest has no limit on how deep the hierarchy can be. GoogleTest has no limit on how deep the hierarchy can be.
For a complete example using derived test fixtures, see For a complete example using derived test fixtures, see
[sample5_unittest.cc](https://github.com/google/googletest/blob/master/googletest/samples/sample5_unittest.cc). [sample5_unittest.cc](https://github.com/google/googletest/blob/main/googletest/samples/sample5_unittest.cc).
## My compiler complains "void value not ignored as it ought to be." What does this mean? ## My compiler complains "void value not ignored as it ought to be." What does this mean?

View File

@ -1424,11 +1424,12 @@ Use `Pair` when comparing maps or other associative containers.
{% raw %} {% raw %}
```cpp ```cpp
using testing::ElementsAre; using ::testing::UnorderedElementsAre;
using testing::Pair; using ::testing::Pair;
... ...
std::map<string, int> m = {{"a", 1}, {"b", 2}, {"c", 3}}; absl::flat_hash_map<string, int> m = {{"a", 1}, {"b", 2}, {"c", 3}};
EXPECT_THAT(m, ElementsAre(Pair("a", 1), Pair("b", 2), Pair("c", 3))); EXPECT_THAT(m, UnorderedElementsAre(
Pair("a", 1), Pair("b", 2), Pair("c", 3)));
``` ```
{% endraw %} {% endraw %}
@ -1445,8 +1446,8 @@ using testing::Pair;
* If the container is passed by pointer instead of by reference, just write * If the container is passed by pointer instead of by reference, just write
`Pointee(ElementsAre*(...))`. `Pointee(ElementsAre*(...))`.
* The order of elements *matters* for `ElementsAre*()`. If you are using it * The order of elements *matters* for `ElementsAre*()`. If you are using it
with containers whose element order are undefined (e.g. `hash_map`) you with containers whose element order are undefined (such as a
should use `WhenSorted` around `ElementsAre`. `std::unordered_map`) you should use `UnorderedElementsAre`.
### Sharing Matchers ### Sharing Matchers

View File

@ -17,7 +17,7 @@ See [Supported Platforms](platforms.md) for more information about platforms
compatible with GoogleTest. compatible with GoogleTest.
If you don't already have Bazel installed, see the If you don't already have Bazel installed, see the
[Bazel installation guide](https://docs.bazel.build/versions/main/install.html). [Bazel installation guide](https://bazel.build/install).
{: .callout .note} {: .callout .note}
Note: The terminal commands in this tutorial show a Unix shell prompt, but the Note: The terminal commands in this tutorial show a Unix shell prompt, but the

View File

@ -109,7 +109,7 @@ namespace:
| `ValuesIn(container)` or `ValuesIn(begin,end)` | Yields values from a C-style array, an STL-style container, or an iterator range `[begin, end)`. | | `ValuesIn(container)` or `ValuesIn(begin,end)` | Yields values from a C-style array, an STL-style container, or an iterator range `[begin, end)`. |
| `Bool()` | Yields sequence `{false, true}`. | | `Bool()` | Yields sequence `{false, true}`. |
| `Combine(g1, g2, ..., gN)` | Yields as `std::tuple` *n*-tuples all combinations (Cartesian product) of the values generated by the given *n* generators `g1`, `g2`, ..., `gN`. | | `Combine(g1, g2, ..., gN)` | Yields as `std::tuple` *n*-tuples all combinations (Cartesian product) of the values generated by the given *n* generators `g1`, `g2`, ..., `gN`. |
| `ConvertGenerator<T>(g)` | Yields values generated by generator `g`, `static_cast` to `T`. |
The optional last argument *`name_generator`* is a function or functor that The optional last argument *`name_generator`* is a function or functor that
generates custom test name suffixes based on the test parameters. The function generates custom test name suffixes based on the test parameters. The function
must accept an argument of type must accept an argument of type

View File

@ -1,7 +1,7 @@
# Googletest Samples # Googletest Samples
If you're like us, you'd like to look at If you're like us, you'd like to look at
[googletest samples.](https://github.com/google/googletest/tree/master/googletest/samples) [googletest samples.](https://github.com/google/googletest/blob/main/googletest/samples)
The sample directory has a number of well-commented samples showing how to use a The sample directory has a number of well-commented samples showing how to use a
variety of googletest features. variety of googletest features.

View File

@ -122,7 +122,7 @@
// MORE INFORMATION: // MORE INFORMATION:
// //
// To learn more about using these macros, please search for 'ACTION' on // To learn more about using these macros, please search for 'ACTION' on
// https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md // https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md
// IWYU pragma: private, include "gmock/gmock.h" // IWYU pragma: private, include "gmock/gmock.h"
// IWYU pragma: friend gmock/.* // IWYU pragma: friend gmock/.*
@ -1428,8 +1428,10 @@ struct WithArgsAction {
// MSVC complains about the I parameter pack not being // MSVC complains about the I parameter pack not being
// expanded (error C3520) despite it being expanded in the // expanded (error C3520) despite it being expanded in the
// type alias. // type alias.
OnceAction<R(typename std::tuple_element< // TupleElement is also an MSVC workaround.
I, std::tuple<Args...>>::type...)>>::value, // See its definition for details.
OnceAction<R(internal::TupleElement<
I, std::tuple<Args...>>...)>>::value,
int>::type = 0> int>::type = 0>
operator OnceAction<R(Args...)>() && { // NOLINT operator OnceAction<R(Args...)>() && { // NOLINT
struct OA { struct OA {
@ -1453,8 +1455,10 @@ struct WithArgsAction {
// MSVC complains about the I parameter pack not being // MSVC complains about the I parameter pack not being
// expanded (error C3520) despite it being expanded in the // expanded (error C3520) despite it being expanded in the
// type alias. // type alias.
Action<R(typename std::tuple_element< // TupleElement is also an MSVC workaround.
I, std::tuple<Args...>>::type...)>>::value, // See its definition for details.
Action<R(internal::TupleElement<
I, std::tuple<Args...>>...)>>::value,
int>::type = 0> int>::type = 0>
operator Action<R(Args...)>() const { // NOLINT operator Action<R(Args...)>() const { // NOLINT
Action<InnerSignature<R, Args...>> converted(inner_action); Action<InnerSignature<R, Args...>> converted(inner_action);

View File

@ -34,8 +34,8 @@
// IWYU pragma: private, include "gmock/gmock.h" // IWYU pragma: private, include "gmock/gmock.h"
// IWYU pragma: friend gmock/.* // IWYU pragma: friend gmock/.*
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_
#include <type_traits> // IWYU pragma: keep #include <type_traits> // IWYU pragma: keep
#include <utility> // IWYU pragma: keep #include <utility> // IWYU pragma: keep
@ -511,4 +511,4 @@ using internal::FunctionMocker;
#define GMOCK_MOCKER_(arity, constness, Method) \ #define GMOCK_MOCKER_(arity, constness, Method) \
GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__) GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ #endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_

View File

@ -240,7 +240,7 @@
// //
// To learn more about using these macros, please search for 'MATCHER' // To learn more about using these macros, please search for 'MATCHER'
// on // on
// https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md // https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md
// //
// This file also implements some commonly used argument matchers. More // This file also implements some commonly used argument matchers. More
// matchers can be defined by the user implementing the // matchers can be defined by the user implementing the
@ -3240,6 +3240,16 @@ auto UnpackStructImpl(const T& t, MakeIndexSequence<17>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q] = t; const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q); return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q);
} }
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<18>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<19>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s);
}
#endif // defined(__cpp_structured_bindings) #endif // defined(__cpp_structured_bindings)
template <size_t I, typename T> template <size_t I, typename T>

View File

@ -40,6 +40,9 @@
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_ #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_ #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_
#include <ostream>
#include <string>
#include "gmock/gmock-matchers.h" #include "gmock/gmock-matchers.h"
namespace testing { namespace testing {
@ -56,16 +59,44 @@ namespace testing {
#endif #endif
#endif #endif
// Defines a matcher that matches an empty container. The container must namespace internal {
// support both size() and empty(), which all STL-like containers provide.
MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") { // Implements the polymorphic IsEmpty matcher, which
if (arg.empty()) { // can be used as a Matcher<T> as long as T is either a container that defines
// empty() and size() (e.g. std::vector or std::string), or a C-style string.
class IsEmptyMatcher {
public:
// Matches anything that defines empty() and size().
template <typename MatcheeContainerType>
bool MatchAndExplain(const MatcheeContainerType& c,
MatchResultListener* listener) const {
if (c.empty()) {
return true; return true;
} }
*result_listener << "whose size is " << arg.size(); *listener << "whose size is " << c.size();
return false; return false;
} }
// Matches C-style strings.
bool MatchAndExplain(const char* s, MatchResultListener* listener) const {
return MatchAndExplain(std::string(s), listener);
}
// Describes what this matcher matches.
void DescribeTo(std::ostream* os) const { *os << "is empty"; }
void DescribeNegationTo(std::ostream* os) const { *os << "isn't empty"; }
};
} // namespace internal
// Creates a polymorphic matcher that matches an empty container or C-style
// string. The container must support both size() and empty(), which all
// STL-like containers provide.
inline PolymorphicMatcher<internal::IsEmptyMatcher> IsEmpty() {
return MakePolymorphicMatcher(internal::IsEmptyMatcher());
}
// Define a matcher that matches a value that evaluates in boolean // Define a matcher that matches a value that evaluates in boolean
// context to true. Useful for types that define "explicit operator // context to true. Useful for types that define "explicit operator
// bool" operators and so can't be compared for equality with true // bool" operators and so can't be compared for equality with true

View File

@ -290,13 +290,6 @@ class WithoutMatchers {
// Internal use only: access the singleton instance of WithoutMatchers. // Internal use only: access the singleton instance of WithoutMatchers.
GTEST_API_ WithoutMatchers GetWithoutMatchers(); GTEST_API_ WithoutMatchers GetWithoutMatchers();
// Disable MSVC warnings for infinite recursion, since in this case the
// recursion is unreachable.
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4717)
#endif
// Invalid<T>() is usable as an expression of type T, but will terminate // Invalid<T>() is usable as an expression of type T, but will terminate
// the program with an assertion failure if actually run. This is useful // the program with an assertion failure if actually run. This is useful
// when a value of type T is needed for compilation, but the statement // when a value of type T is needed for compilation, but the statement
@ -314,10 +307,6 @@ inline T Invalid() {
#endif #endif
} }
#ifdef _MSC_VER
#pragma warning(pop)
#endif
// Given a raw type (i.e. having no top-level reference or const // Given a raw type (i.e. having no top-level reference or const
// modifier) RawContainer that's either an STL-style container or a // modifier) RawContainer that's either an STL-style container or a
// native array, class StlContainerView<RawContainer> has the // native array, class StlContainerView<RawContainer> has the
@ -464,6 +453,13 @@ struct Function<R(Args...)> {
template <typename R, typename... Args> template <typename R, typename... Args>
constexpr size_t Function<R(Args...)>::ArgumentCount; constexpr size_t Function<R(Args...)>::ArgumentCount;
// Workaround for MSVC error C2039: 'type': is not a member of 'std'
// when std::tuple_element is used.
// See: https://github.com/google/googletest/issues/3931
// Can be replaced with std::tuple_element_t in C++14.
template <size_t I, typename T>
using TupleElement = typename std::tuple_element<I, T>::type;
bool Base64Unescape(const std::string& encoded, std::string* decoded); bool Base64Unescape(const std::string& encoded, std::string* decoded);
#ifdef _MSC_VER #ifdef _MSC_VER

View File

@ -200,8 +200,9 @@ GTEST_API_ void IllegalDoDefault(const char* file, int line) {
constexpr char UnBase64Impl(char c, const char* const base64, char carry) { constexpr char UnBase64Impl(char c, const char* const base64, char carry) {
return *base64 == 0 ? static_cast<char>(65) return *base64 == 0 ? static_cast<char>(65)
: *base64 == c ? carry : *base64 == c
: UnBase64Impl(c, base64 + 1, carry + 1); ? carry
: UnBase64Impl(c, base64 + 1, static_cast<char>(carry + 1));
} }
template <size_t... I> template <size_t... I>

View File

@ -51,6 +51,9 @@
#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC #if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC
#include <unistd.h> // NOLINT #include <unistd.h> // NOLINT
#endif #endif
#if GTEST_OS_QURT
#include <qurt_event.h>
#endif
// Silence C4800 (C4800: 'int *const ': forcing value // Silence C4800 (C4800: 'int *const ': forcing value
// to bool 'true' or 'false') for MSVC 15 // to bool 'true' or 'false') for MSVC 15
@ -295,7 +298,7 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg) {
"call should not happen. Do not suppress it by blindly adding " "call should not happen. Do not suppress it by blindly adding "
"an EXPECT_CALL() if you don't mean to enforce the call. " "an EXPECT_CALL() if you don't mean to enforce the call. "
"See " "See "
"https://github.com/google/googletest/blob/master/docs/" "https://github.com/google/googletest/blob/main/docs/"
"gmock_cook_book.md#" "gmock_cook_book.md#"
"knowing-when-to-expect for details.\n", "knowing-when-to-expect for details.\n",
stack_frames_to_skip); stack_frames_to_skip);
@ -521,8 +524,12 @@ class MockObjectRegistry {
// RUN_ALL_TESTS() has already returned when this destructor is // RUN_ALL_TESTS() has already returned when this destructor is
// called. Therefore we cannot use the normal Google Test // called. Therefore we cannot use the normal Google Test
// failure reporting mechanism. // failure reporting mechanism.
#if GTEST_OS_QURT
qurt_exception_raise_fatal();
#else
_exit(1); // We cannot call exit() as it is not reentrant and _exit(1); // We cannot call exit() as it is not reentrant and
// may already have been called. // may already have been called.
#endif
} }
} }

View File

@ -39,6 +39,8 @@
#pragma warning(disable : 4100) #pragma warning(disable : 4100)
#endif #endif
#include <vector>
#include "test/gmock-matchers_test.h" #include "test/gmock-matchers_test.h"
namespace testing { namespace testing {
@ -983,6 +985,30 @@ TEST(ComparisonBaseTest, WorksWithMoveOnly) {
helper.Call(MoveOnly(1)); helper.Call(MoveOnly(1));
} }
TEST(IsEmptyTest, MatchesContainer) {
const Matcher<std::vector<int>> m = IsEmpty();
std::vector<int> a = {};
std::vector<int> b = {1};
EXPECT_TRUE(m.Matches(a));
EXPECT_FALSE(m.Matches(b));
}
TEST(IsEmptyTest, MatchesStdString) {
const Matcher<std::string> m = IsEmpty();
std::string a = "z";
std::string b = "";
EXPECT_FALSE(m.Matches(a));
EXPECT_TRUE(m.Matches(b));
}
TEST(IsEmptyTest, MatchesCString) {
const Matcher<const char*> m = IsEmpty();
const char a[] = "";
const char b[] = "x";
EXPECT_TRUE(m.Matches(a));
EXPECT_FALSE(m.Matches(b));
}
// Tests that IsNull() matches any NULL pointer of any type. // Tests that IsNull() matches any NULL pointer of any type.
TEST(IsNullTest, MatchesNullPointer) { TEST(IsNullTest, MatchesNullPointer) {
Matcher<int*> m1 = IsNull(); Matcher<int*> m1 = IsNull();
@ -1684,6 +1710,21 @@ TEST(FieldsAreTest, StructuredBindings) {
}; };
EXPECT_THAT(MyVarType16{}, EXPECT_THAT(MyVarType16{},
FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
struct MyVarType17 {
int a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q;
};
EXPECT_THAT(MyVarType17{},
FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
struct MyVarType18 {
int a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r;
};
EXPECT_THAT(MyVarType18{},
FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
struct MyVarType19 {
int a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s;
};
EXPECT_THAT(MyVarType19{}, FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0));
} }
#endif #endif

View File

@ -2059,7 +2059,7 @@ class GMockVerboseFlagTest : public VerboseFlagPreservingFixture {
"call should not happen. Do not suppress it by blindly adding " "call should not happen. Do not suppress it by blindly adding "
"an EXPECT_CALL() if you don't mean to enforce the call. " "an EXPECT_CALL() if you don't mean to enforce the call. "
"See " "See "
"https://github.com/google/googletest/blob/master/docs/" "https://github.com/google/googletest/blob/main/docs/"
"gmock_cook_book.md#" "gmock_cook_book.md#"
"knowing-when-to-expect for details."; "knowing-when-to-expect for details.";

View File

@ -75,14 +75,14 @@ GMOCK WARNING:
Uninteresting mock function call - returning default value. Uninteresting mock function call - returning default value.
Function call: Bar2(0, 1) Function call: Bar2(0, 1)
Returns: false Returns: false
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md#knowing-when-to-expect for details. NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md#knowing-when-to-expect for details.
[ OK ] GMockOutputTest.UninterestingCall [ OK ] GMockOutputTest.UninterestingCall
[ RUN ] GMockOutputTest.UninterestingCallToVoidFunction [ RUN ] GMockOutputTest.UninterestingCallToVoidFunction
GMOCK WARNING: GMOCK WARNING:
Uninteresting mock function call - returning directly. Uninteresting mock function call - returning directly.
Function call: Bar3(0, 1) Function call: Bar3(0, 1)
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md#knowing-when-to-expect for details. NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md#knowing-when-to-expect for details.
[ OK ] GMockOutputTest.UninterestingCallToVoidFunction [ OK ] GMockOutputTest.UninterestingCallToVoidFunction
[ RUN ] GMockOutputTest.RetiredExpectation [ RUN ] GMockOutputTest.RetiredExpectation
unknown file: Failure unknown file: Failure
@ -266,14 +266,14 @@ Uninteresting mock function call - taking default action specified at:
FILE:#: FILE:#:
Function call: Bar2(2, 2) Function call: Bar2(2, 2)
Returns: true Returns: true
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md#knowing-when-to-expect for details. NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md#knowing-when-to-expect for details.
GMOCK WARNING: GMOCK WARNING:
Uninteresting mock function call - taking default action specified at: Uninteresting mock function call - taking default action specified at:
FILE:#: FILE:#:
Function call: Bar2(1, 1) Function call: Bar2(1, 1)
Returns: false Returns: false
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md#knowing-when-to-expect for details. NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md#knowing-when-to-expect for details.
[ OK ] GMockOutputTest.UninterestingCallWithDefaultAction [ OK ] GMockOutputTest.UninterestingCallWithDefaultAction
[ RUN ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction [ RUN ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction

View File

@ -125,6 +125,22 @@ include_directories(${gtest_build_include_dirs})
# aggressive about warnings. # aggressive about warnings.
cxx_library(gtest "${cxx_strict}" src/gtest-all.cc) cxx_library(gtest "${cxx_strict}" src/gtest-all.cc)
set_target_properties(gtest PROPERTIES VERSION ${GOOGLETEST_VERSION}) set_target_properties(gtest PROPERTIES VERSION ${GOOGLETEST_VERSION})
if(GTEST_HAS_ABSL)
target_compile_definitions(gtest PUBLIC GTEST_HAS_ABSL=1)
target_link_libraries(gtest PUBLIC
absl::failure_signal_handler
absl::stacktrace
absl::symbolize
absl::flags_parse
absl::flags_reflection
absl::flags_usage
absl::strings
absl::any
absl::optional
absl::variant
re2::re2
)
endif()
cxx_library(gtest_main "${cxx_strict}" src/gtest_main.cc) cxx_library(gtest_main "${cxx_strict}" src/gtest_main.cc)
set_target_properties(gtest_main PROPERTIES VERSION ${GOOGLETEST_VERSION}) set_target_properties(gtest_main PROPERTIES VERSION ${GOOGLETEST_VERSION})
# If the CMake version supports it, attach header directory information # If the CMake version supports it, attach header directory information

View File

@ -9,7 +9,7 @@ depends on which build system you use, and is usually straightforward.
### Build with CMake ### Build with CMake
GoogleTest comes with a CMake build script GoogleTest comes with a CMake build script
([CMakeLists.txt](https://github.com/google/googletest/blob/master/CMakeLists.txt)) ([CMakeLists.txt](https://github.com/google/googletest/blob/main/CMakeLists.txt))
that can be used on a wide range of platforms ("C" stands for cross-platform.). that can be used on a wide range of platforms ("C" stands for cross-platform.).
If you don't have CMake installed already, you can download it for free from If you don't have CMake installed already, you can download it for free from
<http://www.cmake.org/>. <http://www.cmake.org/>.
@ -25,7 +25,7 @@ When building GoogleTest as a standalone project, the typical workflow starts
with with
``` ```
git clone https://github.com/google/googletest.git -b release-1.12.0 git clone https://github.com/google/googletest.git -b release-1.12.1
cd googletest # Main directory of the cloned repository. cd googletest # Main directory of the cloned repository.
mkdir build # Create a directory to hold the build output. mkdir build # Create a directory to hold the build output.
cd build cd build
@ -140,7 +140,7 @@ command line. Generally, these macros are named like `GTEST_XYZ` and you define
them to either 1 or 0 to enable or disable a certain feature. them to either 1 or 0 to enable or disable a certain feature.
We list the most frequently used macros below. For a complete list, see file We list the most frequently used macros below. For a complete list, see file
[include/gtest/internal/gtest-port.h](https://github.com/google/googletest/blob/master/googletest/include/gtest/internal/gtest-port.h). [include/gtest/internal/gtest-port.h](https://github.com/google/googletest/blob/main/googletest/include/gtest/internal/gtest-port.h).
### Multi-threaded Tests ### Multi-threaded Tests

View File

@ -21,8 +21,9 @@ endif (POLICY CMP0054)
# This must be a macro(), as inside a function string() can only # This must be a macro(), as inside a function string() can only
# update variables in the function scope. # update variables in the function scope.
macro(fix_default_compiler_settings_) macro(fix_default_compiler_settings_)
if (MSVC) if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC|Clang")
# For MSVC, CMake sets certain flags to defaults we want to override. # For MSVC and Clang, CMake sets certain flags to defaults we want to
# override.
# This replacement code is taken from sample in the CMake Wiki at # This replacement code is taken from sample in the CMake Wiki at
# https://gitlab.kitware.com/cmake/community/wikis/FAQ#dynamic-replace. # https://gitlab.kitware.com/cmake/community/wikis/FAQ#dynamic-replace.
foreach (flag_var foreach (flag_var
@ -39,6 +40,10 @@ macro(fix_default_compiler_settings_)
# on CRT DLLs being available. CMake always defaults to using shared # on CRT DLLs being available. CMake always defaults to using shared
# CRT libraries, so we override that default here. # CRT libraries, so we override that default here.
string(REPLACE "/MD" "-MT" ${flag_var} "${${flag_var}}") string(REPLACE "/MD" "-MT" ${flag_var} "${${flag_var}}")
# When using Ninja with Clang, static builds pass -D_DLL on Windows.
# This is incorrect and should not happen, so we fix that here.
string(REPLACE "-D_DLL" "" ${flag_var} "${${flag_var}}")
endif() endif()
# We prefer more strict warning checking for building Google Test. # We prefer more strict warning checking for building Google Test.

View File

@ -842,7 +842,7 @@ class MatchesRegexMatcher {
template <class MatcheeStringType> template <class MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s, bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const { MatchResultListener* /* listener */) const {
const std::string& s2(s); const std::string s2(s);
return full_match_ ? RE::FullMatch(s2, *regex_) return full_match_ ? RE::FullMatch(s2, *regex_)
: RE::PartialMatch(s2, *regex_); : RE::PartialMatch(s2, *regex_);
} }

View File

@ -407,9 +407,49 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
return internal::CartesianProductHolder<Generator...>(g...); return internal::CartesianProductHolder<Generator...>(g...);
} }
// ConvertGenerator() wraps a parameter generator in order to cast each prduced
// value through a known type before supplying it to the test suite
//
// Synopsis:
// ConvertGenerator<T>(gen)
// - returns a generator producing the same elements as generated by gen, but
// each element is static_cast to type T before being returned
//
// It is useful when using the Combine() function to get the generated
// parameters in a custom type instead of std::tuple
//
// Example:
//
// This will instantiate tests in test suite AnimalTest each one with
// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
// tuple("dog", BLACK), and tuple("dog", WHITE):
//
// enum Color { BLACK, GRAY, WHITE };
// struct ParamType {
// using TupleT = std::tuple<const char*, Color>;
// std::string animal;
// Color color;
// ParamType(TupleT t) : animal(std::get<0>(t)), color(std::get<1>(t)) {}
// };
// class AnimalTest
// : public testing::TestWithParam<ParamType> {...};
//
// TEST_P(AnimalTest, AnimalLooksNice) {...}
//
// INSTANTIATE_TEST_SUITE_P(AnimalVariations, AnimalTest,
// ConvertGenerator<ParamType::TupleT>(
// Combine(Values("cat", "dog"),
// Values(BLACK, WHITE))));
//
template <typename T>
internal::ParamConverterGenerator<T> ConvertGenerator(
internal::ParamGenerator<T> gen) {
return internal::ParamConverterGenerator<T>(gen);
}
#define TEST_P(test_suite_name, test_name) \ #define TEST_P(test_suite_name, test_name) \
class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \ class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
: public test_suite_name { \ : public test_suite_name, private ::testing::internal::GTestNonCopyable {\
public: \ public: \
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \ GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \
void TestBody() override; \ void TestBody() override; \
@ -429,11 +469,6 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
return 0; \ return 0; \
} \ } \
static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \ static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
(const GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) &) = delete; \
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) & operator=( \
const GTEST_TEST_CLASS_NAME_(test_suite_name, \
test_name) &) = delete; /* NOLINT */ \
}; \ }; \
int GTEST_TEST_CLASS_NAME_(test_suite_name, \ int GTEST_TEST_CLASS_NAME_(test_suite_name, \
test_name)::gtest_registering_dummy_ = \ test_name)::gtest_registering_dummy_ = \

View File

@ -384,7 +384,7 @@ GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char32_t);
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string);
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string);
#ifdef __cpp_char8_t #ifdef __cpp_lib_char8_t
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char8_t, ::std::u8string); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char8_t, ::std::u8string);
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char8_t, ::std::u8string); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char8_t, ::std::u8string);
#endif #endif
@ -556,7 +556,7 @@ inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
} }
// Overloads for ::std::u8string // Overloads for ::std::u8string
#ifdef __cpp_char8_t #ifdef __cpp_lib_char8_t
GTEST_API_ void PrintU8StringTo(const ::std::u8string& s, ::std::ostream* os); GTEST_API_ void PrintU8StringTo(const ::std::u8string& s, ::std::ostream* os);
inline void PrintTo(const ::std::u8string& s, ::std::ostream* os) { inline void PrintTo(const ::std::u8string& s, ::std::ostream* os) {
PrintU8StringTo(s, os); PrintU8StringTo(s, os);
@ -891,6 +891,13 @@ class UniversalTersePrinter<T&> {
UniversalPrint(value, os); UniversalPrint(value, os);
} }
}; };
template <typename T>
class UniversalTersePrinter<std::reference_wrapper<T>> {
public:
static void Print(std::reference_wrapper<T> value, ::std::ostream* os) {
UniversalTersePrinter<T>::Print(value.get(), os);
}
};
template <typename T, size_t N> template <typename T, size_t N>
class UniversalTersePrinter<T[N]> { class UniversalTersePrinter<T[N]> {
public: public:

View File

@ -190,6 +190,17 @@ void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
const std::string& message); const std::string& message);
std::set<std::string>* GetIgnoredParameterizedTestSuites(); std::set<std::string>* GetIgnoredParameterizedTestSuites();
// A base class that prevents subclasses from being copyable.
// We do this instead of using '= delete' so as to avoid triggering warnings
// inside user code regarding any of our declarations.
class GTestNonCopyable {
public:
GTestNonCopyable() = default;
GTestNonCopyable(const GTestNonCopyable &) = delete;
GTestNonCopyable &operator=(const GTestNonCopyable &) = delete;
~GTestNonCopyable() = default;
};
} // namespace internal } // namespace internal
// The friend relationship of some of these classes is cyclic. // The friend relationship of some of these classes is cyclic.
@ -1625,7 +1636,7 @@ class GTEST_API_ AssertHelper {
// the GetParam() method. // the GetParam() method.
// //
// Use it with one of the parameter generator defining functions, like Range(), // Use it with one of the parameter generator defining functions, like Range(),
// Values(), ValuesIn(), Bool(), and Combine(). // Values(), ValuesIn(), Bool(), Combine(), and ConvertGenerator<T>().
// //
// class FooTest : public ::testing::TestWithParam<int> { // class FooTest : public ::testing::TestWithParam<int> {
// protected: // protected:

View File

@ -199,6 +199,16 @@ class GTEST_API_ FilePath {
// separators. Returns NULL if no path separator was found. // separators. Returns NULL if no path separator was found.
const char* FindLastPathSeparator() const; const char* FindLastPathSeparator() const;
// Returns the length of the path root, including the directory separator at
// the end of the prefix. Returns zero by definition if the path is relative.
// Examples:
// - [Windows] "..\Sibling" => 0
// - [Windows] "\Windows" => 1
// - [Windows] "C:/Windows\Notepad.exe" => 3
// - [Windows] "\\Host\Share\C$/Windows" => 13
// - [UNIX] "/bin" => 1
size_t CalculateRootLength() const;
std::string pathname_; std::string pathname_;
}; // class FilePath }; // class FilePath

View File

@ -950,6 +950,78 @@ class CartesianProductHolder {
std::tuple<Gen...> generators_; std::tuple<Gen...> generators_;
}; };
template <typename From, typename To>
class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
public:
ParamGeneratorConverter(ParamGenerator<From> gen) // NOLINT
: generator_(std::move(gen)) {}
ParamIteratorInterface<To>* Begin() const override {
return new Iterator(this, generator_.begin(), generator_.end());
}
ParamIteratorInterface<To>* End() const override {
return new Iterator(this, generator_.end(), generator_.end());
}
private:
class Iterator : public ParamIteratorInterface<To> {
public:
Iterator(const ParamGeneratorInterface<To>* base, ParamIterator<From> it,
ParamIterator<From> end)
: base_(base), it_(it), end_(end) {
if (it_ != end_) value_ = std::make_shared<To>(static_cast<To>(*it_));
}
~Iterator() override {}
const ParamGeneratorInterface<To>* BaseGenerator() const override {
return base_;
}
void Advance() override {
++it_;
if (it_ != end_) value_ = std::make_shared<To>(static_cast<To>(*it_));
}
ParamIteratorInterface<To>* Clone() const override {
return new Iterator(*this);
}
const To* Current() const override { return value_.get(); }
bool Equals(const ParamIteratorInterface<To>& other) const override {
// Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
const ParamIterator<From> other_it =
CheckedDowncastToActualType<const Iterator>(&other)->it_;
return it_ == other_it;
}
private:
Iterator(const Iterator& other) = default;
const ParamGeneratorInterface<To>* const base_;
ParamIterator<From> it_;
ParamIterator<From> end_;
std::shared_ptr<To> value_;
}; // class ParamGeneratorConverter::Iterator
ParamGenerator<From> generator_;
}; // class ParamGeneratorConverter
template <class Gen>
class ParamConverterGenerator {
public:
ParamConverterGenerator(ParamGenerator<Gen> g) // NOLINT
: generator_(std::move(g)) {}
template <typename T>
operator ParamGenerator<T>() const { // NOLINT
return ParamGenerator<T>(new ParamGeneratorConverter<Gen, T>(generator_));
}
private:
ParamGenerator<Gen> generator_;
};
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing

View File

@ -111,6 +111,8 @@
#define GTEST_OS_ESP32 1 #define GTEST_OS_ESP32 1
#elif defined(__XTENSA__) #elif defined(__XTENSA__)
#define GTEST_OS_XTENSA 1 #define GTEST_OS_XTENSA 1
#elif defined(__hexagon__)
#define GTEST_OS_QURT 1
#endif // __CYGWIN__ #endif // __CYGWIN__
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_

View File

@ -385,7 +385,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// On Android, <regex.h> is only available starting with Gingerbread. // On Android, <regex.h> is only available starting with Gingerbread.
#define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9) #define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9)
#else #else
#define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS && !GTEST_OS_XTENSA) #define GTEST_HAS_POSIX_RE \
!(GTEST_OS_WINDOWS || GTEST_OS_XTENSA || GTEST_OS_QURT)
#endif #endif
#endif #endif
@ -457,7 +458,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// no support for it at least as recent as Froyo (2.2). // no support for it at least as recent as Froyo (2.2).
#define GTEST_HAS_STD_WSTRING \ #define GTEST_HAS_STD_WSTRING \
(!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ (!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \
GTEST_OS_HAIKU || GTEST_OS_ESP32 || GTEST_OS_ESP8266 || GTEST_OS_XTENSA)) GTEST_OS_HAIKU || GTEST_OS_ESP32 || GTEST_OS_ESP8266 || \
GTEST_OS_XTENSA || GTEST_OS_QURT))
#endif // GTEST_HAS_STD_WSTRING #endif // GTEST_HAS_STD_WSTRING
@ -578,9 +580,10 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// output correctness and to implement death tests. // output correctness and to implement death tests.
#ifndef GTEST_HAS_STREAM_REDIRECTION #ifndef GTEST_HAS_STREAM_REDIRECTION
// By default, we assume that stream redirection is supported on all // By default, we assume that stream redirection is supported on all
// platforms except known mobile ones. // platforms except known mobile / embedded ones.
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \ #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \
GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_XTENSA GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_XTENSA || \
GTEST_OS_QURT
#define GTEST_HAS_STREAM_REDIRECTION 0 #define GTEST_HAS_STREAM_REDIRECTION 0
#else #else
#define GTEST_HAS_STREAM_REDIRECTION 1 #define GTEST_HAS_STREAM_REDIRECTION 1
@ -639,6 +642,32 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
default: // NOLINT default: // NOLINT
#endif #endif
// GTEST_HAVE_ATTRIBUTE_
//
// A function-like feature checking macro that is a wrapper around
// `__has_attribute`, which is defined by GCC 5+ and Clang and evaluates to a
// nonzero constant integer if the attribute is supported or 0 if not.
//
// It evaluates to zero if `__has_attribute` is not defined by the compiler.
//
// GCC: https://gcc.gnu.org/gcc-5/changes.html
// Clang: https://clang.llvm.org/docs/LanguageExtensions.html
#ifdef __has_attribute
#define GTEST_HAVE_ATTRIBUTE_(x) __has_attribute(x)
#else
#define GTEST_HAVE_ATTRIBUTE_(x) 0
#endif
// GTEST_HAVE_FEATURE_
//
// A function-like feature checking macro that is a wrapper around
// `__has_feature`.
#ifdef __has_feature
#define GTEST_HAVE_FEATURE_(x) __has_feature(x)
#else
#define GTEST_HAVE_FEATURE_(x) 0
#endif
// Use this annotation at the end of a struct/class definition to // Use this annotation at the end of a struct/class definition to
// prevent the compiler from optimizing away instances that are never // prevent the compiler from optimizing away instances that are never
// used. This is useful when all interesting logic happens inside the // used. This is useful when all interesting logic happens inside the
@ -650,30 +679,22 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// //
// Also use it after a variable or parameter declaration to tell the // Also use it after a variable or parameter declaration to tell the
// compiler the variable/parameter does not have to be used. // compiler the variable/parameter does not have to be used.
#if defined(__GNUC__) && !defined(COMPILER_ICC) #if GTEST_HAVE_ATTRIBUTE_(unused)
#define GTEST_ATTRIBUTE_UNUSED_ __attribute__((unused)) #define GTEST_ATTRIBUTE_UNUSED_ __attribute__((unused))
#elif defined(__clang__) #else
#if __has_attribute(unused)
#define GTEST_ATTRIBUTE_UNUSED_ __attribute__((unused))
#endif
#endif
#ifndef GTEST_ATTRIBUTE_UNUSED_
#define GTEST_ATTRIBUTE_UNUSED_ #define GTEST_ATTRIBUTE_UNUSED_
#endif #endif
// Use this annotation before a function that takes a printf format string. // Use this annotation before a function that takes a printf format string.
#if (defined(__GNUC__) || defined(__clang__)) && !defined(COMPILER_ICC) #if GTEST_HAVE_ATTRIBUTE_(format) && defined(__MINGW_PRINTF_FORMAT)
#if defined(__MINGW_PRINTF_FORMAT)
// MinGW has two different printf implementations. Ensure the format macro // MinGW has two different printf implementations. Ensure the format macro
// matches the selected implementation. See // matches the selected implementation. See
// https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/. // https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/.
#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \ #define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \
__attribute__(( \ __attribute__((format(__MINGW_PRINTF_FORMAT, string_index, first_to_check)))
__format__(__MINGW_PRINTF_FORMAT, string_index, first_to_check))) #elif GTEST_HAVE_ATTRIBUTE_(format)
#else
#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \ #define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \
__attribute__((__format__(__printf__, string_index, first_to_check))) __attribute__((format(printf, string_index, first_to_check)))
#endif
#else #else
#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) #define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check)
#endif #endif
@ -683,11 +704,11 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// following the argument list: // following the argument list:
// //
// Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_; // Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_;
#if defined(__GNUC__) && !defined(COMPILER_ICC) #if GTEST_HAVE_ATTRIBUTE_(warn_unused_result)
#define GTEST_MUST_USE_RESULT_ __attribute__((warn_unused_result)) #define GTEST_MUST_USE_RESULT_ __attribute__((warn_unused_result))
#else #else
#define GTEST_MUST_USE_RESULT_ #define GTEST_MUST_USE_RESULT_
#endif // __GNUC__ && !COMPILER_ICC #endif
// MS C++ compiler emits warning when a conditional expression is compile time // MS C++ compiler emits warning when a conditional expression is compile time
// constant. In some contexts this warning is false positive and needs to be // constant. In some contexts this warning is false positive and needs to be
@ -743,7 +764,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#elif GTEST_CREATE_SHARED_LIBRARY #elif GTEST_CREATE_SHARED_LIBRARY
#define GTEST_API_ __declspec(dllexport) #define GTEST_API_ __declspec(dllexport)
#endif #endif
#elif __GNUC__ >= 4 || defined(__clang__) #elif GTEST_HAVE_ATTRIBUTE_(visibility)
#define GTEST_API_ __attribute__((visibility("default"))) #define GTEST_API_ __attribute__((visibility("default")))
#endif // _MSC_VER #endif // _MSC_VER
@ -757,20 +778,17 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#define GTEST_DEFAULT_DEATH_TEST_STYLE "fast" #define GTEST_DEFAULT_DEATH_TEST_STYLE "fast"
#endif // GTEST_DEFAULT_DEATH_TEST_STYLE #endif // GTEST_DEFAULT_DEATH_TEST_STYLE
#ifdef __GNUC__ #if GTEST_HAVE_ATTRIBUTE_(noinline)
// Ask the compiler to never inline a given function. // Ask the compiler to never inline a given function.
#define GTEST_NO_INLINE_ __attribute__((noinline)) #define GTEST_NO_INLINE_ __attribute__((noinline))
#else #else
#define GTEST_NO_INLINE_ #define GTEST_NO_INLINE_
#endif #endif
#if defined(__clang__) #if GTEST_HAVE_ATTRIBUTE_(disable_tail_calls)
// Nested ifs to avoid triggering MSVC warning.
#if __has_attribute(disable_tail_calls)
// Ask the compiler not to perform tail call optimization inside // Ask the compiler not to perform tail call optimization inside
// the marked function. // the marked function.
#define GTEST_NO_TAIL_CALL_ __attribute__((disable_tail_calls)) #define GTEST_NO_TAIL_CALL_ __attribute__((disable_tail_calls))
#endif
#elif __GNUC__ #elif __GNUC__
#define GTEST_NO_TAIL_CALL_ \ #define GTEST_NO_TAIL_CALL_ \
__attribute__((optimize("no-optimize-sibling-calls"))) __attribute__((optimize("no-optimize-sibling-calls")))
@ -789,50 +807,35 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// A function level attribute to disable checking for use of uninitialized // A function level attribute to disable checking for use of uninitialized
// memory when built with MemorySanitizer. // memory when built with MemorySanitizer.
#if defined(__clang__) #if GTEST_HAVE_ATTRIBUTE_(no_sanitize_memory)
#if __has_feature(memory_sanitizer)
#define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ __attribute__((no_sanitize_memory)) #define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ __attribute__((no_sanitize_memory))
#else #else
#define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ #define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
#endif // __has_feature(memory_sanitizer) #endif
#else
#define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
#endif // __clang__
// A function level attribute to disable AddressSanitizer instrumentation. // A function level attribute to disable AddressSanitizer instrumentation.
#if defined(__clang__) #if GTEST_HAVE_ATTRIBUTE_(no_sanitize_address)
#if __has_feature(address_sanitizer)
#define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ \ #define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ \
__attribute__((no_sanitize_address)) __attribute__((no_sanitize_address))
#else #else
#define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ #define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
#endif // __has_feature(address_sanitizer) #endif
#else
#define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
#endif // __clang__
// A function level attribute to disable HWAddressSanitizer instrumentation. // A function level attribute to disable HWAddressSanitizer instrumentation.
#if defined(__clang__) #if GTEST_HAVE_FEATURE_(hwaddress_sanitizer) && \
#if __has_feature(hwaddress_sanitizer) GTEST_HAVE_ATTRIBUTE_(no_sanitize)
#define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ \ #define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ \
__attribute__((no_sanitize("hwaddress"))) __attribute__((no_sanitize("hwaddress")))
#else #else
#define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ #define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
#endif // __has_feature(hwaddress_sanitizer) #endif
#else
#define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
#endif // __clang__
// A function level attribute to disable ThreadSanitizer instrumentation. // A function level attribute to disable ThreadSanitizer instrumentation.
#if defined(__clang__) #if GTEST_HAVE_ATTRIBUTE_(no_sanitize_thread)
#if __has_feature(thread_sanitizer) #define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ __attribute((no_sanitize_thread))
#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ __attribute__((no_sanitize_thread))
#else #else
#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ #define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
#endif // __has_feature(thread_sanitizer) #endif
#else
#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
#endif // __clang__
namespace testing { namespace testing {
@ -2019,7 +2022,12 @@ inline int StrCaseCmp(const char* s1, const char* s2) {
return strcasecmp(s1, s2); return strcasecmp(s1, s2);
} }
inline char* StrDup(const char* src) { return strdup(src); } inline char* StrDup(const char* src) { return strdup(src); }
#if GTEST_OS_QURT
// QuRT doesn't support any directory functions, including rmdir
inline int RmDir(const char*) { return 0; }
#else
inline int RmDir(const char* dir) { return rmdir(dir); } inline int RmDir(const char* dir) { return rmdir(dir); }
#endif
inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
@ -2044,7 +2052,8 @@ GTEST_DISABLE_MSC_DEPRECATED_PUSH_()
// defined there. // defined there.
#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && \ #if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && \
!GTEST_OS_WINDOWS_RT && !GTEST_OS_ESP8266 && !GTEST_OS_XTENSA !GTEST_OS_WINDOWS_RT && !GTEST_OS_ESP8266 && !GTEST_OS_XTENSA && \
!GTEST_OS_QURT
inline int ChDir(const char* dir) { return chdir(dir); } inline int ChDir(const char* dir) { return chdir(dir); }
#endif #endif
inline FILE* FOpen(const char* path, const char* mode) { inline FILE* FOpen(const char* path, const char* mode) {
@ -2058,14 +2067,14 @@ inline FILE* FOpen(const char* path, const char* mode) {
return fopen(path, mode); return fopen(path, mode);
#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW #endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW
} }
#if !GTEST_OS_WINDOWS_MOBILE #if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT
inline FILE* FReopen(const char* path, const char* mode, FILE* stream) { inline FILE* FReopen(const char* path, const char* mode, FILE* stream) {
return freopen(path, mode, stream); return freopen(path, mode, stream);
} }
inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); } inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); }
#endif #endif
inline int FClose(FILE* fp) { return fclose(fp); } inline int FClose(FILE* fp) { return fclose(fp); }
#if !GTEST_OS_WINDOWS_MOBILE #if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT
inline int Read(int fd, void* buf, unsigned int count) { inline int Read(int fd, void* buf, unsigned int count) {
return static_cast<int>(read(fd, buf, count)); return static_cast<int>(read(fd, buf, count));
} }
@ -2077,7 +2086,8 @@ inline const char* StrError(int errnum) { return strerror(errnum); }
#endif #endif
inline const char* GetEnv(const char* name) { inline const char* GetEnv(const char* name) {
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \ #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \
GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_XTENSA GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_XTENSA || \
GTEST_OS_QURT
// We are on an embedded platform, which has no environment variables. // We are on an embedded platform, which has no environment variables.
static_cast<void>(name); // To prevent 'unused argument' warning. static_cast<void>(name); // To prevent 'unused argument' warning.
return nullptr; return nullptr;

View File

@ -249,7 +249,7 @@ static std::string DeathTestThreadWarning(size_t thread_count) {
msg << "detected " << thread_count << " threads."; msg << "detected " << thread_count << " threads.";
} }
msg << " See " msg << " See "
"https://github.com/google/googletest/blob/master/docs/" "https://github.com/google/googletest/blob/main/docs/"
"advanced.md#death-tests-and-threads" "advanced.md#death-tests-and-threads"
<< " for more explanation and suggested solutions, especially if" << " for more explanation and suggested solutions, especially if"
<< " this is the last message you see before your test times out."; << " this is the last message you see before your test times out.";
@ -284,7 +284,7 @@ enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW };
// message is propagated back to the parent process. Otherwise, the // message is propagated back to the parent process. Otherwise, the
// message is simply printed to stderr. In either case, the program // message is simply printed to stderr. In either case, the program
// then exits with status 1. // then exits with status 1.
static void DeathTestAbort(const std::string& message) { [[noreturn]] static void DeathTestAbort(const std::string& message) {
// On a POSIX system, this function may be called from a threadsafe-style // On a POSIX system, this function may be called from a threadsafe-style
// death test child process, which operates on a very small stack. Use // death test child process, which operates on a very small stack. Use
// the heap for any additional non-minuscule memory requirements. // the heap for any additional non-minuscule memory requirements.

View File

@ -96,7 +96,7 @@ static bool IsPathSeparator(char c) {
FilePath FilePath::GetCurrentDir() { FilePath FilePath::GetCurrentDir() {
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \ #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \
GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_ESP32 || \ GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_ESP32 || \
GTEST_OS_XTENSA GTEST_OS_XTENSA || GTEST_OS_QURT
// These platforms do not have a current directory, so we just return // These platforms do not have a current directory, so we just return
// something reasonable. // something reasonable.
return FilePath(kCurrentDirectoryString); return FilePath(kCurrentDirectoryString);
@ -145,6 +145,45 @@ const char* FilePath::FindLastPathSeparator() const {
return last_sep; return last_sep;
} }
size_t FilePath::CalculateRootLength() const {
const auto &path = pathname_;
auto s = path.begin();
auto end = path.end();
#if GTEST_OS_WINDOWS
if (end - s >= 2 && s[1] == ':' &&
(end - s == 2 || IsPathSeparator(s[2])) &&
(('A' <= s[0] && s[0] <= 'Z') || ('a' <= s[0] && s[0] <= 'z'))) {
// A typical absolute path like "C:\Windows" or "D:"
s += 2;
if (s != end) {
++s;
}
} else if (end - s >= 3 && IsPathSeparator(*s) && IsPathSeparator(*(s + 1))
&& !IsPathSeparator(*(s + 2))) {
// Move past the "\\" prefix in a UNC path like "\\Server\Share\Folder"
s += 2;
// Skip 2 components and their following separators ("Server\" and "Share\")
for (int i = 0; i < 2; ++i) {
while (s != end) {
bool stop = IsPathSeparator(*s);
++s;
if (stop) {
break;
}
}
}
} else if (s != end && IsPathSeparator(*s)) {
// A drive-rooted path like "\Windows"
++s;
}
#else
if (s != end && IsPathSeparator(*s)) {
++s;
}
#endif
return static_cast<size_t>(s - path.begin());
}
// Returns a copy of the FilePath with the directory part removed. // Returns a copy of the FilePath with the directory part removed.
// Example: FilePath("path/to/file").RemoveDirectoryName() returns // Example: FilePath("path/to/file").RemoveDirectoryName() returns
// FilePath("file"). If there is no directory part ("just_a_file"), it returns // FilePath("file"). If there is no directory part ("just_a_file"), it returns
@ -246,26 +285,16 @@ bool FilePath::DirectoryExists() const {
} }
// Returns true if pathname describes a root directory. (Windows has one // Returns true if pathname describes a root directory. (Windows has one
// root directory per disk drive.) // root directory per disk drive. UNC share roots are also included.)
bool FilePath::IsRootDirectory() const { bool FilePath::IsRootDirectory() const {
#if GTEST_OS_WINDOWS size_t root_length = CalculateRootLength();
return pathname_.length() == 3 && IsAbsolutePath(); return root_length > 0 && root_length == pathname_.size() &&
#else IsPathSeparator(pathname_[root_length - 1]);
return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]);
#endif
} }
// Returns true if pathname describes an absolute path. // Returns true if pathname describes an absolute path.
bool FilePath::IsAbsolutePath() const { bool FilePath::IsAbsolutePath() const {
const char* const name = pathname_.c_str(); return CalculateRootLength() > 0;
#if GTEST_OS_WINDOWS
return pathname_.length() >= 3 &&
((name[0] >= 'a' && name[0] <= 'z') ||
(name[0] >= 'A' && name[0] <= 'Z')) &&
name[1] == ':' && IsPathSeparator(name[2]);
#else
return IsPathSeparator(name[0]);
#endif
} }
// Returns a pathname for a file that does not currently exist. The pathname // Returns a pathname for a file that does not currently exist. The pathname
@ -323,7 +352,7 @@ bool FilePath::CreateFolder() const {
delete[] unicode; delete[] unicode;
#elif GTEST_OS_WINDOWS #elif GTEST_OS_WINDOWS
int result = _mkdir(pathname_.c_str()); int result = _mkdir(pathname_.c_str());
#elif GTEST_OS_ESP8266 || GTEST_OS_XTENSA #elif GTEST_OS_ESP8266 || GTEST_OS_XTENSA || GTEST_OS_QURT
// do nothing // do nothing
int result = 0; int result = 0;
#else #else
@ -347,17 +376,27 @@ FilePath FilePath::RemoveTrailingPathSeparator() const {
// Removes any redundant separators that might be in the pathname. // Removes any redundant separators that might be in the pathname.
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other // For example, "bar///foo" becomes "bar/foo". Does not eliminate other
// redundancies that might be in a pathname involving "." or "..". // redundancies that might be in a pathname involving "." or "..".
// Note that "\\Host\Share" does not contain a redundancy on Windows!
void FilePath::Normalize() { void FilePath::Normalize() {
auto out = pathname_.begin(); auto out = pathname_.begin();
for (const char character : pathname_) { auto i = pathname_.cbegin();
#if GTEST_OS_WINDOWS
// UNC paths are treated specially
if (pathname_.end() - i >= 3 && IsPathSeparator(*i) &&
IsPathSeparator(*(i + 1)) && !IsPathSeparator(*(i + 2))) {
*(out++) = kPathSeparator;
*(out++) = kPathSeparator;
}
#endif
while (i != pathname_.end()) {
const char character = *i;
if (!IsPathSeparator(character)) { if (!IsPathSeparator(character)) {
*(out++) = character; *(out++) = character;
} else if (out == pathname_.begin() || *std::prev(out) != kPathSeparator) { } else if (out == pathname_.begin() || *std::prev(out) != kPathSeparator) {
*(out++) = kPathSeparator; *(out++) = kPathSeparator;
} else {
continue;
} }
++i;
} }
pathname_.erase(out, pathname_.end()); pathname_.erase(out, pathname_.end());

View File

@ -315,7 +315,7 @@ void PrintTo(__uint128_t v, ::std::ostream* os) {
low = low / 10 + high_mod * 1844674407370955161 + carry / 10; low = low / 10 + high_mod * 1844674407370955161 + carry / 10;
char digit = static_cast<char>(carry % 10); char digit = static_cast<char>(carry % 10);
*--p = '0' + digit; *--p = static_cast<char>('0' + digit);
} }
*os << p; *os << p;
} }

View File

@ -143,6 +143,14 @@
#include "absl/strings/str_replace.h" #include "absl/strings/str_replace.h"
#endif // GTEST_HAS_ABSL #endif // GTEST_HAS_ABSL
// Checks builtin compiler feature |x| while avoiding an extra layer of #ifdefs
// at the callsite.
#if defined(__has_builtin)
#define GTEST_HAS_BUILTIN(x) __has_builtin(x)
#else
#define GTEST_HAS_BUILTIN(x) 0
#endif // defined(__has_builtin)
namespace testing { namespace testing {
using internal::CountIf; using internal::CountIf;
@ -2713,7 +2721,8 @@ TestInfo::TestInfo(const std::string& a_test_suite_name,
internal::TypeId fixture_class_id, internal::TypeId fixture_class_id,
internal::TestFactoryBase* factory) internal::TestFactoryBase* factory)
: test_suite_name_(a_test_suite_name), : test_suite_name_(a_test_suite_name),
name_(a_name), // begin()/end() is MSVC 17.3.3 ASAN crash workaround (GitHub issue #3997)
name_(a_name.begin(), a_name.end()),
type_param_(a_type_param ? new std::string(a_type_param) : nullptr), type_param_(a_type_param ? new std::string(a_type_param) : nullptr),
value_param_(a_value_param ? new std::string(a_value_param) : nullptr), value_param_(a_value_param ? new std::string(a_value_param) : nullptr),
location_(a_code_location), location_(a_code_location),
@ -3247,18 +3256,15 @@ bool ShouldUseColor(bool stdout_is_tty) {
#else #else
// On non-Windows platforms, we rely on the TERM variable. // On non-Windows platforms, we rely on the TERM variable.
const char* const term = posix::GetEnv("TERM"); const char* const term = posix::GetEnv("TERM");
const bool term_supports_color = const bool term_supports_color = term != nullptr && (
String::CStringEquals(term, "xterm") || String::CStringEquals(term, "xterm") ||
String::CStringEquals(term, "xterm-color") || String::CStringEquals(term, "xterm-color") ||
String::CStringEquals(term, "xterm-256color") ||
String::CStringEquals(term, "screen") || String::CStringEquals(term, "screen") ||
String::CStringEquals(term, "screen-256color") ||
String::CStringEquals(term, "tmux") || String::CStringEquals(term, "tmux") ||
String::CStringEquals(term, "tmux-256color") ||
String::CStringEquals(term, "rxvt-unicode") || String::CStringEquals(term, "rxvt-unicode") ||
String::CStringEquals(term, "rxvt-unicode-256color") ||
String::CStringEquals(term, "linux") || String::CStringEquals(term, "linux") ||
String::CStringEquals(term, "cygwin"); String::CStringEquals(term, "cygwin") ||
String::EndsWithCaseInsensitive(term, "-256color"));
return stdout_is_tty && term_supports_color; return stdout_is_tty && term_supports_color;
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
} }
@ -4837,6 +4843,9 @@ void JsonUnitTestResultPrinter::PrintJsonUnitTest(std::ostream* stream,
// If there was a test failure outside of one of the test suites (like in a // If there was a test failure outside of one of the test suites (like in a
// test environment) include that in the output. // test environment) include that in the output.
if (unit_test.ad_hoc_test_result().Failed()) { if (unit_test.ad_hoc_test_result().Failed()) {
if (comma) {
*stream << ",\n";
}
OutputJsonTestSuiteForTestResult(stream, unit_test.ad_hoc_test_result()); OutputJsonTestSuiteForTestResult(stream, unit_test.ad_hoc_test_result());
} }
@ -5347,6 +5356,10 @@ void UnitTest::AddTestPartResult(TestPartResult::Type result_type,
(defined(__x86_64__) || defined(__i386__))) (defined(__x86_64__) || defined(__i386__)))
// with clang/gcc we can achieve the same effect on x86 by invoking int3 // with clang/gcc we can achieve the same effect on x86 by invoking int3
asm("int3"); asm("int3");
#elif GTEST_HAS_BUILTIN(__builtin_trap)
__builtin_trap();
#elif defined(SIGTRAP)
raise(SIGTRAP);
#else #else
// Dereference nullptr through a volatile pointer to prevent the compiler // Dereference nullptr through a volatile pointer to prevent the compiler
// from removing. We use this rather than abort() or __builtin_trap() for // from removing. We use this rather than abort() or __builtin_trap() for
@ -6053,7 +6066,7 @@ bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) {
// each TestSuite and TestInfo object. // each TestSuite and TestInfo object.
// If shard_tests == true, further filters tests based on sharding // If shard_tests == true, further filters tests based on sharding
// variables in the environment - see // variables in the environment - see
// https://github.com/google/googletest/blob/master/googletest/docs/advanced.md // https://github.com/google/googletest/blob/main/docs/advanced.md
// . Returns the number of tests that should run. // . Returns the number of tests that should run.
int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
const int32_t total_shards = shard_tests == HONOR_SHARDING_PROTOCOL const int32_t total_shards = shard_tests == HONOR_SHARDING_PROTOCOL

View File

@ -32,9 +32,12 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#if GTEST_OS_ESP8266 || GTEST_OS_ESP32 #if GTEST_OS_ESP8266 || GTEST_OS_ESP32
// Arduino-like platforms: program entry points are setup/loop instead of main.
#if GTEST_OS_ESP8266 #if GTEST_OS_ESP8266
extern "C" { extern "C" {
#endif #endif
void setup() { testing::InitGoogleTest(); } void setup() { testing::InitGoogleTest(); }
void loop() { RUN_ALL_TESTS(); } void loop() { RUN_ALL_TESTS(); }
@ -43,7 +46,16 @@ void loop() { RUN_ALL_TESTS(); }
} }
#endif #endif
#elif GTEST_OS_QURT
// QuRT: program entry point is main, but argc/argv are unusable.
GTEST_API_ int main() {
printf("Running main() from %s\n", __FILE__);
testing::InitGoogleTest();
return RUN_ALL_TESTS();
}
#else #else
// Normal platforms: program entry point is main, argc/argv are initialized.
GTEST_API_ int main(int argc, char **argv) { GTEST_API_ int main(int argc, char **argv) {
printf("Running main() from %s\n", __FILE__); printf("Running main() from %s\n", __FILE__);

View File

@ -421,8 +421,13 @@ TEST(NormalizeTest, MultipleConsecutiveSeparatorsInMidstring) {
// "/bar" == //bar" == "///bar" // "/bar" == //bar" == "///bar"
TEST(NormalizeTest, MultipleConsecutiveSeparatorsAtStringStart) { TEST(NormalizeTest, MultipleConsecutiveSeparatorsAtStringStart) {
EXPECT_EQ(GTEST_PATH_SEP_ "bar", FilePath(GTEST_PATH_SEP_ "bar").string()); EXPECT_EQ(GTEST_PATH_SEP_ "bar", FilePath(GTEST_PATH_SEP_ "bar").string());
#if GTEST_OS_WINDOWS
EXPECT_EQ(GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar",
FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string());
#else
EXPECT_EQ(GTEST_PATH_SEP_ "bar", EXPECT_EQ(GTEST_PATH_SEP_ "bar",
FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string()); FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string());
#endif
EXPECT_EQ( EXPECT_EQ(
GTEST_PATH_SEP_ "bar", GTEST_PATH_SEP_ "bar",
FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string()); FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string());
@ -621,6 +626,9 @@ TEST(FilePathTest, IsAbsolutePath) {
EXPECT_TRUE( EXPECT_TRUE(
FilePath("c:/" GTEST_PATH_SEP_ "is_not" GTEST_PATH_SEP_ "relative") FilePath("c:/" GTEST_PATH_SEP_ "is_not" GTEST_PATH_SEP_ "relative")
.IsAbsolutePath()); .IsAbsolutePath());
EXPECT_TRUE(FilePath("d:/Windows").IsAbsolutePath());
EXPECT_TRUE(FilePath("\\\\Host\\Share").IsAbsolutePath());
EXPECT_TRUE(FilePath("\\\\Host\\Share\\Folder").IsAbsolutePath());
#else #else
EXPECT_TRUE(FilePath(GTEST_PATH_SEP_ "is_not" GTEST_PATH_SEP_ "relative") EXPECT_TRUE(FilePath(GTEST_PATH_SEP_ "is_not" GTEST_PATH_SEP_ "relative")
.IsAbsolutePath()); .IsAbsolutePath());
@ -637,6 +645,16 @@ TEST(FilePathTest, IsRootDirectory) {
EXPECT_FALSE(FilePath("b:a").IsRootDirectory()); EXPECT_FALSE(FilePath("b:a").IsRootDirectory());
EXPECT_FALSE(FilePath("8:/").IsRootDirectory()); EXPECT_FALSE(FilePath("8:/").IsRootDirectory());
EXPECT_FALSE(FilePath("c|/").IsRootDirectory()); EXPECT_FALSE(FilePath("c|/").IsRootDirectory());
EXPECT_TRUE(FilePath("c:/").IsRootDirectory());
EXPECT_FALSE(FilePath("d:/Windows").IsRootDirectory());
// This is for backward compatibility, since callers (even in this library)
// have assumed IsRootDirectory() implies a trailing directory separator.
EXPECT_FALSE(FilePath("\\\\Host\\Share").IsRootDirectory());
EXPECT_TRUE(FilePath("\\\\Host\\Share\\").IsRootDirectory());
EXPECT_FALSE(FilePath("\\\\Host\\Share\\.").IsRootDirectory());
EXPECT_FALSE(FilePath("\\\\Host\\Share\\C$\\").IsRootDirectory());
#else #else
EXPECT_TRUE(FilePath("/").IsRootDirectory()); EXPECT_TRUE(FilePath("/").IsRootDirectory());
EXPECT_TRUE(FilePath("//").IsRootDirectory()); EXPECT_TRUE(FilePath("//").IsRootDirectory());

View File

@ -40,6 +40,7 @@
#include <set> #include <set>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <tuple>
#include <vector> #include <vector>
#include "gtest/gtest.h" #include "gtest/gtest.h"
@ -51,6 +52,7 @@ using ::std::vector;
using ::testing::AddGlobalTestEnvironment; using ::testing::AddGlobalTestEnvironment;
using ::testing::Bool; using ::testing::Bool;
using ::testing::Combine; using ::testing::Combine;
using ::testing::ConvertGenerator;
using ::testing::Message; using ::testing::Message;
using ::testing::Range; using ::testing::Range;
using ::testing::TestWithParam; using ::testing::TestWithParam;
@ -523,6 +525,64 @@ TEST(CombineTest, NonDefaultConstructAssign) {
EXPECT_TRUE(it == gen.end()); EXPECT_TRUE(it == gen.end());
} }
template <typename T>
class ConstructFromT {
public:
explicit ConstructFromT(const T& t) : t_(t) {}
template <typename... Args,
typename std::enable_if<sizeof...(Args) != 1, int>::type = 0>
ConstructFromT(Args&&... args) : t_(std::forward<Args>(args)...) {}
bool operator==(const ConstructFromT& other) const { return other.t_ == t_; }
const T& get() const { return t_; }
private:
T t_;
};
TEST(ConvertTest, CombineWithTwoParameters) {
const char* foo = "foo";
const char* bar = "bar";
const ParamGenerator<ConstructFromT<std::tuple<const char*, int>>> gen =
ConvertGenerator<std::tuple<const char*, int>>(
Combine(Values(foo, bar), Values(3, 4)));
ConstructFromT<std::tuple<const char*, int>> expected_values[] = {
{foo, 3}, {foo, 4}, {bar, 3}, {bar, 4}};
VerifyGenerator(gen, expected_values);
}
TEST(ConvertTest, NonDefaultConstructAssign) {
const ParamGenerator<
ConstructFromT<std::tuple<int, NonDefaultConstructAssignString>>>
gen = ConvertGenerator<std::tuple<int, NonDefaultConstructAssignString>>(
Combine(Values(0, 1), Values(NonDefaultConstructAssignString("A"),
NonDefaultConstructAssignString("B"))));
ParamGenerator<ConstructFromT<
std::tuple<int, NonDefaultConstructAssignString>>>::iterator it =
gen.begin();
EXPECT_EQ(0, std::get<0>(it->get()));
EXPECT_EQ("A", std::get<1>(it->get()).str());
++it;
EXPECT_EQ(0, std::get<0>(it->get()));
EXPECT_EQ("B", std::get<1>(it->get()).str());
++it;
EXPECT_EQ(1, std::get<0>(it->get()));
EXPECT_EQ("A", std::get<1>(it->get()).str());
++it;
EXPECT_EQ(1, std::get<0>(it->get()));
EXPECT_EQ("B", std::get<1>(it->get()).str());
++it;
EXPECT_TRUE(it == gen.end());
}
// Tests that an generator produces correct sequence after being // Tests that an generator produces correct sequence after being
// assigned from another generator. // assigned from another generator.
TEST(ParamGeneratorTest, AssignmentWorks) { TEST(ParamGeneratorTest, AssignmentWorks) {

View File

@ -37,6 +37,7 @@
#include <cstring> #include <cstring>
#include <deque> #include <deque>
#include <forward_list> #include <forward_list>
#include <functional>
#include <limits> #include <limits>
#include <list> #include <list>
#include <map> #include <map>
@ -193,6 +194,11 @@ OutputStream& operator<<(OutputStream& os,
return os; return os;
} }
struct StreamableInLocal {};
void operator<<(::std::ostream& os, const StreamableInLocal& /* x */) {
os << "StreamableInLocal";
}
// A user-defined streamable but recursively-defined container type in // A user-defined streamable but recursively-defined container type in
// a user namespace, it mimics therefore std::filesystem::path or // a user namespace, it mimics therefore std::filesystem::path or
// boost::filesystem::path. // boost::filesystem::path.
@ -1604,6 +1610,23 @@ TEST(PrintToStringTest, ContainsNonLatin) {
"\n As Text: \"From ä — ẑ\""); "\n As Text: \"From ä — ẑ\"");
} }
TEST(PrintToStringTest, PrintStreamableInLocal) {
EXPECT_STREQ("StreamableInLocal",
PrintToString(foo::StreamableInLocal()).c_str());
}
TEST(PrintToStringTest, PrintReferenceToStreamableInLocal) {
foo::StreamableInLocal s;
std::reference_wrapper<foo::StreamableInLocal> r(s);
EXPECT_STREQ("StreamableInLocal", PrintToString(r).c_str());
}
TEST(PrintToStringTest, PrintReferenceToStreamableInGlobal) {
StreamableInGlobal s;
std::reference_wrapper<StreamableInGlobal> r(s);
EXPECT_STREQ("StreamableInGlobal", PrintToString(r).c_str());
}
TEST(IsValidUTF8Test, IllFormedUTF8) { TEST(IsValidUTF8Test, IllFormedUTF8) {
// The following test strings are ill-formed UTF-8 and are printed // The following test strings are ill-formed UTF-8 and are printed
// as hex only (or ASCII, in case of ASCII bytes) because IsValidUTF8() is // as hex only (or ASCII, in case of ASCII bytes) because IsValidUTF8() is

View File

@ -3475,10 +3475,10 @@ TEST_F(NoFatalFailureTest, MessageIsStreamable) {
TestPartResultArray gtest_failures; TestPartResultArray gtest_failures;
{ {
ScopedFakeTestPartResultReporter gtest_reporter(&gtest_failures); ScopedFakeTestPartResultReporter gtest_reporter(&gtest_failures);
EXPECT_NO_FATAL_FAILURE(FAIL() << "foo") << "my message"; EXPECT_NO_FATAL_FAILURE([] { FAIL() << "foo"; }()) << "my message";
} }
ASSERT_EQ(2, gtest_failures.size()); ASSERT_EQ(2, gtest_failures.size());
EXPECT_EQ(TestPartResult::kNonFatalFailure, EXPECT_EQ(TestPartResult::kFatalFailure,
gtest_failures.GetTestPartResult(0).type()); gtest_failures.GetTestPartResult(0).type());
EXPECT_EQ(TestPartResult::kNonFatalFailure, EXPECT_EQ(TestPartResult::kNonFatalFailure,
gtest_failures.GetTestPartResult(1).type()); gtest_failures.GetTestPartResult(1).type());