Compare commits
103 Commits
release-1.
...
main
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1a3e2a265f | ||
![]() |
4848324c5f | ||
![]() |
1b18723e87 | ||
![]() |
25208a60a2 | ||
![]() |
9ca071b6e5 | ||
![]() |
7f2288476b | ||
![]() |
6c8a386513 | ||
![]() |
e4ffd4d715 | ||
![]() |
79efd968bf | ||
![]() |
aa486f165e | ||
![]() |
c3792825bf | ||
![]() |
d4e084a1cc | ||
![]() |
5d1e4af673 | ||
![]() |
bf0701daa9 | ||
![]() |
51536300a1 | ||
![]() |
cbf46d3f27 | ||
![]() |
5a93ce1247 | ||
![]() |
7cf37a18d1 | ||
![]() |
b3062166a1 | ||
![]() |
489ef888d9 | ||
![]() |
f503588aee | ||
![]() |
3c958ac47c | ||
![]() |
16f637fbf4 | ||
![]() |
178cfacb24 | ||
![]() |
dc7a0779d1 | ||
![]() |
b2dda9ed83 | ||
![]() |
9e3fb4ea94 | ||
![]() |
075810f7a2 | ||
![]() |
3b49be074d | ||
![]() |
ab36804e42 | ||
![]() |
ee1be03b43 | ||
![]() |
e4717df71a | ||
![]() |
09074c1571 | ||
![]() |
319a9d19bc | ||
![]() |
0570d97fb6 | ||
![]() |
de34ef4e4c | ||
![]() |
277e0a0168 | ||
![]() |
5b43f14be9 | ||
![]() |
861a75ed5d | ||
![]() |
a070f33c19 | ||
![]() |
40dfd4b775 | ||
![]() |
6bfab0becc | ||
![]() |
8aa657ee39 | ||
![]() |
314adcd40e | ||
![]() |
4ea61b9669 | ||
![]() |
7ee2683007 | ||
![]() |
6202251f09 | ||
![]() |
061973710e | ||
![]() |
159c9ad23e | ||
![]() |
955c7f837e | ||
![]() |
ff21b36e1e | ||
![]() |
6204633979 | ||
![]() |
2f80c2ba71 | ||
![]() |
088e6ed9a8 | ||
![]() |
0134d73a49 | ||
![]() |
8d8b488a8d | ||
![]() |
21514e0be7 | ||
![]() |
47f819c3ca | ||
![]() |
eb7e38dfb4 | ||
![]() |
046c4d018e | ||
![]() |
0e66bbd5b0 | ||
![]() |
b36e55d357 | ||
![]() |
aefb45469e | ||
![]() |
26f9d55719 | ||
![]() |
f91723cb90 | ||
![]() |
5b40153003 | ||
![]() |
652ec31f9f | ||
![]() |
c22ce88775 | ||
![]() |
29d2540622 | ||
![]() |
97ff0fec11 | ||
![]() |
2d924d7a97 | ||
![]() |
df43ce9675 | ||
![]() |
2f3e2e39cc | ||
![]() |
96f4ce02a3 | ||
![]() |
ce4895aae8 | ||
![]() |
8d6a4f8afe | ||
![]() |
56e4b1a515 | ||
![]() |
efc6b36cb3 | ||
![]() |
a42111b49b | ||
![]() |
8d51ffdfab | ||
![]() |
43cf52911a | ||
![]() |
8306020a3e | ||
![]() |
977cffc442 | ||
![]() |
4cfd14984f | ||
![]() |
f0ff512b75 | ||
![]() |
155de14cd8 | ||
![]() |
4ec4cd23f4 | ||
![]() |
5f97ce4c70 | ||
![]() |
b89480e02c | ||
![]() |
22e6055c75 | ||
![]() |
255323cf09 | ||
![]() |
4281d2149c | ||
![]() |
1008850435 | ||
![]() |
355d57d90d | ||
![]() |
f7902802f1 | ||
![]() |
7153098229 | ||
![]() |
22a2e019c4 | ||
![]() |
996328bb8e | ||
![]() |
5ef9f63a72 | ||
![]() |
1745a405eb | ||
![]() |
05e9fa23f7 | ||
![]() |
9614d8c1d6 | ||
![]() |
263220d2c1 |
21
BUILD.bazel
21
BUILD.bazel
@ -30,19 +30,32 @@
|
|||||||
#
|
#
|
||||||
# Bazel Build for Google C++ Testing Framework(Google Test)
|
# Bazel Build for Google C++ Testing Framework(Google Test)
|
||||||
|
|
||||||
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
|
|
||||||
|
|
||||||
package(default_visibility = ["//visibility:public"])
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
licenses(["notice"])
|
licenses(["notice"])
|
||||||
|
|
||||||
exports_files(["LICENSE"])
|
exports_files(["LICENSE"])
|
||||||
|
|
||||||
|
config_setting(
|
||||||
|
name = "qnx",
|
||||||
|
constraint_values = ["@platforms//os:qnx"],
|
||||||
|
)
|
||||||
|
|
||||||
config_setting(
|
config_setting(
|
||||||
name = "windows",
|
name = "windows",
|
||||||
constraint_values = ["@platforms//os:windows"],
|
constraint_values = ["@platforms//os:windows"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
config_setting(
|
||||||
|
name = "freebsd",
|
||||||
|
constraint_values = ["@platforms//os:freebsd"],
|
||||||
|
)
|
||||||
|
|
||||||
|
config_setting(
|
||||||
|
name = "openbsd",
|
||||||
|
constraint_values = ["@platforms//os:openbsd"],
|
||||||
|
)
|
||||||
|
|
||||||
config_setting(
|
config_setting(
|
||||||
name = "msvc_compiler",
|
name = "msvc_compiler",
|
||||||
flag_values = {
|
flag_values = {
|
||||||
@ -86,6 +99,7 @@ cc_library(
|
|||||||
"googlemock/include/gmock/*.h",
|
"googlemock/include/gmock/*.h",
|
||||||
]),
|
]),
|
||||||
copts = select({
|
copts = select({
|
||||||
|
":qnx": [],
|
||||||
":windows": [],
|
":windows": [],
|
||||||
"//conditions:default": ["-pthread"],
|
"//conditions:default": ["-pthread"],
|
||||||
}),
|
}),
|
||||||
@ -104,7 +118,10 @@ cc_library(
|
|||||||
"googletest/include",
|
"googletest/include",
|
||||||
],
|
],
|
||||||
linkopts = select({
|
linkopts = select({
|
||||||
|
":qnx": ["-lregex"],
|
||||||
":windows": [],
|
":windows": [],
|
||||||
|
":freebsd": ["-lm", "-pthread"],
|
||||||
|
":openbsd": ["-lm", "-pthread"],
|
||||||
"//conditions:default": ["-pthread"],
|
"//conditions:default": ["-pthread"],
|
||||||
}),
|
}),
|
||||||
deps = select({
|
deps = select({
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Note: CMake support is community-based. The maintainers do not use CMake
|
# Note: CMake support is community-based. The maintainers do not use CMake
|
||||||
# internally.
|
# internally.
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 2.8.12)
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
if (POLICY CMP0048)
|
if (POLICY CMP0048)
|
||||||
cmake_policy(SET CMP0048 NEW)
|
cmake_policy(SET CMP0048 NEW)
|
||||||
@ -10,10 +10,8 @@ endif (POLICY CMP0048)
|
|||||||
project(googletest-distribution)
|
project(googletest-distribution)
|
||||||
set(GOOGLETEST_VERSION 1.11.0)
|
set(GOOGLETEST_VERSION 1.11.0)
|
||||||
|
|
||||||
if (CMAKE_VERSION VERSION_GREATER "3.0.2")
|
if(NOT CYGWIN AND NOT MSYS AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL QNX)
|
||||||
if(NOT CYGWIN AND NOT MSYS AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL QNX)
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
@ -36,7 +36,8 @@ PR is acceptable as an alternative.
|
|||||||
This ensures that work isn't being duplicated and communicating your plan
|
This ensures that work isn't being duplicated and communicating your plan
|
||||||
early also generally leads to better patches.
|
early also generally leads to better patches.
|
||||||
4. If your proposed change is accepted, and you haven't already done so, sign a
|
4. If your proposed change is accepted, and you haven't already done so, sign a
|
||||||
Contributor License Agreement (see details above).
|
Contributor License Agreement
|
||||||
|
([see details above](#contributor-license-agreements)).
|
||||||
5. Fork the desired repo, develop and test your code changes.
|
5. Fork the desired repo, develop and test your code changes.
|
||||||
6. Ensure that your code adheres to the existing style in the sample to which
|
6. Ensure that your code adheres to the existing style in the sample to which
|
||||||
you are contributing.
|
you are contributing.
|
||||||
|
@ -34,6 +34,7 @@ Manuel Klimek <klimek@google.com>
|
|||||||
Mario Tanev <radix@google.com>
|
Mario Tanev <radix@google.com>
|
||||||
Mark Paskin
|
Mark Paskin
|
||||||
Markus Heule <markus.heule@gmail.com>
|
Markus Heule <markus.heule@gmail.com>
|
||||||
|
Martijn Vels <mvels@google.com>
|
||||||
Matthew Simmons <simmonmt@acm.org>
|
Matthew Simmons <simmonmt@acm.org>
|
||||||
Mika Raento <mikie@iki.fi>
|
Mika Raento <mikie@iki.fi>
|
||||||
Mike Bland <mbland@google.com>
|
Mike Bland <mbland@google.com>
|
||||||
|
@ -14,9 +14,9 @@ Our documentation is now live on GitHub Pages at
|
|||||||
https://google.github.io/googletest/. We recommend browsing the documentation on
|
https://google.github.io/googletest/. We recommend browsing the documentation on
|
||||||
GitHub Pages rather than directly in the repository.
|
GitHub Pages rather than directly in the repository.
|
||||||
|
|
||||||
#### Release 1.10.x
|
#### Release 1.11.0
|
||||||
|
|
||||||
[Release 1.10.x](https://github.com/google/googletest/releases/tag/release-1.10.0)
|
[Release 1.11.0](https://github.com/google/googletest/releases/tag/release-1.11.0)
|
||||||
is now available.
|
is now available.
|
||||||
|
|
||||||
#### Coming Soon
|
#### Coming Soon
|
||||||
@ -109,8 +109,8 @@ Windows and Linux platforms.
|
|||||||
|
|
||||||
[GoogleTest UI](https://github.com/ospector/gtest-gbar) is a test runner that
|
[GoogleTest UI](https://github.com/ospector/gtest-gbar) is a test runner that
|
||||||
runs your test binary, allows you to track its progress via a progress bar, and
|
runs your test binary, allows you to track its progress via a progress bar, and
|
||||||
displays a list of test failures. Clicking on one shows failure text. Google
|
displays a list of test failures. Clicking on one shows failure text. GoogleTest
|
||||||
Test UI is written in C#.
|
UI is written in C#.
|
||||||
|
|
||||||
[GTest TAP Listener](https://github.com/kinow/gtest-tap-listener) is an event
|
[GTest TAP Listener](https://github.com/kinow/gtest-tap-listener) is an event
|
||||||
listener for GoogleTest that implements the
|
listener for GoogleTest that implements the
|
||||||
|
19
WORKSPACE
19
WORKSPACE
@ -4,21 +4,14 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
|||||||
|
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "com_google_absl",
|
name = "com_google_absl",
|
||||||
urls = ["https://github.com/abseil/abseil-cpp/archive/7971fb358ae376e016d2d4fc9327aad95659b25e.zip"], # 2021-05-20T02:59:16Z
|
|
||||||
strip_prefix = "abseil-cpp-7971fb358ae376e016d2d4fc9327aad95659b25e",
|
|
||||||
sha256 = "aeba534f7307e36fe084b452299e49b97420667a8d28102cf9a0daeed340b859",
|
sha256 = "aeba534f7307e36fe084b452299e49b97420667a8d28102cf9a0daeed340b859",
|
||||||
|
strip_prefix = "abseil-cpp-7971fb358ae376e016d2d4fc9327aad95659b25e",
|
||||||
|
urls = ["https://github.com/abseil/abseil-cpp/archive/7971fb358ae376e016d2d4fc9327aad95659b25e.zip"], # 2021-05-20T02:59:16Z
|
||||||
)
|
)
|
||||||
|
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "rules_cc",
|
name = "rules_python",
|
||||||
urls = ["https://github.com/bazelbuild/rules_cc/archive/68cb652a71e7e7e2858c50593e5a9e3b94e5b9a9.zip"], # 2021-05-14T14:51:14Z
|
sha256 = "98b3c592faea9636ac8444bfd9de7f3fb4c60590932d6e6ac5946e3f8dbd5ff6",
|
||||||
strip_prefix = "rules_cc-68cb652a71e7e7e2858c50593e5a9e3b94e5b9a9",
|
strip_prefix = "rules_python-ed6cc8f2c3692a6a7f013ff8bc185ba77eb9b4d2",
|
||||||
sha256 = "1e19e9a3bc3d4ee91d7fcad00653485ee6c798efbbf9588d40b34cbfbded143d",
|
urls = ["https://github.com/bazelbuild/rules_python/archive/ed6cc8f2c3692a6a7f013ff8bc185ba77eb9b4d2.zip"], # 2021-05-17T00:24:16Z
|
||||||
)
|
|
||||||
|
|
||||||
http_archive(
|
|
||||||
name = "rules_python",
|
|
||||||
urls = ["https://github.com/bazelbuild/rules_python/archive/ed6cc8f2c3692a6a7f013ff8bc185ba77eb9b4d2.zip"], # 2021-05-17T00:24:16Z
|
|
||||||
strip_prefix = "rules_python-ed6cc8f2c3692a6a7f013ff8bc185ba77eb9b4d2",
|
|
||||||
sha256 = "98b3c592faea9636ac8444bfd9de7f3fb4c60590932d6e6ac5946e3f8dbd5ff6",
|
|
||||||
)
|
)
|
||||||
|
@ -31,8 +31,8 @@
|
|||||||
|
|
||||||
set -euox pipefail
|
set -euox pipefail
|
||||||
|
|
||||||
readonly LINUX_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20210525"
|
readonly LINUX_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20210617"
|
||||||
readonly LINUX_GCC_FLOOR_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-floor:20201015"
|
readonly LINUX_GCC_FLOOR_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-floor:20210617"
|
||||||
|
|
||||||
if [[ -z ${GTEST_ROOT:-} ]]; then
|
if [[ -z ${GTEST_ROOT:-} ]]; then
|
||||||
GTEST_ROOT="$(realpath $(dirname ${0})/..)"
|
GTEST_ROOT="$(realpath $(dirname ${0})/..)"
|
||||||
|
121
docs/advanced.md
121
docs/advanced.md
@ -157,8 +157,11 @@ that can be used in the predicate assertion macro
|
|||||||
example:
|
example:
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
EXPECT_PRED_FORMAT2(testing::FloatLE, val1, val2);
|
using ::testing::FloatLE;
|
||||||
EXPECT_PRED_FORMAT2(testing::DoubleLE, val1, val2);
|
using ::testing::DoubleLE;
|
||||||
|
...
|
||||||
|
EXPECT_PRED_FORMAT2(FloatLE, val1, val2);
|
||||||
|
EXPECT_PRED_FORMAT2(DoubleLE, val1, val2);
|
||||||
```
|
```
|
||||||
|
|
||||||
The above code verifies that `val1` is less than, or approximately equal to,
|
The above code verifies that `val1` is less than, or approximately equal to,
|
||||||
@ -202,10 +205,9 @@ You can call the function
|
|||||||
|
|
||||||
to assert that types `T1` and `T2` are the same. The function does nothing if
|
to assert that types `T1` and `T2` are the same. The function does nothing if
|
||||||
the assertion is satisfied. If the types are different, the function call will
|
the assertion is satisfied. If the types are different, the function call will
|
||||||
fail to compile, the compiler error message will say that
|
fail to compile, the compiler error message will say that `T1 and T2 are not the
|
||||||
`T1 and T2 are not the same type` and most likely (depending on the compiler)
|
same type` and most likely (depending on the compiler) show you the actual
|
||||||
show you the actual values of `T1` and `T2`. This is mainly useful inside
|
values of `T1` and `T2`. This is mainly useful inside template code.
|
||||||
template code.
|
|
||||||
|
|
||||||
**Caveat**: When used inside a member function of a class template or a function
|
**Caveat**: When used inside a member function of a class template or a function
|
||||||
template, `StaticAssertTypeEq<T1, T2>()` is effective only if the function is
|
template, `StaticAssertTypeEq<T1, T2>()` is effective only if the function is
|
||||||
@ -383,10 +385,10 @@ EXPECT_TRUE(IsCorrectBarIntVector(bar_ints))
|
|||||||
## Death Tests
|
## Death Tests
|
||||||
|
|
||||||
In many applications, there are assertions that can cause application failure if
|
In many applications, there are assertions that can cause application failure if
|
||||||
a condition is not met. These sanity checks, which ensure that the program is in
|
a condition is not met. These consistency checks, which ensure that the program
|
||||||
a known good state, are there to fail at the earliest possible time after some
|
is in a known good state, are there to fail at the earliest possible time after
|
||||||
program state is corrupted. If the assertion checks the wrong condition, then
|
some program state is corrupted. If the assertion checks the wrong condition,
|
||||||
the program may proceed in an erroneous state, which could lead to memory
|
then the program may proceed in an erroneous state, which could lead to memory
|
||||||
corruption, security holes, or worse. Hence it is vitally important to test that
|
corruption, security holes, or worse. Hence it is vitally important to test that
|
||||||
such assertion statements work as expected.
|
such assertion statements work as expected.
|
||||||
|
|
||||||
@ -558,7 +560,7 @@ The automated testing framework does not set the style flag. You can choose a
|
|||||||
particular style of death tests by setting the flag programmatically:
|
particular style of death tests by setting the flag programmatically:
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
testing::FLAGS_gtest_death_test_style="threadsafe"
|
GTEST_FLAG_SET(death_test_style, "threadsafe")
|
||||||
```
|
```
|
||||||
|
|
||||||
You can do this in `main()` to set the style for all death tests in the binary,
|
You can do this in `main()` to set the style for all death tests in the binary,
|
||||||
@ -568,12 +570,12 @@ restored afterwards, so you need not do that yourself. For example:
|
|||||||
```c++
|
```c++
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
testing::InitGoogleTest(&argc, argv);
|
testing::InitGoogleTest(&argc, argv);
|
||||||
testing::FLAGS_gtest_death_test_style = "fast";
|
GTEST_FLAG_SET(death_test_style, "fast");
|
||||||
return RUN_ALL_TESTS();
|
return RUN_ALL_TESTS();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MyDeathTest, TestOne) {
|
TEST(MyDeathTest, TestOne) {
|
||||||
testing::FLAGS_gtest_death_test_style = "threadsafe";
|
GTEST_FLAG_SET(death_test_style, "threadsafe");
|
||||||
// This test is run in the "threadsafe" style:
|
// This test is run in the "threadsafe" style:
|
||||||
ASSERT_DEATH(ThisShouldDie(), "");
|
ASSERT_DEATH(ThisShouldDie(), "");
|
||||||
}
|
}
|
||||||
@ -610,15 +612,14 @@ Despite the improved thread safety afforded by the "threadsafe" style of death
|
|||||||
test, thread problems such as deadlock are still possible in the presence of
|
test, thread problems such as deadlock are still possible in the presence of
|
||||||
handlers registered with `pthread_atfork(3)`.
|
handlers registered with `pthread_atfork(3)`.
|
||||||
|
|
||||||
|
|
||||||
## Using Assertions in Sub-routines
|
## Using Assertions in Sub-routines
|
||||||
|
|
||||||
{: .callout .note}
|
{: .callout .note}
|
||||||
Note: If you want to put a series of test assertions in a subroutine to check
|
Note: If you want to put a series of test assertions in a subroutine to check
|
||||||
for a complex condition, consider using
|
for a complex condition, consider using
|
||||||
[a custom GMock matcher](gmock_cook_book.md#NewMatchers)
|
[a custom GMock matcher](gmock_cook_book.md#NewMatchers) instead. This lets you
|
||||||
instead. This lets you provide a more readable error message in case of failure
|
provide a more readable error message in case of failure and avoid all of the
|
||||||
and avoid all of the issues described below.
|
issues described below.
|
||||||
|
|
||||||
### Adding Traces to Assertions
|
### Adding Traces to Assertions
|
||||||
|
|
||||||
@ -631,6 +632,7 @@ the `SCOPED_TRACE` macro or the `ScopedTrace` utility:
|
|||||||
```c++
|
```c++
|
||||||
SCOPED_TRACE(message);
|
SCOPED_TRACE(message);
|
||||||
```
|
```
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
ScopedTrace trace("file_path", line_number, message);
|
ScopedTrace trace("file_path", line_number, message);
|
||||||
```
|
```
|
||||||
@ -888,6 +890,12 @@ preceding or following another. Also, the tests must either not modify the state
|
|||||||
of any shared resource, or, if they do modify the state, they must restore the
|
of any shared resource, or, if they do modify the state, they must restore the
|
||||||
state to its original value before passing control to the next test.
|
state to its original value before passing control to the next test.
|
||||||
|
|
||||||
|
Note that `SetUpTestSuite()` may be called multiple times for a test fixture
|
||||||
|
class that has derived classes, so you should not expect code in the function
|
||||||
|
body to be run only once. Also, derived classes still have access to shared
|
||||||
|
resources defined as static members, so careful consideration is needed when
|
||||||
|
managing shared resources to avoid memory leaks.
|
||||||
|
|
||||||
Here's an example of per-test-suite set-up and tear-down:
|
Here's an example of per-test-suite set-up and tear-down:
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
@ -897,7 +905,10 @@ class FooTest : public testing::Test {
|
|||||||
// Called before the first test in this test suite.
|
// Called before the first test in this test suite.
|
||||||
// Can be omitted if not needed.
|
// Can be omitted if not needed.
|
||||||
static void SetUpTestSuite() {
|
static void SetUpTestSuite() {
|
||||||
shared_resource_ = new ...;
|
// Avoid reallocating static objects if called in subclasses of FooTest.
|
||||||
|
if (shared_resource_ == nullptr) {
|
||||||
|
shared_resource_ = new ...;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Per-test-suite tear-down.
|
// Per-test-suite tear-down.
|
||||||
@ -1481,8 +1492,8 @@ In frameworks that report a failure by throwing an exception, you could catch
|
|||||||
the exception and assert on it. But googletest doesn't use exceptions, so how do
|
the exception and assert on it. But googletest doesn't use exceptions, so how do
|
||||||
we test that a piece of code generates an expected failure?
|
we test that a piece of code generates an expected failure?
|
||||||
|
|
||||||
`"gtest/gtest-spi.h"` contains some constructs to do this. After #including this header,
|
`"gtest/gtest-spi.h"` contains some constructs to do this.
|
||||||
you can use
|
After #including this header, you can use
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
EXPECT_FATAL_FAILURE(statement, substring);
|
EXPECT_FATAL_FAILURE(statement, substring);
|
||||||
@ -1586,12 +1597,14 @@ void RegisterMyTests(const std::vector<int>& values) {
|
|||||||
}
|
}
|
||||||
...
|
...
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
std::vector<int> values_to_test = LoadValuesFromConfig();
|
std::vector<int> values_to_test = LoadValuesFromConfig();
|
||||||
RegisterMyTests(values_to_test);
|
RegisterMyTests(values_to_test);
|
||||||
...
|
...
|
||||||
return RUN_ALL_TESTS();
|
return RUN_ALL_TESTS();
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Getting the Current Test's Name
|
## Getting the Current Test's Name
|
||||||
|
|
||||||
Sometimes a function may need to know the name of the currently running test.
|
Sometimes a function may need to know the name of the currently running test.
|
||||||
@ -1816,8 +1829,7 @@ By default, a googletest program runs all tests the user has defined. In some
|
|||||||
cases (e.g. iterative test development & execution) it may be desirable stop
|
cases (e.g. iterative test development & execution) it may be desirable stop
|
||||||
test execution upon first failure (trading improved latency for completeness).
|
test execution upon first failure (trading improved latency for completeness).
|
||||||
If `GTEST_FAIL_FAST` environment variable or `--gtest_fail_fast` flag is set,
|
If `GTEST_FAIL_FAST` environment variable or `--gtest_fail_fast` flag is set,
|
||||||
the test runner will stop execution as soon as the first test failure is
|
the test runner will stop execution as soon as the first test failure is found.
|
||||||
found.
|
|
||||||
|
|
||||||
#### Temporarily Disabling Tests
|
#### Temporarily Disabling Tests
|
||||||
|
|
||||||
@ -1911,6 +1923,58 @@ time.
|
|||||||
If you combine this with `--gtest_repeat=N`, googletest will pick a different
|
If you combine this with `--gtest_repeat=N`, googletest will pick a different
|
||||||
random seed and re-shuffle the tests in each iteration.
|
random seed and re-shuffle the tests in each iteration.
|
||||||
|
|
||||||
|
### Distributing Test Functions to Multiple Machines
|
||||||
|
|
||||||
|
If you have more than one machine you can use to run a test program, you might
|
||||||
|
want to run the test functions in parallel and get the result faster. We call
|
||||||
|
this technique *sharding*, where each machine is called a *shard*.
|
||||||
|
|
||||||
|
GoogleTest is compatible with test sharding. To take advantage of this feature,
|
||||||
|
your test runner (not part of GoogleTest) needs to do the following:
|
||||||
|
|
||||||
|
1. Allocate a number of machines (shards) to run the tests.
|
||||||
|
1. On each shard, set the `GTEST_TOTAL_SHARDS` environment variable to the total
|
||||||
|
number of shards. It must be the same for all shards.
|
||||||
|
1. On each shard, set the `GTEST_SHARD_INDEX` environment variable to the index
|
||||||
|
of the shard. Different shards must be assigned different indices, which
|
||||||
|
must be in the range `[0, GTEST_TOTAL_SHARDS - 1]`.
|
||||||
|
1. Run the same test program on all shards. When GoogleTest sees the above two
|
||||||
|
environment variables, it will select a subset of the test functions to run.
|
||||||
|
Across all shards, each test function in the program will be run exactly
|
||||||
|
once.
|
||||||
|
1. Wait for all shards to finish, then collect and report the results.
|
||||||
|
|
||||||
|
Your project may have tests that were written without GoogleTest and thus don't
|
||||||
|
understand this protocol. In order for your test runner to figure out which test
|
||||||
|
supports sharding, it can set the environment variable `GTEST_SHARD_STATUS_FILE`
|
||||||
|
to a non-existent file path. If a test program supports sharding, it will create
|
||||||
|
this file to acknowledge that fact; otherwise it will not create it. The actual
|
||||||
|
contents of the file are not important at this time, although we may put some
|
||||||
|
useful information in it in the future.
|
||||||
|
|
||||||
|
Here's an example to make it clear. Suppose you have a test program `foo_test`
|
||||||
|
that contains the following 5 test functions:
|
||||||
|
|
||||||
|
```
|
||||||
|
TEST(A, V)
|
||||||
|
TEST(A, W)
|
||||||
|
TEST(B, X)
|
||||||
|
TEST(B, Y)
|
||||||
|
TEST(B, Z)
|
||||||
|
```
|
||||||
|
|
||||||
|
Suppose you have 3 machines at your disposal. To run the test functions in
|
||||||
|
parallel, you would set `GTEST_TOTAL_SHARDS` to 3 on all machines, and set
|
||||||
|
`GTEST_SHARD_INDEX` to 0, 1, and 2 on the machines respectively. Then you would
|
||||||
|
run the same `foo_test` on each machine.
|
||||||
|
|
||||||
|
GoogleTest reserves the right to change how the work is distributed across the
|
||||||
|
shards, but here's one possible scenario:
|
||||||
|
|
||||||
|
* Machine #0 runs `A.V` and `B.X`.
|
||||||
|
* Machine #1 runs `A.W` and `B.Y`.
|
||||||
|
* Machine #2 runs `B.Z`.
|
||||||
|
|
||||||
### Controlling Test Output
|
### Controlling Test Output
|
||||||
|
|
||||||
#### Colored Terminal Output
|
#### Colored Terminal Output
|
||||||
@ -1965,8 +2029,6 @@ text because, for example, you don't have an UTF-8 compatible output medium, run
|
|||||||
the test program with `--gtest_print_utf8=0` or set the `GTEST_PRINT_UTF8`
|
the test program with `--gtest_print_utf8=0` or set the `GTEST_PRINT_UTF8`
|
||||||
environment variable to `0`.
|
environment variable to `0`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### Generating an XML Report
|
#### Generating an XML Report
|
||||||
|
|
||||||
googletest can emit a detailed XML report to a file in addition to its normal
|
googletest can emit a detailed XML report to a file in addition to its normal
|
||||||
@ -2253,12 +2315,11 @@ IMPORTANT: The exact format of the JSON document is subject to change.
|
|||||||
|
|
||||||
#### Detecting Test Premature Exit
|
#### Detecting Test Premature Exit
|
||||||
|
|
||||||
Google Test implements the _premature-exit-file_ protocol for test runners
|
Google Test implements the _premature-exit-file_ protocol for test runners to
|
||||||
to catch any kind of unexpected exits of test programs. Upon start,
|
catch any kind of unexpected exits of test programs. Upon start, Google Test
|
||||||
Google Test creates the file which will be automatically deleted after
|
creates the file which will be automatically deleted after all work has been
|
||||||
all work has been finished. Then, the test runner can check if this file
|
finished. Then, the test runner can check if this file exists. In case the file
|
||||||
exists. In case the file remains undeleted, the inspected test has exited
|
remains undeleted, the inspected test has exited prematurely.
|
||||||
prematurely.
|
|
||||||
|
|
||||||
This feature is enabled only if the `TEST_PREMATURE_EXIT_FILE` environment
|
This feature is enabled only if the `TEST_PREMATURE_EXIT_FILE` environment
|
||||||
variable has been set.
|
variable has been set.
|
||||||
|
@ -410,7 +410,6 @@ C++ is case-sensitive. Did you spell it as `Setup()`?
|
|||||||
Similarly, sometimes people spell `SetUpTestSuite()` as `SetupTestSuite()` and
|
Similarly, sometimes people spell `SetUpTestSuite()` as `SetupTestSuite()` and
|
||||||
wonder why it's never called.
|
wonder why it's never called.
|
||||||
|
|
||||||
|
|
||||||
## I have several test suites which share the same test fixture logic, do I have to define a new test fixture class for each of them? This seems pretty tedious.
|
## I have several test suites which share the same test fixture logic, do I have to define a new test fixture class for each of them? This seems pretty tedious.
|
||||||
|
|
||||||
You don't have to. Instead of
|
You don't have to. Instead of
|
||||||
|
@ -230,7 +230,7 @@ class MockFunction<R(A1, ..., An)> {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
See this [recipe](gmock_cook_book.md#using-check-points) for one application of
|
See this [recipe](gmock_cook_book.md#UsingCheckPoints) for one application of
|
||||||
it.
|
it.
|
||||||
|
|
||||||
## Flags
|
## Flags
|
||||||
|
@ -1452,7 +1452,7 @@ the pointer is copied. When the last matcher that references the implementation
|
|||||||
object dies, the implementation object will be deleted.
|
object dies, the implementation object will be deleted.
|
||||||
|
|
||||||
Therefore, if you have some complex matcher that you want to use again and
|
Therefore, if you have some complex matcher that you want to use again and
|
||||||
again, there is no need to build it everytime. Just assign it to a matcher
|
again, there is no need to build it every time. Just assign it to a matcher
|
||||||
variable and use that variable repeatedly! For example,
|
variable and use that variable repeatedly! For example,
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
@ -1754,7 +1754,7 @@ specifies the following DAG (where `s1` is `A -> B`, and `s2` is `A -> C -> D`):
|
|||||||
|
|
|
|
||||||
A ---|
|
A ---|
|
||||||
|
|
|
|
||||||
+---> C ---> D
|
+---> C ---> D
|
||||||
```
|
```
|
||||||
|
|
||||||
This means that A must occur before B and C, and C must occur before D. There's
|
This means that A must occur before B and C, and C must occur before D. There's
|
||||||
@ -1980,6 +1980,7 @@ If the mock method also needs to return a value as well, you can chain
|
|||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
using ::testing::_;
|
using ::testing::_;
|
||||||
|
using ::testing::DoAll;
|
||||||
using ::testing::Return;
|
using ::testing::Return;
|
||||||
using ::testing::SetArgPointee;
|
using ::testing::SetArgPointee;
|
||||||
|
|
||||||
@ -2033,10 +2034,7 @@ class MockRolodex : public Rolodex {
|
|||||||
}
|
}
|
||||||
...
|
...
|
||||||
MockRolodex rolodex;
|
MockRolodex rolodex;
|
||||||
vector<string> names;
|
vector<string> names = {"George", "John", "Thomas"};
|
||||||
names.push_back("George");
|
|
||||||
names.push_back("John");
|
|
||||||
names.push_back("Thomas");
|
|
||||||
EXPECT_CALL(rolodex, GetNames(_))
|
EXPECT_CALL(rolodex, GetNames(_))
|
||||||
.WillOnce(SetArrayArgument<0>(names.begin(), names.end()));
|
.WillOnce(SetArrayArgument<0>(names.begin(), names.end()));
|
||||||
```
|
```
|
||||||
@ -2604,7 +2602,7 @@ efficient. When the last action that references the implementation object dies,
|
|||||||
the implementation object will be deleted.
|
the implementation object will be deleted.
|
||||||
|
|
||||||
If you have some complex action that you want to use again and again, you may
|
If you have some complex action that you want to use again and again, you may
|
||||||
not have to build it from scratch everytime. If the action doesn't have an
|
not have to build it from scratch every time. If the action doesn't have an
|
||||||
internal state (i.e. if it always does the same thing no matter how many times
|
internal state (i.e. if it always does the same thing no matter how many times
|
||||||
it has been called), you can assign it to an action variable and use that
|
it has been called), you can assign it to an action variable and use that
|
||||||
variable repeatedly. For example:
|
variable repeatedly. For example:
|
||||||
@ -4191,7 +4189,7 @@ This implementation class does *not* need to inherit from any particular class.
|
|||||||
What matters is that it must have a `Perform()` method template. This method
|
What matters is that it must have a `Perform()` method template. This method
|
||||||
template takes the mock function's arguments as a tuple in a **single**
|
template takes the mock function's arguments as a tuple in a **single**
|
||||||
argument, and returns the result of the action. It can be either `const` or not,
|
argument, and returns the result of the action. It can be either `const` or not,
|
||||||
but must be invokable with exactly one template argument, which is the result
|
but must be invocable with exactly one template argument, which is the result
|
||||||
type. In other words, you must be able to call `Perform<R>(args)` where `R` is
|
type. In other words, you must be able to call `Perform<R>(args)` where `R` is
|
||||||
the mock function's return type and `args` is its arguments in a tuple.
|
the mock function's return type and `args` is its arguments in a tuple.
|
||||||
|
|
||||||
|
@ -480,8 +480,8 @@ the *default* action for the function every time (unless, of course, you have a
|
|||||||
`WillRepeatedly()`.).
|
`WillRepeatedly()`.).
|
||||||
|
|
||||||
What can we do inside `WillOnce()` besides `Return()`? You can return a
|
What can we do inside `WillOnce()` besides `Return()`? You can return a
|
||||||
reference using `ReturnRef(*variable*)`, or invoke a pre-defined function, among
|
reference using `ReturnRef(`*`variable`*`)`, or invoke a pre-defined function,
|
||||||
[others](gmock_cook_book.md#using-actions).
|
among [others](gmock_cook_book.md#using-actions).
|
||||||
|
|
||||||
**Important note:** The `EXPECT_CALL()` statement evaluates the action clause
|
**Important note:** The `EXPECT_CALL()` statement evaluates the action clause
|
||||||
only once, even though the action may be performed many times. Therefore you
|
only once, even though the action may be performed many times. Therefore you
|
||||||
|
@ -105,7 +105,7 @@ includedir=/usr/include
|
|||||||
|
|
||||||
Name: gtest
|
Name: gtest
|
||||||
Description: GoogleTest (without main() function)
|
Description: GoogleTest (without main() function)
|
||||||
Version: 1.10.0
|
Version: 1.11.0
|
||||||
URL: https://github.com/google/googletest
|
URL: https://github.com/google/googletest
|
||||||
Libs: -L${libdir} -lgtest -lpthread
|
Libs: -L${libdir} -lgtest -lpthread
|
||||||
Cflags: -I${includedir} -DGTEST_HAS_PTHREAD=1 -lpthread
|
Cflags: -I${includedir} -DGTEST_HAS_PTHREAD=1 -lpthread
|
||||||
|
@ -162,9 +162,9 @@ TEST(TestSuiteName, TestName) {
|
|||||||
|
|
||||||
`TEST()` arguments go from general to specific. The *first* argument is the name
|
`TEST()` arguments go from general to specific. The *first* argument is the name
|
||||||
of the test suite, and the *second* argument is the test's name within the test
|
of the test suite, and the *second* argument is the test's name within the test
|
||||||
suite. Both names must be valid C++ identifiers, and they should not contain
|
suite. Both names must be valid C++ identifiers, and they should not contain any
|
||||||
any underscores (`_`). A test's *full name* consists of its containing test suite and
|
underscores (`_`). A test's *full name* consists of its containing test suite
|
||||||
its individual name. Tests from different test suites can have the same
|
and its individual name. Tests from different test suites can have the same
|
||||||
individual name.
|
individual name.
|
||||||
|
|
||||||
For example, let's take a simple integer function:
|
For example, let's take a simple integer function:
|
||||||
@ -245,8 +245,8 @@ Also, you must first define a test fixture class before using it in a
|
|||||||
declaration`".
|
declaration`".
|
||||||
|
|
||||||
For each test defined with `TEST_F()`, googletest will create a *fresh* test
|
For each test defined with `TEST_F()`, googletest will create a *fresh* test
|
||||||
fixture at runtime, immediately initialize it via `SetUp()`, run the test,
|
fixture at runtime, immediately initialize it via `SetUp()`, run the test, clean
|
||||||
clean up by calling `TearDown()`, and then delete the test fixture. Note that
|
up by calling `TearDown()`, and then delete the test fixture. Note that
|
||||||
different tests in the same test suite have different test fixture objects, and
|
different tests in the same test suite have different test fixture objects, and
|
||||||
googletest always deletes a test fixture before it creates the next one.
|
googletest always deletes a test fixture before it creates the next one.
|
||||||
googletest does **not** reuse the same test fixture for multiple tests. Any
|
googletest does **not** reuse the same test fixture for multiple tests. Any
|
||||||
@ -342,8 +342,8 @@ your defined tests in order to run them.
|
|||||||
|
|
||||||
After defining your tests, you can run them with `RUN_ALL_TESTS()`, which
|
After defining your tests, you can run them with `RUN_ALL_TESTS()`, which
|
||||||
returns `0` if all the tests are successful, or `1` otherwise. Note that
|
returns `0` if all the tests are successful, or `1` otherwise. Note that
|
||||||
`RUN_ALL_TESTS()` runs *all tests* in your link unit--they can be from
|
`RUN_ALL_TESTS()` runs *all tests* in your link unit--they can be from different
|
||||||
different test suites, or even different source files.
|
test suites, or even different source files.
|
||||||
|
|
||||||
When invoked, the `RUN_ALL_TESTS()` macro:
|
When invoked, the `RUN_ALL_TESTS()` macro:
|
||||||
|
|
||||||
@ -456,8 +456,8 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
The `::testing::InitGoogleTest()` function parses the command line for
|
The `::testing::InitGoogleTest()` function parses the command line for
|
||||||
googletest flags, and removes all recognized flags. This allows the user to
|
googletest flags, and removes all recognized flags. This allows the user to
|
||||||
control a test program's behavior via various flags, which we'll cover in
|
control a test program's behavior via various flags, which we'll cover in the
|
||||||
the [AdvancedGuide](advanced.md). You **must** call this function before calling
|
[AdvancedGuide](advanced.md). You **must** call this function before calling
|
||||||
`RUN_ALL_TESTS()`, or the flags won't be properly initialized.
|
`RUN_ALL_TESTS()`, or the flags won't be properly initialized.
|
||||||
|
|
||||||
On Windows, `InitGoogleTest()` also works with wide strings, so it can be used
|
On Windows, `InitGoogleTest()` also works with wide strings, so it can be used
|
||||||
|
@ -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/master/install.html).
|
[Bazel installation guide](https://docs.bazel.build/versions/main/install.html).
|
||||||
|
|
||||||
{: .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
|
||||||
@ -26,7 +26,7 @@ commands work on the Windows command line as well.
|
|||||||
## Set up a Bazel workspace
|
## Set up a Bazel workspace
|
||||||
|
|
||||||
A
|
A
|
||||||
[Bazel workspace](https://docs.bazel.build/versions/master/build-ref.html#workspace)
|
[Bazel workspace](https://docs.bazel.build/versions/main/build-ref.html#workspace)
|
||||||
is a directory on your filesystem that you use to manage source files for the
|
is a directory on your filesystem that you use to manage source files for the
|
||||||
software you want to build. Each workspace directory has a text file named
|
software you want to build. Each workspace directory has a text file named
|
||||||
`WORKSPACE` which may be empty, or may contain references to external
|
`WORKSPACE` which may be empty, or may contain references to external
|
||||||
@ -40,9 +40,9 @@ $ mkdir my_workspace && cd my_workspace
|
|||||||
|
|
||||||
Next, you’ll create the `WORKSPACE` file to specify dependencies. A common and
|
Next, you’ll create the `WORKSPACE` file to specify dependencies. A common and
|
||||||
recommended way to depend on GoogleTest is to use a
|
recommended way to depend on GoogleTest is to use a
|
||||||
[Bazel external dependency](https://docs.bazel.build/versions/master/external.html)
|
[Bazel external dependency](https://docs.bazel.build/versions/main/external.html)
|
||||||
via the
|
via the
|
||||||
[`http_archive` rule](https://docs.bazel.build/versions/master/repo/http.html#http_archive).
|
[`http_archive` rule](https://docs.bazel.build/versions/main/repo/http.html#http_archive).
|
||||||
To do this, in the root directory of your workspace (`my_workspace/`), create a
|
To do this, in the root directory of your workspace (`my_workspace/`), create a
|
||||||
file named `WORKSPACE` with the following contents:
|
file named `WORKSPACE` with the following contents:
|
||||||
|
|
||||||
@ -62,18 +62,6 @@ as a ZIP archive from GitHub. In the above example,
|
|||||||
GoogleTest version to use; we recommend updating the hash often to point to the
|
GoogleTest version to use; we recommend updating the hash often to point to the
|
||||||
latest version.
|
latest version.
|
||||||
|
|
||||||
Bazel also needs a dependency on the
|
|
||||||
[`rules_cc` repository](https://github.com/bazelbuild/rules_cc) to build C++
|
|
||||||
code, so add the following to the `WORKSPACE` file:
|
|
||||||
|
|
||||||
```
|
|
||||||
http_archive(
|
|
||||||
name = "rules_cc",
|
|
||||||
urls = ["https://github.com/bazelbuild/rules_cc/archive/40548a2974f1aea06215272d9c2b47a14a24e556.zip"],
|
|
||||||
strip_prefix = "rules_cc-40548a2974f1aea06215272d9c2b47a14a24e556",
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
Now you're ready to build C++ code that uses GoogleTest.
|
Now you're ready to build C++ code that uses GoogleTest.
|
||||||
|
|
||||||
## Create and run a binary
|
## Create and run a binary
|
||||||
@ -104,8 +92,6 @@ To build the code, create a file named `BUILD` in the same directory with the
|
|||||||
following contents:
|
following contents:
|
||||||
|
|
||||||
```
|
```
|
||||||
load("@rules_cc//cc:defs.bzl", "cc_test")
|
|
||||||
|
|
||||||
cc_test(
|
cc_test(
|
||||||
name = "hello_test",
|
name = "hello_test",
|
||||||
size = "small",
|
size = "small",
|
||||||
@ -118,7 +104,7 @@ This `cc_test` rule declares the C++ test binary you want to build, and links to
|
|||||||
GoogleTest (`//:gtest_main`) using the prefix you specified in the `WORKSPACE`
|
GoogleTest (`//:gtest_main`) using the prefix you specified in the `WORKSPACE`
|
||||||
file (`@com_google_googletest`). For more information about Bazel `BUILD` files,
|
file (`@com_google_googletest`). For more information about Bazel `BUILD` files,
|
||||||
see the
|
see the
|
||||||
[Bazel C++ Tutorial](https://docs.bazel.build/versions/master/tutorial/cpp.html).
|
[Bazel C++ Tutorial](https://docs.bazel.build/versions/main/tutorial/cpp.html).
|
||||||
|
|
||||||
Now you can build and run your test:
|
Now you can build and run your test:
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ provided by GoogleTest. All actions are defined in the `::testing` namespace.
|
|||||||
|
|
||||||
## Returning a Value
|
## Returning a Value
|
||||||
|
|
||||||
| | |
|
| Action | Description |
|
||||||
| :-------------------------------- | :-------------------------------------------- |
|
| :-------------------------------- | :-------------------------------------------- |
|
||||||
| `Return()` | Return from a `void` mock function. |
|
| `Return()` | Return from a `void` mock function. |
|
||||||
| `Return(value)` | Return `value`. If the type of `value` is different to the mock function's return type, `value` is converted to the latter type <i>at the time the expectation is set</i>, not when the action is executed. |
|
| `Return(value)` | Return `value`. If the type of `value` is different to the mock function's return type, `value` is converted to the latter type <i>at the time the expectation is set</i>, not when the action is executed. |
|
||||||
@ -20,7 +20,7 @@ provided by GoogleTest. All actions are defined in the `::testing` namespace.
|
|||||||
|
|
||||||
## Side Effects
|
## Side Effects
|
||||||
|
|
||||||
| | |
|
| Action | Description |
|
||||||
| :--------------------------------- | :-------------------------------------- |
|
| :--------------------------------- | :-------------------------------------- |
|
||||||
| `Assign(&variable, value)` | Assign `value` to variable. |
|
| `Assign(&variable, value)` | Assign `value` to variable. |
|
||||||
| `DeleteArg<N>()` | Delete the `N`-th (0-based) argument, which must be a pointer. |
|
| `DeleteArg<N>()` | Delete the `N`-th (0-based) argument, which must be a pointer. |
|
||||||
@ -38,9 +38,9 @@ provided by GoogleTest. All actions are defined in the `::testing` namespace.
|
|||||||
In the following, by "callable" we mean a free function, `std::function`,
|
In the following, by "callable" we mean a free function, `std::function`,
|
||||||
functor, or lambda.
|
functor, or lambda.
|
||||||
|
|
||||||
| | |
|
| Action | Description |
|
||||||
| :---------------------------------- | :------------------------------------- |
|
| :---------------------------------- | :------------------------------------- |
|
||||||
| `f` | Invoke f with the arguments passed to the mock function, where f is a callable. |
|
| `f` | Invoke `f` with the arguments passed to the mock function, where `f` is a callable. |
|
||||||
| `Invoke(f)` | Invoke `f` with the arguments passed to the mock function, where `f` can be a global/static function or a functor. |
|
| `Invoke(f)` | Invoke `f` with the arguments passed to the mock function, where `f` can be a global/static function or a functor. |
|
||||||
| `Invoke(object_pointer, &class::method)` | Invoke the method on the object with the arguments passed to the mock function. |
|
| `Invoke(object_pointer, &class::method)` | Invoke the method on the object with the arguments passed to the mock function. |
|
||||||
| `InvokeWithoutArgs(f)` | Invoke `f`, which can be a global/static function or a functor. `f` must take no arguments. |
|
| `InvokeWithoutArgs(f)` | Invoke `f`, which can be a global/static function or a functor. `f` must take no arguments. |
|
||||||
@ -86,7 +86,7 @@ value, and `foo` by reference.
|
|||||||
|
|
||||||
## Default Action
|
## Default Action
|
||||||
|
|
||||||
| Matcher | Description |
|
| Action | Description |
|
||||||
| :------------ | :----------------------------------------------------- |
|
| :------------ | :----------------------------------------------------- |
|
||||||
| `DoDefault()` | Do the default action (specified by `ON_CALL()` or the built-in one). |
|
| `DoDefault()` | Do the default action (specified by `ON_CALL()` or the built-in one). |
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ composite action - trying to do so will result in a run-time error.
|
|||||||
|
|
||||||
## Composite Actions
|
## Composite Actions
|
||||||
|
|
||||||
| | |
|
| Action | Description |
|
||||||
| :----------------------------- | :------------------------------------------ |
|
| :----------------------------- | :------------------------------------------ |
|
||||||
| `DoAll(a1, a2, ..., an)` | Do all actions `a1` to `an` and return the result of `an` in each invocation. The first `n - 1` sub-actions must return void and will receive a readonly view of the arguments. |
|
| `DoAll(a1, a2, ..., an)` | Do all actions `a1` to `an` and return the result of `an` in each invocation. The first `n - 1` sub-actions must return void and will receive a readonly view of the arguments. |
|
||||||
| `IgnoreResult(a)` | Perform action `a` and ignore its result. `a` must not return void. |
|
| `IgnoreResult(a)` | Perform action `a` and ignore its result. `a` must not return void. |
|
||||||
@ -106,7 +106,7 @@ composite action - trying to do so will result in a run-time error.
|
|||||||
|
|
||||||
## Defining Actions
|
## Defining Actions
|
||||||
|
|
||||||
| | |
|
| Macro | Description |
|
||||||
| :--------------------------------- | :-------------------------------------- |
|
| :--------------------------------- | :-------------------------------------- |
|
||||||
| `ACTION(Sum) { return arg0 + arg1; }` | Defines an action `Sum()` to return the sum of the mock function's argument #0 and #1. |
|
| `ACTION(Sum) { return arg0 + arg1; }` | Defines an action `Sum()` to return the sum of the mock function's argument #0 and #1. |
|
||||||
| `ACTION_P(Plus, n) { return arg0 + n; }` | Defines an action `Plus(n)` to return the sum of the mock function's argument #0 and `n`. |
|
| `ACTION_P(Plus, n) { return arg0 + n; }` | Defines an action `Plus(n)` to return the sum of the mock function's argument #0 and `n`. |
|
||||||
|
@ -88,16 +88,17 @@ The `argument` can be either a C string or a C++ string object:
|
|||||||
|
|
||||||
| Matcher | Description |
|
| Matcher | Description |
|
||||||
| :---------------------- | :------------------------------------------------- |
|
| :---------------------- | :------------------------------------------------- |
|
||||||
| `ContainsRegex(string)` | `argument` matches the given regular expression. |
|
| `ContainsRegex(string)` | `argument` matches the given regular expression. |
|
||||||
| `EndsWith(suffix)` | `argument` ends with string `suffix`. |
|
| `EndsWith(suffix)` | `argument` ends with string `suffix`. |
|
||||||
| `HasSubstr(string)` | `argument` contains `string` as a sub-string. |
|
| `HasSubstr(string)` | `argument` contains `string` as a sub-string. |
|
||||||
| `IsEmpty()` | `argument` is an empty string. |
|
| `IsEmpty()` | `argument` is an empty string. |
|
||||||
| `MatchesRegex(string)` | `argument` matches the given regular expression with the match starting at the first character and ending at the last character. |
|
| `MatchesRegex(string)` | `argument` matches the given regular expression with the match starting at the first character and ending at the last character. |
|
||||||
| `StartsWith(prefix)` | `argument` starts with string `prefix`. |
|
| `StartsWith(prefix)` | `argument` starts with string `prefix`. |
|
||||||
| `StrCaseEq(string)` | `argument` is equal to `string`, ignoring case. |
|
| `StrCaseEq(string)` | `argument` is equal to `string`, ignoring case. |
|
||||||
| `StrCaseNe(string)` | `argument` is not equal to `string`, ignoring case. |
|
| `StrCaseNe(string)` | `argument` is not equal to `string`, ignoring case. |
|
||||||
| `StrEq(string)` | `argument` is equal to `string`. |
|
| `StrEq(string)` | `argument` is equal to `string`. |
|
||||||
| `StrNe(string)` | `argument` is not equal to `string`. |
|
| `StrNe(string)` | `argument` is not equal to `string`. |
|
||||||
|
| `WhenBase64Unescaped(m)` | `argument` is a base-64 escaped string whose unescaped string matches `m`. |
|
||||||
|
|
||||||
`ContainsRegex()` and `MatchesRegex()` take ownership of the `RE` object. They
|
`ContainsRegex()` and `MatchesRegex()` take ownership of the `RE` object. They
|
||||||
use the regular expression syntax defined
|
use the regular expression syntax defined
|
||||||
@ -116,6 +117,7 @@ messages, you can use:
|
|||||||
| `BeginEndDistanceIs(m)` | `argument` is a container whose `begin()` and `end()` iterators are separated by a number of increments matching `m`. E.g. `BeginEndDistanceIs(2)` or `BeginEndDistanceIs(Lt(2))`. For containers that define a `size()` method, `SizeIs(m)` may be more efficient. |
|
| `BeginEndDistanceIs(m)` | `argument` is a container whose `begin()` and `end()` iterators are separated by a number of increments matching `m`. E.g. `BeginEndDistanceIs(2)` or `BeginEndDistanceIs(Lt(2))`. For containers that define a `size()` method, `SizeIs(m)` may be more efficient. |
|
||||||
| `ContainerEq(container)` | The same as `Eq(container)` except that the failure message also includes which elements are in one container but not the other. |
|
| `ContainerEq(container)` | The same as `Eq(container)` except that the failure message also includes which elements are in one container but not the other. |
|
||||||
| `Contains(e)` | `argument` contains an element that matches `e`, which can be either a value or a matcher. |
|
| `Contains(e)` | `argument` contains an element that matches `e`, which can be either a value or a matcher. |
|
||||||
|
| `Contains(e).Times(n)` | `argument` contains elements that match `e`, which can be either a value or a matcher, and the number of matches is `n`, which can be either a value or a matcher. Unlike the plain `Contains` and `Each` this allows to check for arbitrary occurrences including testing for absence with `Contains(e).Times(0)`. |
|
||||||
| `Each(e)` | `argument` is a container where *every* element matches `e`, which can be either a value or a matcher. |
|
| `Each(e)` | `argument` is a container where *every* element matches `e`, which can be either a value or a matcher. |
|
||||||
| `ElementsAre(e0, e1, ..., en)` | `argument` has `n + 1` elements, where the *i*-th element matches `ei`, which can be a value or a matcher. |
|
| `ElementsAre(e0, e1, ..., en)` | `argument` has `n + 1` elements, where the *i*-th element matches `ei`, which can be a value or a matcher. |
|
||||||
| `ElementsAreArray({e0, e1, ..., en})`, `ElementsAreArray(a_container)`, `ElementsAreArray(begin, end)`, `ElementsAreArray(array)`, or `ElementsAreArray(array, count)` | The same as `ElementsAre()` except that the expected element values/matchers come from an initializer list, STL-style container, iterator range, or C-style array. |
|
| `ElementsAreArray({e0, e1, ..., en})`, `ElementsAreArray(a_container)`, `ElementsAreArray(begin, end)`, `ElementsAreArray(array)`, or `ElementsAreArray(array, count)` | The same as `ElementsAre()` except that the expected element values/matchers come from an initializer list, STL-style container, iterator range, or C-style array. |
|
||||||
@ -146,7 +148,6 @@ messages, you can use:
|
|||||||
one might write:
|
one might write:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
using ::std::get;
|
|
||||||
MATCHER(FooEq, "") {
|
MATCHER(FooEq, "") {
|
||||||
return std::get<0>(arg).Equals(std::get<1>(arg));
|
return std::get<0>(arg).Equals(std::get<1>(arg));
|
||||||
}
|
}
|
||||||
@ -237,6 +238,7 @@ You can make a matcher from one or more other matchers:
|
|||||||
| `AnyOf(m1, m2, ..., mn)` | `argument` matches at least one of the matchers `m1` to `mn`. |
|
| `AnyOf(m1, m2, ..., mn)` | `argument` matches at least one of the matchers `m1` to `mn`. |
|
||||||
| `AnyOfArray({m0, m1, ..., mn})`, `AnyOfArray(a_container)`, `AnyOfArray(begin, end)`, `AnyOfArray(array)`, or `AnyOfArray(array, count)` | The same as `AnyOf()` except that the matchers come from an initializer list, STL-style container, iterator range, or C-style array. |
|
| `AnyOfArray({m0, m1, ..., mn})`, `AnyOfArray(a_container)`, `AnyOfArray(begin, end)`, `AnyOfArray(array)`, or `AnyOfArray(array, count)` | The same as `AnyOf()` except that the matchers come from an initializer list, STL-style container, iterator range, or C-style array. |
|
||||||
| `Not(m)` | `argument` doesn't match matcher `m`. |
|
| `Not(m)` | `argument` doesn't match matcher `m`. |
|
||||||
|
| `Conditional(cond, m1, m2)` | Matches matcher `m1` if `cond` evaluates to true, else matches `m2`.|
|
||||||
|
|
||||||
## Adapters for Matchers
|
## Adapters for Matchers
|
||||||
|
|
||||||
@ -259,7 +261,7 @@ which must be a permanent callback.
|
|||||||
|
|
||||||
## Defining Matchers
|
## Defining Matchers
|
||||||
|
|
||||||
| Matcher | Description |
|
| Macro | Description |
|
||||||
| :----------------------------------- | :------------------------------------ |
|
| :----------------------------------- | :------------------------------------ |
|
||||||
| `MATCHER(IsEven, "") { return (arg % 2) == 0; }` | Defines a matcher `IsEven()` to match an even number. |
|
| `MATCHER(IsEven, "") { return (arg % 2) == 0; }` | Defines a matcher `IsEven()` to match an even number. |
|
||||||
| `MATCHER_P(IsDivisibleBy, n, "") { *result_listener << "where the remainder is " << (arg % n); return (arg % n) == 0; }` | Defines a matcher `IsDivisibleBy(n)` to match a number divisible by `n`. |
|
| `MATCHER_P(IsDivisibleBy, n, "") { *result_listener << "where the remainder is " << (arg % n); return (arg % n) == 0; }` | Defines a matcher `IsDivisibleBy(n)` to match a number divisible by `n`. |
|
||||||
|
@ -36,13 +36,9 @@ endif()
|
|||||||
# as ${gmock_SOURCE_DIR} and to the root binary directory as
|
# as ${gmock_SOURCE_DIR} and to the root binary directory as
|
||||||
# ${gmock_BINARY_DIR}.
|
# ${gmock_BINARY_DIR}.
|
||||||
# Language "C" is required for find_package(Threads).
|
# Language "C" is required for find_package(Threads).
|
||||||
if (CMAKE_VERSION VERSION_LESS 3.0)
|
cmake_minimum_required(VERSION 3.5)
|
||||||
project(gmock CXX C)
|
cmake_policy(SET CMP0048 NEW)
|
||||||
else()
|
project(gmock VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)
|
||||||
cmake_policy(SET CMP0048 NEW)
|
|
||||||
project(gmock VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)
|
|
||||||
endif()
|
|
||||||
cmake_minimum_required(VERSION 2.8.12)
|
|
||||||
|
|
||||||
if (COMMAND set_up_hermetic_build)
|
if (COMMAND set_up_hermetic_build)
|
||||||
set_up_hermetic_build()
|
set_up_hermetic_build()
|
||||||
|
@ -35,10 +35,6 @@ Details and examples can be found here:
|
|||||||
* [gMock Cookbook](https://google.github.io/googletest/gmock_cook_book.html)
|
* [gMock Cookbook](https://google.github.io/googletest/gmock_cook_book.html)
|
||||||
* [gMock Cheat Sheet](https://google.github.io/googletest/gmock_cheat_sheet.html)
|
* [gMock Cheat Sheet](https://google.github.io/googletest/gmock_cheat_sheet.html)
|
||||||
|
|
||||||
Please note that code under scripts/generator/ is from the
|
|
||||||
[cppclean project](http://code.google.com/p/cppclean/) and under the Apache
|
|
||||||
License, which is different from GoogleMock's license.
|
|
||||||
|
|
||||||
GoogleMock is a part of
|
GoogleMock is a part of
|
||||||
[GoogleTest C++ testing framework](http://github.com/google/googletest/) and a
|
[GoogleTest C++ testing framework](http://github.com/google/googletest/) and a
|
||||||
subject to the same requirements.
|
subject to the same requirements.
|
||||||
|
@ -125,8 +125,6 @@
|
|||||||
// 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/master/docs/gmock_cook_book.md
|
||||||
|
|
||||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
|
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
|
||||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
|
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
|
||||||
|
|
||||||
|
@ -34,8 +34,6 @@
|
|||||||
// cardinalities can be defined by the user implementing the
|
// cardinalities can be defined by the user implementing the
|
||||||
// CardinalityInterface interface if necessary.
|
// CardinalityInterface interface if necessary.
|
||||||
|
|
||||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
||||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
||||||
|
|
||||||
|
@ -31,8 +31,6 @@
|
|||||||
//
|
//
|
||||||
// This file implements MOCK_METHOD.
|
// This file implements MOCK_METHOD.
|
||||||
|
|
||||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
|
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
|
||||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
|
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
|
||||||
|
|
||||||
@ -64,6 +62,39 @@ struct ThisRefAdjuster {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr bool PrefixOf(const char* a, const char* b) {
|
||||||
|
return *a == 0 || (*a == *b && internal::PrefixOf(a + 1, b + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <int N, int M>
|
||||||
|
constexpr bool StartsWith(const char (&prefix)[N], const char (&str)[M]) {
|
||||||
|
return N <= M && internal::PrefixOf(prefix, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <int N, int M>
|
||||||
|
constexpr bool EndsWith(const char (&suffix)[N], const char (&str)[M]) {
|
||||||
|
return N <= M && internal::PrefixOf(suffix, str + M - N);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <int N, int M>
|
||||||
|
constexpr bool Equals(const char (&a)[N], const char (&b)[M]) {
|
||||||
|
return N == M && internal::PrefixOf(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <int N>
|
||||||
|
constexpr bool ValidateSpec(const char (&spec)[N]) {
|
||||||
|
return internal::Equals("const", spec) ||
|
||||||
|
internal::Equals("override", spec) ||
|
||||||
|
internal::Equals("final", spec) ||
|
||||||
|
internal::Equals("noexcept", spec) ||
|
||||||
|
(internal::StartsWith("noexcept(", spec) &&
|
||||||
|
internal::EndsWith(")", spec)) ||
|
||||||
|
internal::Equals("ref(&)", spec) ||
|
||||||
|
internal::Equals("ref(&&)", spec) ||
|
||||||
|
(internal::StartsWith("Calltype(", spec) &&
|
||||||
|
internal::EndsWith(")", spec));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
// The style guide prohibits "using" statements in a namespace scope
|
// The style guide prohibits "using" statements in a namespace scope
|
||||||
@ -86,17 +117,18 @@ using internal::FunctionMocker;
|
|||||||
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_3(_Ret, _MethodName, _Args) \
|
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_3(_Ret, _MethodName, _Args) \
|
||||||
GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, ())
|
GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, ())
|
||||||
|
|
||||||
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, _Spec) \
|
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, _Spec) \
|
||||||
GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Args); \
|
GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Args); \
|
||||||
GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Spec); \
|
GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Spec); \
|
||||||
GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE( \
|
GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE( \
|
||||||
GMOCK_PP_NARG0 _Args, GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)); \
|
GMOCK_PP_NARG0 _Args, GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)); \
|
||||||
GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \
|
GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \
|
||||||
GMOCK_INTERNAL_MOCK_METHOD_IMPL( \
|
GMOCK_INTERNAL_MOCK_METHOD_IMPL( \
|
||||||
GMOCK_PP_NARG0 _Args, _MethodName, GMOCK_INTERNAL_HAS_CONST(_Spec), \
|
GMOCK_PP_NARG0 _Args, _MethodName, GMOCK_INTERNAL_HAS_CONST(_Spec), \
|
||||||
GMOCK_INTERNAL_HAS_OVERRIDE(_Spec), GMOCK_INTERNAL_HAS_FINAL(_Spec), \
|
GMOCK_INTERNAL_HAS_OVERRIDE(_Spec), GMOCK_INTERNAL_HAS_FINAL(_Spec), \
|
||||||
GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Spec), \
|
GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Spec), \
|
||||||
GMOCK_INTERNAL_GET_CALLTYPE(_Spec), GMOCK_INTERNAL_GET_REF_SPEC(_Spec), \
|
GMOCK_INTERNAL_GET_CALLTYPE_SPEC(_Spec), \
|
||||||
|
GMOCK_INTERNAL_GET_REF_SPEC(_Spec), \
|
||||||
(GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)))
|
(GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)))
|
||||||
|
|
||||||
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_5(...) \
|
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_5(...) \
|
||||||
@ -170,7 +202,7 @@ using internal::FunctionMocker;
|
|||||||
|
|
||||||
#define GMOCK_INTERNAL_EXPAND(...) __VA_ARGS__
|
#define GMOCK_INTERNAL_EXPAND(...) __VA_ARGS__
|
||||||
|
|
||||||
// Five Valid modifiers.
|
// Valid modifiers.
|
||||||
#define GMOCK_INTERNAL_HAS_CONST(_Tuple) \
|
#define GMOCK_INTERNAL_HAS_CONST(_Tuple) \
|
||||||
GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_CONST, ~, _Tuple))
|
GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_CONST, ~, _Tuple))
|
||||||
|
|
||||||
@ -189,6 +221,14 @@ using internal::FunctionMocker;
|
|||||||
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)), \
|
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)), \
|
||||||
_elem, )
|
_elem, )
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_GET_CALLTYPE_SPEC(_Tuple) \
|
||||||
|
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_CALLTYPE_SPEC_IF_CALLTYPE, ~, _Tuple)
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_CALLTYPE_SPEC_IF_CALLTYPE(_i, _, _elem) \
|
||||||
|
GMOCK_PP_IF( \
|
||||||
|
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CALLTYPE(_i, _, _elem)), \
|
||||||
|
GMOCK_PP_CAT(GMOCK_INTERNAL_UNPACK_, _elem), )
|
||||||
|
|
||||||
#define GMOCK_INTERNAL_GET_REF_SPEC(_Tuple) \
|
#define GMOCK_INTERNAL_GET_REF_SPEC(_Tuple) \
|
||||||
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_REF_SPEC_IF_REF, ~, _Tuple)
|
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_REF_SPEC_IF_REF, ~, _Tuple)
|
||||||
|
|
||||||
@ -196,19 +236,25 @@ using internal::FunctionMocker;
|
|||||||
GMOCK_PP_IF(GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)), \
|
GMOCK_PP_IF(GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)), \
|
||||||
GMOCK_PP_CAT(GMOCK_INTERNAL_UNPACK_, _elem), )
|
GMOCK_PP_CAT(GMOCK_INTERNAL_UNPACK_, _elem), )
|
||||||
|
|
||||||
#define GMOCK_INTERNAL_GET_CALLTYPE(_Tuple) \
|
#ifdef GMOCK_INTERNAL_STRICT_SPEC_ASSERT
|
||||||
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_CALLTYPE_IMPL, ~, _Tuple)
|
#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem) \
|
||||||
|
static_assert( \
|
||||||
#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem) \
|
::testing::internal::ValidateSpec(GMOCK_PP_STRINGIZE(_elem)), \
|
||||||
static_assert( \
|
"Token \'" GMOCK_PP_STRINGIZE( \
|
||||||
(GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem)) + \
|
_elem) "\' cannot be recognized as a valid specification " \
|
||||||
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem)) + \
|
"modifier. Is a ',' missing?");
|
||||||
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem)) + \
|
#else
|
||||||
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)) + \
|
#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem) \
|
||||||
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)) + \
|
static_assert( \
|
||||||
GMOCK_INTERNAL_IS_CALLTYPE(_elem)) == 1, \
|
(GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem)) + \
|
||||||
GMOCK_PP_STRINGIZE( \
|
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem)) + \
|
||||||
|
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem)) + \
|
||||||
|
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)) + \
|
||||||
|
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)) + \
|
||||||
|
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CALLTYPE(_i, _, _elem))) == 1, \
|
||||||
|
GMOCK_PP_STRINGIZE( \
|
||||||
_elem) " cannot be recognized as a valid specification modifier.");
|
_elem) " cannot be recognized as a valid specification modifier.");
|
||||||
|
#endif // GMOCK_INTERNAL_STRICT_SPEC_ASSERT
|
||||||
|
|
||||||
// Modifiers implementation.
|
// Modifiers implementation.
|
||||||
#define GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem) \
|
#define GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem) \
|
||||||
@ -238,26 +284,12 @@ using internal::FunctionMocker;
|
|||||||
|
|
||||||
#define GMOCK_INTERNAL_UNPACK_ref(x) x
|
#define GMOCK_INTERNAL_UNPACK_ref(x) x
|
||||||
|
|
||||||
#define GMOCK_INTERNAL_GET_CALLTYPE_IMPL(_i, _, _elem) \
|
#define GMOCK_INTERNAL_DETECT_CALLTYPE(_i, _, _elem) \
|
||||||
GMOCK_PP_IF(GMOCK_INTERNAL_IS_CALLTYPE(_elem), \
|
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_CALLTYPE_I_, _elem)
|
||||||
GMOCK_INTERNAL_GET_VALUE_CALLTYPE, GMOCK_PP_EMPTY) \
|
|
||||||
(_elem)
|
|
||||||
|
|
||||||
// TODO(iserna): GMOCK_INTERNAL_IS_CALLTYPE and
|
#define GMOCK_INTERNAL_DETECT_CALLTYPE_I_Calltype ,
|
||||||
// GMOCK_INTERNAL_GET_VALUE_CALLTYPE needed more expansions to work on windows
|
|
||||||
// maybe they can be simplified somehow.
|
|
||||||
#define GMOCK_INTERNAL_IS_CALLTYPE(_arg) \
|
|
||||||
GMOCK_INTERNAL_IS_CALLTYPE_I( \
|
|
||||||
GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg))
|
|
||||||
#define GMOCK_INTERNAL_IS_CALLTYPE_I(_arg) GMOCK_PP_IS_ENCLOSED_PARENS(_arg)
|
|
||||||
|
|
||||||
#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE(_arg) \
|
#define GMOCK_INTERNAL_UNPACK_Calltype(...) __VA_ARGS__
|
||||||
GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I( \
|
|
||||||
GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg))
|
|
||||||
#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I(_arg) \
|
|
||||||
GMOCK_PP_IDENTITY _arg
|
|
||||||
|
|
||||||
#define GMOCK_INTERNAL_IS_CALLTYPE_HELPER_Calltype
|
|
||||||
|
|
||||||
// Note: The use of `identity_t` here allows _Ret to represent return types that
|
// Note: The use of `identity_t` here allows _Ret to represent return types that
|
||||||
// would normally need to be specified in a different way. For example, a method
|
// would normally need to be specified in a different way. For example, a method
|
||||||
|
@ -250,8 +250,6 @@
|
|||||||
// See googletest/include/gtest/gtest-matchers.h for the definition of class
|
// See googletest/include/gtest/gtest-matchers.h for the definition of class
|
||||||
// Matcher, class MatcherInterface, and others.
|
// Matcher, class MatcherInterface, and others.
|
||||||
|
|
||||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
|
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
|
||||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
|
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
|
||||||
|
|
||||||
@ -1124,6 +1122,45 @@ class EndsWithMatcher {
|
|||||||
const StringType suffix_;
|
const StringType suffix_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Implements the polymorphic WhenBase64Unescaped(matcher) matcher, which can be
|
||||||
|
// used as a Matcher<T> as long as T can be converted to a string.
|
||||||
|
class WhenBase64UnescapedMatcher {
|
||||||
|
public:
|
||||||
|
using is_gtest_matcher = void;
|
||||||
|
|
||||||
|
explicit WhenBase64UnescapedMatcher(
|
||||||
|
const Matcher<const std::string&>& internal_matcher)
|
||||||
|
: internal_matcher_(internal_matcher) {}
|
||||||
|
|
||||||
|
// Matches anything that can convert to std::string.
|
||||||
|
template <typename MatcheeStringType>
|
||||||
|
bool MatchAndExplain(const MatcheeStringType& s,
|
||||||
|
MatchResultListener* listener) const {
|
||||||
|
const std::string s2(s); // NOLINT (needed for working with string_view).
|
||||||
|
std::string unescaped;
|
||||||
|
if (!internal::Base64Unescape(s2, &unescaped)) {
|
||||||
|
if (listener != nullptr) {
|
||||||
|
*listener << "is not a valid base64 escaped string";
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return MatchPrintAndExplain(unescaped, internal_matcher_, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DescribeTo(::std::ostream* os) const {
|
||||||
|
*os << "matches after Base64Unescape ";
|
||||||
|
internal_matcher_.DescribeTo(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DescribeNegationTo(::std::ostream* os) const {
|
||||||
|
*os << "does not match after Base64Unescape ";
|
||||||
|
internal_matcher_.DescribeTo(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Matcher<const std::string&> internal_matcher_;
|
||||||
|
};
|
||||||
|
|
||||||
// Implements a matcher that compares the two fields of a 2-tuple
|
// Implements a matcher that compares the two fields of a 2-tuple
|
||||||
// using one of the ==, <=, <, etc, operators. The two fields being
|
// using one of the ==, <=, <, etc, operators. The two fields being
|
||||||
// compared don't have to have the same type.
|
// compared don't have to have the same type.
|
||||||
@ -1405,6 +1442,30 @@ class AnyOfMatcherImpl : public MatcherInterface<const T&> {
|
|||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
using AnyOfMatcher = VariadicMatcher<AnyOfMatcherImpl, Args...>;
|
using AnyOfMatcher = VariadicMatcher<AnyOfMatcherImpl, Args...>;
|
||||||
|
|
||||||
|
// ConditionalMatcher is the implementation of Conditional(cond, m1, m2)
|
||||||
|
template <typename MatcherTrue, typename MatcherFalse>
|
||||||
|
class ConditionalMatcher {
|
||||||
|
public:
|
||||||
|
ConditionalMatcher(bool condition, MatcherTrue matcher_true,
|
||||||
|
MatcherFalse matcher_false)
|
||||||
|
: condition_(condition),
|
||||||
|
matcher_true_(std::move(matcher_true)),
|
||||||
|
matcher_false_(std::move(matcher_false)) {}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
operator Matcher<T>() const { // NOLINT(runtime/explicit)
|
||||||
|
return condition_ ? SafeMatcherCast<T>(matcher_true_)
|
||||||
|
: SafeMatcherCast<T>(matcher_false_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool condition_;
|
||||||
|
MatcherTrue matcher_true_;
|
||||||
|
MatcherFalse matcher_false_;
|
||||||
|
|
||||||
|
GTEST_DISALLOW_ASSIGN_(ConditionalMatcher);
|
||||||
|
};
|
||||||
|
|
||||||
// Wrapper for implementation of Any/AllOfArray().
|
// Wrapper for implementation of Any/AllOfArray().
|
||||||
template <template <class> class MatcherImpl, typename T>
|
template <template <class> class MatcherImpl, typename T>
|
||||||
class SomeOfArrayMatcher {
|
class SomeOfArrayMatcher {
|
||||||
@ -2364,7 +2425,6 @@ class ContainerEqMatcher {
|
|||||||
typedef internal::StlContainerView<
|
typedef internal::StlContainerView<
|
||||||
typename std::remove_const<LhsContainer>::type>
|
typename std::remove_const<LhsContainer>::type>
|
||||||
LhsView;
|
LhsView;
|
||||||
typedef typename LhsView::type LhsStlContainer;
|
|
||||||
StlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);
|
StlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);
|
||||||
if (lhs_stl_container == expected_)
|
if (lhs_stl_container == expected_)
|
||||||
return true;
|
return true;
|
||||||
@ -2373,8 +2433,7 @@ class ContainerEqMatcher {
|
|||||||
if (os != nullptr) {
|
if (os != nullptr) {
|
||||||
// Something is different. Check for extra values first.
|
// Something is different. Check for extra values first.
|
||||||
bool printed_header = false;
|
bool printed_header = false;
|
||||||
for (typename LhsStlContainer::const_iterator it =
|
for (auto it = lhs_stl_container.begin();
|
||||||
lhs_stl_container.begin();
|
|
||||||
it != lhs_stl_container.end(); ++it) {
|
it != lhs_stl_container.end(); ++it) {
|
||||||
if (internal::ArrayAwareFind(expected_.begin(), expected_.end(), *it) ==
|
if (internal::ArrayAwareFind(expected_.begin(), expected_.end(), *it) ==
|
||||||
expected_.end()) {
|
expected_.end()) {
|
||||||
@ -2390,7 +2449,7 @@ class ContainerEqMatcher {
|
|||||||
|
|
||||||
// Now check for missing values.
|
// Now check for missing values.
|
||||||
bool printed_header2 = false;
|
bool printed_header2 = false;
|
||||||
for (typename StlContainer::const_iterator it = expected_.begin();
|
for (auto it = expected_.begin();
|
||||||
it != expected_.end(); ++it) {
|
it != expected_.end(); ++it) {
|
||||||
if (internal::ArrayAwareFind(
|
if (internal::ArrayAwareFind(
|
||||||
lhs_stl_container.begin(), lhs_stl_container.end(), *it) ==
|
lhs_stl_container.begin(), lhs_stl_container.end(), *it) ==
|
||||||
@ -2574,14 +2633,14 @@ class PointwiseMatcher {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
typename LhsStlContainer::const_iterator left = lhs_stl_container.begin();
|
auto left = lhs_stl_container.begin();
|
||||||
typename RhsStlContainer::const_iterator right = rhs_.begin();
|
auto right = rhs_.begin();
|
||||||
for (size_t i = 0; i != actual_size; ++i, ++left, ++right) {
|
for (size_t i = 0; i != actual_size; ++i, ++left, ++right) {
|
||||||
if (listener->IsInterested()) {
|
if (listener->IsInterested()) {
|
||||||
StringMatchResultListener inner_listener;
|
StringMatchResultListener inner_listener;
|
||||||
// Create InnerMatcherArg as a temporarily object to avoid it outlives
|
// Create InnerMatcherArg as a temporarily object to avoid it outlives
|
||||||
// *left and *right. Dereference or the conversion to `const T&` may
|
// *left and *right. Dereference or the conversion to `const T&` may
|
||||||
// return temp objects, e.g for vector<bool>.
|
// return temp objects, e.g. for vector<bool>.
|
||||||
if (!mono_tuple_matcher_.MatchAndExplain(
|
if (!mono_tuple_matcher_.MatchAndExplain(
|
||||||
InnerMatcherArg(ImplicitCast_<const LhsValue&>(*left),
|
InnerMatcherArg(ImplicitCast_<const LhsValue&>(*left),
|
||||||
ImplicitCast_<const RhsValue&>(*right)),
|
ImplicitCast_<const RhsValue&>(*right)),
|
||||||
@ -2638,7 +2697,7 @@ class QuantifierMatcherImpl : public MatcherInterface<Container> {
|
|||||||
MatchResultListener* listener) const {
|
MatchResultListener* listener) const {
|
||||||
StlContainerReference stl_container = View::ConstReference(container);
|
StlContainerReference stl_container = View::ConstReference(container);
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
for (typename StlContainer::const_iterator it = stl_container.begin();
|
for (auto it = stl_container.begin();
|
||||||
it != stl_container.end(); ++it, ++i) {
|
it != stl_container.end(); ++it, ++i) {
|
||||||
StringMatchResultListener inner_listener;
|
StringMatchResultListener inner_listener;
|
||||||
const bool matches = inner_matcher_.MatchAndExplain(*it, &inner_listener);
|
const bool matches = inner_matcher_.MatchAndExplain(*it, &inner_listener);
|
||||||
@ -2653,6 +2712,54 @@ class QuantifierMatcherImpl : public MatcherInterface<Container> {
|
|||||||
return all_elements_should_match;
|
return all_elements_should_match;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MatchAndExplainImpl(const Matcher<size_t>& count_matcher,
|
||||||
|
Container container,
|
||||||
|
MatchResultListener* listener) const {
|
||||||
|
StlContainerReference stl_container = View::ConstReference(container);
|
||||||
|
size_t i = 0;
|
||||||
|
std::vector<size_t> match_elements;
|
||||||
|
for (auto it = stl_container.begin(); it != stl_container.end();
|
||||||
|
++it, ++i) {
|
||||||
|
StringMatchResultListener inner_listener;
|
||||||
|
const bool matches = inner_matcher_.MatchAndExplain(*it, &inner_listener);
|
||||||
|
if (matches) {
|
||||||
|
match_elements.push_back(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (listener->IsInterested()) {
|
||||||
|
if (match_elements.empty()) {
|
||||||
|
*listener << "has no element that matches";
|
||||||
|
} else if (match_elements.size() == 1) {
|
||||||
|
*listener << "whose element #" << match_elements[0] << " matches";
|
||||||
|
} else {
|
||||||
|
*listener << "whose elements (";
|
||||||
|
std::string sep = "";
|
||||||
|
for (size_t e : match_elements) {
|
||||||
|
*listener << sep << e;
|
||||||
|
sep = ", ";
|
||||||
|
}
|
||||||
|
*listener << ") match";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StringMatchResultListener count_listener;
|
||||||
|
if (count_matcher.MatchAndExplain(match_elements.size(), &count_listener)) {
|
||||||
|
*listener << " and whose match quantity of " << match_elements.size()
|
||||||
|
<< " matches";
|
||||||
|
PrintIfNotEmpty(count_listener.str(), listener->stream());
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
if (match_elements.empty()) {
|
||||||
|
*listener << " and";
|
||||||
|
} else {
|
||||||
|
*listener << " but";
|
||||||
|
}
|
||||||
|
*listener << " whose match quantity of " << match_elements.size()
|
||||||
|
<< " does not match";
|
||||||
|
PrintIfNotEmpty(count_listener.str(), listener->stream());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const Matcher<const Element&> inner_matcher_;
|
const Matcher<const Element&> inner_matcher_;
|
||||||
};
|
};
|
||||||
@ -2709,6 +2816,58 @@ class EachMatcherImpl : public QuantifierMatcherImpl<Container> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Implements Contains(element_matcher).Times(n) for the given argument type
|
||||||
|
// Container.
|
||||||
|
template <typename Container>
|
||||||
|
class ContainsTimesMatcherImpl : public QuantifierMatcherImpl<Container> {
|
||||||
|
public:
|
||||||
|
template <typename InnerMatcher>
|
||||||
|
explicit ContainsTimesMatcherImpl(InnerMatcher inner_matcher,
|
||||||
|
Matcher<size_t> count_matcher)
|
||||||
|
: QuantifierMatcherImpl<Container>(inner_matcher),
|
||||||
|
count_matcher_(std::move(count_matcher)) {}
|
||||||
|
|
||||||
|
void DescribeTo(::std::ostream* os) const override {
|
||||||
|
*os << "quantity of elements that match ";
|
||||||
|
this->inner_matcher_.DescribeTo(os);
|
||||||
|
*os << " ";
|
||||||
|
count_matcher_.DescribeTo(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DescribeNegationTo(::std::ostream* os) const override {
|
||||||
|
*os << "quantity of elements that match ";
|
||||||
|
this->inner_matcher_.DescribeTo(os);
|
||||||
|
*os << " ";
|
||||||
|
count_matcher_.DescribeNegationTo(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MatchAndExplain(Container container,
|
||||||
|
MatchResultListener* listener) const override {
|
||||||
|
return this->MatchAndExplainImpl(count_matcher_, container, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Matcher<size_t> count_matcher_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Implements polymorphic Contains(element_matcher).Times(n).
|
||||||
|
template <typename M>
|
||||||
|
class ContainsTimesMatcher {
|
||||||
|
public:
|
||||||
|
explicit ContainsTimesMatcher(M m, Matcher<size_t> count_matcher)
|
||||||
|
: inner_matcher_(m), count_matcher_(std::move(count_matcher)) {}
|
||||||
|
|
||||||
|
template <typename Container>
|
||||||
|
operator Matcher<Container>() const { // NOLINT
|
||||||
|
return Matcher<Container>(new ContainsTimesMatcherImpl<const Container&>(
|
||||||
|
inner_matcher_, count_matcher_));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const M inner_matcher_;
|
||||||
|
const Matcher<size_t> count_matcher_;
|
||||||
|
};
|
||||||
|
|
||||||
// Implements polymorphic Contains(element_matcher).
|
// Implements polymorphic Contains(element_matcher).
|
||||||
template <typename M>
|
template <typename M>
|
||||||
class ContainsMatcher {
|
class ContainsMatcher {
|
||||||
@ -2716,11 +2875,15 @@ class ContainsMatcher {
|
|||||||
explicit ContainsMatcher(M m) : inner_matcher_(m) {}
|
explicit ContainsMatcher(M m) : inner_matcher_(m) {}
|
||||||
|
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
operator Matcher<Container>() const {
|
operator Matcher<Container>() const { // NOLINT
|
||||||
return Matcher<Container>(
|
return Matcher<Container>(
|
||||||
new ContainsMatcherImpl<const Container&>(inner_matcher_));
|
new ContainsMatcherImpl<const Container&>(inner_matcher_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ContainsTimesMatcher<M> Times(Matcher<size_t> count_matcher) const {
|
||||||
|
return ContainsTimesMatcher<M>(inner_matcher_, std::move(count_matcher));
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const M inner_matcher_;
|
const M inner_matcher_;
|
||||||
};
|
};
|
||||||
@ -2732,7 +2895,7 @@ class EachMatcher {
|
|||||||
explicit EachMatcher(M m) : inner_matcher_(m) {}
|
explicit EachMatcher(M m) : inner_matcher_(m) {}
|
||||||
|
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
operator Matcher<Container>() const {
|
operator Matcher<Container>() const { // NOLINT
|
||||||
return Matcher<Container>(
|
return Matcher<Container>(
|
||||||
new EachMatcherImpl<const Container&>(inner_matcher_));
|
new EachMatcherImpl<const Container&>(inner_matcher_));
|
||||||
}
|
}
|
||||||
@ -3235,7 +3398,7 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> {
|
|||||||
// explanations[i] is the explanation of the element at index i.
|
// explanations[i] is the explanation of the element at index i.
|
||||||
::std::vector<std::string> explanations(count());
|
::std::vector<std::string> explanations(count());
|
||||||
StlContainerReference stl_container = View::ConstReference(container);
|
StlContainerReference stl_container = View::ConstReference(container);
|
||||||
typename StlContainer::const_iterator it = stl_container.begin();
|
auto it = stl_container.begin();
|
||||||
size_t exam_pos = 0;
|
size_t exam_pos = 0;
|
||||||
bool mismatch_found = false; // Have we found a mismatched element yet?
|
bool mismatch_found = false; // Have we found a mismatched element yet?
|
||||||
|
|
||||||
@ -3428,7 +3591,6 @@ class UnorderedElementsAreMatcherImpl
|
|||||||
typedef internal::StlContainerView<RawContainer> View;
|
typedef internal::StlContainerView<RawContainer> View;
|
||||||
typedef typename View::type StlContainer;
|
typedef typename View::type StlContainer;
|
||||||
typedef typename View::const_reference StlContainerReference;
|
typedef typename View::const_reference StlContainerReference;
|
||||||
typedef typename StlContainer::const_iterator StlContainerConstIterator;
|
|
||||||
typedef typename StlContainer::value_type Element;
|
typedef typename StlContainer::value_type Element;
|
||||||
|
|
||||||
template <typename InputIter>
|
template <typename InputIter>
|
||||||
@ -3981,26 +4143,26 @@ ElementsAreArray(Iter first, Iter last) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline internal::ElementsAreArrayMatcher<T> ElementsAreArray(
|
inline auto ElementsAreArray(const T* pointer, size_t count)
|
||||||
const T* pointer, size_t count) {
|
-> decltype(ElementsAreArray(pointer, pointer + count)) {
|
||||||
return ElementsAreArray(pointer, pointer + count);
|
return ElementsAreArray(pointer, pointer + count);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, size_t N>
|
template <typename T, size_t N>
|
||||||
inline internal::ElementsAreArrayMatcher<T> ElementsAreArray(
|
inline auto ElementsAreArray(const T (&array)[N])
|
||||||
const T (&array)[N]) {
|
-> decltype(ElementsAreArray(array, N)) {
|
||||||
return ElementsAreArray(array, N);
|
return ElementsAreArray(array, N);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
inline internal::ElementsAreArrayMatcher<typename Container::value_type>
|
inline auto ElementsAreArray(const Container& container)
|
||||||
ElementsAreArray(const Container& container) {
|
-> decltype(ElementsAreArray(container.begin(), container.end())) {
|
||||||
return ElementsAreArray(container.begin(), container.end());
|
return ElementsAreArray(container.begin(), container.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline internal::ElementsAreArrayMatcher<T>
|
inline auto ElementsAreArray(::std::initializer_list<T> xs)
|
||||||
ElementsAreArray(::std::initializer_list<T> xs) {
|
-> decltype(ElementsAreArray(xs.begin(), xs.end())) {
|
||||||
return ElementsAreArray(xs.begin(), xs.end());
|
return ElementsAreArray(xs.begin(), xs.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4595,7 +4757,7 @@ UnorderedPointwise(const Tuple2Matcher& tuple2_matcher,
|
|||||||
|
|
||||||
// Create a matcher for each element in rhs_container.
|
// Create a matcher for each element in rhs_container.
|
||||||
::std::vector<internal::BoundSecondMatcher<Tuple2Matcher, Second> > matchers;
|
::std::vector<internal::BoundSecondMatcher<Tuple2Matcher, Second> > matchers;
|
||||||
for (typename RhsStlContainer::const_iterator it = rhs_stl_container.begin();
|
for (auto it = rhs_stl_container.begin();
|
||||||
it != rhs_stl_container.end(); ++it) {
|
it != rhs_stl_container.end(); ++it) {
|
||||||
matchers.push_back(
|
matchers.push_back(
|
||||||
internal::MatcherBindSecond(tuple2_matcher, *it));
|
internal::MatcherBindSecond(tuple2_matcher, *it));
|
||||||
@ -4615,7 +4777,6 @@ UnorderedPointwise(const Tuple2Matcher& tuple2_matcher,
|
|||||||
return UnorderedPointwise(tuple2_matcher, std::vector<T>(rhs));
|
return UnorderedPointwise(tuple2_matcher, std::vector<T>(rhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Matches an STL-style container or a native array that contains at
|
// Matches an STL-style container or a native array that contains at
|
||||||
// least one element matching the given value or matcher.
|
// least one element matching the given value or matcher.
|
||||||
//
|
//
|
||||||
@ -4625,7 +4786,7 @@ UnorderedPointwise(const Tuple2Matcher& tuple2_matcher,
|
|||||||
// page_ids.insert(1);
|
// page_ids.insert(1);
|
||||||
// EXPECT_THAT(page_ids, Contains(1));
|
// EXPECT_THAT(page_ids, Contains(1));
|
||||||
// EXPECT_THAT(page_ids, Contains(Gt(2)));
|
// EXPECT_THAT(page_ids, Contains(Gt(2)));
|
||||||
// EXPECT_THAT(page_ids, Not(Contains(4)));
|
// EXPECT_THAT(page_ids, Not(Contains(4))); // See below for Times(0)
|
||||||
//
|
//
|
||||||
// ::std::map<int, size_t> page_lengths;
|
// ::std::map<int, size_t> page_lengths;
|
||||||
// page_lengths[1] = 100;
|
// page_lengths[1] = 100;
|
||||||
@ -4634,6 +4795,19 @@ UnorderedPointwise(const Tuple2Matcher& tuple2_matcher,
|
|||||||
//
|
//
|
||||||
// const char* user_ids[] = { "joe", "mike", "tom" };
|
// const char* user_ids[] = { "joe", "mike", "tom" };
|
||||||
// EXPECT_THAT(user_ids, Contains(Eq(::std::string("tom"))));
|
// EXPECT_THAT(user_ids, Contains(Eq(::std::string("tom"))));
|
||||||
|
//
|
||||||
|
// The matcher supports a modifier `Times` that allows to check for arbitrary
|
||||||
|
// occurrences including testing for absence with Times(0).
|
||||||
|
//
|
||||||
|
// Examples:
|
||||||
|
// ::std::vector<int> ids;
|
||||||
|
// ids.insert(1);
|
||||||
|
// ids.insert(1);
|
||||||
|
// ids.insert(3);
|
||||||
|
// EXPECT_THAT(ids, Contains(1).Times(2)); // 1 occurs 2 times
|
||||||
|
// EXPECT_THAT(ids, Contains(2).Times(0)); // 2 is not present
|
||||||
|
// EXPECT_THAT(ids, Contains(3).Times(Ge(1))); // 3 occurs at least once
|
||||||
|
|
||||||
template <typename M>
|
template <typename M>
|
||||||
inline internal::ContainsMatcher<M> Contains(M matcher) {
|
inline internal::ContainsMatcher<M> Contains(M matcher) {
|
||||||
return internal::ContainsMatcher<M>(matcher);
|
return internal::ContainsMatcher<M>(matcher);
|
||||||
@ -4760,7 +4934,7 @@ inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(
|
|||||||
// Matches an STL-style container or a native array that contains only
|
// Matches an STL-style container or a native array that contains only
|
||||||
// elements matching the given value or matcher.
|
// elements matching the given value or matcher.
|
||||||
//
|
//
|
||||||
// Each(m) is semantically equivalent to Not(Contains(Not(m))). Only
|
// Each(m) is semantically equivalent to `Not(Contains(Not(m)))`. Only
|
||||||
// the messages are different.
|
// the messages are different.
|
||||||
//
|
//
|
||||||
// Examples:
|
// Examples:
|
||||||
@ -4810,6 +4984,18 @@ Pair(FirstMatcher first_matcher, SecondMatcher second_matcher) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace no_adl {
|
namespace no_adl {
|
||||||
|
// Conditional() creates a matcher that conditionally uses either the first or
|
||||||
|
// second matcher provided. For example, we could create an `equal if, and only
|
||||||
|
// if' matcher using the Conditional wrapper as follows:
|
||||||
|
//
|
||||||
|
// EXPECT_THAT(result, Conditional(condition, Eq(expected), Ne(expected)));
|
||||||
|
template <typename MatcherTrue, typename MatcherFalse>
|
||||||
|
internal::ConditionalMatcher<MatcherTrue, MatcherFalse> Conditional(
|
||||||
|
bool condition, MatcherTrue matcher_true, MatcherFalse matcher_false) {
|
||||||
|
return internal::ConditionalMatcher<MatcherTrue, MatcherFalse>(
|
||||||
|
condition, std::move(matcher_true), std::move(matcher_false));
|
||||||
|
}
|
||||||
|
|
||||||
// FieldsAre(matchers...) matches piecewise the fields of compatible structs.
|
// FieldsAre(matchers...) matches piecewise the fields of compatible structs.
|
||||||
// These include those that support `get<I>(obj)`, and when structured bindings
|
// These include those that support `get<I>(obj)`, and when structured bindings
|
||||||
// are enabled any class that supports them.
|
// are enabled any class that supports them.
|
||||||
@ -4836,6 +5022,14 @@ inline internal::AddressMatcher<InnerMatcher> Address(
|
|||||||
const InnerMatcher& inner_matcher) {
|
const InnerMatcher& inner_matcher) {
|
||||||
return internal::AddressMatcher<InnerMatcher>(inner_matcher);
|
return internal::AddressMatcher<InnerMatcher>(inner_matcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Matches a base64 escaped string, when the unescaped string matches the
|
||||||
|
// internal matcher.
|
||||||
|
template <typename MatcherType>
|
||||||
|
internal::WhenBase64UnescapedMatcher WhenBase64Unescaped(
|
||||||
|
const MatcherType& internal_matcher) {
|
||||||
|
return internal::WhenBase64UnescapedMatcher(internal_matcher);
|
||||||
|
}
|
||||||
} // namespace no_adl
|
} // namespace no_adl
|
||||||
|
|
||||||
// Returns a predicate that is satisfied by anything that matches the
|
// Returns a predicate that is satisfied by anything that matches the
|
||||||
@ -5072,7 +5266,8 @@ class WithWhatMatcherImpl {
|
|||||||
|
|
||||||
template <typename Err>
|
template <typename Err>
|
||||||
bool MatchAndExplain(const Err& err, MatchResultListener* listener) const {
|
bool MatchAndExplain(const Err& err, MatchResultListener* listener) const {
|
||||||
*listener << "which contains .what() that ";
|
*listener << "which contains .what() (of value = " << err.what()
|
||||||
|
<< ") that ";
|
||||||
return matcher_.MatchAndExplain(err.what(), listener);
|
return matcher_.MatchAndExplain(err.what(), listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5227,7 +5422,7 @@ PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> ThrowsMessage(
|
|||||||
#define EXPECT_THAT(value, matcher) EXPECT_PRED_FORMAT1(\
|
#define EXPECT_THAT(value, matcher) EXPECT_PRED_FORMAT1(\
|
||||||
::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
|
::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
|
||||||
|
|
||||||
// MATCHER* macroses itself are listed below.
|
// MATCHER* macros itself are listed below.
|
||||||
#define MATCHER(name, description) \
|
#define MATCHER(name, description) \
|
||||||
class name##Matcher \
|
class name##Matcher \
|
||||||
: public ::testing::internal::MatcherBaseImpl<name##Matcher> { \
|
: public ::testing::internal::MatcherBaseImpl<name##Matcher> { \
|
||||||
@ -5248,6 +5443,7 @@ PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> ThrowsMessage(
|
|||||||
\
|
\
|
||||||
private: \
|
private: \
|
||||||
::std::string FormatDescription(bool negation) const { \
|
::std::string FormatDescription(bool negation) const { \
|
||||||
|
/* NOLINTNEXTLINE readability-redundant-string-init */ \
|
||||||
::std::string gmock_description = (description); \
|
::std::string gmock_description = (description); \
|
||||||
if (!gmock_description.empty()) { \
|
if (!gmock_description.empty()) { \
|
||||||
return gmock_description; \
|
return gmock_description; \
|
||||||
|
@ -32,8 +32,6 @@
|
|||||||
//
|
//
|
||||||
// This file implements some commonly used variadic actions.
|
// This file implements some commonly used variadic actions.
|
||||||
|
|
||||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
||||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
||||||
|
|
||||||
|
@ -35,8 +35,6 @@
|
|||||||
// Note that tests are implemented in gmock-matchers_test.cc rather than
|
// Note that tests are implemented in gmock-matchers_test.cc rather than
|
||||||
// gmock-more-matchers-test.cc.
|
// gmock-more-matchers-test.cc.
|
||||||
|
|
||||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
|
||||||
|
|
||||||
#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_
|
||||||
|
|
||||||
|
@ -58,8 +58,6 @@
|
|||||||
// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
|
// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
|
||||||
// supported.
|
// supported.
|
||||||
|
|
||||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
|
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
|
||||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
|
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
|
||||||
|
|
||||||
|
@ -56,8 +56,6 @@
|
|||||||
// where all clauses are optional, and .InSequence()/.After()/
|
// where all clauses are optional, and .InSequence()/.After()/
|
||||||
// .WillOnce() can appear any number of times.
|
// .WillOnce() can appear any number of times.
|
||||||
|
|
||||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
|
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
|
||||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
|
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
|
||||||
|
|
||||||
@ -890,7 +888,7 @@ class GTEST_API_ ExpectationBase {
|
|||||||
mutable Mutex mutex_; // Protects action_count_checked_.
|
mutable Mutex mutex_; // Protects action_count_checked_.
|
||||||
}; // class ExpectationBase
|
}; // class ExpectationBase
|
||||||
|
|
||||||
// Impements an expectation for the given function type.
|
// Implements an expectation for the given function type.
|
||||||
template <typename F>
|
template <typename F>
|
||||||
class TypedExpectation : public ExpectationBase {
|
class TypedExpectation : public ExpectationBase {
|
||||||
public:
|
public:
|
||||||
@ -1510,7 +1508,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
|||||||
|
|
||||||
// Performs the default action of this mock function on the given
|
// Performs the default action of this mock function on the given
|
||||||
// arguments and returns the result. Asserts (or throws if
|
// arguments and returns the result. Asserts (or throws if
|
||||||
// exceptions are enabled) with a helpful call descrption if there
|
// exceptions are enabled) with a helpful call description if there
|
||||||
// is no valid return value. This method doesn't depend on the
|
// is no valid return value. This method doesn't depend on the
|
||||||
// mutable state of this object, and thus can be called concurrently
|
// mutable state of this object, and thus can be called concurrently
|
||||||
// without locking.
|
// without locking.
|
||||||
|
@ -32,8 +32,6 @@
|
|||||||
//
|
//
|
||||||
// This is the main header file a user should include.
|
// This is the main header file a user should include.
|
||||||
|
|
||||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_
|
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_
|
||||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_
|
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_
|
||||||
|
|
||||||
@ -65,13 +63,13 @@
|
|||||||
#include "gmock/gmock-nice-strict.h"
|
#include "gmock/gmock-nice-strict.h"
|
||||||
#include "gmock/internal/gmock-internal-utils.h"
|
#include "gmock/internal/gmock-internal-utils.h"
|
||||||
|
|
||||||
namespace testing {
|
|
||||||
|
|
||||||
// Declares Google Mock flags that we want a user to use programmatically.
|
// Declares Google Mock flags that we want a user to use programmatically.
|
||||||
GMOCK_DECLARE_bool_(catch_leaked_mocks);
|
GMOCK_DECLARE_bool_(catch_leaked_mocks);
|
||||||
GMOCK_DECLARE_string_(verbose);
|
GMOCK_DECLARE_string_(verbose);
|
||||||
GMOCK_DECLARE_int32_(default_mock_behavior);
|
GMOCK_DECLARE_int32_(default_mock_behavior);
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
// Initializes Google Mock. This must be called before running the
|
// Initializes Google Mock. This must be called before running the
|
||||||
// tests. In particular, it parses the command line for the flags
|
// tests. In particular, it parses the command line for the flags
|
||||||
// that Google Mock recognizes. Whenever a Google Mock flag is seen,
|
// that Google Mock recognizes. Whenever a Google Mock flag is seen,
|
||||||
|
@ -14,3 +14,5 @@ The following macros can be defined:
|
|||||||
* `GMOCK_DEFINE_bool_(name, default_val, doc)`
|
* `GMOCK_DEFINE_bool_(name, default_val, doc)`
|
||||||
* `GMOCK_DEFINE_int32_(name, default_val, doc)`
|
* `GMOCK_DEFINE_int32_(name, default_val, doc)`
|
||||||
* `GMOCK_DEFINE_string_(name, default_val, doc)`
|
* `GMOCK_DEFINE_string_(name, default_val, doc)`
|
||||||
|
* `GMOCK_FLAG_GET(flag_name)`
|
||||||
|
* `GMOCK_FLAG_SET(flag_name, value)`
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
|
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
|
||||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
|
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
|
||||||
|
|
||||||
|
@ -28,8 +28,6 @@
|
|||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
// Injection point for custom user configurations. See README for details
|
// Injection point for custom user configurations. See README for details
|
||||||
//
|
|
||||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
|
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
|
||||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
|
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
|
||||||
|
@ -31,8 +31,6 @@
|
|||||||
//
|
//
|
||||||
// ** Custom implementation starts here **
|
// ** Custom implementation starts here **
|
||||||
|
|
||||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
|
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
|
||||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
|
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
|
||||||
|
|
||||||
|
@ -34,8 +34,6 @@
|
|||||||
// Mock. They are subject to change without notice, so please DO NOT
|
// Mock. They are subject to change without notice, so please DO NOT
|
||||||
// USE THEM IN USER CODE.
|
// USE THEM IN USER CODE.
|
||||||
|
|
||||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
||||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
||||||
|
|
||||||
@ -281,7 +279,7 @@ class WithoutMatchers {
|
|||||||
GTEST_API_ WithoutMatchers GetWithoutMatchers();
|
GTEST_API_ WithoutMatchers GetWithoutMatchers();
|
||||||
|
|
||||||
// Disable MSVC warnings for infinite recursion, since in this case the
|
// Disable MSVC warnings for infinite recursion, since in this case the
|
||||||
// the recursion is unreachable.
|
// recursion is unreachable.
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# pragma warning(push)
|
# pragma warning(push)
|
||||||
# pragma warning(disable:4717)
|
# pragma warning(disable:4717)
|
||||||
@ -449,6 +447,8 @@ 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;
|
||||||
|
|
||||||
|
bool Base64Unescape(const std::string& encoded, std::string* decoded);
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# pragma warning(pop)
|
# pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
@ -35,8 +35,6 @@
|
|||||||
// end with _ are part of Google Mock's public API and can be used by
|
// end with _ are part of Google Mock's public API and can be used by
|
||||||
// code outside Google Mock.
|
// code outside Google Mock.
|
||||||
|
|
||||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||||
|
|
||||||
@ -69,19 +67,37 @@
|
|||||||
#if !defined(GMOCK_DECLARE_bool_)
|
#if !defined(GMOCK_DECLARE_bool_)
|
||||||
|
|
||||||
// Macros for declaring flags.
|
// Macros for declaring flags.
|
||||||
# define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name)
|
#define GMOCK_DECLARE_bool_(name) \
|
||||||
# define GMOCK_DECLARE_int32_(name) extern GTEST_API_ int32_t GMOCK_FLAG(name)
|
namespace testing { \
|
||||||
# define GMOCK_DECLARE_string_(name) \
|
GTEST_API_ extern bool GMOCK_FLAG(name); \
|
||||||
extern GTEST_API_ ::std::string GMOCK_FLAG(name)
|
} static_assert(true, "no-op to require trailing semicolon")
|
||||||
|
#define GMOCK_DECLARE_int32_(name) \
|
||||||
|
namespace testing { \
|
||||||
|
GTEST_API_ extern int32_t GMOCK_FLAG(name); \
|
||||||
|
} static_assert(true, "no-op to require trailing semicolon")
|
||||||
|
#define GMOCK_DECLARE_string_(name) \
|
||||||
|
namespace testing { \
|
||||||
|
GTEST_API_ extern ::std::string GMOCK_FLAG(name); \
|
||||||
|
} static_assert(true, "no-op to require trailing semicolon")
|
||||||
|
|
||||||
// Macros for defining flags.
|
// Macros for defining flags.
|
||||||
# define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||||
GTEST_API_ bool GMOCK_FLAG(name) = (default_val)
|
namespace testing { \
|
||||||
# define GMOCK_DEFINE_int32_(name, default_val, doc) \
|
GTEST_API_ bool GMOCK_FLAG(name) = (default_val); \
|
||||||
GTEST_API_ int32_t GMOCK_FLAG(name) = (default_val)
|
} static_assert(true, "no-op to require trailing semicolon")
|
||||||
# define GMOCK_DEFINE_string_(name, default_val, doc) \
|
#define GMOCK_DEFINE_int32_(name, default_val, doc) \
|
||||||
GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val)
|
namespace testing { \
|
||||||
|
GTEST_API_ int32_t GMOCK_FLAG(name) = (default_val); \
|
||||||
|
} static_assert(true, "no-op to require trailing semicolon")
|
||||||
|
#define GMOCK_DEFINE_string_(name, default_val, doc) \
|
||||||
|
namespace testing { \
|
||||||
|
GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val); \
|
||||||
|
} static_assert(true, "no-op to require trailing semicolon")
|
||||||
#endif // !defined(GMOCK_DECLARE_bool_)
|
#endif // !defined(GMOCK_DECLARE_bool_)
|
||||||
|
|
||||||
|
#if !defined(GMOCK_FLAG_GET)
|
||||||
|
#define GMOCK_FLAG_GET(name) ::testing::GMOCK_FLAG(name)
|
||||||
|
#define GMOCK_FLAG_SET(name, value) (void)(::testing::GMOCK_FLAG(name) = value)
|
||||||
|
#endif // !defined(GMOCK_FLAG_GET)
|
||||||
|
|
||||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
# Please Note:
|
|
||||||
|
|
||||||
Files in this directory are no longer supported by the maintainers. They
|
|
||||||
represent mostly historical artifacts and supported by the community only. There
|
|
||||||
is no guarantee whatsoever that these scripts still work.
|
|
@ -1,256 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# Copyright 2009, 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.
|
|
||||||
"""fuse_gmock_files.py v0.1.0.
|
|
||||||
|
|
||||||
Fuses Google Mock and Google Test source code into two .h files and a .cc file.
|
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
fuse_gmock_files.py [GMOCK_ROOT_DIR] OUTPUT_DIR
|
|
||||||
|
|
||||||
Scans GMOCK_ROOT_DIR for Google Mock and Google Test source
|
|
||||||
code, assuming Google Test is in the GMOCK_ROOT_DIR/../googletest
|
|
||||||
directory, and generates three files:
|
|
||||||
OUTPUT_DIR/gtest/gtest.h, OUTPUT_DIR/gmock/gmock.h, and
|
|
||||||
OUTPUT_DIR/gmock-gtest-all.cc. Then you can build your tests
|
|
||||||
by adding OUTPUT_DIR to the include search path and linking
|
|
||||||
with OUTPUT_DIR/gmock-gtest-all.cc. These three files contain
|
|
||||||
everything you need to use Google Mock. Hence you can
|
|
||||||
"install" Google Mock by copying them to wherever you want.
|
|
||||||
|
|
||||||
GMOCK_ROOT_DIR can be omitted and defaults to the parent
|
|
||||||
directory of the directory holding this script.
|
|
||||||
|
|
||||||
EXAMPLES
|
|
||||||
./fuse_gmock_files.py fused_gmock
|
|
||||||
./fuse_gmock_files.py path/to/unpacked/gmock fused_gmock
|
|
||||||
|
|
||||||
This tool is experimental. In particular, it assumes that there is no
|
|
||||||
conditional inclusion of Google Mock or Google Test headers. Please
|
|
||||||
report any problems to googlemock@googlegroups.com. You can read
|
|
||||||
https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md
|
|
||||||
for more
|
|
||||||
information.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
|
|
||||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
|
||||||
|
|
||||||
# We assume that this file is in the scripts/ directory in the Google
|
|
||||||
# Mock root directory.
|
|
||||||
DEFAULT_GMOCK_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..')
|
|
||||||
|
|
||||||
# We need to call into googletest/scripts/fuse_gtest_files.py.
|
|
||||||
sys.path.append(os.path.join(DEFAULT_GMOCK_ROOT_DIR, '../googletest/scripts'))
|
|
||||||
import fuse_gtest_files as gtest # pylint:disable=g-import-not-at-top
|
|
||||||
|
|
||||||
# Regex for matching
|
|
||||||
# '#include "gmock/..."'.
|
|
||||||
INCLUDE_GMOCK_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(gmock/.+)"')
|
|
||||||
|
|
||||||
# Where to find the source seed files.
|
|
||||||
GMOCK_H_SEED = 'include/gmock/gmock.h'
|
|
||||||
GMOCK_ALL_CC_SEED = 'src/gmock-all.cc'
|
|
||||||
|
|
||||||
# Where to put the generated files.
|
|
||||||
GTEST_H_OUTPUT = 'gtest/gtest.h'
|
|
||||||
GMOCK_H_OUTPUT = 'gmock/gmock.h'
|
|
||||||
GMOCK_GTEST_ALL_CC_OUTPUT = 'gmock-gtest-all.cc'
|
|
||||||
|
|
||||||
|
|
||||||
def GetGTestRootDir(gmock_root):
|
|
||||||
"""Returns the root directory of Google Test."""
|
|
||||||
|
|
||||||
return os.path.join(gmock_root, '../googletest')
|
|
||||||
|
|
||||||
|
|
||||||
def ValidateGMockRootDir(gmock_root):
|
|
||||||
"""Makes sure gmock_root points to a valid gmock root directory.
|
|
||||||
|
|
||||||
The function aborts the program on failure.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
gmock_root: A string with the mock root directory.
|
|
||||||
"""
|
|
||||||
|
|
||||||
gtest.ValidateGTestRootDir(GetGTestRootDir(gmock_root))
|
|
||||||
gtest.VerifyFileExists(gmock_root, GMOCK_H_SEED)
|
|
||||||
gtest.VerifyFileExists(gmock_root, GMOCK_ALL_CC_SEED)
|
|
||||||
|
|
||||||
|
|
||||||
def ValidateOutputDir(output_dir):
|
|
||||||
"""Makes sure output_dir points to a valid output directory.
|
|
||||||
|
|
||||||
The function aborts the program on failure.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
output_dir: A string representing the output directory.
|
|
||||||
"""
|
|
||||||
|
|
||||||
gtest.VerifyOutputFile(output_dir, gtest.GTEST_H_OUTPUT)
|
|
||||||
gtest.VerifyOutputFile(output_dir, GMOCK_H_OUTPUT)
|
|
||||||
gtest.VerifyOutputFile(output_dir, GMOCK_GTEST_ALL_CC_OUTPUT)
|
|
||||||
|
|
||||||
|
|
||||||
def FuseGMockH(gmock_root, output_dir):
|
|
||||||
"""Scans folder gmock_root to generate gmock/gmock.h in output_dir."""
|
|
||||||
|
|
||||||
output_file = open(os.path.join(output_dir, GMOCK_H_OUTPUT), 'w')
|
|
||||||
processed_files = set() # Holds all gmock headers we've processed.
|
|
||||||
|
|
||||||
def ProcessFile(gmock_header_path):
|
|
||||||
"""Processes the given gmock header file."""
|
|
||||||
|
|
||||||
# We don't process the same header twice.
|
|
||||||
if gmock_header_path in processed_files:
|
|
||||||
return
|
|
||||||
|
|
||||||
processed_files.add(gmock_header_path)
|
|
||||||
|
|
||||||
# Reads each line in the given gmock header.
|
|
||||||
|
|
||||||
with open(os.path.join(gmock_root, gmock_header_path), 'r') as fh:
|
|
||||||
for line in fh:
|
|
||||||
m = INCLUDE_GMOCK_FILE_REGEX.match(line)
|
|
||||||
if m:
|
|
||||||
# '#include "gmock/..."'
|
|
||||||
# - let's process it recursively.
|
|
||||||
ProcessFile('include/' + m.group(1))
|
|
||||||
else:
|
|
||||||
m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line)
|
|
||||||
if m:
|
|
||||||
# '#include "gtest/foo.h"'
|
|
||||||
# We translate it to "gtest/gtest.h", regardless of what foo is,
|
|
||||||
# since all gtest headers are fused into gtest/gtest.h.
|
|
||||||
|
|
||||||
# There is no need to #include gtest.h twice.
|
|
||||||
if gtest.GTEST_H_SEED not in processed_files:
|
|
||||||
processed_files.add(gtest.GTEST_H_SEED)
|
|
||||||
output_file.write('#include "%s"\n' % (gtest.GTEST_H_OUTPUT,))
|
|
||||||
else:
|
|
||||||
# Otherwise we copy the line unchanged to the output file.
|
|
||||||
output_file.write(line)
|
|
||||||
|
|
||||||
ProcessFile(GMOCK_H_SEED)
|
|
||||||
output_file.close()
|
|
||||||
|
|
||||||
|
|
||||||
def FuseGMockAllCcToFile(gmock_root, output_file):
|
|
||||||
"""Scans folder gmock_root to fuse gmock-all.cc into output_file."""
|
|
||||||
|
|
||||||
processed_files = set()
|
|
||||||
|
|
||||||
def ProcessFile(gmock_source_file):
|
|
||||||
"""Processes the given gmock source file."""
|
|
||||||
|
|
||||||
# We don't process the same #included file twice.
|
|
||||||
if gmock_source_file in processed_files:
|
|
||||||
return
|
|
||||||
|
|
||||||
processed_files.add(gmock_source_file)
|
|
||||||
|
|
||||||
# Reads each line in the given gmock source file.
|
|
||||||
|
|
||||||
with open(os.path.join(gmock_root, gmock_source_file), 'r') as fh:
|
|
||||||
for line in fh:
|
|
||||||
m = INCLUDE_GMOCK_FILE_REGEX.match(line)
|
|
||||||
if m:
|
|
||||||
# '#include "gmock/foo.h"'
|
|
||||||
# We treat it as '#include "gmock/gmock.h"', as all other gmock
|
|
||||||
# headers are being fused into gmock.h and cannot be
|
|
||||||
# included directly. No need to
|
|
||||||
# #include "gmock/gmock.h"
|
|
||||||
# more than once.
|
|
||||||
|
|
||||||
if GMOCK_H_SEED not in processed_files:
|
|
||||||
processed_files.add(GMOCK_H_SEED)
|
|
||||||
output_file.write('#include "%s"\n' % (GMOCK_H_OUTPUT,))
|
|
||||||
else:
|
|
||||||
m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line)
|
|
||||||
if m:
|
|
||||||
# '#include "gtest/..."'
|
|
||||||
# There is no need to #include gtest.h as it has been
|
|
||||||
# #included by gtest-all.cc.
|
|
||||||
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
m = gtest.INCLUDE_SRC_FILE_REGEX.match(line)
|
|
||||||
if m:
|
|
||||||
# It's '#include "src/foo"' - let's process it recursively.
|
|
||||||
ProcessFile(m.group(1))
|
|
||||||
else:
|
|
||||||
# Otherwise we copy the line unchanged to the output file.
|
|
||||||
output_file.write(line)
|
|
||||||
|
|
||||||
ProcessFile(GMOCK_ALL_CC_SEED)
|
|
||||||
|
|
||||||
|
|
||||||
def FuseGMockGTestAllCc(gmock_root, output_dir):
|
|
||||||
"""Scans folder gmock_root to generate gmock-gtest-all.cc in output_dir."""
|
|
||||||
|
|
||||||
with open(os.path.join(output_dir, GMOCK_GTEST_ALL_CC_OUTPUT),
|
|
||||||
'w') as output_file:
|
|
||||||
# First, fuse gtest-all.cc into gmock-gtest-all.cc.
|
|
||||||
gtest.FuseGTestAllCcToFile(GetGTestRootDir(gmock_root), output_file)
|
|
||||||
# Next, append fused gmock-all.cc to gmock-gtest-all.cc.
|
|
||||||
FuseGMockAllCcToFile(gmock_root, output_file)
|
|
||||||
|
|
||||||
|
|
||||||
def FuseGMock(gmock_root, output_dir):
|
|
||||||
"""Fuses gtest.h, gmock.h, and gmock-gtest-all.h."""
|
|
||||||
|
|
||||||
ValidateGMockRootDir(gmock_root)
|
|
||||||
ValidateOutputDir(output_dir)
|
|
||||||
|
|
||||||
gtest.FuseGTestH(GetGTestRootDir(gmock_root), output_dir)
|
|
||||||
FuseGMockH(gmock_root, output_dir)
|
|
||||||
FuseGMockGTestAllCc(gmock_root, output_dir)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
argc = len(sys.argv)
|
|
||||||
if argc == 2:
|
|
||||||
# fuse_gmock_files.py OUTPUT_DIR
|
|
||||||
FuseGMock(DEFAULT_GMOCK_ROOT_DIR, sys.argv[1])
|
|
||||||
elif argc == 3:
|
|
||||||
# fuse_gmock_files.py GMOCK_ROOT_DIR OUTPUT_DIR
|
|
||||||
FuseGMock(sys.argv[1], sys.argv[2])
|
|
||||||
else:
|
|
||||||
print(__doc__)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
@ -1,203 +0,0 @@
|
|||||||
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [2007] Neal Norwitz
|
|
||||||
Portions Copyright [2007] Google Inc.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
@ -1,34 +0,0 @@
|
|||||||
|
|
||||||
The Google Mock class generator is an application that is part of cppclean.
|
|
||||||
For more information about cppclean, visit http://code.google.com/p/cppclean/
|
|
||||||
|
|
||||||
The mock generator requires Python 2.3.5 or later. If you don't have Python
|
|
||||||
installed on your system, you will also need to install it. You can download
|
|
||||||
Python from: http://www.python.org/download/releases/
|
|
||||||
|
|
||||||
To use the Google Mock class generator, you need to call it
|
|
||||||
on the command line passing the header file and class for which you want
|
|
||||||
to generate a Google Mock class.
|
|
||||||
|
|
||||||
Make sure to install the scripts somewhere in your path. Then you can
|
|
||||||
run the program.
|
|
||||||
|
|
||||||
gmock_gen.py header-file.h [ClassName]...
|
|
||||||
|
|
||||||
If no ClassNames are specified, all classes in the file are emitted.
|
|
||||||
|
|
||||||
To change the indentation from the default of 2, set INDENT in
|
|
||||||
the environment. For example to use an indent of 4 spaces:
|
|
||||||
|
|
||||||
INDENT=4 gmock_gen.py header-file.h ClassName
|
|
||||||
|
|
||||||
This version was made from SVN revision 281 in the cppclean repository.
|
|
||||||
|
|
||||||
Known Limitations
|
|
||||||
-----------------
|
|
||||||
Not all code will be generated properly. For example, when mocking templated
|
|
||||||
classes, the template information is lost. You will need to add the template
|
|
||||||
information manually.
|
|
||||||
|
|
||||||
Not all permutations of using multiple pointers/references will be rendered
|
|
||||||
properly. These will also have to be fixed manually.
|
|
@ -1,115 +0,0 @@
|
|||||||
Goal:
|
|
||||||
-----
|
|
||||||
CppClean attempts to find problems in C++ source that slow development
|
|
||||||
in large code bases, for example various forms of unused code.
|
|
||||||
Unused code can be unused functions, methods, data members, types, etc
|
|
||||||
to unnecessary #include directives. Unnecessary #includes can cause
|
|
||||||
considerable extra compiles increasing the edit-compile-run cycle.
|
|
||||||
|
|
||||||
The project home page is: http://code.google.com/p/cppclean/
|
|
||||||
|
|
||||||
|
|
||||||
Features:
|
|
||||||
---------
|
|
||||||
* Find and print C++ language constructs: classes, methods, functions, etc.
|
|
||||||
* Find classes with virtual methods, no virtual destructor, and no bases
|
|
||||||
* Find global/static data that are potential problems when using threads
|
|
||||||
* Unnecessary forward class declarations
|
|
||||||
* Unnecessary function declarations
|
|
||||||
* Undeclared function definitions
|
|
||||||
* (planned) Find unnecessary header files #included
|
|
||||||
- No direct reference to anything in the header
|
|
||||||
- Header is unnecessary if classes were forward declared instead
|
|
||||||
* (planned) Source files that reference headers not directly #included,
|
|
||||||
ie, files that rely on a transitive #include from another header
|
|
||||||
* (planned) Unused members (private, protected, & public) methods and data
|
|
||||||
* (planned) Store AST in a SQL database so relationships can be queried
|
|
||||||
|
|
||||||
AST is Abstract Syntax Tree, a representation of parsed source code.
|
|
||||||
http://en.wikipedia.org/wiki/Abstract_syntax_tree
|
|
||||||
|
|
||||||
|
|
||||||
System Requirements:
|
|
||||||
--------------------
|
|
||||||
* Python 2.4 or later (2.3 probably works too)
|
|
||||||
* Works on Windows (untested), Mac OS X, and Unix
|
|
||||||
|
|
||||||
|
|
||||||
How to Run:
|
|
||||||
-----------
|
|
||||||
For all examples, it is assumed that cppclean resides in a directory called
|
|
||||||
/cppclean.
|
|
||||||
|
|
||||||
To print warnings for classes with virtual methods, no virtual destructor and
|
|
||||||
no base classes:
|
|
||||||
|
|
||||||
/cppclean/run.sh nonvirtual_dtors.py file1.h file2.h file3.cc ...
|
|
||||||
|
|
||||||
To print all the functions defined in header file(s):
|
|
||||||
|
|
||||||
/cppclean/run.sh functions.py file1.h file2.h ...
|
|
||||||
|
|
||||||
All the commands take multiple files on the command line. Other programs
|
|
||||||
include: find_warnings, headers, methods, and types. Some other programs
|
|
||||||
are available, but used primarily for debugging.
|
|
||||||
|
|
||||||
run.sh is a simple wrapper that sets PYTHONPATH to /cppclean and then
|
|
||||||
runs the program in /cppclean/cpp/PROGRAM.py. There is currently
|
|
||||||
no equivalent for Windows. Contributions for a run.bat file
|
|
||||||
would be greatly appreciated.
|
|
||||||
|
|
||||||
|
|
||||||
How to Configure:
|
|
||||||
-----------------
|
|
||||||
You can add a siteheaders.py file in /cppclean/cpp to configure where
|
|
||||||
to look for other headers (typically -I options passed to a compiler).
|
|
||||||
Currently two values are supported: _TRANSITIVE and GetIncludeDirs.
|
|
||||||
_TRANSITIVE should be set to a boolean value (True or False) indicating
|
|
||||||
whether to transitively process all header files. The default is False.
|
|
||||||
|
|
||||||
GetIncludeDirs is a function that takes a single argument and returns
|
|
||||||
a sequence of directories to include. This can be a generator or
|
|
||||||
return a static list.
|
|
||||||
|
|
||||||
def GetIncludeDirs(filename):
|
|
||||||
return ['/some/path/with/other/headers']
|
|
||||||
|
|
||||||
# Here is a more complicated example.
|
|
||||||
def GetIncludeDirs(filename):
|
|
||||||
yield '/path1'
|
|
||||||
yield os.path.join('/path2', os.path.dirname(filename))
|
|
||||||
yield '/path3'
|
|
||||||
|
|
||||||
|
|
||||||
How to Test:
|
|
||||||
------------
|
|
||||||
For all examples, it is assumed that cppclean resides in a directory called
|
|
||||||
/cppclean. The tests require
|
|
||||||
|
|
||||||
cd /cppclean
|
|
||||||
make test
|
|
||||||
# To generate expected results after a change:
|
|
||||||
make expected
|
|
||||||
|
|
||||||
|
|
||||||
Current Status:
|
|
||||||
---------------
|
|
||||||
The parser works pretty well for header files, parsing about 99% of Google's
|
|
||||||
header files. Anything which inspects structure of C++ source files should
|
|
||||||
work reasonably well. Function bodies are not transformed to an AST,
|
|
||||||
but left as tokens. Much work is still needed on finding unused header files
|
|
||||||
and storing an AST in a database.
|
|
||||||
|
|
||||||
|
|
||||||
Non-goals:
|
|
||||||
----------
|
|
||||||
* Parsing all valid C++ source
|
|
||||||
* Handling invalid C++ source gracefully
|
|
||||||
* Compiling to machine code (or anything beyond an AST)
|
|
||||||
|
|
||||||
|
|
||||||
Contact:
|
|
||||||
--------
|
|
||||||
If you used cppclean, I would love to hear about your experiences
|
|
||||||
cppclean@googlegroups.com. Even if you don't use cppclean, I'd like to
|
|
||||||
hear from you. :-) (You can contact me directly at: nnorwitz@gmail.com)
|
|
File diff suppressed because it is too large
Load Diff
@ -1,247 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# Copyright 2008 Google Inc. All Rights Reserved.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
"""Generate Google Mock classes from base classes.
|
|
||||||
|
|
||||||
This program will read in a C++ source file and output the Google Mock
|
|
||||||
classes for the specified classes. If no class is specified, all
|
|
||||||
classes in the source file are emitted.
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
gmock_class.py header-file.h [ClassName]...
|
|
||||||
|
|
||||||
Output is sent to stdout.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from cpp import ast
|
|
||||||
from cpp import utils
|
|
||||||
|
|
||||||
# Preserve compatibility with Python 2.3.
|
|
||||||
try:
|
|
||||||
_dummy = set
|
|
||||||
except NameError:
|
|
||||||
import sets
|
|
||||||
|
|
||||||
set = sets.Set
|
|
||||||
|
|
||||||
_VERSION = (1, 0, 1) # The version of this script.
|
|
||||||
# How many spaces to indent. Can set me with the INDENT environment variable.
|
|
||||||
_INDENT = 2
|
|
||||||
|
|
||||||
|
|
||||||
def _RenderType(ast_type):
|
|
||||||
"""Renders the potentially recursively templated type into a string.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
ast_type: The AST of the type.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Rendered string of the type.
|
|
||||||
"""
|
|
||||||
# Add modifiers like 'const'.
|
|
||||||
modifiers = ''
|
|
||||||
if ast_type.modifiers:
|
|
||||||
modifiers = ' '.join(ast_type.modifiers) + ' '
|
|
||||||
return_type = modifiers + ast_type.name
|
|
||||||
if ast_type.templated_types:
|
|
||||||
# Collect template args.
|
|
||||||
template_args = []
|
|
||||||
for arg in ast_type.templated_types:
|
|
||||||
rendered_arg = _RenderType(arg)
|
|
||||||
template_args.append(rendered_arg)
|
|
||||||
return_type += '<' + ', '.join(template_args) + '>'
|
|
||||||
if ast_type.pointer:
|
|
||||||
return_type += '*'
|
|
||||||
if ast_type.reference:
|
|
||||||
return_type += '&'
|
|
||||||
return return_type
|
|
||||||
|
|
||||||
|
|
||||||
def _GenerateArg(source):
|
|
||||||
"""Strips out comments, default arguments, and redundant spaces from a single argument.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
source: A string for a single argument.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Rendered string of the argument.
|
|
||||||
"""
|
|
||||||
# Remove end of line comments before eliminating newlines.
|
|
||||||
arg = re.sub(r'//.*', '', source)
|
|
||||||
|
|
||||||
# Remove c-style comments.
|
|
||||||
arg = re.sub(r'/\*.*\*/', '', arg)
|
|
||||||
|
|
||||||
# Remove default arguments.
|
|
||||||
arg = re.sub(r'=.*', '', arg)
|
|
||||||
|
|
||||||
# Collapse spaces and newlines into a single space.
|
|
||||||
arg = re.sub(r'\s+', ' ', arg)
|
|
||||||
return arg.strip()
|
|
||||||
|
|
||||||
|
|
||||||
def _EscapeForMacro(s):
|
|
||||||
"""Escapes a string for use as an argument to a C++ macro."""
|
|
||||||
paren_count = 0
|
|
||||||
for c in s:
|
|
||||||
if c == '(':
|
|
||||||
paren_count += 1
|
|
||||||
elif c == ')':
|
|
||||||
paren_count -= 1
|
|
||||||
elif c == ',' and paren_count == 0:
|
|
||||||
return '(' + s + ')'
|
|
||||||
return s
|
|
||||||
|
|
||||||
|
|
||||||
def _GenerateMethods(output_lines, source, class_node):
|
|
||||||
function_type = (
|
|
||||||
ast.FUNCTION_VIRTUAL | ast.FUNCTION_PURE_VIRTUAL | ast.FUNCTION_OVERRIDE)
|
|
||||||
ctor_or_dtor = ast.FUNCTION_CTOR | ast.FUNCTION_DTOR
|
|
||||||
indent = ' ' * _INDENT
|
|
||||||
|
|
||||||
for node in class_node.body:
|
|
||||||
# We only care about virtual functions.
|
|
||||||
if (isinstance(node, ast.Function) and node.modifiers & function_type and
|
|
||||||
not node.modifiers & ctor_or_dtor):
|
|
||||||
# Pick out all the elements we need from the original function.
|
|
||||||
modifiers = 'override'
|
|
||||||
if node.modifiers & ast.FUNCTION_CONST:
|
|
||||||
modifiers = 'const, ' + modifiers
|
|
||||||
|
|
||||||
return_type = 'void'
|
|
||||||
if node.return_type:
|
|
||||||
return_type = _EscapeForMacro(_RenderType(node.return_type))
|
|
||||||
|
|
||||||
args = []
|
|
||||||
for p in node.parameters:
|
|
||||||
arg = _GenerateArg(source[p.start:p.end])
|
|
||||||
if arg != 'void':
|
|
||||||
args.append(_EscapeForMacro(arg))
|
|
||||||
|
|
||||||
# Create the mock method definition.
|
|
||||||
output_lines.extend([
|
|
||||||
'%sMOCK_METHOD(%s, %s, (%s), (%s));' %
|
|
||||||
(indent, return_type, node.name, ', '.join(args), modifiers)
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
def _GenerateMocks(filename, source, ast_list, desired_class_names):
|
|
||||||
processed_class_names = set()
|
|
||||||
lines = []
|
|
||||||
for node in ast_list:
|
|
||||||
if (isinstance(node, ast.Class) and node.body and
|
|
||||||
# desired_class_names being None means that all classes are selected.
|
|
||||||
(not desired_class_names or node.name in desired_class_names)):
|
|
||||||
class_name = node.name
|
|
||||||
parent_name = class_name
|
|
||||||
processed_class_names.add(class_name)
|
|
||||||
class_node = node
|
|
||||||
# Add namespace before the class.
|
|
||||||
if class_node.namespace:
|
|
||||||
lines.extend(['namespace %s {' % n for n in class_node.namespace]) # }
|
|
||||||
lines.append('')
|
|
||||||
|
|
||||||
# Add template args for templated classes.
|
|
||||||
if class_node.templated_types:
|
|
||||||
# TODO(paulchang): Handle non-type template arguments (e.g.
|
|
||||||
# template<typename T, int N>).
|
|
||||||
|
|
||||||
# class_node.templated_types is an OrderedDict from strings to a tuples.
|
|
||||||
# The key is the name of the template, and the value is
|
|
||||||
# (type_name, default). Both type_name and default could be None.
|
|
||||||
template_args = class_node.templated_types.keys()
|
|
||||||
template_decls = ['typename ' + arg for arg in template_args]
|
|
||||||
lines.append('template <' + ', '.join(template_decls) + '>')
|
|
||||||
parent_name += '<' + ', '.join(template_args) + '>'
|
|
||||||
|
|
||||||
# Add the class prolog.
|
|
||||||
lines.append('class Mock%s : public %s {' # }
|
|
||||||
% (class_name, parent_name))
|
|
||||||
lines.append('%spublic:' % (' ' * (_INDENT // 2)))
|
|
||||||
|
|
||||||
# Add all the methods.
|
|
||||||
_GenerateMethods(lines, source, class_node)
|
|
||||||
|
|
||||||
# Close the class.
|
|
||||||
if lines:
|
|
||||||
# If there are no virtual methods, no need for a public label.
|
|
||||||
if len(lines) == 2:
|
|
||||||
del lines[-1]
|
|
||||||
|
|
||||||
# Only close the class if there really is a class.
|
|
||||||
lines.append('};')
|
|
||||||
lines.append('') # Add an extra newline.
|
|
||||||
|
|
||||||
# Close the namespace.
|
|
||||||
if class_node.namespace:
|
|
||||||
for i in range(len(class_node.namespace) - 1, -1, -1):
|
|
||||||
lines.append('} // namespace %s' % class_node.namespace[i])
|
|
||||||
lines.append('') # Add an extra newline.
|
|
||||||
|
|
||||||
if desired_class_names:
|
|
||||||
missing_class_name_list = list(desired_class_names - processed_class_names)
|
|
||||||
if missing_class_name_list:
|
|
||||||
missing_class_name_list.sort()
|
|
||||||
sys.stderr.write('Class(es) not found in %s: %s\n' %
|
|
||||||
(filename, ', '.join(missing_class_name_list)))
|
|
||||||
elif not processed_class_names:
|
|
||||||
sys.stderr.write('No class found in %s\n' % filename)
|
|
||||||
|
|
||||||
return lines
|
|
||||||
|
|
||||||
|
|
||||||
def main(argv=sys.argv):
|
|
||||||
if len(argv) < 2:
|
|
||||||
sys.stderr.write('Google Mock Class Generator v%s\n\n' %
|
|
||||||
'.'.join(map(str, _VERSION)))
|
|
||||||
sys.stderr.write(__doc__)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
global _INDENT
|
|
||||||
try:
|
|
||||||
_INDENT = int(os.environ['INDENT'])
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
sys.stderr.write('Unable to use indent of %s\n' % os.environ.get('INDENT'))
|
|
||||||
|
|
||||||
filename = argv[1]
|
|
||||||
desired_class_names = None # None means all classes in the source file.
|
|
||||||
if len(argv) >= 3:
|
|
||||||
desired_class_names = set(argv[2:])
|
|
||||||
source = utils.ReadFile(filename)
|
|
||||||
if source is None:
|
|
||||||
return 1
|
|
||||||
|
|
||||||
builder = ast.BuilderFromSource(source, filename)
|
|
||||||
try:
|
|
||||||
entire_ast = filter(None, builder.Generate())
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
return
|
|
||||||
except:
|
|
||||||
# An error message was already printed since we couldn't parse.
|
|
||||||
sys.exit(1)
|
|
||||||
else:
|
|
||||||
lines = _GenerateMocks(filename, source, entire_ast, desired_class_names)
|
|
||||||
sys.stdout.write('\n'.join(lines))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main(sys.argv)
|
|
@ -1,570 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# Copyright 2009 Neal Norwitz All Rights Reserved.
|
|
||||||
# Portions Copyright 2009 Google Inc. All Rights Reserved.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
"""Tests for gmock.scripts.generator.cpp.gmock_class."""
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
# Allow the cpp imports below to work when run as a standalone script.
|
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
|
||||||
|
|
||||||
from cpp import ast
|
|
||||||
from cpp import gmock_class
|
|
||||||
|
|
||||||
|
|
||||||
class TestCase(unittest.TestCase):
|
|
||||||
"""Helper class that adds assert methods."""
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def StripLeadingWhitespace(lines):
|
|
||||||
"""Strip leading whitespace in each line in 'lines'."""
|
|
||||||
return '\n'.join([s.lstrip() for s in lines.split('\n')])
|
|
||||||
|
|
||||||
def assertEqualIgnoreLeadingWhitespace(self, expected_lines, lines):
|
|
||||||
"""Specialized assert that ignores the indent level."""
|
|
||||||
self.assertEqual(expected_lines, self.StripLeadingWhitespace(lines))
|
|
||||||
|
|
||||||
|
|
||||||
class GenerateMethodsTest(TestCase):
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def GenerateMethodSource(cpp_source):
|
|
||||||
"""Convert C++ source to Google Mock output source lines."""
|
|
||||||
method_source_lines = []
|
|
||||||
# <test> is a pseudo-filename, it is not read or written.
|
|
||||||
builder = ast.BuilderFromSource(cpp_source, '<test>')
|
|
||||||
ast_list = list(builder.Generate())
|
|
||||||
gmock_class._GenerateMethods(method_source_lines, cpp_source, ast_list[0])
|
|
||||||
return '\n'.join(method_source_lines)
|
|
||||||
|
|
||||||
def testSimpleMethod(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual int Bar();
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(int, Bar, (), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testSimpleConstructorsAndDestructor(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
Foo();
|
|
||||||
Foo(int x);
|
|
||||||
Foo(const Foo& f);
|
|
||||||
Foo(Foo&& f);
|
|
||||||
~Foo();
|
|
||||||
virtual int Bar() = 0;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
# The constructors and destructor should be ignored.
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(int, Bar, (), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testVirtualDestructor(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual ~Foo();
|
|
||||||
virtual int Bar() = 0;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
# The destructor should be ignored.
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(int, Bar, (), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testExplicitlyDefaultedConstructorsAndDestructor(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
Foo() = default;
|
|
||||||
Foo(const Foo& f) = default;
|
|
||||||
Foo(Foo&& f) = default;
|
|
||||||
~Foo() = default;
|
|
||||||
virtual int Bar() = 0;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
# The constructors and destructor should be ignored.
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(int, Bar, (), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testExplicitlyDeletedConstructorsAndDestructor(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
Foo() = delete;
|
|
||||||
Foo(const Foo& f) = delete;
|
|
||||||
Foo(Foo&& f) = delete;
|
|
||||||
~Foo() = delete;
|
|
||||||
virtual int Bar() = 0;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
# The constructors and destructor should be ignored.
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(int, Bar, (), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testSimpleOverrideMethod(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
int Bar() override;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(int, Bar, (), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testSimpleConstMethod(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual void Bar(bool flag) const;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(void, Bar, (bool flag), (const, override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testExplicitVoid(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual int Bar(void);
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(int, Bar, (), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testStrangeNewlineInParameter(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual void Bar(int
|
|
||||||
a) = 0;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(void, Bar, (int a), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testDefaultParameters(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual void Bar(int a, char c = 'x') = 0;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(void, Bar, (int a, char c), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testMultipleDefaultParameters(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual void Bar(
|
|
||||||
int a = 42,
|
|
||||||
char c = 'x',
|
|
||||||
const int* const p = nullptr,
|
|
||||||
const std::string& s = "42",
|
|
||||||
char tab[] = {'4','2'},
|
|
||||||
int const *& rp = aDefaultPointer) = 0;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(void, Bar, '
|
|
||||||
'(int a, char c, const int* const p, const std::string& s, char tab[], int const *& rp), '
|
|
||||||
'(override));', self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testMultipleSingleLineDefaultParameters(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual void Bar(int a = 42, int b = 43, int c = 44) = 0;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(void, Bar, (int a, int b, int c), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testConstDefaultParameter(self):
|
|
||||||
source = """
|
|
||||||
class Test {
|
|
||||||
public:
|
|
||||||
virtual bool Bar(const int test_arg = 42) = 0;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(bool, Bar, (const int test_arg), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testConstRefDefaultParameter(self):
|
|
||||||
source = """
|
|
||||||
class Test {
|
|
||||||
public:
|
|
||||||
virtual bool Bar(const std::string& test_arg = "42" ) = 0;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(bool, Bar, (const std::string& test_arg), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testRemovesCommentsWhenDefaultsArePresent(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual void Bar(int a = 42 /* a comment */,
|
|
||||||
char /* other comment */ c= 'x') = 0;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(void, Bar, (int a, char c), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testDoubleSlashCommentsInParameterListAreRemoved(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual void Bar(int a, // inline comments should be elided.
|
|
||||||
int b // inline comments should be elided.
|
|
||||||
) const = 0;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(void, Bar, (int a, int b), (const, override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testCStyleCommentsInParameterListAreNotRemoved(self):
|
|
||||||
# NOTE(nnorwitz): I'm not sure if it's the best behavior to keep these
|
|
||||||
# comments. Also note that C style comments after the last parameter
|
|
||||||
# are still elided.
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual const string& Bar(int /* keeper */, int b);
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(const string&, Bar, (int, int b), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testArgsOfTemplateTypes(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual int Bar(const vector<int>& v, map<int, string>* output);
|
|
||||||
};"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(int, Bar, (const vector<int>& v, (map<int, string>* output)), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testReturnTypeWithOneTemplateArg(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual vector<int>* Bar(int n);
|
|
||||||
};"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(vector<int>*, Bar, (int n), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testReturnTypeWithManyTemplateArgs(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual map<int, string> Bar();
|
|
||||||
};"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD((map<int, string>), Bar, (), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testSimpleMethodInTemplatedClass(self):
|
|
||||||
source = """
|
|
||||||
template<class T>
|
|
||||||
class Foo {
|
|
||||||
public:
|
|
||||||
virtual int Bar();
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(int, Bar, (), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testPointerArgWithoutNames(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
virtual int Bar(C*);
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(int, Bar, (C*), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testReferenceArgWithoutNames(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
virtual int Bar(C&);
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(int, Bar, (C&), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
def testArrayArgWithoutNames(self):
|
|
||||||
source = """
|
|
||||||
class Foo {
|
|
||||||
virtual int Bar(C[]);
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(
|
|
||||||
'MOCK_METHOD(int, Bar, (C[]), (override));',
|
|
||||||
self.GenerateMethodSource(source))
|
|
||||||
|
|
||||||
|
|
||||||
class GenerateMocksTest(TestCase):
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def GenerateMocks(cpp_source):
|
|
||||||
"""Convert C++ source to complete Google Mock output source."""
|
|
||||||
# <test> is a pseudo-filename, it is not read or written.
|
|
||||||
filename = '<test>'
|
|
||||||
builder = ast.BuilderFromSource(cpp_source, filename)
|
|
||||||
ast_list = list(builder.Generate())
|
|
||||||
lines = gmock_class._GenerateMocks(filename, cpp_source, ast_list, None)
|
|
||||||
return '\n'.join(lines)
|
|
||||||
|
|
||||||
def testNamespaces(self):
|
|
||||||
source = """
|
|
||||||
namespace Foo {
|
|
||||||
namespace Bar { class Forward; }
|
|
||||||
namespace Baz::Qux {
|
|
||||||
|
|
||||||
class Test {
|
|
||||||
public:
|
|
||||||
virtual void Foo();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Baz::Qux
|
|
||||||
} // namespace Foo
|
|
||||||
"""
|
|
||||||
expected = """\
|
|
||||||
namespace Foo {
|
|
||||||
namespace Baz::Qux {
|
|
||||||
|
|
||||||
class MockTest : public Test {
|
|
||||||
public:
|
|
||||||
MOCK_METHOD(void, Foo, (), (override));
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Baz::Qux
|
|
||||||
} // namespace Foo
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
|
||||||
self.GenerateMocks(source))
|
|
||||||
|
|
||||||
def testClassWithStorageSpecifierMacro(self):
|
|
||||||
source = """
|
|
||||||
class STORAGE_SPECIFIER Test {
|
|
||||||
public:
|
|
||||||
virtual void Foo();
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
expected = """\
|
|
||||||
class MockTest : public Test {
|
|
||||||
public:
|
|
||||||
MOCK_METHOD(void, Foo, (), (override));
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
|
||||||
self.GenerateMocks(source))
|
|
||||||
|
|
||||||
def testTemplatedForwardDeclaration(self):
|
|
||||||
source = """
|
|
||||||
template <class T> class Forward; // Forward declaration should be ignored.
|
|
||||||
class Test {
|
|
||||||
public:
|
|
||||||
virtual void Foo();
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
expected = """\
|
|
||||||
class MockTest : public Test {
|
|
||||||
public:
|
|
||||||
MOCK_METHOD(void, Foo, (), (override));
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
|
||||||
self.GenerateMocks(source))
|
|
||||||
|
|
||||||
def testTemplatedClass(self):
|
|
||||||
source = """
|
|
||||||
template <typename S, typename T>
|
|
||||||
class Test {
|
|
||||||
public:
|
|
||||||
virtual void Foo();
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
expected = """\
|
|
||||||
template <typename S, typename T>
|
|
||||||
class MockTest : public Test<S, T> {
|
|
||||||
public:
|
|
||||||
MOCK_METHOD(void, Foo, (), (override));
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
|
||||||
self.GenerateMocks(source))
|
|
||||||
|
|
||||||
def testTemplateInATemplateTypedef(self):
|
|
||||||
source = """
|
|
||||||
class Test {
|
|
||||||
public:
|
|
||||||
typedef std::vector<std::list<int>> FooType;
|
|
||||||
virtual void Bar(const FooType& test_arg);
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
expected = """\
|
|
||||||
class MockTest : public Test {
|
|
||||||
public:
|
|
||||||
MOCK_METHOD(void, Bar, (const FooType& test_arg), (override));
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
|
||||||
self.GenerateMocks(source))
|
|
||||||
|
|
||||||
def testTemplatedClassWithTemplatedArguments(self):
|
|
||||||
source = """
|
|
||||||
template <typename S, typename T, typename U, typename V, typename W>
|
|
||||||
class Test {
|
|
||||||
public:
|
|
||||||
virtual U Foo(T some_arg);
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
expected = """\
|
|
||||||
template <typename S, typename T, typename U, typename V, typename W>
|
|
||||||
class MockTest : public Test<S, T, U, V, W> {
|
|
||||||
public:
|
|
||||||
MOCK_METHOD(U, Foo, (T some_arg), (override));
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
|
||||||
self.GenerateMocks(source))
|
|
||||||
|
|
||||||
def testTemplateInATemplateTypedefWithComma(self):
|
|
||||||
source = """
|
|
||||||
class Test {
|
|
||||||
public:
|
|
||||||
typedef std::function<void(
|
|
||||||
const vector<std::list<int>>&, int> FooType;
|
|
||||||
virtual void Bar(const FooType& test_arg);
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
expected = """\
|
|
||||||
class MockTest : public Test {
|
|
||||||
public:
|
|
||||||
MOCK_METHOD(void, Bar, (const FooType& test_arg), (override));
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
|
||||||
self.GenerateMocks(source))
|
|
||||||
|
|
||||||
def testParenthesizedCommaInArg(self):
|
|
||||||
source = """
|
|
||||||
class Test {
|
|
||||||
public:
|
|
||||||
virtual void Bar(std::function<void(int, int)> f);
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
expected = """\
|
|
||||||
class MockTest : public Test {
|
|
||||||
public:
|
|
||||||
MOCK_METHOD(void, Bar, (std::function<void(int, int)> f), (override));
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
|
||||||
self.GenerateMocks(source))
|
|
||||||
|
|
||||||
def testEnumType(self):
|
|
||||||
source = """
|
|
||||||
class Test {
|
|
||||||
public:
|
|
||||||
enum Bar {
|
|
||||||
BAZ, QUX, QUUX, QUUUX
|
|
||||||
};
|
|
||||||
virtual void Foo();
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
expected = """\
|
|
||||||
class MockTest : public Test {
|
|
||||||
public:
|
|
||||||
MOCK_METHOD(void, Foo, (), (override));
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
|
||||||
self.GenerateMocks(source))
|
|
||||||
|
|
||||||
def testEnumClassType(self):
|
|
||||||
source = """
|
|
||||||
class Test {
|
|
||||||
public:
|
|
||||||
enum class Bar {
|
|
||||||
BAZ, QUX, QUUX, QUUUX
|
|
||||||
};
|
|
||||||
virtual void Foo();
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
expected = """\
|
|
||||||
class MockTest : public Test {
|
|
||||||
public:
|
|
||||||
MOCK_METHOD(void, Foo, (), (override));
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
|
||||||
self.GenerateMocks(source))
|
|
||||||
|
|
||||||
def testStdFunction(self):
|
|
||||||
source = """
|
|
||||||
class Test {
|
|
||||||
public:
|
|
||||||
Test(std::function<int(std::string)> foo) : foo_(foo) {}
|
|
||||||
|
|
||||||
virtual std::function<int(std::string)> foo();
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::function<int(std::string)> foo_;
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
expected = """\
|
|
||||||
class MockTest : public Test {
|
|
||||||
public:
|
|
||||||
MOCK_METHOD(std::function<int (std::string)>, foo, (), (override));
|
|
||||||
};
|
|
||||||
"""
|
|
||||||
self.assertEqualIgnoreLeadingWhitespace(expected,
|
|
||||||
self.GenerateMocks(source))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
unittest.main()
|
|
@ -1,56 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# Copyright 2007 Neal Norwitz
|
|
||||||
# Portions Copyright 2007 Google Inc.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
"""C++ keywords and helper utilities for determining keywords."""
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Python 3.x
|
|
||||||
import builtins
|
|
||||||
except ImportError:
|
|
||||||
# Python 2.x
|
|
||||||
import __builtin__ as builtins
|
|
||||||
|
|
||||||
|
|
||||||
if not hasattr(builtins, 'set'):
|
|
||||||
# Nominal support for Python 2.3.
|
|
||||||
from sets import Set as set
|
|
||||||
|
|
||||||
|
|
||||||
TYPES = set('bool char int long short double float void wchar_t unsigned signed'.split())
|
|
||||||
TYPE_MODIFIERS = set('auto register const inline extern static virtual volatile mutable'.split())
|
|
||||||
ACCESS = set('public protected private friend'.split())
|
|
||||||
|
|
||||||
CASTS = set('static_cast const_cast dynamic_cast reinterpret_cast'.split())
|
|
||||||
|
|
||||||
OTHERS = set('true false asm class namespace using explicit this operator sizeof'.split())
|
|
||||||
OTHER_TYPES = set('new delete typedef struct union enum typeid typename template'.split())
|
|
||||||
|
|
||||||
CONTROL = set('case switch default if else return goto'.split())
|
|
||||||
EXCEPTION = set('try catch throw'.split())
|
|
||||||
LOOP = set('while do for break continue'.split())
|
|
||||||
|
|
||||||
ALL = TYPES | TYPE_MODIFIERS | ACCESS | CASTS | OTHERS | OTHER_TYPES | CONTROL | EXCEPTION | LOOP
|
|
||||||
|
|
||||||
|
|
||||||
def IsKeyword(token):
|
|
||||||
return token in ALL
|
|
||||||
|
|
||||||
def IsBuiltinType(token):
|
|
||||||
if token in ('virtual', 'inline'):
|
|
||||||
# These only apply to methods, they can't be types by themselves.
|
|
||||||
return False
|
|
||||||
return token in TYPES or token in TYPE_MODIFIERS
|
|
@ -1,284 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# Copyright 2007 Neal Norwitz
|
|
||||||
# Portions Copyright 2007 Google Inc.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
"""Tokenize C++ source code."""
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Python 3.x
|
|
||||||
import builtins
|
|
||||||
except ImportError:
|
|
||||||
# Python 2.x
|
|
||||||
import __builtin__ as builtins
|
|
||||||
|
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from cpp import utils
|
|
||||||
|
|
||||||
|
|
||||||
if not hasattr(builtins, 'set'):
|
|
||||||
# Nominal support for Python 2.3.
|
|
||||||
from sets import Set as set
|
|
||||||
|
|
||||||
|
|
||||||
# Add $ as a valid identifier char since so much code uses it.
|
|
||||||
_letters = 'abcdefghijklmnopqrstuvwxyz'
|
|
||||||
VALID_IDENTIFIER_CHARS = set(_letters + _letters.upper() + '_0123456789$')
|
|
||||||
HEX_DIGITS = set('0123456789abcdefABCDEF')
|
|
||||||
INT_OR_FLOAT_DIGITS = set('01234567890eE-+')
|
|
||||||
|
|
||||||
|
|
||||||
# C++0x string preffixes.
|
|
||||||
_STR_PREFIXES = set(('R', 'u8', 'u8R', 'u', 'uR', 'U', 'UR', 'L', 'LR'))
|
|
||||||
|
|
||||||
|
|
||||||
# Token types.
|
|
||||||
UNKNOWN = 'UNKNOWN'
|
|
||||||
SYNTAX = 'SYNTAX'
|
|
||||||
CONSTANT = 'CONSTANT'
|
|
||||||
NAME = 'NAME'
|
|
||||||
PREPROCESSOR = 'PREPROCESSOR'
|
|
||||||
|
|
||||||
# Where the token originated from. This can be used for backtracking.
|
|
||||||
# It is always set to WHENCE_STREAM in this code.
|
|
||||||
WHENCE_STREAM, WHENCE_QUEUE = range(2)
|
|
||||||
|
|
||||||
|
|
||||||
class Token(object):
|
|
||||||
"""Data container to represent a C++ token.
|
|
||||||
|
|
||||||
Tokens can be identifiers, syntax char(s), constants, or
|
|
||||||
pre-processor directives.
|
|
||||||
|
|
||||||
start contains the index of the first char of the token in the source
|
|
||||||
end contains the index of the last char of the token in the source
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, token_type, name, start, end):
|
|
||||||
self.token_type = token_type
|
|
||||||
self.name = name
|
|
||||||
self.start = start
|
|
||||||
self.end = end
|
|
||||||
self.whence = WHENCE_STREAM
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
if not utils.DEBUG:
|
|
||||||
return 'Token(%r)' % self.name
|
|
||||||
return 'Token(%r, %s, %s)' % (self.name, self.start, self.end)
|
|
||||||
|
|
||||||
__repr__ = __str__
|
|
||||||
|
|
||||||
|
|
||||||
def _GetString(source, start, i):
|
|
||||||
i = source.find('"', i+1)
|
|
||||||
while source[i-1] == '\\':
|
|
||||||
# Count the trailing backslashes.
|
|
||||||
backslash_count = 1
|
|
||||||
j = i - 2
|
|
||||||
while source[j] == '\\':
|
|
||||||
backslash_count += 1
|
|
||||||
j -= 1
|
|
||||||
# When trailing backslashes are even, they escape each other.
|
|
||||||
if (backslash_count % 2) == 0:
|
|
||||||
break
|
|
||||||
i = source.find('"', i+1)
|
|
||||||
return i + 1
|
|
||||||
|
|
||||||
|
|
||||||
def _GetChar(source, start, i):
|
|
||||||
# NOTE(nnorwitz): may not be quite correct, should be good enough.
|
|
||||||
i = source.find("'", i+1)
|
|
||||||
while source[i-1] == '\\':
|
|
||||||
# Need to special case '\\'.
|
|
||||||
if (i - 2) > start and source[i-2] == '\\':
|
|
||||||
break
|
|
||||||
i = source.find("'", i+1)
|
|
||||||
# Try to handle unterminated single quotes (in a #if 0 block).
|
|
||||||
if i < 0:
|
|
||||||
i = start
|
|
||||||
return i + 1
|
|
||||||
|
|
||||||
|
|
||||||
def GetTokens(source):
|
|
||||||
"""Returns a sequence of Tokens.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
source: string of C++ source code.
|
|
||||||
|
|
||||||
Yields:
|
|
||||||
Token that represents the next token in the source.
|
|
||||||
"""
|
|
||||||
# Cache various valid character sets for speed.
|
|
||||||
valid_identifier_chars = VALID_IDENTIFIER_CHARS
|
|
||||||
hex_digits = HEX_DIGITS
|
|
||||||
int_or_float_digits = INT_OR_FLOAT_DIGITS
|
|
||||||
int_or_float_digits2 = int_or_float_digits | set('.')
|
|
||||||
|
|
||||||
# Only ignore errors while in a #if 0 block.
|
|
||||||
ignore_errors = False
|
|
||||||
count_ifs = 0
|
|
||||||
|
|
||||||
i = 0
|
|
||||||
end = len(source)
|
|
||||||
while i < end:
|
|
||||||
# Skip whitespace.
|
|
||||||
while i < end and source[i].isspace():
|
|
||||||
i += 1
|
|
||||||
if i >= end:
|
|
||||||
return
|
|
||||||
|
|
||||||
token_type = UNKNOWN
|
|
||||||
start = i
|
|
||||||
c = source[i]
|
|
||||||
if c.isalpha() or c == '_': # Find a string token.
|
|
||||||
token_type = NAME
|
|
||||||
while source[i] in valid_identifier_chars:
|
|
||||||
i += 1
|
|
||||||
# String and character constants can look like a name if
|
|
||||||
# they are something like L"".
|
|
||||||
if (source[i] == "'" and (i - start) == 1 and
|
|
||||||
source[start:i] in 'uUL'):
|
|
||||||
# u, U, and L are valid C++0x character preffixes.
|
|
||||||
token_type = CONSTANT
|
|
||||||
i = _GetChar(source, start, i)
|
|
||||||
elif source[i] == "'" and source[start:i] in _STR_PREFIXES:
|
|
||||||
token_type = CONSTANT
|
|
||||||
i = _GetString(source, start, i)
|
|
||||||
elif c == '/' and source[i+1] == '/': # Find // comments.
|
|
||||||
i = source.find('\n', i)
|
|
||||||
if i == -1: # Handle EOF.
|
|
||||||
i = end
|
|
||||||
continue
|
|
||||||
elif c == '/' and source[i+1] == '*': # Find /* comments. */
|
|
||||||
i = source.find('*/', i) + 2
|
|
||||||
continue
|
|
||||||
elif c in ':+-<>&|*=': # : or :: (plus other chars).
|
|
||||||
token_type = SYNTAX
|
|
||||||
i += 1
|
|
||||||
new_ch = source[i]
|
|
||||||
if new_ch == c and c != '>': # Treat ">>" as two tokens.
|
|
||||||
i += 1
|
|
||||||
elif c == '-' and new_ch == '>':
|
|
||||||
i += 1
|
|
||||||
elif new_ch == '=':
|
|
||||||
i += 1
|
|
||||||
elif c in '()[]{}~!?^%;/.,': # Handle single char tokens.
|
|
||||||
token_type = SYNTAX
|
|
||||||
i += 1
|
|
||||||
if c == '.' and source[i].isdigit():
|
|
||||||
token_type = CONSTANT
|
|
||||||
i += 1
|
|
||||||
while source[i] in int_or_float_digits:
|
|
||||||
i += 1
|
|
||||||
# Handle float suffixes.
|
|
||||||
for suffix in ('l', 'f'):
|
|
||||||
if suffix == source[i:i+1].lower():
|
|
||||||
i += 1
|
|
||||||
break
|
|
||||||
elif c.isdigit(): # Find integer.
|
|
||||||
token_type = CONSTANT
|
|
||||||
if c == '0' and source[i+1] in 'xX':
|
|
||||||
# Handle hex digits.
|
|
||||||
i += 2
|
|
||||||
while source[i] in hex_digits:
|
|
||||||
i += 1
|
|
||||||
else:
|
|
||||||
while source[i] in int_or_float_digits2:
|
|
||||||
i += 1
|
|
||||||
# Handle integer (and float) suffixes.
|
|
||||||
for suffix in ('ull', 'll', 'ul', 'l', 'f', 'u'):
|
|
||||||
size = len(suffix)
|
|
||||||
if suffix == source[i:i+size].lower():
|
|
||||||
i += size
|
|
||||||
break
|
|
||||||
elif c == '"': # Find string.
|
|
||||||
token_type = CONSTANT
|
|
||||||
i = _GetString(source, start, i)
|
|
||||||
elif c == "'": # Find char.
|
|
||||||
token_type = CONSTANT
|
|
||||||
i = _GetChar(source, start, i)
|
|
||||||
elif c == '#': # Find pre-processor command.
|
|
||||||
token_type = PREPROCESSOR
|
|
||||||
got_if = source[i:i+3] == '#if' and source[i+3:i+4].isspace()
|
|
||||||
if got_if:
|
|
||||||
count_ifs += 1
|
|
||||||
elif source[i:i+6] == '#endif':
|
|
||||||
count_ifs -= 1
|
|
||||||
if count_ifs == 0:
|
|
||||||
ignore_errors = False
|
|
||||||
|
|
||||||
# TODO(nnorwitz): handle preprocessor statements (\ continuations).
|
|
||||||
while 1:
|
|
||||||
i1 = source.find('\n', i)
|
|
||||||
i2 = source.find('//', i)
|
|
||||||
i3 = source.find('/*', i)
|
|
||||||
i4 = source.find('"', i)
|
|
||||||
# NOTE(nnorwitz): doesn't handle comments in #define macros.
|
|
||||||
# Get the first important symbol (newline, comment, EOF/end).
|
|
||||||
i = min([x for x in (i1, i2, i3, i4, end) if x != -1])
|
|
||||||
|
|
||||||
# Handle #include "dir//foo.h" properly.
|
|
||||||
if source[i] == '"':
|
|
||||||
i = source.find('"', i+1) + 1
|
|
||||||
assert i > 0
|
|
||||||
continue
|
|
||||||
# Keep going if end of the line and the line ends with \.
|
|
||||||
if not (i == i1 and source[i-1] == '\\'):
|
|
||||||
if got_if:
|
|
||||||
condition = source[start+4:i].lstrip()
|
|
||||||
if (condition.startswith('0') or
|
|
||||||
condition.startswith('(0)')):
|
|
||||||
ignore_errors = True
|
|
||||||
break
|
|
||||||
i += 1
|
|
||||||
elif c == '\\': # Handle \ in code.
|
|
||||||
# This is different from the pre-processor \ handling.
|
|
||||||
i += 1
|
|
||||||
continue
|
|
||||||
elif ignore_errors:
|
|
||||||
# The tokenizer seems to be in pretty good shape. This
|
|
||||||
# raise is conditionally disabled so that bogus code
|
|
||||||
# in an #if 0 block can be handled. Since we will ignore
|
|
||||||
# it anyways, this is probably fine. So disable the
|
|
||||||
# exception and return the bogus char.
|
|
||||||
i += 1
|
|
||||||
else:
|
|
||||||
sys.stderr.write('Got invalid token in %s @ %d token:%s: %r\n' %
|
|
||||||
('?', i, c, source[i-10:i+10]))
|
|
||||||
raise RuntimeError('unexpected token')
|
|
||||||
|
|
||||||
if i <= 0:
|
|
||||||
print('Invalid index, exiting now.')
|
|
||||||
return
|
|
||||||
yield Token(token_type, source[start:i], start, i)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
def main(argv):
|
|
||||||
"""Driver mostly for testing purposes."""
|
|
||||||
for filename in argv[1:]:
|
|
||||||
source = utils.ReadFile(filename)
|
|
||||||
if source is None:
|
|
||||||
continue
|
|
||||||
|
|
||||||
for token in GetTokens(source):
|
|
||||||
print('%-12s: %s' % (token.token_type, token.name))
|
|
||||||
# print('\r%6.2f%%' % (100.0 * index / token.end),)
|
|
||||||
sys.stdout.write('\n')
|
|
||||||
|
|
||||||
|
|
||||||
main(sys.argv)
|
|
@ -1,37 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# Copyright 2007 Neal Norwitz
|
|
||||||
# Portions Copyright 2007 Google Inc.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
"""Generic utilities for C++ parsing."""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
# Set to True to see the start/end token indices.
|
|
||||||
DEBUG = True
|
|
||||||
|
|
||||||
|
|
||||||
def ReadFile(filename, print_error=True):
|
|
||||||
"""Returns the contents of a file."""
|
|
||||||
try:
|
|
||||||
fp = open(filename)
|
|
||||||
try:
|
|
||||||
return fp.read()
|
|
||||||
finally:
|
|
||||||
fp.close()
|
|
||||||
except IOError:
|
|
||||||
if print_error:
|
|
||||||
print('Error reading %s: %s' % (filename, sys.exc_info()[1]))
|
|
||||||
return None
|
|
@ -1,30 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# Copyright 2008 Google Inc. All Rights Reserved.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
"""Driver for starting up Google Mock class generator."""
|
|
||||||
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
# Add the directory of this script to the path so we can import gmock_class.
|
|
||||||
sys.path.append(os.path.dirname(__file__))
|
|
||||||
|
|
||||||
from cpp import gmock_class
|
|
||||||
# Fix the docstring in case they require the usage.
|
|
||||||
gmock_class.__doc__ = gmock_class.__doc__.replace('gmock_class.py', __file__)
|
|
||||||
gmock_class.main()
|
|
@ -37,8 +37,14 @@
|
|||||||
#include "gmock/internal/gmock-internal-utils.h"
|
#include "gmock/internal/gmock-internal-utils.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <cctype>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
#include <ostream> // NOLINT
|
#include <ostream> // NOLINT
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
#include "gmock/internal/gmock-port.h"
|
#include "gmock/internal/gmock-port.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
@ -126,10 +132,10 @@ static GTEST_DEFINE_STATIC_MUTEX_(g_log_mutex);
|
|||||||
// Returns true if and only if a log with the given severity is visible
|
// Returns true if and only if a log with the given severity is visible
|
||||||
// according to the --gmock_verbose flag.
|
// according to the --gmock_verbose flag.
|
||||||
GTEST_API_ bool LogIsVisible(LogSeverity severity) {
|
GTEST_API_ bool LogIsVisible(LogSeverity severity) {
|
||||||
if (GMOCK_FLAG(verbose) == kInfoVerbosity) {
|
if (GMOCK_FLAG_GET(verbose) == kInfoVerbosity) {
|
||||||
// Always show the log if --gmock_verbose=info.
|
// Always show the log if --gmock_verbose=info.
|
||||||
return true;
|
return true;
|
||||||
} else if (GMOCK_FLAG(verbose) == kErrorVerbosity) {
|
} else if (GMOCK_FLAG_GET(verbose) == kErrorVerbosity) {
|
||||||
// Always hide it if --gmock_verbose=error.
|
// Always hide it if --gmock_verbose=error.
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
@ -196,5 +202,53 @@ GTEST_API_ void IllegalDoDefault(const char* file, int line) {
|
|||||||
"the variable in various places.");
|
"the variable in various places.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr char UnBase64Impl(char c, const char* const base64, char carry) {
|
||||||
|
return *base64 == 0 ? static_cast<char>(65)
|
||||||
|
: *base64 == c ? carry
|
||||||
|
: UnBase64Impl(c, base64 + 1, carry + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <size_t... I>
|
||||||
|
constexpr std::array<char, 256> UnBase64Impl(IndexSequence<I...>,
|
||||||
|
const char* const base64) {
|
||||||
|
return {{UnBase64Impl(static_cast<char>(I), base64, 0)...}};
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr std::array<char, 256> UnBase64(const char* const base64) {
|
||||||
|
return UnBase64Impl(MakeIndexSequence<256>{}, base64);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr char kBase64[] =
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
static constexpr std::array<char, 256> kUnBase64 = UnBase64(kBase64);
|
||||||
|
|
||||||
|
bool Base64Unescape(const std::string& encoded, std::string* decoded) {
|
||||||
|
decoded->clear();
|
||||||
|
size_t encoded_len = encoded.size();
|
||||||
|
decoded->reserve(3 * (encoded_len / 4) + (encoded_len % 4));
|
||||||
|
int bit_pos = 0;
|
||||||
|
char dst = 0;
|
||||||
|
for (int src : encoded) {
|
||||||
|
if (std::isspace(src) || src == '=') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
char src_bin = kUnBase64[static_cast<size_t>(src)];
|
||||||
|
if (src_bin >= 64) {
|
||||||
|
decoded->clear();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (bit_pos == 0) {
|
||||||
|
dst |= src_bin << 2;
|
||||||
|
bit_pos = 6;
|
||||||
|
} else {
|
||||||
|
dst |= static_cast<char>(src_bin >> (bit_pos - 2));
|
||||||
|
decoded->push_back(dst);
|
||||||
|
dst = static_cast<char>(src_bin << (10 - bit_pos));
|
||||||
|
bit_pos = (bit_pos + 6) % 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
@ -264,10 +264,10 @@ void ExpectationBase::UntypedTimes(const Cardinality& a_cardinality) {
|
|||||||
".Times() cannot appear "
|
".Times() cannot appear "
|
||||||
"more than once in an EXPECT_CALL().");
|
"more than once in an EXPECT_CALL().");
|
||||||
} else {
|
} else {
|
||||||
ExpectSpecProperty(last_clause_ < kTimes,
|
ExpectSpecProperty(
|
||||||
".Times() cannot appear after "
|
last_clause_ < kTimes,
|
||||||
".InSequence(), .WillOnce(), .WillRepeatedly(), "
|
".Times() may only appear *before* .InSequence(), .WillOnce(), "
|
||||||
"or .RetiresOnSaturation().");
|
".WillRepeatedly(), or .RetiresonSaturation(), not after.");
|
||||||
}
|
}
|
||||||
last_clause_ = kTimes;
|
last_clause_ = kTimes;
|
||||||
|
|
||||||
@ -283,7 +283,7 @@ GTEST_API_ ThreadLocal<Sequence*> g_gmock_implicit_sequence;
|
|||||||
void ReportUninterestingCall(CallReaction reaction, const std::string& msg) {
|
void ReportUninterestingCall(CallReaction reaction, const std::string& msg) {
|
||||||
// Include a stack trace only if --gmock_verbose=info is specified.
|
// Include a stack trace only if --gmock_verbose=info is specified.
|
||||||
const int stack_frames_to_skip =
|
const int stack_frames_to_skip =
|
||||||
GMOCK_FLAG(verbose) == kInfoVerbosity ? 3 : -1;
|
GMOCK_FLAG_GET(verbose) == kInfoVerbosity ? 3 : -1;
|
||||||
switch (reaction) {
|
switch (reaction) {
|
||||||
case kAllow:
|
case kAllow:
|
||||||
Log(kInfo, msg, stack_frames_to_skip);
|
Log(kInfo, msg, stack_frames_to_skip);
|
||||||
@ -613,8 +613,7 @@ class MockObjectRegistry {
|
|||||||
// object alive. Therefore we report any living object as test
|
// object alive. Therefore we report any living object as test
|
||||||
// failure, unless the user explicitly asked us to ignore it.
|
// failure, unless the user explicitly asked us to ignore it.
|
||||||
~MockObjectRegistry() {
|
~MockObjectRegistry() {
|
||||||
if (!GMOCK_FLAG(catch_leaked_mocks))
|
if (!GMOCK_FLAG_GET(catch_leaked_mocks)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
int leaked_count = 0;
|
int leaked_count = 0;
|
||||||
for (StateMap::const_iterator it = states_.begin(); it != states_.end();
|
for (StateMap::const_iterator it = states_.begin(); it != states_.end();
|
||||||
@ -716,9 +715,10 @@ internal::CallReaction Mock::GetReactionOnUninterestingCalls(
|
|||||||
const void* mock_obj)
|
const void* mock_obj)
|
||||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||||
return (g_uninteresting_call_reaction.count(mock_obj) == 0) ?
|
return (g_uninteresting_call_reaction.count(mock_obj) == 0)
|
||||||
internal::intToCallReaction(GMOCK_FLAG(default_mock_behavior)) :
|
? internal::intToCallReaction(
|
||||||
g_uninteresting_call_reaction[mock_obj];
|
GMOCK_FLAG_GET(default_mock_behavior))
|
||||||
|
: g_uninteresting_call_reaction[mock_obj];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tells Google Mock to ignore mock_obj when checking for leaked mock
|
// Tells Google Mock to ignore mock_obj when checking for leaked mock
|
||||||
|
@ -31,13 +31,11 @@
|
|||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
#include "gmock/internal/gmock-port.h"
|
#include "gmock/internal/gmock-port.h"
|
||||||
|
|
||||||
namespace testing {
|
|
||||||
|
|
||||||
GMOCK_DEFINE_bool_(catch_leaked_mocks, true,
|
GMOCK_DEFINE_bool_(catch_leaked_mocks, true,
|
||||||
"true if and only if Google Mock should report leaked "
|
"true if and only if Google Mock should report leaked "
|
||||||
"mock objects as failures.");
|
"mock objects as failures.");
|
||||||
|
|
||||||
GMOCK_DEFINE_string_(verbose, internal::kWarningVerbosity,
|
GMOCK_DEFINE_string_(verbose, testing::internal::kWarningVerbosity,
|
||||||
"Controls how verbose Google Mock's output is."
|
"Controls how verbose Google Mock's output is."
|
||||||
" Valid values:\n"
|
" Valid values:\n"
|
||||||
" info - prints all messages.\n"
|
" info - prints all messages.\n"
|
||||||
@ -51,6 +49,7 @@ GMOCK_DEFINE_int32_(default_mock_behavior, 1,
|
|||||||
" 1 - by default, mocks act as NaggyMocks.\n"
|
" 1 - by default, mocks act as NaggyMocks.\n"
|
||||||
" 2 - by default, mocks act as StrictMocks.");
|
" 2 - by default, mocks act as StrictMocks.");
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// Parses a string as a command line flag. The string should have the
|
// Parses a string as a command line flag. The string should have the
|
||||||
@ -59,18 +58,18 @@ namespace internal {
|
|||||||
//
|
//
|
||||||
// Returns the value of the flag, or NULL if the parsing failed.
|
// Returns the value of the flag, or NULL if the parsing failed.
|
||||||
static const char* ParseGoogleMockFlagValue(const char* str,
|
static const char* ParseGoogleMockFlagValue(const char* str,
|
||||||
const char* flag,
|
const char* flag_name,
|
||||||
bool def_optional) {
|
bool def_optional) {
|
||||||
// str and flag must not be NULL.
|
// str and flag must not be NULL.
|
||||||
if (str == nullptr || flag == nullptr) return nullptr;
|
if (str == nullptr || flag_name == nullptr) return nullptr;
|
||||||
|
|
||||||
// The flag must start with "--gmock_".
|
// The flag must start with "--gmock_".
|
||||||
const std::string flag_str = std::string("--gmock_") + flag;
|
const std::string flag_name_str = std::string("--gmock_") + flag_name;
|
||||||
const size_t flag_len = flag_str.length();
|
const size_t flag_name_len = flag_name_str.length();
|
||||||
if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr;
|
if (strncmp(str, flag_name_str.c_str(), flag_name_len) != 0) return nullptr;
|
||||||
|
|
||||||
// Skips the flag name.
|
// Skips the flag name.
|
||||||
const char* flag_end = str + flag_len;
|
const char* flag_end = str + flag_name_len;
|
||||||
|
|
||||||
// When def_optional is true, it's OK to not have a "=value" part.
|
// When def_optional is true, it's OK to not have a "=value" part.
|
||||||
if (def_optional && (flag_end[0] == '\0')) {
|
if (def_optional && (flag_end[0] == '\0')) {
|
||||||
@ -91,10 +90,10 @@ static const char* ParseGoogleMockFlagValue(const char* str,
|
|||||||
//
|
//
|
||||||
// On success, stores the value of the flag in *value, and returns
|
// On success, stores the value of the flag in *value, and returns
|
||||||
// true. On failure, returns false without changing *value.
|
// true. On failure, returns false without changing *value.
|
||||||
static bool ParseGoogleMockBoolFlag(const char* str, const char* flag,
|
static bool ParseGoogleMockFlag(const char* str, const char* flag_name,
|
||||||
bool* value) {
|
bool* value) {
|
||||||
// Gets the value of the flag as a string.
|
// Gets the value of the flag as a string.
|
||||||
const char* const value_str = ParseGoogleMockFlagValue(str, flag, true);
|
const char* const value_str = ParseGoogleMockFlagValue(str, flag_name, true);
|
||||||
|
|
||||||
// Aborts if the parsing failed.
|
// Aborts if the parsing failed.
|
||||||
if (value_str == nullptr) return false;
|
if (value_str == nullptr) return false;
|
||||||
@ -110,10 +109,10 @@ static bool ParseGoogleMockBoolFlag(const char* str, const char* flag,
|
|||||||
// On success, stores the value of the flag in *value, and returns
|
// On success, stores the value of the flag in *value, and returns
|
||||||
// true. On failure, returns false without changing *value.
|
// true. On failure, returns false without changing *value.
|
||||||
template <typename String>
|
template <typename String>
|
||||||
static bool ParseGoogleMockStringFlag(const char* str, const char* flag,
|
static bool ParseGoogleMockFlag(const char* str, const char* flag_name,
|
||||||
String* value) {
|
String* value) {
|
||||||
// Gets the value of the flag as a string.
|
// Gets the value of the flag as a string.
|
||||||
const char* const value_str = ParseGoogleMockFlagValue(str, flag, false);
|
const char* const value_str = ParseGoogleMockFlagValue(str, flag_name, false);
|
||||||
|
|
||||||
// Aborts if the parsing failed.
|
// Aborts if the parsing failed.
|
||||||
if (value_str == nullptr) return false;
|
if (value_str == nullptr) return false;
|
||||||
@ -123,17 +122,17 @@ static bool ParseGoogleMockStringFlag(const char* str, const char* flag,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ParseGoogleMockIntFlag(const char* str, const char* flag,
|
static bool ParseGoogleMockFlag(const char* str, const char* flag_name,
|
||||||
int32_t* value) {
|
int32_t* value) {
|
||||||
// Gets the value of the flag as a string.
|
// Gets the value of the flag as a string.
|
||||||
const char* const value_str = ParseGoogleMockFlagValue(str, flag, true);
|
const char* const value_str = ParseGoogleMockFlagValue(str, flag_name, true);
|
||||||
|
|
||||||
// Aborts if the parsing failed.
|
// Aborts if the parsing failed.
|
||||||
if (value_str == nullptr) return false;
|
if (value_str == nullptr) return false;
|
||||||
|
|
||||||
// Sets *value to the value of the flag.
|
// Sets *value to the value of the flag.
|
||||||
return ParseInt32(Message() << "The value of flag --" << flag,
|
return ParseInt32(Message() << "The value of flag --" << flag_name, value_str,
|
||||||
value_str, value);
|
value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The internal implementation of InitGoogleMock().
|
// The internal implementation of InitGoogleMock().
|
||||||
@ -152,11 +151,22 @@ void InitGoogleMockImpl(int* argc, CharType** argv) {
|
|||||||
const char* const arg = arg_string.c_str();
|
const char* const arg = arg_string.c_str();
|
||||||
|
|
||||||
// Do we see a Google Mock flag?
|
// Do we see a Google Mock flag?
|
||||||
if (ParseGoogleMockBoolFlag(arg, "catch_leaked_mocks",
|
bool found_gmock_flag = false;
|
||||||
&GMOCK_FLAG(catch_leaked_mocks)) ||
|
|
||||||
ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose)) ||
|
#define GMOCK_INTERNAL_PARSE_FLAG(flag_name) \
|
||||||
ParseGoogleMockIntFlag(arg, "default_mock_behavior",
|
if (!found_gmock_flag) { \
|
||||||
&GMOCK_FLAG(default_mock_behavior))) {
|
auto value = GMOCK_FLAG_GET(flag_name); \
|
||||||
|
if (ParseGoogleMockFlag(arg, #flag_name, &value)) { \
|
||||||
|
GMOCK_FLAG_SET(flag_name, value); \
|
||||||
|
found_gmock_flag = true; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
GMOCK_INTERNAL_PARSE_FLAG(catch_leaked_mocks)
|
||||||
|
GMOCK_INTERNAL_PARSE_FLAG(verbose)
|
||||||
|
GMOCK_INTERNAL_PARSE_FLAG(default_mock_behavior)
|
||||||
|
|
||||||
|
if (found_gmock_flag) {
|
||||||
// Yes. Shift the remainder of the argv list left by one. Note
|
// Yes. Shift the remainder of the argv list left by one. Note
|
||||||
// that argv has (*argc + 1) elements, the last one always being
|
// that argv has (*argc + 1) elements, the last one always being
|
||||||
// NULL. The following loop moves the trailing NULL element as
|
// NULL. The following loop moves the trailing NULL element as
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
#
|
#
|
||||||
# Bazel Build for Google C++ Testing Framework(Google Test)-googlemock
|
# Bazel Build for Google C++ Testing Framework(Google Test)-googlemock
|
||||||
|
|
||||||
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test")
|
|
||||||
load("@rules_python//python:defs.bzl", "py_library", "py_test")
|
load("@rules_python//python:defs.bzl", "py_library", "py_test")
|
||||||
|
|
||||||
licenses(["notice"])
|
licenses(["notice"])
|
||||||
@ -41,6 +40,7 @@ cc_test(
|
|||||||
size = "small",
|
size = "small",
|
||||||
srcs = glob(include = ["gmock-*.cc"]),
|
srcs = glob(include = ["gmock-*.cc"]),
|
||||||
linkopts = select({
|
linkopts = select({
|
||||||
|
"//:qnx": [],
|
||||||
"//:windows": [],
|
"//:windows": [],
|
||||||
"//conditions:default": ["-pthread"],
|
"//conditions:default": ["-pthread"],
|
||||||
}),
|
}),
|
||||||
|
@ -384,7 +384,7 @@ TEST(ActionInterfaceTest, MakeAction) {
|
|||||||
EXPECT_EQ(5, action.Perform(std::make_tuple(true, 5)));
|
EXPECT_EQ(5, action.Perform(std::make_tuple(true, 5)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that Action<F> can be contructed from a pointer to
|
// Tests that Action<F> can be constructed from a pointer to
|
||||||
// ActionInterface<F>.
|
// ActionInterface<F>.
|
||||||
TEST(ActionTest, CanBeConstructedFromActionInterface) {
|
TEST(ActionTest, CanBeConstructedFromActionInterface) {
|
||||||
Action<MyGlobalFunction> action(new MyActionImpl);
|
Action<MyGlobalFunction> action(new MyActionImpl);
|
||||||
|
@ -361,27 +361,27 @@ TEST(ExpectTest, FailsNonfatallyOnFalse) {
|
|||||||
|
|
||||||
class LogIsVisibleTest : public ::testing::Test {
|
class LogIsVisibleTest : public ::testing::Test {
|
||||||
protected:
|
protected:
|
||||||
void SetUp() override { original_verbose_ = GMOCK_FLAG(verbose); }
|
void SetUp() override { original_verbose_ = GMOCK_FLAG_GET(verbose); }
|
||||||
|
|
||||||
void TearDown() override { GMOCK_FLAG(verbose) = original_verbose_; }
|
void TearDown() override { GMOCK_FLAG_SET(verbose, original_verbose_); }
|
||||||
|
|
||||||
std::string original_verbose_;
|
std::string original_verbose_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(LogIsVisibleTest, AlwaysReturnsTrueIfVerbosityIsInfo) {
|
TEST_F(LogIsVisibleTest, AlwaysReturnsTrueIfVerbosityIsInfo) {
|
||||||
GMOCK_FLAG(verbose) = kInfoVerbosity;
|
GMOCK_FLAG_SET(verbose, kInfoVerbosity);
|
||||||
EXPECT_TRUE(LogIsVisible(kInfo));
|
EXPECT_TRUE(LogIsVisible(kInfo));
|
||||||
EXPECT_TRUE(LogIsVisible(kWarning));
|
EXPECT_TRUE(LogIsVisible(kWarning));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(LogIsVisibleTest, AlwaysReturnsFalseIfVerbosityIsError) {
|
TEST_F(LogIsVisibleTest, AlwaysReturnsFalseIfVerbosityIsError) {
|
||||||
GMOCK_FLAG(verbose) = kErrorVerbosity;
|
GMOCK_FLAG_SET(verbose, kErrorVerbosity);
|
||||||
EXPECT_FALSE(LogIsVisible(kInfo));
|
EXPECT_FALSE(LogIsVisible(kInfo));
|
||||||
EXPECT_FALSE(LogIsVisible(kWarning));
|
EXPECT_FALSE(LogIsVisible(kWarning));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(LogIsVisibleTest, WorksWhenVerbosityIsWarning) {
|
TEST_F(LogIsVisibleTest, WorksWhenVerbosityIsWarning) {
|
||||||
GMOCK_FLAG(verbose) = kWarningVerbosity;
|
GMOCK_FLAG_SET(verbose, kWarningVerbosity);
|
||||||
EXPECT_FALSE(LogIsVisible(kInfo));
|
EXPECT_FALSE(LogIsVisible(kInfo));
|
||||||
EXPECT_TRUE(LogIsVisible(kWarning));
|
EXPECT_TRUE(LogIsVisible(kWarning));
|
||||||
}
|
}
|
||||||
@ -394,8 +394,8 @@ TEST_F(LogIsVisibleTest, WorksWhenVerbosityIsWarning) {
|
|||||||
// and log severity.
|
// and log severity.
|
||||||
void TestLogWithSeverity(const std::string& verbosity, LogSeverity severity,
|
void TestLogWithSeverity(const std::string& verbosity, LogSeverity severity,
|
||||||
bool should_print) {
|
bool should_print) {
|
||||||
const std::string old_flag = GMOCK_FLAG(verbose);
|
const std::string old_flag = GMOCK_FLAG_GET(verbose);
|
||||||
GMOCK_FLAG(verbose) = verbosity;
|
GMOCK_FLAG_SET(verbose, verbosity);
|
||||||
CaptureStdout();
|
CaptureStdout();
|
||||||
Log(severity, "Test log.\n", 0);
|
Log(severity, "Test log.\n", 0);
|
||||||
if (should_print) {
|
if (should_print) {
|
||||||
@ -407,18 +407,18 @@ void TestLogWithSeverity(const std::string& verbosity, LogSeverity severity,
|
|||||||
} else {
|
} else {
|
||||||
EXPECT_STREQ("", GetCapturedStdout().c_str());
|
EXPECT_STREQ("", GetCapturedStdout().c_str());
|
||||||
}
|
}
|
||||||
GMOCK_FLAG(verbose) = old_flag;
|
GMOCK_FLAG_SET(verbose, old_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that when the stack_frames_to_skip parameter is negative,
|
// Tests that when the stack_frames_to_skip parameter is negative,
|
||||||
// Log() doesn't include the stack trace in the output.
|
// Log() doesn't include the stack trace in the output.
|
||||||
TEST(LogTest, NoStackTraceWhenStackFramesToSkipIsNegative) {
|
TEST(LogTest, NoStackTraceWhenStackFramesToSkipIsNegative) {
|
||||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||||
GMOCK_FLAG(verbose) = kInfoVerbosity;
|
GMOCK_FLAG_SET(verbose, kInfoVerbosity);
|
||||||
CaptureStdout();
|
CaptureStdout();
|
||||||
Log(kInfo, "Test log.\n", -1);
|
Log(kInfo, "Test log.\n", -1);
|
||||||
EXPECT_STREQ("\nTest log.\n", GetCapturedStdout().c_str());
|
EXPECT_STREQ("\nTest log.\n", GetCapturedStdout().c_str());
|
||||||
GMOCK_FLAG(verbose) = saved_flag;
|
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MockStackTraceGetter : testing::internal::OsStackTraceGetterInterface {
|
struct MockStackTraceGetter : testing::internal::OsStackTraceGetterInterface {
|
||||||
@ -440,7 +440,8 @@ TEST(LogTest, NoSkippingStackFrameInOptMode) {
|
|||||||
const std::string log = GetCapturedStdout();
|
const std::string log = GetCapturedStdout();
|
||||||
|
|
||||||
std::string expected_trace =
|
std::string expected_trace =
|
||||||
(testing::Message() << GTEST_FLAG(stack_trace_depth) << "::").GetString();
|
(testing::Message() << GTEST_FLAG_GET(stack_trace_depth) << "::")
|
||||||
|
.GetString();
|
||||||
std::string expected_message =
|
std::string expected_message =
|
||||||
"\nGMOCK WARNING:\n"
|
"\nGMOCK WARNING:\n"
|
||||||
"Test log.\n"
|
"Test log.\n"
|
||||||
@ -498,11 +499,11 @@ TEST(LogTest, OnlyWarningsArePrintedWhenVerbosityIsInvalid) {
|
|||||||
// Verifies that Log() behaves correctly for the given verbosity level
|
// Verifies that Log() behaves correctly for the given verbosity level
|
||||||
// and log severity.
|
// and log severity.
|
||||||
std::string GrabOutput(void(*logger)(), const char* verbosity) {
|
std::string GrabOutput(void(*logger)(), const char* verbosity) {
|
||||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||||
GMOCK_FLAG(verbose) = verbosity;
|
GMOCK_FLAG_SET(verbose, verbosity);
|
||||||
CaptureStdout();
|
CaptureStdout();
|
||||||
logger();
|
logger();
|
||||||
GMOCK_FLAG(verbose) = saved_flag;
|
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||||
return GetCapturedStdout();
|
return GetCapturedStdout();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -715,6 +716,46 @@ TEST(FunctionTest, LongArgumentList) {
|
|||||||
F::MakeResultIgnoredValue>::value));
|
F::MakeResultIgnoredValue>::value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Base64Unescape, InvalidString) {
|
||||||
|
std::string unescaped;
|
||||||
|
EXPECT_FALSE(Base64Unescape("(invalid)", &unescaped));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Base64Unescape, ShortString) {
|
||||||
|
std::string unescaped;
|
||||||
|
EXPECT_TRUE(Base64Unescape("SGVsbG8gd29ybGQh", &unescaped));
|
||||||
|
EXPECT_EQ("Hello world!", unescaped);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Base64Unescape, ShortStringWithPadding) {
|
||||||
|
std::string unescaped;
|
||||||
|
EXPECT_TRUE(Base64Unescape("SGVsbG8gd29ybGQ=", &unescaped));
|
||||||
|
EXPECT_EQ("Hello world", unescaped);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Base64Unescape, ShortStringWithoutPadding) {
|
||||||
|
std::string unescaped;
|
||||||
|
EXPECT_TRUE(Base64Unescape("SGVsbG8gd29ybGQ", &unescaped));
|
||||||
|
EXPECT_EQ("Hello world", unescaped);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Base64Unescape, LongStringWithWhiteSpaces) {
|
||||||
|
std::string escaped =
|
||||||
|
R"(TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz
|
||||||
|
IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg
|
||||||
|
dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu
|
||||||
|
dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo
|
||||||
|
ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=)";
|
||||||
|
std::string expected =
|
||||||
|
"Man is distinguished, not only by his reason, but by this singular "
|
||||||
|
"passion from other animals, which is a lust of the mind, that by a "
|
||||||
|
"perseverance of delight in the continued and indefatigable generation "
|
||||||
|
"of knowledge, exceeds the short vehemence of any carnal pleasure.";
|
||||||
|
std::string unescaped;
|
||||||
|
EXPECT_TRUE(Base64Unescape(escaped, &unescaped));
|
||||||
|
EXPECT_EQ(expected, unescaped);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
@ -114,31 +114,32 @@ std::vector<std::unique_ptr<int>> MakeUniquePtrs(const std::vector<int>& ints) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For testing ExplainMatchResultTo().
|
// For testing ExplainMatchResultTo().
|
||||||
class GreaterThanMatcher : public MatcherInterface<int> {
|
template <typename T = int>
|
||||||
|
class GreaterThanMatcher : public MatcherInterface<T> {
|
||||||
public:
|
public:
|
||||||
explicit GreaterThanMatcher(int rhs) : rhs_(rhs) {}
|
explicit GreaterThanMatcher(T rhs) : rhs_(rhs) {}
|
||||||
|
|
||||||
void DescribeTo(ostream* os) const override { *os << "is > " << rhs_; }
|
void DescribeTo(ostream* os) const override { *os << "is > " << rhs_; }
|
||||||
|
|
||||||
bool MatchAndExplain(int lhs, MatchResultListener* listener) const override {
|
bool MatchAndExplain(T lhs, MatchResultListener* listener) const override {
|
||||||
const int diff = lhs - rhs_;
|
if (lhs > rhs_) {
|
||||||
if (diff > 0) {
|
*listener << "which is " << (lhs - rhs_) << " more than " << rhs_;
|
||||||
*listener << "which is " << diff << " more than " << rhs_;
|
} else if (lhs == rhs_) {
|
||||||
} else if (diff == 0) {
|
|
||||||
*listener << "which is the same as " << rhs_;
|
*listener << "which is the same as " << rhs_;
|
||||||
} else {
|
} else {
|
||||||
*listener << "which is " << -diff << " less than " << rhs_;
|
*listener << "which is " << (rhs_ - lhs) << " less than " << rhs_;
|
||||||
}
|
}
|
||||||
|
|
||||||
return lhs > rhs_;
|
return lhs > rhs_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int rhs_;
|
const T rhs_;
|
||||||
};
|
};
|
||||||
|
|
||||||
Matcher<int> GreaterThan(int n) {
|
template <typename T>
|
||||||
return MakeMatcher(new GreaterThanMatcher(n));
|
Matcher<T> GreaterThan(T n) {
|
||||||
|
return MakeMatcher(new GreaterThanMatcher<T>(n));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string OfType(const std::string& type_name) {
|
std::string OfType(const std::string& type_name) {
|
||||||
@ -1865,6 +1866,33 @@ TEST(EndsWithTest, CanDescribeSelf) {
|
|||||||
EXPECT_EQ("ends with \"Hi\"", Describe(m));
|
EXPECT_EQ("ends with \"Hi\"", Describe(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests WhenBase64Unescaped.
|
||||||
|
|
||||||
|
TEST(WhenBase64UnescapedTest, MatchesUnescapedBase64Strings) {
|
||||||
|
const Matcher<const char*> m1 = WhenBase64Unescaped(EndsWith("!"));
|
||||||
|
EXPECT_FALSE(m1.Matches("invalid base64"));
|
||||||
|
EXPECT_FALSE(m1.Matches("aGVsbG8gd29ybGQ=")); // hello world
|
||||||
|
EXPECT_TRUE(m1.Matches("aGVsbG8gd29ybGQh")); // hello world!
|
||||||
|
|
||||||
|
const Matcher<const std::string&> m2 = WhenBase64Unescaped(EndsWith("!"));
|
||||||
|
EXPECT_FALSE(m2.Matches("invalid base64"));
|
||||||
|
EXPECT_FALSE(m2.Matches("aGVsbG8gd29ybGQ=")); // hello world
|
||||||
|
EXPECT_TRUE(m2.Matches("aGVsbG8gd29ybGQh")); // hello world!
|
||||||
|
|
||||||
|
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||||
|
const Matcher<const internal::StringView&> m3 =
|
||||||
|
WhenBase64Unescaped(EndsWith("!"));
|
||||||
|
EXPECT_FALSE(m3.Matches("invalid base64"));
|
||||||
|
EXPECT_FALSE(m3.Matches("aGVsbG8gd29ybGQ=")); // hello world
|
||||||
|
EXPECT_TRUE(m3.Matches("aGVsbG8gd29ybGQh")); // hello world!
|
||||||
|
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(WhenBase64UnescapedTest, CanDescribeSelf) {
|
||||||
|
const Matcher<const char*> m = WhenBase64Unescaped(EndsWith("!"));
|
||||||
|
EXPECT_EQ("matches after Base64Unescape ends with \"!\"", Describe(m));
|
||||||
|
}
|
||||||
|
|
||||||
// Tests MatchesRegex().
|
// Tests MatchesRegex().
|
||||||
|
|
||||||
TEST(MatchesRegexTest, MatchesStringMatchingGivenRegex) {
|
TEST(MatchesRegexTest, MatchesStringMatchingGivenRegex) {
|
||||||
@ -2771,6 +2799,34 @@ TEST(AnyOfTest, VariadicMatchesWhenAnyMatches) {
|
|||||||
"43", "44", "45", "46", "47", "48", "49", "50"));
|
"43", "44", "45", "46", "47", "48", "49", "50"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(ConditionalTest, MatchesFirstIfCondition) {
|
||||||
|
Matcher<std::string> eq_red = Eq("red");
|
||||||
|
Matcher<std::string> ne_red = Ne("red");
|
||||||
|
Matcher<std::string> m = Conditional(true, eq_red, ne_red);
|
||||||
|
EXPECT_TRUE(m.Matches("red"));
|
||||||
|
EXPECT_FALSE(m.Matches("green"));
|
||||||
|
|
||||||
|
StringMatchResultListener listener;
|
||||||
|
StringMatchResultListener expected;
|
||||||
|
EXPECT_FALSE(m.MatchAndExplain("green", &listener));
|
||||||
|
EXPECT_FALSE(eq_red.MatchAndExplain("green", &expected));
|
||||||
|
EXPECT_THAT(listener.str(), Eq(expected.str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ConditionalTest, MatchesSecondIfCondition) {
|
||||||
|
Matcher<std::string> eq_red = Eq("red");
|
||||||
|
Matcher<std::string> ne_red = Ne("red");
|
||||||
|
Matcher<std::string> m = Conditional(false, eq_red, ne_red);
|
||||||
|
EXPECT_FALSE(m.Matches("red"));
|
||||||
|
EXPECT_TRUE(m.Matches("green"));
|
||||||
|
|
||||||
|
StringMatchResultListener listener;
|
||||||
|
StringMatchResultListener expected;
|
||||||
|
EXPECT_FALSE(m.MatchAndExplain("red", &listener));
|
||||||
|
EXPECT_FALSE(ne_red.MatchAndExplain("red", &expected));
|
||||||
|
EXPECT_THAT(listener.str(), Eq(expected.str()));
|
||||||
|
}
|
||||||
|
|
||||||
// Tests the variadic version of the ElementsAreMatcher
|
// Tests the variadic version of the ElementsAreMatcher
|
||||||
TEST(ElementsAreTest, HugeMatcher) {
|
TEST(ElementsAreTest, HugeMatcher) {
|
||||||
vector<int> test_vector{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
vector<int> test_vector{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||||
@ -5368,12 +5424,14 @@ class Streamlike {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class ConstIter : public std::iterator<std::input_iterator_tag,
|
class ConstIter {
|
||||||
value_type,
|
|
||||||
ptrdiff_t,
|
|
||||||
const value_type*,
|
|
||||||
const value_type&> {
|
|
||||||
public:
|
public:
|
||||||
|
using iterator_category = std::input_iterator_tag;
|
||||||
|
using value_type = T;
|
||||||
|
using difference_type = ptrdiff_t;
|
||||||
|
using pointer = const value_type*;
|
||||||
|
using reference = const value_type&;
|
||||||
|
|
||||||
ConstIter(const Streamlike* s,
|
ConstIter(const Streamlike* s,
|
||||||
typename std::list<value_type>::iterator pos)
|
typename std::list<value_type>::iterator pos)
|
||||||
: s_(s), pos_(pos) {}
|
: s_(s), pos_(pos) {}
|
||||||
@ -6327,7 +6385,7 @@ TEST_P(BipartiteRandomTest, LargerNets) {
|
|||||||
int iters = GetParam().second;
|
int iters = GetParam().second;
|
||||||
MatchMatrix graph(static_cast<size_t>(nodes), static_cast<size_t>(nodes));
|
MatchMatrix graph(static_cast<size_t>(nodes), static_cast<size_t>(nodes));
|
||||||
|
|
||||||
auto seed = static_cast<uint32_t>(GTEST_FLAG(random_seed));
|
auto seed = static_cast<uint32_t>(GTEST_FLAG_GET(random_seed));
|
||||||
if (seed == 0) {
|
if (seed == 0) {
|
||||||
seed = static_cast<uint32_t>(time(nullptr));
|
seed = static_cast<uint32_t>(time(nullptr));
|
||||||
}
|
}
|
||||||
@ -7231,7 +7289,7 @@ TEST(ElementsAreTest, CanDescribeNegationOfExpectingNoElement) {
|
|||||||
EXPECT_EQ("isn't empty", DescribeNegation(m));
|
EXPECT_EQ("isn't empty", DescribeNegation(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ElementsAreTest, CanDescribeNegationOfExpectingOneElment) {
|
TEST(ElementsAreTest, CanDescribeNegationOfExpectingOneElement) {
|
||||||
Matcher<const list<int>&> m = ElementsAre(Gt(5));
|
Matcher<const list<int>&> m = ElementsAre(Gt(5));
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
"doesn't have 1 element, or\n"
|
"doesn't have 1 element, or\n"
|
||||||
@ -8023,6 +8081,7 @@ TEST(ContainsTest, ListMatchesWhenElementIsInContainer) {
|
|||||||
some_list.push_back(3);
|
some_list.push_back(3);
|
||||||
some_list.push_back(1);
|
some_list.push_back(1);
|
||||||
some_list.push_back(2);
|
some_list.push_back(2);
|
||||||
|
some_list.push_back(3);
|
||||||
EXPECT_THAT(some_list, Contains(1));
|
EXPECT_THAT(some_list, Contains(1));
|
||||||
EXPECT_THAT(some_list, Contains(Gt(2.5)));
|
EXPECT_THAT(some_list, Contains(Gt(2.5)));
|
||||||
EXPECT_THAT(some_list, Contains(Eq(2.0f)));
|
EXPECT_THAT(some_list, Contains(Eq(2.0f)));
|
||||||
@ -8147,6 +8206,79 @@ TEST(ContainsTest, WorksForTwoDimensionalNativeArray) {
|
|||||||
EXPECT_THAT(a, Contains(Not(Contains(5))));
|
EXPECT_THAT(a, Contains(Not(Contains(5))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests Contains().Times().
|
||||||
|
|
||||||
|
TEST(ContainsTimes, ListMatchesWhenElementQuantityMatches) {
|
||||||
|
list<int> some_list;
|
||||||
|
some_list.push_back(3);
|
||||||
|
some_list.push_back(1);
|
||||||
|
some_list.push_back(2);
|
||||||
|
some_list.push_back(3);
|
||||||
|
EXPECT_THAT(some_list, Contains(3).Times(2));
|
||||||
|
EXPECT_THAT(some_list, Contains(2).Times(1));
|
||||||
|
EXPECT_THAT(some_list, Contains(Ge(2)).Times(3));
|
||||||
|
EXPECT_THAT(some_list, Contains(Ge(2)).Times(Gt(2)));
|
||||||
|
EXPECT_THAT(some_list, Contains(4).Times(0));
|
||||||
|
EXPECT_THAT(some_list, Contains(_).Times(4));
|
||||||
|
EXPECT_THAT(some_list, Not(Contains(5).Times(1)));
|
||||||
|
EXPECT_THAT(some_list, Contains(5).Times(_)); // Times(_) always matches
|
||||||
|
EXPECT_THAT(some_list, Not(Contains(3).Times(1)));
|
||||||
|
EXPECT_THAT(some_list, Contains(3).Times(Not(1)));
|
||||||
|
EXPECT_THAT(list<int>{}, Not(Contains(_)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ContainsTimes, ExplainsMatchResultCorrectly) {
|
||||||
|
const int a[2] = {1, 2};
|
||||||
|
Matcher<const int(&)[2]> m = Contains(2).Times(3);
|
||||||
|
EXPECT_EQ(
|
||||||
|
"whose element #1 matches but whose match quantity of 1 does not match",
|
||||||
|
Explain(m, a));
|
||||||
|
|
||||||
|
m = Contains(3).Times(0);
|
||||||
|
EXPECT_EQ("has no element that matches and whose match quantity of 0 matches",
|
||||||
|
Explain(m, a));
|
||||||
|
|
||||||
|
m = Contains(3).Times(4);
|
||||||
|
EXPECT_EQ(
|
||||||
|
"has no element that matches and whose match quantity of 0 does not "
|
||||||
|
"match",
|
||||||
|
Explain(m, a));
|
||||||
|
|
||||||
|
m = Contains(2).Times(4);
|
||||||
|
EXPECT_EQ(
|
||||||
|
"whose element #1 matches but whose match quantity of 1 does not "
|
||||||
|
"match",
|
||||||
|
Explain(m, a));
|
||||||
|
|
||||||
|
m = Contains(GreaterThan(0)).Times(2);
|
||||||
|
EXPECT_EQ("whose elements (0, 1) match and whose match quantity of 2 matches",
|
||||||
|
Explain(m, a));
|
||||||
|
|
||||||
|
m = Contains(GreaterThan(10)).Times(Gt(1));
|
||||||
|
EXPECT_EQ(
|
||||||
|
"has no element that matches and whose match quantity of 0 does not "
|
||||||
|
"match",
|
||||||
|
Explain(m, a));
|
||||||
|
|
||||||
|
m = Contains(GreaterThan(0)).Times(GreaterThan<size_t>(5));
|
||||||
|
EXPECT_EQ(
|
||||||
|
"whose elements (0, 1) match but whose match quantity of 2 does not "
|
||||||
|
"match, which is 3 less than 5",
|
||||||
|
Explain(m, a));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ContainsTimes, DescribesItselfCorrectly) {
|
||||||
|
Matcher<vector<int>> m = Contains(1).Times(2);
|
||||||
|
EXPECT_EQ("quantity of elements that match is equal to 1 is equal to 2",
|
||||||
|
Describe(m));
|
||||||
|
|
||||||
|
Matcher<vector<int>> m2 = Not(m);
|
||||||
|
EXPECT_EQ("quantity of elements that match is equal to 1 isn't equal to 2",
|
||||||
|
Describe(m2));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests AllOfArray()
|
||||||
|
|
||||||
TEST(AllOfArrayTest, BasicForms) {
|
TEST(AllOfArrayTest, BasicForms) {
|
||||||
// Iterator
|
// Iterator
|
||||||
std::vector<int> v0{};
|
std::vector<int> v0{};
|
||||||
@ -8275,7 +8407,7 @@ TEST(AnyOfArrayTest, ExplainsMatchResultCorrectly) {
|
|||||||
// Explain with matchers
|
// Explain with matchers
|
||||||
const Matcher<int> g1 = AnyOfArray({GreaterThan(1)});
|
const Matcher<int> g1 = AnyOfArray({GreaterThan(1)});
|
||||||
const Matcher<int> g2 = AnyOfArray({GreaterThan(1), GreaterThan(2)});
|
const Matcher<int> g2 = AnyOfArray({GreaterThan(1), GreaterThan(2)});
|
||||||
// Explains the first positiv match and all prior negative matches...
|
// Explains the first positive match and all prior negative matches...
|
||||||
EXPECT_EQ("which is 1 less than 1", Explain(g1, 0));
|
EXPECT_EQ("which is 1 less than 1", Explain(g1, 0));
|
||||||
EXPECT_EQ("which is the same as 1", Explain(g1, 1));
|
EXPECT_EQ("which is the same as 1", Explain(g1, 1));
|
||||||
EXPECT_EQ("which is 1 more than 1", Explain(g1, 2));
|
EXPECT_EQ("which is 1 more than 1", Explain(g1, 2));
|
||||||
@ -8385,6 +8517,12 @@ TEST(ThrowsTest, Examples) {
|
|||||||
ThrowsMessage<std::runtime_error>(HasSubstr("message")));
|
ThrowsMessage<std::runtime_error>(HasSubstr("message")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(ThrowsTest, PrintsExceptionWhat) {
|
||||||
|
EXPECT_THAT(
|
||||||
|
std::function<void()>([]() { throw std::runtime_error("ABC123XYZ"); }),
|
||||||
|
ThrowsMessage<std::runtime_error>(HasSubstr("ABC123XYZ")));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(ThrowsTest, DoesNotGenerateDuplicateCatchClauseWarning) {
|
TEST(ThrowsTest, DoesNotGenerateDuplicateCatchClauseWarning) {
|
||||||
EXPECT_THAT(std::function<void()>([]() { throw std::exception(); }),
|
EXPECT_THAT(std::function<void()>([]() { throw std::exception(); }),
|
||||||
Throws<std::exception>());
|
Throws<std::exception>());
|
||||||
@ -8500,15 +8638,6 @@ TEST_P(ThrowsPredicateTest, FailWrongTypeNonStd) {
|
|||||||
HasSubstr("throws an exception of an unknown type"));
|
HasSubstr("throws an exception of an unknown type"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(ThrowsPredicateTest, FailWrongMessage) {
|
|
||||||
Matcher<std::function<void()>> matcher = GetParam();
|
|
||||||
StringMatchResultListener listener;
|
|
||||||
EXPECT_FALSE(matcher.MatchAndExplain(
|
|
||||||
[]() { throw std::runtime_error("wrong message"); }, &listener));
|
|
||||||
EXPECT_THAT(listener.str(), HasSubstr("std::runtime_error"));
|
|
||||||
EXPECT_THAT(listener.str(), Not(HasSubstr("wrong message")));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(ThrowsPredicateTest, FailNoThrow) {
|
TEST_P(ThrowsPredicateTest, FailNoThrow) {
|
||||||
Matcher<std::function<void()>> matcher = GetParam();
|
Matcher<std::function<void()>> matcher = GetParam();
|
||||||
StringMatchResultListener listener;
|
StringMatchResultListener listener;
|
||||||
|
@ -50,7 +50,6 @@ class Mock {
|
|||||||
namespace testing {
|
namespace testing {
|
||||||
namespace gmock_nice_strict_test {
|
namespace gmock_nice_strict_test {
|
||||||
|
|
||||||
using testing::GMOCK_FLAG(verbose);
|
|
||||||
using testing::HasSubstr;
|
using testing::HasSubstr;
|
||||||
using testing::NaggyMock;
|
using testing::NaggyMock;
|
||||||
using testing::NiceMock;
|
using testing::NiceMock;
|
||||||
@ -140,8 +139,8 @@ class MockBaz {
|
|||||||
|
|
||||||
// Tests that a raw mock generates warnings for uninteresting calls.
|
// Tests that a raw mock generates warnings for uninteresting calls.
|
||||||
TEST(RawMockTest, WarningForUninterestingCall) {
|
TEST(RawMockTest, WarningForUninterestingCall) {
|
||||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||||
GMOCK_FLAG(verbose) = "warning";
|
GMOCK_FLAG_SET(verbose, "warning");
|
||||||
|
|
||||||
MockFoo raw_foo;
|
MockFoo raw_foo;
|
||||||
|
|
||||||
@ -151,14 +150,14 @@ TEST(RawMockTest, WarningForUninterestingCall) {
|
|||||||
EXPECT_THAT(GetCapturedStdout(),
|
EXPECT_THAT(GetCapturedStdout(),
|
||||||
HasSubstr("Uninteresting mock function call"));
|
HasSubstr("Uninteresting mock function call"));
|
||||||
|
|
||||||
GMOCK_FLAG(verbose) = saved_flag;
|
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that a raw mock generates warnings for uninteresting calls
|
// Tests that a raw mock generates warnings for uninteresting calls
|
||||||
// that delete the mock object.
|
// that delete the mock object.
|
||||||
TEST(RawMockTest, WarningForUninterestingCallAfterDeath) {
|
TEST(RawMockTest, WarningForUninterestingCallAfterDeath) {
|
||||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||||
GMOCK_FLAG(verbose) = "warning";
|
GMOCK_FLAG_SET(verbose, "warning");
|
||||||
|
|
||||||
MockFoo* const raw_foo = new MockFoo;
|
MockFoo* const raw_foo = new MockFoo;
|
||||||
|
|
||||||
@ -170,7 +169,7 @@ TEST(RawMockTest, WarningForUninterestingCallAfterDeath) {
|
|||||||
EXPECT_THAT(GetCapturedStdout(),
|
EXPECT_THAT(GetCapturedStdout(),
|
||||||
HasSubstr("Uninteresting mock function call"));
|
HasSubstr("Uninteresting mock function call"));
|
||||||
|
|
||||||
GMOCK_FLAG(verbose) = saved_flag;
|
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that a raw mock generates informational logs for
|
// Tests that a raw mock generates informational logs for
|
||||||
@ -178,14 +177,14 @@ TEST(RawMockTest, WarningForUninterestingCallAfterDeath) {
|
|||||||
TEST(RawMockTest, InfoForUninterestingCall) {
|
TEST(RawMockTest, InfoForUninterestingCall) {
|
||||||
MockFoo raw_foo;
|
MockFoo raw_foo;
|
||||||
|
|
||||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||||
GMOCK_FLAG(verbose) = "info";
|
GMOCK_FLAG_SET(verbose, "info");
|
||||||
CaptureStdout();
|
CaptureStdout();
|
||||||
raw_foo.DoThis();
|
raw_foo.DoThis();
|
||||||
EXPECT_THAT(GetCapturedStdout(),
|
EXPECT_THAT(GetCapturedStdout(),
|
||||||
HasSubstr("Uninteresting mock function call"));
|
HasSubstr("Uninteresting mock function call"));
|
||||||
|
|
||||||
GMOCK_FLAG(verbose) = saved_flag;
|
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(RawMockTest, IsNaggy_IsNice_IsStrict) {
|
TEST(RawMockTest, IsNaggy_IsNice_IsStrict) {
|
||||||
@ -223,14 +222,14 @@ TEST(NiceMockTest, NoWarningForUninterestingCallAfterDeath) {
|
|||||||
TEST(NiceMockTest, InfoForUninterestingCall) {
|
TEST(NiceMockTest, InfoForUninterestingCall) {
|
||||||
NiceMock<MockFoo> nice_foo;
|
NiceMock<MockFoo> nice_foo;
|
||||||
|
|
||||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||||
GMOCK_FLAG(verbose) = "info";
|
GMOCK_FLAG_SET(verbose, "info");
|
||||||
CaptureStdout();
|
CaptureStdout();
|
||||||
nice_foo.DoThis();
|
nice_foo.DoThis();
|
||||||
EXPECT_THAT(GetCapturedStdout(),
|
EXPECT_THAT(GetCapturedStdout(),
|
||||||
HasSubstr("Uninteresting mock function call"));
|
HasSubstr("Uninteresting mock function call"));
|
||||||
|
|
||||||
GMOCK_FLAG(verbose) = saved_flag;
|
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // GTEST_HAS_STREAM_REDIRECTION
|
#endif // GTEST_HAS_STREAM_REDIRECTION
|
||||||
@ -326,8 +325,8 @@ TEST(NiceMockTest, IsNaggy_IsNice_IsStrict) {
|
|||||||
|
|
||||||
// Tests that a naggy mock generates warnings for uninteresting calls.
|
// Tests that a naggy mock generates warnings for uninteresting calls.
|
||||||
TEST(NaggyMockTest, WarningForUninterestingCall) {
|
TEST(NaggyMockTest, WarningForUninterestingCall) {
|
||||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||||
GMOCK_FLAG(verbose) = "warning";
|
GMOCK_FLAG_SET(verbose, "warning");
|
||||||
|
|
||||||
NaggyMock<MockFoo> naggy_foo;
|
NaggyMock<MockFoo> naggy_foo;
|
||||||
|
|
||||||
@ -337,14 +336,14 @@ TEST(NaggyMockTest, WarningForUninterestingCall) {
|
|||||||
EXPECT_THAT(GetCapturedStdout(),
|
EXPECT_THAT(GetCapturedStdout(),
|
||||||
HasSubstr("Uninteresting mock function call"));
|
HasSubstr("Uninteresting mock function call"));
|
||||||
|
|
||||||
GMOCK_FLAG(verbose) = saved_flag;
|
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that a naggy mock generates a warning for an uninteresting call
|
// Tests that a naggy mock generates a warning for an uninteresting call
|
||||||
// that deletes the mock object.
|
// that deletes the mock object.
|
||||||
TEST(NaggyMockTest, WarningForUninterestingCallAfterDeath) {
|
TEST(NaggyMockTest, WarningForUninterestingCallAfterDeath) {
|
||||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||||
GMOCK_FLAG(verbose) = "warning";
|
GMOCK_FLAG_SET(verbose, "warning");
|
||||||
|
|
||||||
NaggyMock<MockFoo>* const naggy_foo = new NaggyMock<MockFoo>;
|
NaggyMock<MockFoo>* const naggy_foo = new NaggyMock<MockFoo>;
|
||||||
|
|
||||||
@ -356,7 +355,7 @@ TEST(NaggyMockTest, WarningForUninterestingCallAfterDeath) {
|
|||||||
EXPECT_THAT(GetCapturedStdout(),
|
EXPECT_THAT(GetCapturedStdout(),
|
||||||
HasSubstr("Uninteresting mock function call"));
|
HasSubstr("Uninteresting mock function call"));
|
||||||
|
|
||||||
GMOCK_FLAG(verbose) = saved_flag;
|
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // GTEST_HAS_STREAM_REDIRECTION
|
#endif // GTEST_HAS_STREAM_REDIRECTION
|
||||||
@ -419,8 +418,8 @@ TEST(NaggyMockTest, AcceptsClassNamedMock) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(NaggyMockTest, IsNaggyInDestructor) {
|
TEST(NaggyMockTest, IsNaggyInDestructor) {
|
||||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||||
GMOCK_FLAG(verbose) = "warning";
|
GMOCK_FLAG_SET(verbose, "warning");
|
||||||
CaptureStdout();
|
CaptureStdout();
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -431,7 +430,7 @@ TEST(NaggyMockTest, IsNaggyInDestructor) {
|
|||||||
EXPECT_THAT(GetCapturedStdout(),
|
EXPECT_THAT(GetCapturedStdout(),
|
||||||
HasSubstr("Uninteresting mock function call"));
|
HasSubstr("Uninteresting mock function call"));
|
||||||
|
|
||||||
GMOCK_FLAG(verbose) = saved_flag;
|
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(NaggyMockTest, IsNaggy_IsNice_IsStrict) {
|
TEST(NaggyMockTest, IsNaggy_IsNice_IsStrict) {
|
||||||
|
@ -76,7 +76,6 @@ using testing::DoDefault;
|
|||||||
using testing::Eq;
|
using testing::Eq;
|
||||||
using testing::Expectation;
|
using testing::Expectation;
|
||||||
using testing::ExpectationSet;
|
using testing::ExpectationSet;
|
||||||
using testing::GMOCK_FLAG(verbose);
|
|
||||||
using testing::Gt;
|
using testing::Gt;
|
||||||
using testing::IgnoreResult;
|
using testing::IgnoreResult;
|
||||||
using testing::InSequence;
|
using testing::InSequence;
|
||||||
@ -391,7 +390,7 @@ TEST(ExpectCallSyntaxTest, TimesMustBeBeforeInSequence) {
|
|||||||
EXPECT_CALL(a, DoA(1))
|
EXPECT_CALL(a, DoA(1))
|
||||||
.InSequence(s)
|
.InSequence(s)
|
||||||
.Times(1);
|
.Times(1);
|
||||||
}, ".Times() cannot appear after ");
|
}, ".Times() may only appear *before* ");
|
||||||
|
|
||||||
a.DoA(1);
|
a.DoA(1);
|
||||||
}
|
}
|
||||||
@ -696,9 +695,9 @@ TEST(ExpectCallSyntaxTest, WarnsOnTooFewActions) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
|
TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
|
||||||
int original_behavior = testing::GMOCK_FLAG(default_mock_behavior);
|
int original_behavior = GMOCK_FLAG_GET(default_mock_behavior);
|
||||||
|
|
||||||
testing::GMOCK_FLAG(default_mock_behavior) = kAllow;
|
GMOCK_FLAG_SET(default_mock_behavior, kAllow);
|
||||||
CaptureStdout();
|
CaptureStdout();
|
||||||
{
|
{
|
||||||
MockA a;
|
MockA a;
|
||||||
@ -707,7 +706,7 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
|
|||||||
std::string output = GetCapturedStdout();
|
std::string output = GetCapturedStdout();
|
||||||
EXPECT_TRUE(output.empty()) << output;
|
EXPECT_TRUE(output.empty()) << output;
|
||||||
|
|
||||||
testing::GMOCK_FLAG(default_mock_behavior) = kWarn;
|
GMOCK_FLAG_SET(default_mock_behavior, kWarn);
|
||||||
CaptureStdout();
|
CaptureStdout();
|
||||||
{
|
{
|
||||||
MockA a;
|
MockA a;
|
||||||
@ -718,14 +717,14 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
|
|||||||
EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call",
|
EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call",
|
||||||
warning_output);
|
warning_output);
|
||||||
|
|
||||||
testing::GMOCK_FLAG(default_mock_behavior) = kFail;
|
GMOCK_FLAG_SET(default_mock_behavior, kFail);
|
||||||
EXPECT_NONFATAL_FAILURE({
|
EXPECT_NONFATAL_FAILURE({
|
||||||
MockA a;
|
MockA a;
|
||||||
a.DoA(0);
|
a.DoA(0);
|
||||||
}, "Uninteresting mock function call");
|
}, "Uninteresting mock function call");
|
||||||
|
|
||||||
// Out of bounds values are converted to kWarn
|
// Out of bounds values are converted to kWarn
|
||||||
testing::GMOCK_FLAG(default_mock_behavior) = -1;
|
GMOCK_FLAG_SET(default_mock_behavior, -1);
|
||||||
CaptureStdout();
|
CaptureStdout();
|
||||||
{
|
{
|
||||||
MockA a;
|
MockA a;
|
||||||
@ -735,7 +734,7 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
|
|||||||
EXPECT_PRED_FORMAT2(IsSubstring, "GMOCK WARNING", warning_output);
|
EXPECT_PRED_FORMAT2(IsSubstring, "GMOCK WARNING", warning_output);
|
||||||
EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call",
|
EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call",
|
||||||
warning_output);
|
warning_output);
|
||||||
testing::GMOCK_FLAG(default_mock_behavior) = 3;
|
GMOCK_FLAG_SET(default_mock_behavior, 3);
|
||||||
CaptureStdout();
|
CaptureStdout();
|
||||||
{
|
{
|
||||||
MockA a;
|
MockA a;
|
||||||
@ -746,7 +745,7 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
|
|||||||
EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call",
|
EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call",
|
||||||
warning_output);
|
warning_output);
|
||||||
|
|
||||||
testing::GMOCK_FLAG(default_mock_behavior) = original_behavior;
|
GMOCK_FLAG_SET(default_mock_behavior, original_behavior);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // GTEST_HAS_STREAM_REDIRECTION
|
#endif // GTEST_HAS_STREAM_REDIRECTION
|
||||||
@ -2024,10 +2023,10 @@ class MockC {
|
|||||||
class VerboseFlagPreservingFixture : public testing::Test {
|
class VerboseFlagPreservingFixture : public testing::Test {
|
||||||
protected:
|
protected:
|
||||||
VerboseFlagPreservingFixture()
|
VerboseFlagPreservingFixture()
|
||||||
: saved_verbose_flag_(GMOCK_FLAG(verbose)) {}
|
: saved_verbose_flag_(GMOCK_FLAG_GET(verbose)) {}
|
||||||
|
|
||||||
~VerboseFlagPreservingFixture() override {
|
~VerboseFlagPreservingFixture() override {
|
||||||
GMOCK_FLAG(verbose) = saved_verbose_flag_;
|
GMOCK_FLAG_SET(verbose, saved_verbose_flag_);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -2043,7 +2042,7 @@ class VerboseFlagPreservingFixture : public testing::Test {
|
|||||||
// --gmock_verbose=warning is specified.
|
// --gmock_verbose=warning is specified.
|
||||||
TEST(FunctionCallMessageTest,
|
TEST(FunctionCallMessageTest,
|
||||||
UninterestingCallOnNaggyMockGeneratesNoStackTraceWhenVerboseWarning) {
|
UninterestingCallOnNaggyMockGeneratesNoStackTraceWhenVerboseWarning) {
|
||||||
GMOCK_FLAG(verbose) = kWarningVerbosity;
|
GMOCK_FLAG_SET(verbose, kWarningVerbosity);
|
||||||
NaggyMock<MockC> c;
|
NaggyMock<MockC> c;
|
||||||
CaptureStdout();
|
CaptureStdout();
|
||||||
c.VoidMethod(false, 5, "Hi", nullptr, Printable(), Unprintable());
|
c.VoidMethod(false, 5, "Hi", nullptr, Printable(), Unprintable());
|
||||||
@ -2057,7 +2056,7 @@ TEST(FunctionCallMessageTest,
|
|||||||
// --gmock_verbose=info is specified.
|
// --gmock_verbose=info is specified.
|
||||||
TEST(FunctionCallMessageTest,
|
TEST(FunctionCallMessageTest,
|
||||||
UninterestingCallOnNaggyMockGeneratesFyiWithStackTraceWhenVerboseInfo) {
|
UninterestingCallOnNaggyMockGeneratesFyiWithStackTraceWhenVerboseInfo) {
|
||||||
GMOCK_FLAG(verbose) = kInfoVerbosity;
|
GMOCK_FLAG_SET(verbose, kInfoVerbosity);
|
||||||
NaggyMock<MockC> c;
|
NaggyMock<MockC> c;
|
||||||
CaptureStdout();
|
CaptureStdout();
|
||||||
c.VoidMethod(false, 5, "Hi", nullptr, Printable(), Unprintable());
|
c.VoidMethod(false, 5, "Hi", nullptr, Printable(), Unprintable());
|
||||||
@ -2213,7 +2212,7 @@ class GMockVerboseFlagTest : public VerboseFlagPreservingFixture {
|
|||||||
// Tests that --gmock_verbose=info causes both expected and
|
// Tests that --gmock_verbose=info causes both expected and
|
||||||
// uninteresting calls to be reported.
|
// uninteresting calls to be reported.
|
||||||
TEST_F(GMockVerboseFlagTest, Info) {
|
TEST_F(GMockVerboseFlagTest, Info) {
|
||||||
GMOCK_FLAG(verbose) = kInfoVerbosity;
|
GMOCK_FLAG_SET(verbose, kInfoVerbosity);
|
||||||
TestExpectedCall(true);
|
TestExpectedCall(true);
|
||||||
TestUninterestingCallOnNaggyMock(true);
|
TestUninterestingCallOnNaggyMock(true);
|
||||||
}
|
}
|
||||||
@ -2221,7 +2220,7 @@ TEST_F(GMockVerboseFlagTest, Info) {
|
|||||||
// Tests that --gmock_verbose=warning causes uninteresting calls to be
|
// Tests that --gmock_verbose=warning causes uninteresting calls to be
|
||||||
// reported.
|
// reported.
|
||||||
TEST_F(GMockVerboseFlagTest, Warning) {
|
TEST_F(GMockVerboseFlagTest, Warning) {
|
||||||
GMOCK_FLAG(verbose) = kWarningVerbosity;
|
GMOCK_FLAG_SET(verbose, kWarningVerbosity);
|
||||||
TestExpectedCall(false);
|
TestExpectedCall(false);
|
||||||
TestUninterestingCallOnNaggyMock(true);
|
TestUninterestingCallOnNaggyMock(true);
|
||||||
}
|
}
|
||||||
@ -2229,7 +2228,7 @@ TEST_F(GMockVerboseFlagTest, Warning) {
|
|||||||
// Tests that --gmock_verbose=warning causes neither expected nor
|
// Tests that --gmock_verbose=warning causes neither expected nor
|
||||||
// uninteresting calls to be reported.
|
// uninteresting calls to be reported.
|
||||||
TEST_F(GMockVerboseFlagTest, Error) {
|
TEST_F(GMockVerboseFlagTest, Error) {
|
||||||
GMOCK_FLAG(verbose) = kErrorVerbosity;
|
GMOCK_FLAG_SET(verbose, kErrorVerbosity);
|
||||||
TestExpectedCall(false);
|
TestExpectedCall(false);
|
||||||
TestUninterestingCallOnNaggyMock(false);
|
TestUninterestingCallOnNaggyMock(false);
|
||||||
}
|
}
|
||||||
@ -2237,7 +2236,7 @@ TEST_F(GMockVerboseFlagTest, Error) {
|
|||||||
// Tests that --gmock_verbose=SOME_INVALID_VALUE has the same effect
|
// Tests that --gmock_verbose=SOME_INVALID_VALUE has the same effect
|
||||||
// as --gmock_verbose=warning.
|
// as --gmock_verbose=warning.
|
||||||
TEST_F(GMockVerboseFlagTest, InvalidFlagIsTreatedAsWarning) {
|
TEST_F(GMockVerboseFlagTest, InvalidFlagIsTreatedAsWarning) {
|
||||||
GMOCK_FLAG(verbose) = "invalid"; // Treated as "warning".
|
GMOCK_FLAG_SET(verbose, "invalid"); // Treated as "warning".
|
||||||
TestExpectedCall(false);
|
TestExpectedCall(false);
|
||||||
TestUninterestingCallOnNaggyMock(true);
|
TestUninterestingCallOnNaggyMock(true);
|
||||||
}
|
}
|
||||||
@ -2270,21 +2269,21 @@ class GMockLogTest : public VerboseFlagPreservingFixture {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(GMockLogTest, DoesNotPrintGoodCallInternallyIfVerbosityIsWarning) {
|
TEST_F(GMockLogTest, DoesNotPrintGoodCallInternallyIfVerbosityIsWarning) {
|
||||||
GMOCK_FLAG(verbose) = kWarningVerbosity;
|
GMOCK_FLAG_SET(verbose, kWarningVerbosity);
|
||||||
EXPECT_CALL(helper_, Foo(_))
|
EXPECT_CALL(helper_, Foo(_))
|
||||||
.WillOnce(Return(PrintMeNot()));
|
.WillOnce(Return(PrintMeNot()));
|
||||||
helper_.Foo(PrintMeNot()); // This is an expected call.
|
helper_.Foo(PrintMeNot()); // This is an expected call.
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GMockLogTest, DoesNotPrintGoodCallInternallyIfVerbosityIsError) {
|
TEST_F(GMockLogTest, DoesNotPrintGoodCallInternallyIfVerbosityIsError) {
|
||||||
GMOCK_FLAG(verbose) = kErrorVerbosity;
|
GMOCK_FLAG_SET(verbose, kErrorVerbosity);
|
||||||
EXPECT_CALL(helper_, Foo(_))
|
EXPECT_CALL(helper_, Foo(_))
|
||||||
.WillOnce(Return(PrintMeNot()));
|
.WillOnce(Return(PrintMeNot()));
|
||||||
helper_.Foo(PrintMeNot()); // This is an expected call.
|
helper_.Foo(PrintMeNot()); // This is an expected call.
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GMockLogTest, DoesNotPrintWarningInternallyIfVerbosityIsError) {
|
TEST_F(GMockLogTest, DoesNotPrintWarningInternallyIfVerbosityIsError) {
|
||||||
GMOCK_FLAG(verbose) = kErrorVerbosity;
|
GMOCK_FLAG_SET(verbose, kErrorVerbosity);
|
||||||
ON_CALL(helper_, Foo(_))
|
ON_CALL(helper_, Foo(_))
|
||||||
.WillByDefault(Return(PrintMeNot()));
|
.WillByDefault(Return(PrintMeNot()));
|
||||||
helper_.Foo(PrintMeNot()); // This should generate a warning.
|
helper_.Foo(PrintMeNot()); // This should generate a warning.
|
||||||
@ -2768,8 +2767,8 @@ int main(int argc, char **argv) {
|
|||||||
testing::InitGoogleMock(&argc, argv);
|
testing::InitGoogleMock(&argc, argv);
|
||||||
// Ensures that the tests pass no matter what value of
|
// Ensures that the tests pass no matter what value of
|
||||||
// --gmock_catch_leaked_mocks and --gmock_verbose the user specifies.
|
// --gmock_catch_leaked_mocks and --gmock_verbose the user specifies.
|
||||||
testing::GMOCK_FLAG(catch_leaked_mocks) = true;
|
GMOCK_FLAG_SET(catch_leaked_mocks, true);
|
||||||
testing::GMOCK_FLAG(verbose) = testing::internal::kWarningVerbosity;
|
GMOCK_FLAG_SET(verbose, testing::internal::kWarningVerbosity);
|
||||||
|
|
||||||
return RUN_ALL_TESTS();
|
return RUN_ALL_TESTS();
|
||||||
}
|
}
|
||||||
|
@ -72,21 +72,21 @@ class GMockOutputTest : public testing::Test {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(GMockOutputTest, ExpectedCall) {
|
TEST_F(GMockOutputTest, ExpectedCall) {
|
||||||
testing::GMOCK_FLAG(verbose) = "info";
|
GMOCK_FLAG_SET(verbose, "info");
|
||||||
|
|
||||||
EXPECT_CALL(foo_, Bar2(0, _));
|
EXPECT_CALL(foo_, Bar2(0, _));
|
||||||
foo_.Bar2(0, 0); // Expected call
|
foo_.Bar2(0, 0); // Expected call
|
||||||
|
|
||||||
testing::GMOCK_FLAG(verbose) = "warning";
|
GMOCK_FLAG_SET(verbose, "warning");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GMockOutputTest, ExpectedCallToVoidFunction) {
|
TEST_F(GMockOutputTest, ExpectedCallToVoidFunction) {
|
||||||
testing::GMOCK_FLAG(verbose) = "info";
|
GMOCK_FLAG_SET(verbose, "info");
|
||||||
|
|
||||||
EXPECT_CALL(foo_, Bar3(0, _));
|
EXPECT_CALL(foo_, Bar3(0, _));
|
||||||
foo_.Bar3(0, 0); // Expected call
|
foo_.Bar3(0, 0); // Expected call
|
||||||
|
|
||||||
testing::GMOCK_FLAG(verbose) = "warning";
|
GMOCK_FLAG_SET(verbose, "warning");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GMockOutputTest, ExplicitActionsRunOut) {
|
TEST_F(GMockOutputTest, ExplicitActionsRunOut) {
|
||||||
@ -297,8 +297,8 @@ int main(int argc, char **argv) {
|
|||||||
testing::InitGoogleMock(&argc, argv);
|
testing::InitGoogleMock(&argc, argv);
|
||||||
// Ensures that the tests pass no matter what value of
|
// Ensures that the tests pass no matter what value of
|
||||||
// --gmock_catch_leaked_mocks and --gmock_verbose the user specifies.
|
// --gmock_catch_leaked_mocks and --gmock_verbose the user specifies.
|
||||||
testing::GMOCK_FLAG(catch_leaked_mocks) = true;
|
GMOCK_FLAG_SET(catch_leaked_mocks, true);
|
||||||
testing::GMOCK_FLAG(verbose) = "warning";
|
GMOCK_FLAG_SET(verbose, "warning");
|
||||||
|
|
||||||
TestCatchesLeakedMocksInAdHocTests();
|
TestCatchesLeakedMocksInAdHocTests();
|
||||||
return RUN_ALL_TESTS();
|
return RUN_ALL_TESTS();
|
||||||
|
@ -40,8 +40,6 @@
|
|||||||
|
|
||||||
#if !defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
#if !defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
||||||
|
|
||||||
using testing::GMOCK_FLAG(default_mock_behavior);
|
|
||||||
using testing::GMOCK_FLAG(verbose);
|
|
||||||
using testing::InitGoogleMock;
|
using testing::InitGoogleMock;
|
||||||
|
|
||||||
// Verifies that calling InitGoogleMock() on argv results in new_argv,
|
// Verifies that calling InitGoogleMock() on argv results in new_argv,
|
||||||
@ -49,7 +47,7 @@ using testing::InitGoogleMock;
|
|||||||
template <typename Char, int M, int N>
|
template <typename Char, int M, int N>
|
||||||
void TestInitGoogleMock(const Char* (&argv)[M], const Char* (&new_argv)[N],
|
void TestInitGoogleMock(const Char* (&argv)[M], const Char* (&new_argv)[N],
|
||||||
const ::std::string& expected_gmock_verbose) {
|
const ::std::string& expected_gmock_verbose) {
|
||||||
const ::std::string old_verbose = GMOCK_FLAG(verbose);
|
const ::std::string old_verbose = GMOCK_FLAG_GET(verbose);
|
||||||
|
|
||||||
int argc = M - 1;
|
int argc = M - 1;
|
||||||
InitGoogleMock(&argc, const_cast<Char**>(argv));
|
InitGoogleMock(&argc, const_cast<Char**>(argv));
|
||||||
@ -59,8 +57,8 @@ void TestInitGoogleMock(const Char* (&argv)[M], const Char* (&new_argv)[N],
|
|||||||
EXPECT_STREQ(new_argv[i], argv[i]);
|
EXPECT_STREQ(new_argv[i], argv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPECT_EQ(expected_gmock_verbose, GMOCK_FLAG(verbose).c_str());
|
EXPECT_EQ(expected_gmock_verbose, GMOCK_FLAG_GET(verbose));
|
||||||
GMOCK_FLAG(verbose) = old_verbose; // Restores the gmock_verbose flag.
|
GMOCK_FLAG_SET(verbose, old_verbose); // Restores the gmock_verbose flag.
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(InitGoogleMockTest, ParsesInvalidCommandLine) {
|
TEST(InitGoogleMockTest, ParsesInvalidCommandLine) {
|
||||||
@ -68,7 +66,7 @@ TEST(InitGoogleMockTest, ParsesInvalidCommandLine) {
|
|||||||
|
|
||||||
const char* new_argv[] = {nullptr};
|
const char* new_argv[] = {nullptr};
|
||||||
|
|
||||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG_GET(verbose));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(InitGoogleMockTest, ParsesEmptyCommandLine) {
|
TEST(InitGoogleMockTest, ParsesEmptyCommandLine) {
|
||||||
@ -76,7 +74,7 @@ TEST(InitGoogleMockTest, ParsesEmptyCommandLine) {
|
|||||||
|
|
||||||
const char* new_argv[] = {"foo.exe", nullptr};
|
const char* new_argv[] = {"foo.exe", nullptr};
|
||||||
|
|
||||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG_GET(verbose));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(InitGoogleMockTest, ParsesSingleFlag) {
|
TEST(InitGoogleMockTest, ParsesSingleFlag) {
|
||||||
@ -88,16 +86,16 @@ TEST(InitGoogleMockTest, ParsesSingleFlag) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(InitGoogleMockTest, ParsesMultipleFlags) {
|
TEST(InitGoogleMockTest, ParsesMultipleFlags) {
|
||||||
int old_default_behavior = GMOCK_FLAG(default_mock_behavior);
|
int old_default_behavior = GMOCK_FLAG_GET(default_mock_behavior);
|
||||||
const wchar_t* argv[] = {L"foo.exe", L"--gmock_verbose=info",
|
const wchar_t* argv[] = {L"foo.exe", L"--gmock_verbose=info",
|
||||||
L"--gmock_default_mock_behavior=2", nullptr};
|
L"--gmock_default_mock_behavior=2", nullptr};
|
||||||
|
|
||||||
const wchar_t* new_argv[] = {L"foo.exe", nullptr};
|
const wchar_t* new_argv[] = {L"foo.exe", nullptr};
|
||||||
|
|
||||||
TestInitGoogleMock(argv, new_argv, "info");
|
TestInitGoogleMock(argv, new_argv, "info");
|
||||||
EXPECT_EQ(2, GMOCK_FLAG(default_mock_behavior));
|
EXPECT_EQ(2, GMOCK_FLAG_GET(default_mock_behavior));
|
||||||
EXPECT_NE(2, old_default_behavior);
|
EXPECT_NE(2, old_default_behavior);
|
||||||
GMOCK_FLAG(default_mock_behavior) = old_default_behavior;
|
GMOCK_FLAG_SET(default_mock_behavior, old_default_behavior);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(InitGoogleMockTest, ParsesUnrecognizedFlag) {
|
TEST(InitGoogleMockTest, ParsesUnrecognizedFlag) {
|
||||||
@ -105,7 +103,7 @@ TEST(InitGoogleMockTest, ParsesUnrecognizedFlag) {
|
|||||||
|
|
||||||
const char* new_argv[] = {"foo.exe", "--non_gmock_flag=blah", nullptr};
|
const char* new_argv[] = {"foo.exe", "--non_gmock_flag=blah", nullptr};
|
||||||
|
|
||||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG_GET(verbose));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(InitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
|
TEST(InitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
|
||||||
@ -122,7 +120,7 @@ TEST(WideInitGoogleMockTest, ParsesInvalidCommandLine) {
|
|||||||
|
|
||||||
const wchar_t* new_argv[] = {nullptr};
|
const wchar_t* new_argv[] = {nullptr};
|
||||||
|
|
||||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG_GET(verbose));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(WideInitGoogleMockTest, ParsesEmptyCommandLine) {
|
TEST(WideInitGoogleMockTest, ParsesEmptyCommandLine) {
|
||||||
@ -130,7 +128,7 @@ TEST(WideInitGoogleMockTest, ParsesEmptyCommandLine) {
|
|||||||
|
|
||||||
const wchar_t* new_argv[] = {L"foo.exe", nullptr};
|
const wchar_t* new_argv[] = {L"foo.exe", nullptr};
|
||||||
|
|
||||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG_GET(verbose));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(WideInitGoogleMockTest, ParsesSingleFlag) {
|
TEST(WideInitGoogleMockTest, ParsesSingleFlag) {
|
||||||
@ -142,16 +140,16 @@ TEST(WideInitGoogleMockTest, ParsesSingleFlag) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(WideInitGoogleMockTest, ParsesMultipleFlags) {
|
TEST(WideInitGoogleMockTest, ParsesMultipleFlags) {
|
||||||
int old_default_behavior = GMOCK_FLAG(default_mock_behavior);
|
int old_default_behavior = GMOCK_FLAG_GET(default_mock_behavior);
|
||||||
const wchar_t* argv[] = {L"foo.exe", L"--gmock_verbose=info",
|
const wchar_t* argv[] = {L"foo.exe", L"--gmock_verbose=info",
|
||||||
L"--gmock_default_mock_behavior=2", nullptr};
|
L"--gmock_default_mock_behavior=2", nullptr};
|
||||||
|
|
||||||
const wchar_t* new_argv[] = {L"foo.exe", nullptr};
|
const wchar_t* new_argv[] = {L"foo.exe", nullptr};
|
||||||
|
|
||||||
TestInitGoogleMock(argv, new_argv, "info");
|
TestInitGoogleMock(argv, new_argv, "info");
|
||||||
EXPECT_EQ(2, GMOCK_FLAG(default_mock_behavior));
|
EXPECT_EQ(2, GMOCK_FLAG_GET(default_mock_behavior));
|
||||||
EXPECT_NE(2, old_default_behavior);
|
EXPECT_NE(2, old_default_behavior);
|
||||||
GMOCK_FLAG(default_mock_behavior) = old_default_behavior;
|
GMOCK_FLAG_SET(default_mock_behavior, old_default_behavior);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(WideInitGoogleMockTest, ParsesUnrecognizedFlag) {
|
TEST(WideInitGoogleMockTest, ParsesUnrecognizedFlag) {
|
||||||
@ -159,7 +157,7 @@ TEST(WideInitGoogleMockTest, ParsesUnrecognizedFlag) {
|
|||||||
|
|
||||||
const wchar_t* new_argv[] = {L"foo.exe", L"--non_gmock_flag=blah", nullptr};
|
const wchar_t* new_argv[] = {L"foo.exe", L"--non_gmock_flag=blah", nullptr};
|
||||||
|
|
||||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG_GET(verbose));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(WideInitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
|
TEST(WideInitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
|
||||||
@ -175,7 +173,7 @@ TEST(WideInitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
|
|||||||
|
|
||||||
// Makes sure Google Mock flags can be accessed in code.
|
// Makes sure Google Mock flags can be accessed in code.
|
||||||
TEST(FlagTest, IsAccessibleInCode) {
|
TEST(FlagTest, IsAccessibleInCode) {
|
||||||
bool dummy = testing::GMOCK_FLAG(catch_leaked_mocks) &&
|
bool dummy =
|
||||||
testing::GMOCK_FLAG(verbose) == "";
|
GMOCK_FLAG_GET(catch_leaked_mocks) && GMOCK_FLAG_GET(verbose) == "";
|
||||||
(void)dummy; // Avoids the "unused local variable" warning.
|
(void)dummy; // Avoids the "unused local variable" warning.
|
||||||
}
|
}
|
||||||
|
@ -46,14 +46,9 @@ endif()
|
|||||||
|
|
||||||
# Project version:
|
# Project version:
|
||||||
|
|
||||||
if (CMAKE_VERSION VERSION_LESS 3.0)
|
cmake_minimum_required(VERSION 3.5)
|
||||||
project(gtest CXX C)
|
cmake_policy(SET CMP0048 NEW)
|
||||||
set(PROJECT_VERSION ${GOOGLETEST_VERSION})
|
project(gtest VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)
|
||||||
else()
|
|
||||||
cmake_policy(SET CMP0048 NEW)
|
|
||||||
project(gtest VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)
|
|
||||||
endif()
|
|
||||||
cmake_minimum_required(VERSION 2.8.12)
|
|
||||||
|
|
||||||
if (POLICY CMP0063) # Visibility
|
if (POLICY CMP0063) # Visibility
|
||||||
cmake_policy(SET CMP0063 NEW)
|
cmake_policy(SET CMP0063 NEW)
|
||||||
|
@ -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.10.0
|
git clone https://github.com/google/googletest.git -b release-1.11.0
|
||||||
cd googletest # Main directory of the cloned repository.
|
cd googletest # Main directory of the cloned repository.
|
||||||
mkdir build # Create a directory to hold the build output.
|
mkdir build # Create a directory to hold the build output.
|
||||||
cd build
|
cd build
|
||||||
@ -203,7 +203,9 @@ add
|
|||||||
-DGTEST_DONT_DEFINE_FOO=1
|
-DGTEST_DONT_DEFINE_FOO=1
|
||||||
|
|
||||||
to the compiler flags to tell GoogleTest to change the macro's name from `FOO`
|
to the compiler flags to tell GoogleTest to change the macro's name from `FOO`
|
||||||
to `GTEST_FOO`. Currently `FOO` can be `FAIL`, `SUCCEED`, or `TEST`. For
|
to `GTEST_FOO`. Currently `FOO` can be `ASSERT_EQ`, `ASSERT_FALSE`, `ASSERT_GE`,
|
||||||
|
`ASSERT_GT`, `ASSERT_LE`, `ASSERT_LT`, `ASSERT_NE`, `ASSERT_TRUE`,
|
||||||
|
`EXPECT_FALSE`, `EXPECT_TRUE`, `FAIL`, `SUCCEED`, `TEST`, or `TEST_F`. For
|
||||||
example, with `-DGTEST_DONT_DEFINE_TEST=1`, you'll need to write
|
example, with `-DGTEST_DONT_DEFINE_TEST=1`, you'll need to write
|
||||||
|
|
||||||
GTEST_TEST(SomeTest, DoesThis) { ... }
|
GTEST_TEST(SomeTest, DoesThis) { ... }
|
||||||
|
@ -84,13 +84,13 @@ macro(config_compiler_and_linker)
|
|||||||
# Ensure MSVC treats source files as UTF-8 encoded.
|
# Ensure MSVC treats source files as UTF-8 encoded.
|
||||||
set(cxx_base_flags "${cxx_base_flags} -utf-8")
|
set(cxx_base_flags "${cxx_base_flags} -utf-8")
|
||||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
set(cxx_base_flags "-Wall -Wshadow -Werror -Wconversion")
|
set(cxx_base_flags "-Wall -Wshadow -Wconversion")
|
||||||
set(cxx_exception_flags "-fexceptions")
|
set(cxx_exception_flags "-fexceptions")
|
||||||
set(cxx_no_exception_flags "-fno-exceptions")
|
set(cxx_no_exception_flags "-fno-exceptions")
|
||||||
set(cxx_strict_flags "-W -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wunused-parameter -Wcast-align -Wchar-subscripts -Winline -Wredundant-decls")
|
set(cxx_strict_flags "-W -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wunused-parameter -Wcast-align -Wchar-subscripts -Winline -Wredundant-decls")
|
||||||
set(cxx_no_rtti_flags "-fno-rtti")
|
set(cxx_no_rtti_flags "-fno-rtti")
|
||||||
elseif (CMAKE_COMPILER_IS_GNUCXX)
|
elseif (CMAKE_COMPILER_IS_GNUCXX)
|
||||||
set(cxx_base_flags "-Wall -Wshadow -Werror")
|
set(cxx_base_flags "-Wall -Wshadow")
|
||||||
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0)
|
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0)
|
||||||
set(cxx_base_flags "${cxx_base_flags} -Wno-error=dangling-else")
|
set(cxx_base_flags "${cxx_base_flags} -Wno-error=dangling-else")
|
||||||
endif()
|
endif()
|
||||||
|
@ -33,15 +33,12 @@
|
|||||||
// This header file defines the public API for death tests. It is
|
// This header file defines the public API for death tests. It is
|
||||||
// #included by gtest.h so a user doesn't need to include this
|
// #included by gtest.h so a user doesn't need to include this
|
||||||
// directly.
|
// directly.
|
||||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
||||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
#define GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
||||||
|
|
||||||
#include "gtest/internal/gtest-death-test-internal.h"
|
#include "gtest/internal/gtest-death-test-internal.h"
|
||||||
|
|
||||||
namespace testing {
|
|
||||||
|
|
||||||
// This flag controls the style of death tests. Valid values are "threadsafe",
|
// This flag controls the style of death tests. Valid values are "threadsafe",
|
||||||
// meaning that the death test child process will re-execute the test binary
|
// meaning that the death test child process will re-execute the test binary
|
||||||
// from the start, running only a single death test, or "fast",
|
// from the start, running only a single death test, or "fast",
|
||||||
@ -49,6 +46,8 @@ namespace testing {
|
|||||||
// after forking.
|
// after forking.
|
||||||
GTEST_DECLARE_string_(death_test_style);
|
GTEST_DECLARE_string_(death_test_style);
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
#if GTEST_HAS_DEATH_TEST
|
#if GTEST_HAS_DEATH_TEST
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
@ -103,7 +102,6 @@ GTEST_API_ bool InDeathTestChild();
|
|||||||
//
|
//
|
||||||
// On the regular expressions used in death tests:
|
// On the regular expressions used in death tests:
|
||||||
//
|
//
|
||||||
// GOOGLETEST_CM0005 DO NOT DELETE
|
|
||||||
// On POSIX-compliant systems (*nix), we use the <regex.h> library,
|
// On POSIX-compliant systems (*nix), we use the <regex.h> library,
|
||||||
// which uses the POSIX extended regex syntax.
|
// which uses the POSIX extended regex syntax.
|
||||||
//
|
//
|
||||||
@ -204,7 +202,6 @@ class GTEST_API_ ExitedWithCode {
|
|||||||
# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
|
# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
|
||||||
// Tests that an exit code describes an exit due to termination by a
|
// Tests that an exit code describes an exit due to termination by a
|
||||||
// given signal.
|
// given signal.
|
||||||
// GOOGLETEST_CM0006 DO NOT DELETE
|
|
||||||
class GTEST_API_ KilledBySignal {
|
class GTEST_API_ KilledBySignal {
|
||||||
public:
|
public:
|
||||||
explicit KilledBySignal(int signum);
|
explicit KilledBySignal(int signum);
|
||||||
|
@ -42,8 +42,6 @@
|
|||||||
// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user
|
// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user
|
||||||
// program!
|
// program!
|
||||||
|
|
||||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
|
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
|
||||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
|
#define GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
|
||||||
|
|
||||||
|
@ -29,8 +29,6 @@
|
|||||||
//
|
//
|
||||||
// Macros and functions for implementing parameterized tests
|
// Macros and functions for implementing parameterized tests
|
||||||
// in Google C++ Testing and Mocking Framework (Google Test)
|
// in Google C++ Testing and Mocking Framework (Google Test)
|
||||||
//
|
|
||||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
|
||||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
||||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
||||||
|
|
||||||
|
@ -95,8 +95,6 @@
|
|||||||
// being defined as many user-defined container types don't have
|
// being defined as many user-defined container types don't have
|
||||||
// value_type.
|
// value_type.
|
||||||
|
|
||||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
||||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
||||||
|
|
||||||
@ -360,7 +358,7 @@ GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char);
|
|||||||
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char);
|
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char);
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t);
|
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t);
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t);
|
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t);
|
||||||
#ifdef __cpp_char8_t
|
#ifdef __cpp_lib_char8_t
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char8_t);
|
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char8_t);
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char8_t);
|
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char8_t);
|
||||||
#endif
|
#endif
|
||||||
@ -479,6 +477,12 @@ inline void PrintTo(char8_t c, ::std::ostream* os) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// gcc/clang __{u,}int128_t
|
||||||
|
#if defined(__SIZEOF_INT128__)
|
||||||
|
GTEST_API_ void PrintTo(__uint128_t v, ::std::ostream* os);
|
||||||
|
GTEST_API_ void PrintTo(__int128_t v, ::std::ostream* os);
|
||||||
|
#endif // __SIZEOF_INT128__
|
||||||
|
|
||||||
// Overloads for C strings.
|
// Overloads for C strings.
|
||||||
GTEST_API_ void PrintTo(const char* s, ::std::ostream* os);
|
GTEST_API_ void PrintTo(const char* s, ::std::ostream* os);
|
||||||
inline void PrintTo(char* s, ::std::ostream* os) {
|
inline void PrintTo(char* s, ::std::ostream* os) {
|
||||||
@ -587,6 +591,12 @@ inline void PrintTo(internal::StringView sp, ::std::ostream* os) {
|
|||||||
|
|
||||||
inline void PrintTo(std::nullptr_t, ::std::ostream* os) { *os << "(nullptr)"; }
|
inline void PrintTo(std::nullptr_t, ::std::ostream* os) { *os << "(nullptr)"; }
|
||||||
|
|
||||||
|
#if GTEST_HAS_RTTI
|
||||||
|
inline void PrintTo(const std::type_info& info, std::ostream* os) {
|
||||||
|
*os << internal::GetTypeName(info);
|
||||||
|
}
|
||||||
|
#endif // GTEST_HAS_RTTI
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void PrintTo(std::reference_wrapper<T> ref, ::std::ostream* os) {
|
void PrintTo(std::reference_wrapper<T> ref, ::std::ostream* os) {
|
||||||
UniversalPrinter<T&>::Print(ref.get(), os);
|
UniversalPrinter<T&>::Print(ref.get(), os);
|
||||||
@ -744,6 +754,14 @@ class UniversalPrinter<Optional<T>> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class UniversalPrinter<decltype(Nullopt())> {
|
||||||
|
public:
|
||||||
|
static void Print(decltype(Nullopt()), ::std::ostream* os) {
|
||||||
|
*os << "(nullopt)";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#endif // GTEST_INTERNAL_HAS_OPTIONAL
|
#endif // GTEST_INTERNAL_HAS_OPTIONAL
|
||||||
|
|
||||||
#if GTEST_INTERNAL_HAS_VARIANT
|
#if GTEST_INTERNAL_HAS_VARIANT
|
||||||
|
@ -31,8 +31,6 @@
|
|||||||
// Utilities for testing Google Test itself and code that uses Google Test
|
// Utilities for testing Google Test itself and code that uses Google Test
|
||||||
// (e.g. frameworks built on top of Google Test).
|
// (e.g. frameworks built on top of Google Test).
|
||||||
|
|
||||||
// GOOGLETEST_CM0004 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_
|
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_
|
||||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_
|
#define GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_
|
||||||
|
|
||||||
|
@ -26,8 +26,6 @@
|
|||||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
|
||||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
||||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
#define GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
||||||
|
@ -27,8 +27,6 @@
|
|||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
|
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
|
||||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
|
#define GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
|
||||||
|
|
||||||
|
@ -47,8 +47,6 @@
|
|||||||
// registration from Barthelemy Dagenais' (barthelemy@prologique.com)
|
// registration from Barthelemy Dagenais' (barthelemy@prologique.com)
|
||||||
// easyUnit framework.
|
// easyUnit framework.
|
||||||
|
|
||||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_H_
|
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_H_
|
||||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_H_
|
#define GOOGLETEST_INCLUDE_GTEST_GTEST_H_
|
||||||
|
|
||||||
@ -73,17 +71,6 @@
|
|||||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||||
/* class A needs to have dll-interface to be used by clients of class B */)
|
/* class A needs to have dll-interface to be used by clients of class B */)
|
||||||
|
|
||||||
namespace testing {
|
|
||||||
|
|
||||||
// Silence C4100 (unreferenced formal parameter) and 4805
|
|
||||||
// unsafe mix of type 'const int' and type 'const bool'
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
# pragma warning(push)
|
|
||||||
# pragma warning(disable:4805)
|
|
||||||
# pragma warning(disable:4100)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// Declares the flags.
|
// Declares the flags.
|
||||||
|
|
||||||
// This flag temporary enables the disabled tests.
|
// This flag temporary enables the disabled tests.
|
||||||
@ -138,6 +125,12 @@ GTEST_DECLARE_int32_(random_seed);
|
|||||||
// is 1. If the value is -1 the tests are repeating forever.
|
// is 1. If the value is -1 the tests are repeating forever.
|
||||||
GTEST_DECLARE_int32_(repeat);
|
GTEST_DECLARE_int32_(repeat);
|
||||||
|
|
||||||
|
// This flag controls whether Google Test Environments are recreated for each
|
||||||
|
// repeat of the tests. The default value is true. If set to false the global
|
||||||
|
// test Environment objects are only set up once, for the first iteration, and
|
||||||
|
// only torn down once, for the last.
|
||||||
|
GTEST_DECLARE_bool_(recreate_environments_when_repeating);
|
||||||
|
|
||||||
// This flag controls whether Google Test includes Google Test internal
|
// This flag controls whether Google Test includes Google Test internal
|
||||||
// stack frames in failure stack traces.
|
// stack frames in failure stack traces.
|
||||||
GTEST_DECLARE_bool_(show_internal_stack_frames);
|
GTEST_DECLARE_bool_(show_internal_stack_frames);
|
||||||
@ -163,6 +156,16 @@ GTEST_DECLARE_string_(stream_result_to);
|
|||||||
GTEST_DECLARE_string_(flagfile);
|
GTEST_DECLARE_string_(flagfile);
|
||||||
#endif // GTEST_USE_OWN_FLAGFILE_FLAG_
|
#endif // GTEST_USE_OWN_FLAGFILE_FLAG_
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
|
// Silence C4100 (unreferenced formal parameter) and 4805
|
||||||
|
// unsafe mix of type 'const int' and type 'const bool'
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4805)
|
||||||
|
#pragma warning(disable : 4100)
|
||||||
|
#endif
|
||||||
|
|
||||||
// The upper limit for valid stack trace depths.
|
// The upper limit for valid stack trace depths.
|
||||||
const int kMaxStackTraceDepth = 100;
|
const int kMaxStackTraceDepth = 100;
|
||||||
|
|
||||||
@ -1120,6 +1123,9 @@ class TestEventListener {
|
|||||||
// Fired before the test starts.
|
// Fired before the test starts.
|
||||||
virtual void OnTestStart(const TestInfo& test_info) = 0;
|
virtual void OnTestStart(const TestInfo& test_info) = 0;
|
||||||
|
|
||||||
|
// Fired when a test is disabled
|
||||||
|
virtual void OnTestDisabled(const TestInfo& /*test_info*/) {}
|
||||||
|
|
||||||
// Fired after a failed assertion or a SUCCEED() invocation.
|
// Fired after a failed assertion or a SUCCEED() invocation.
|
||||||
// If you want to throw an exception from this function to skip to the next
|
// If you want to throw an exception from this function to skip to the next
|
||||||
// TEST, it must be AssertionException defined above, or inherited from it.
|
// TEST, it must be AssertionException defined above, or inherited from it.
|
||||||
@ -1169,6 +1175,7 @@ class EmptyTestEventListener : public TestEventListener {
|
|||||||
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
|
||||||
void OnTestStart(const TestInfo& /*test_info*/) override {}
|
void OnTestStart(const TestInfo& /*test_info*/) override {}
|
||||||
|
void OnTestDisabled(const TestInfo& /*test_info*/) override {}
|
||||||
void OnTestPartResult(const TestPartResult& /*test_part_result*/) override {}
|
void OnTestPartResult(const TestPartResult& /*test_part_result*/) override {}
|
||||||
void OnTestEnd(const TestInfo& /*test_info*/) override {}
|
void OnTestEnd(const TestInfo& /*test_info*/) override {}
|
||||||
void OnTestSuiteEnd(const TestSuite& /*test_suite*/) override {}
|
void OnTestSuiteEnd(const TestSuite& /*test_suite*/) override {}
|
||||||
@ -2378,13 +2385,12 @@ constexpr bool StaticAssertTypeEq() noexcept {
|
|||||||
// EXPECT_EQ(a_.size(), 0);
|
// EXPECT_EQ(a_.size(), 0);
|
||||||
// EXPECT_EQ(b_.size(), 1);
|
// EXPECT_EQ(b_.size(), 1);
|
||||||
// }
|
// }
|
||||||
//
|
#define GTEST_TEST_F(test_fixture, test_name)\
|
||||||
// GOOGLETEST_CM0011 DO NOT DELETE
|
|
||||||
#if !GTEST_DONT_DEFINE_TEST
|
|
||||||
#define TEST_F(test_fixture, test_name)\
|
|
||||||
GTEST_TEST_(test_fixture, test_name, test_fixture, \
|
GTEST_TEST_(test_fixture, test_name, test_fixture, \
|
||||||
::testing::internal::GetTypeId<test_fixture>())
|
::testing::internal::GetTypeId<test_fixture>())
|
||||||
#endif // !GTEST_DONT_DEFINE_TEST
|
#if !GTEST_DONT_DEFINE_TEST_F
|
||||||
|
#define TEST_F(test_fixture, test_name) GTEST_TEST_F(test_fixture, test_name)
|
||||||
|
#endif
|
||||||
|
|
||||||
// Returns a path to temporary directory.
|
// Returns a path to temporary directory.
|
||||||
// Tries to determine an appropriate directory for the platform.
|
// Tries to determine an appropriate directory for the platform.
|
||||||
@ -2445,6 +2451,7 @@ GTEST_API_ std::string TempDir();
|
|||||||
// }
|
// }
|
||||||
// ...
|
// ...
|
||||||
// int main(int argc, char** argv) {
|
// int main(int argc, char** argv) {
|
||||||
|
// ::testing::InitGoogleTest(&argc, argv);
|
||||||
// std::vector<int> values_to_test = LoadValuesFromConfig();
|
// std::vector<int> values_to_test = LoadValuesFromConfig();
|
||||||
// RegisterMyTests(values_to_test);
|
// RegisterMyTests(values_to_test);
|
||||||
// ...
|
// ...
|
||||||
|
@ -27,11 +27,10 @@
|
|||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
// This file is AUTOMATICALLY GENERATED on 01/02/2019 by command
|
// This file is AUTOMATICALLY GENERATED on 07/21/2021 by command
|
||||||
// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND!
|
// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND!
|
||||||
//
|
//
|
||||||
// Implements a family of generic predicate assertion macros.
|
// Implements a family of generic predicate assertion macros.
|
||||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
|
|
||||||
//
|
//
|
||||||
// Google C++ Testing and Mocking Framework definitions useful in production code.
|
// Google C++ Testing and Mocking Framework definitions useful in production code.
|
||||||
// GOOGLETEST_CM0003 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_
|
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_
|
||||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_
|
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_
|
||||||
|
@ -26,6 +26,8 @@ The following macros can be defined:
|
|||||||
* `GTEST_DEFINE_bool_(name, default_val, doc)`
|
* `GTEST_DEFINE_bool_(name, default_val, doc)`
|
||||||
* `GTEST_DEFINE_int32_(name, default_val, doc)`
|
* `GTEST_DEFINE_int32_(name, default_val, doc)`
|
||||||
* `GTEST_DEFINE_string_(name, default_val, doc)`
|
* `GTEST_DEFINE_string_(name, default_val, doc)`
|
||||||
|
* `GTEST_FLAG_GET(flag_name)`
|
||||||
|
* `GTEST_FLAG_SET(flag_name, value)`
|
||||||
|
|
||||||
### Logging:
|
### Logging:
|
||||||
|
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
//
|
//
|
||||||
// This header file defines internal utilities needed for implementing
|
// This header file defines internal utilities needed for implementing
|
||||||
// death tests. They are subject to change without notice.
|
// death tests. They are subject to change without notice.
|
||||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
||||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
||||||
@ -42,11 +41,11 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
GTEST_DECLARE_string_(internal_run_death_test);
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
GTEST_DECLARE_string_(internal_run_death_test);
|
|
||||||
|
|
||||||
// Names of the flags (needed for parsing Google Test flags).
|
// Names of the flags (needed for parsing Google Test flags).
|
||||||
const char kDeathTestStyleFlag[] = "death_test_style";
|
const char kDeathTestStyleFlag[] = "death_test_style";
|
||||||
const char kDeathTestUseFork[] = "death_test_use_fork";
|
const char kDeathTestUseFork[] = "death_test_use_fork";
|
||||||
@ -236,8 +235,6 @@ inline Matcher<const ::std::string&> MakeDeathTestMatcher(
|
|||||||
gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
|
gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
default: \
|
|
||||||
break; \
|
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
} else \
|
} else \
|
||||||
|
@ -35,8 +35,6 @@
|
|||||||
// This file is #included in gtest/internal/gtest-internal.h.
|
// This file is #included in gtest/internal/gtest-internal.h.
|
||||||
// Do not include this header file separately!
|
// Do not include this header file separately!
|
||||||
|
|
||||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||||
|
|
||||||
|
@ -32,8 +32,6 @@
|
|||||||
// This header file declares functions and macros used internally by
|
// This header file declares functions and macros used internally by
|
||||||
// Google Test. They are subject to change without notice.
|
// Google Test. They are subject to change without notice.
|
||||||
|
|
||||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
|
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
|
||||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
|
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
|
||||||
|
|
||||||
@ -510,11 +508,11 @@ inline SetUpTearDownSuiteFuncType GetNotDefaultOrNull(
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
// Note that SuiteApiResolver inherits from T because
|
// Note that SuiteApiResolver inherits from T because
|
||||||
// SetUpTestSuite()/TearDownTestSuite() could be protected. Ths way
|
// SetUpTestSuite()/TearDownTestSuite() could be protected. This way
|
||||||
// SuiteApiResolver can access them.
|
// SuiteApiResolver can access them.
|
||||||
struct SuiteApiResolver : T {
|
struct SuiteApiResolver : T {
|
||||||
// testing::Test is only forward declared at this point. So we make it a
|
// testing::Test is only forward declared at this point. So we make it a
|
||||||
// dependend class for the compiler to be OK with it.
|
// dependent class for the compiler to be OK with it.
|
||||||
using Test =
|
using Test =
|
||||||
typename std::conditional<sizeof(T) != 0, ::testing::Test, void>::type;
|
typename std::conditional<sizeof(T) != 0, ::testing::Test, void>::type;
|
||||||
|
|
||||||
|
@ -30,8 +30,6 @@
|
|||||||
|
|
||||||
// Type and function utilities for implementing parameterized tests.
|
// Type and function utilities for implementing parameterized tests.
|
||||||
|
|
||||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
|
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
|
||||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
|
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
|
||||||
|
|
||||||
|
@ -78,6 +78,8 @@
|
|||||||
# define GTEST_OS_FREEBSD 1
|
# define GTEST_OS_FREEBSD 1
|
||||||
#elif defined __Fuchsia__
|
#elif defined __Fuchsia__
|
||||||
# define GTEST_OS_FUCHSIA 1
|
# define GTEST_OS_FUCHSIA 1
|
||||||
|
#elif defined(__GNU__)
|
||||||
|
# define GTEST_OS_GNU_HURD 1
|
||||||
#elif defined(__GLIBC__) && defined(__FreeBSD_kernel__)
|
#elif defined(__GLIBC__) && defined(__FreeBSD_kernel__)
|
||||||
# define GTEST_OS_GNU_KFREEBSD 1
|
# define GTEST_OS_GNU_KFREEBSD 1
|
||||||
#elif defined __linux__
|
#elif defined __linux__
|
||||||
|
@ -38,8 +38,6 @@
|
|||||||
// files are expected to #include this. Therefore, it cannot #include
|
// files are expected to #include this. Therefore, it cannot #include
|
||||||
// any other Google Test header.
|
// any other Google Test header.
|
||||||
|
|
||||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
|
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
|
||||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
|
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
|
||||||
|
|
||||||
@ -116,6 +114,7 @@
|
|||||||
// GTEST_OS_DRAGONFLY - DragonFlyBSD
|
// GTEST_OS_DRAGONFLY - DragonFlyBSD
|
||||||
// GTEST_OS_FREEBSD - FreeBSD
|
// GTEST_OS_FREEBSD - FreeBSD
|
||||||
// GTEST_OS_FUCHSIA - Fuchsia
|
// GTEST_OS_FUCHSIA - Fuchsia
|
||||||
|
// GTEST_OS_GNU_HURD - GNU/Hurd
|
||||||
// GTEST_OS_GNU_KFREEBSD - GNU/kFreeBSD
|
// GTEST_OS_GNU_KFREEBSD - GNU/kFreeBSD
|
||||||
// GTEST_OS_HAIKU - Haiku
|
// GTEST_OS_HAIKU - Haiku
|
||||||
// GTEST_OS_HPUX - HP-UX
|
// GTEST_OS_HPUX - HP-UX
|
||||||
@ -167,7 +166,6 @@
|
|||||||
// GTEST_HAS_TYPED_TEST - typed tests
|
// GTEST_HAS_TYPED_TEST - typed tests
|
||||||
// GTEST_HAS_TYPED_TEST_P - type-parameterized tests
|
// GTEST_HAS_TYPED_TEST_P - type-parameterized tests
|
||||||
// GTEST_IS_THREADSAFE - Google Test is thread-safe.
|
// GTEST_IS_THREADSAFE - Google Test is thread-safe.
|
||||||
// GOOGLETEST_CM0007 DO NOT DELETE
|
|
||||||
// GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with
|
// GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with
|
||||||
// GTEST_HAS_POSIX_RE (see above) which users can
|
// GTEST_HAS_POSIX_RE (see above) which users can
|
||||||
// define themselves.
|
// define themselves.
|
||||||
@ -219,7 +217,6 @@
|
|||||||
// Regular expressions:
|
// Regular expressions:
|
||||||
// RE - a simple regular expression class using the POSIX
|
// RE - a simple regular expression class using the POSIX
|
||||||
// Extended Regular Expression syntax on UNIX-like platforms
|
// Extended Regular Expression syntax on UNIX-like platforms
|
||||||
// GOOGLETEST_CM0008 DO NOT DELETE
|
|
||||||
// or a reduced regular exception syntax on other
|
// or a reduced regular exception syntax on other
|
||||||
// platforms, including Windows.
|
// platforms, including Windows.
|
||||||
// Logging:
|
// Logging:
|
||||||
@ -263,9 +260,17 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
|
// #include <condition_variable> // Guarded by GTEST_IS_THREADSAFE below
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <iostream>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <locale>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
// #include <mutex> // Guarded by GTEST_IS_THREADSAFE below
|
||||||
|
#include <tuple>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#ifndef _WIN32_WCE
|
#ifndef _WIN32_WCE
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
@ -277,13 +282,6 @@
|
|||||||
# include <TargetConditionals.h>
|
# include <TargetConditionals.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <iostream> // NOLINT
|
|
||||||
#include <locale>
|
|
||||||
#include <memory>
|
|
||||||
#include <string> // NOLINT
|
|
||||||
#include <tuple>
|
|
||||||
#include <vector> // NOLINT
|
|
||||||
|
|
||||||
#include "gtest/internal/custom/gtest-port.h"
|
#include "gtest/internal/custom/gtest-port.h"
|
||||||
#include "gtest/internal/gtest-port-arch.h"
|
#include "gtest/internal/gtest-port-arch.h"
|
||||||
|
|
||||||
@ -547,7 +545,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
|||||||
(GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX || GTEST_OS_QNX || \
|
(GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX || GTEST_OS_QNX || \
|
||||||
GTEST_OS_FREEBSD || GTEST_OS_NACL || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA || \
|
GTEST_OS_FREEBSD || GTEST_OS_NACL || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA || \
|
||||||
GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_OPENBSD || \
|
GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_OPENBSD || \
|
||||||
GTEST_OS_HAIKU)
|
GTEST_OS_HAIKU || GTEST_OS_GNU_HURD)
|
||||||
#endif // GTEST_HAS_PTHREAD
|
#endif // GTEST_HAS_PTHREAD
|
||||||
|
|
||||||
#if GTEST_HAS_PTHREAD
|
#if GTEST_HAS_PTHREAD
|
||||||
@ -607,7 +605,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
|||||||
(GTEST_OS_WINDOWS_DESKTOP && _MSC_VER) || GTEST_OS_WINDOWS_MINGW || \
|
(GTEST_OS_WINDOWS_DESKTOP && _MSC_VER) || GTEST_OS_WINDOWS_MINGW || \
|
||||||
GTEST_OS_AIX || GTEST_OS_HPUX || GTEST_OS_OPENBSD || GTEST_OS_QNX || \
|
GTEST_OS_AIX || GTEST_OS_HPUX || GTEST_OS_OPENBSD || GTEST_OS_QNX || \
|
||||||
GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA || \
|
GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA || \
|
||||||
GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_HAIKU)
|
GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_HAIKU || \
|
||||||
|
GTEST_OS_GNU_HURD)
|
||||||
# define GTEST_HAS_DEATH_TEST 1
|
# define GTEST_HAS_DEATH_TEST 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -627,7 +626,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
|||||||
|
|
||||||
// Determines whether test results can be streamed to a socket.
|
// Determines whether test results can be streamed to a socket.
|
||||||
#if GTEST_OS_LINUX || GTEST_OS_GNU_KFREEBSD || GTEST_OS_DRAGONFLY || \
|
#if GTEST_OS_LINUX || GTEST_OS_GNU_KFREEBSD || GTEST_OS_DRAGONFLY || \
|
||||||
GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_OPENBSD
|
GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_OPENBSD || \
|
||||||
|
GTEST_OS_GNU_HURD
|
||||||
# define GTEST_CAN_STREAM_RESULTS_ 1
|
# define GTEST_CAN_STREAM_RESULTS_ 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -758,6 +758,12 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
|||||||
|
|
||||||
#endif // GTEST_IS_THREADSAFE
|
#endif // GTEST_IS_THREADSAFE
|
||||||
|
|
||||||
|
#if GTEST_IS_THREADSAFE
|
||||||
|
// Some platforms don't support including these threading related headers.
|
||||||
|
#include <condition_variable> // NOLINT
|
||||||
|
#include <mutex> // NOLINT
|
||||||
|
#endif // GTEST_IS_THREADSAFE
|
||||||
|
|
||||||
// GTEST_API_ qualifies all symbols that must be exported. The definitions below
|
// GTEST_API_ qualifies all symbols that must be exported. The definitions below
|
||||||
// are guarded by #ifndef to give embedders a chance to define GTEST_API_ in
|
// are guarded by #ifndef to give embedders a chance to define GTEST_API_ in
|
||||||
// gtest/internal/custom/gtest-port.h
|
// gtest/internal/custom/gtest-port.h
|
||||||
@ -995,7 +1001,7 @@ inline void FlushInfoLog() { fflush(nullptr); }
|
|||||||
//
|
//
|
||||||
// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition
|
// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition
|
||||||
// is not satisfied.
|
// is not satisfied.
|
||||||
// Synopsys:
|
// Synopsis:
|
||||||
// GTEST_CHECK_(boolean_condition);
|
// GTEST_CHECK_(boolean_condition);
|
||||||
// or
|
// or
|
||||||
// GTEST_CHECK_(boolean_condition) << "Additional message";
|
// GTEST_CHECK_(boolean_condition) << "Additional message";
|
||||||
@ -1050,7 +1056,7 @@ struct ConstRef<T&> { typedef T& type; };
|
|||||||
// const Foo*). When you use ImplicitCast_, the compiler checks that
|
// const Foo*). When you use ImplicitCast_, the compiler checks that
|
||||||
// the cast is safe. Such explicit ImplicitCast_s are necessary in
|
// the cast is safe. Such explicit ImplicitCast_s are necessary in
|
||||||
// surprisingly many situations where C++ demands an exact type match
|
// surprisingly many situations where C++ demands an exact type match
|
||||||
// instead of an argument type convertable to a target type.
|
// instead of an argument type convertible to a target type.
|
||||||
//
|
//
|
||||||
// The syntax for using ImplicitCast_ is the same as for static_cast:
|
// The syntax for using ImplicitCast_ is the same as for static_cast:
|
||||||
//
|
//
|
||||||
@ -1162,71 +1168,8 @@ void ClearInjectableArgvs();
|
|||||||
|
|
||||||
// Defines synchronization primitives.
|
// Defines synchronization primitives.
|
||||||
#if GTEST_IS_THREADSAFE
|
#if GTEST_IS_THREADSAFE
|
||||||
# if GTEST_HAS_PTHREAD
|
|
||||||
// Sleeps for (roughly) n milliseconds. This function is only for testing
|
|
||||||
// Google Test's own constructs. Don't use it in user tests, either
|
|
||||||
// directly or indirectly.
|
|
||||||
inline void SleepMilliseconds(int n) {
|
|
||||||
const timespec time = {
|
|
||||||
0, // 0 seconds.
|
|
||||||
n * 1000L * 1000L, // And n ms.
|
|
||||||
};
|
|
||||||
nanosleep(&time, nullptr);
|
|
||||||
}
|
|
||||||
# endif // GTEST_HAS_PTHREAD
|
|
||||||
|
|
||||||
# if GTEST_HAS_NOTIFICATION_
|
|
||||||
// Notification has already been imported into the namespace.
|
|
||||||
// Nothing to do here.
|
|
||||||
|
|
||||||
# elif GTEST_HAS_PTHREAD
|
|
||||||
// Allows a controller thread to pause execution of newly created
|
|
||||||
// threads until notified. Instances of this class must be created
|
|
||||||
// and destroyed in the controller thread.
|
|
||||||
//
|
|
||||||
// This class is only for testing Google Test's own constructs. Do not
|
|
||||||
// use it in user tests, either directly or indirectly.
|
|
||||||
class Notification {
|
|
||||||
public:
|
|
||||||
Notification() : notified_(false) {
|
|
||||||
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, nullptr));
|
|
||||||
}
|
|
||||||
~Notification() {
|
|
||||||
pthread_mutex_destroy(&mutex_);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notifies all threads created with this notification to start. Must
|
|
||||||
// be called from the controller thread.
|
|
||||||
void Notify() {
|
|
||||||
pthread_mutex_lock(&mutex_);
|
|
||||||
notified_ = true;
|
|
||||||
pthread_mutex_unlock(&mutex_);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Blocks until the controller thread notifies. Must be called from a test
|
|
||||||
// thread.
|
|
||||||
void WaitForNotification() {
|
|
||||||
for (;;) {
|
|
||||||
pthread_mutex_lock(&mutex_);
|
|
||||||
const bool notified = notified_;
|
|
||||||
pthread_mutex_unlock(&mutex_);
|
|
||||||
if (notified)
|
|
||||||
break;
|
|
||||||
SleepMilliseconds(10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
pthread_mutex_t mutex_;
|
|
||||||
bool notified_;
|
|
||||||
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification);
|
|
||||||
};
|
|
||||||
|
|
||||||
# elif GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT
|
|
||||||
|
|
||||||
GTEST_API_ void SleepMilliseconds(int n);
|
|
||||||
|
|
||||||
|
# if GTEST_OS_WINDOWS
|
||||||
// Provides leak-safe Windows kernel handle ownership.
|
// Provides leak-safe Windows kernel handle ownership.
|
||||||
// Used in death tests and in threading support.
|
// Used in death tests and in threading support.
|
||||||
class GTEST_API_ AutoHandle {
|
class GTEST_API_ AutoHandle {
|
||||||
@ -1255,23 +1198,45 @@ class GTEST_API_ AutoHandle {
|
|||||||
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle);
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle);
|
||||||
};
|
};
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if GTEST_HAS_NOTIFICATION_
|
||||||
|
// Notification has already been imported into the namespace.
|
||||||
|
// Nothing to do here.
|
||||||
|
|
||||||
|
# else
|
||||||
// Allows a controller thread to pause execution of newly created
|
// Allows a controller thread to pause execution of newly created
|
||||||
// threads until notified. Instances of this class must be created
|
// threads until notified. Instances of this class must be created
|
||||||
// and destroyed in the controller thread.
|
// and destroyed in the controller thread.
|
||||||
//
|
//
|
||||||
// This class is only for testing Google Test's own constructs. Do not
|
// This class is only for testing Google Test's own constructs. Do not
|
||||||
// use it in user tests, either directly or indirectly.
|
// use it in user tests, either directly or indirectly.
|
||||||
|
// TODO(b/203539622): Replace unconditionally with absl::Notification.
|
||||||
class GTEST_API_ Notification {
|
class GTEST_API_ Notification {
|
||||||
public:
|
public:
|
||||||
Notification();
|
Notification() : notified_(false) {}
|
||||||
void Notify();
|
Notification(const Notification&) = delete;
|
||||||
void WaitForNotification();
|
Notification& operator=(const Notification&) = delete;
|
||||||
|
|
||||||
|
// Notifies all threads created with this notification to start. Must
|
||||||
|
// be called from the controller thread.
|
||||||
|
void Notify() {
|
||||||
|
std::lock_guard<std::mutex> lock(mu_);
|
||||||
|
notified_ = true;
|
||||||
|
cv_.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blocks until the controller thread notifies. Must be called from a test
|
||||||
|
// thread.
|
||||||
|
void WaitForNotification() {
|
||||||
|
std::unique_lock<std::mutex> lock(mu_);
|
||||||
|
cv_.wait(lock, [this]() { return notified_; });
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AutoHandle event_;
|
std::mutex mu_;
|
||||||
|
std::condition_variable cv_;
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification);
|
bool notified_;
|
||||||
};
|
};
|
||||||
# endif // GTEST_HAS_NOTIFICATION_
|
# endif // GTEST_HAS_NOTIFICATION_
|
||||||
|
|
||||||
@ -2213,22 +2178,40 @@ using TimeInMillis = int64_t; // Represents time in milliseconds.
|
|||||||
# define GTEST_FLAG_SAVER_ ::testing::internal::GTestFlagSaver
|
# define GTEST_FLAG_SAVER_ ::testing::internal::GTestFlagSaver
|
||||||
|
|
||||||
// Macros for declaring flags.
|
// Macros for declaring flags.
|
||||||
# define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name)
|
#define GTEST_DECLARE_bool_(name) \
|
||||||
# define GTEST_DECLARE_int32_(name) \
|
namespace testing { \
|
||||||
GTEST_API_ extern std::int32_t GTEST_FLAG(name)
|
GTEST_API_ extern bool GTEST_FLAG(name); \
|
||||||
# define GTEST_DECLARE_string_(name) \
|
} static_assert(true, "no-op to require trailing semicolon")
|
||||||
GTEST_API_ extern ::std::string GTEST_FLAG(name)
|
#define GTEST_DECLARE_int32_(name) \
|
||||||
|
namespace testing { \
|
||||||
|
GTEST_API_ extern std::int32_t GTEST_FLAG(name); \
|
||||||
|
} static_assert(true, "no-op to require trailing semicolon")
|
||||||
|
#define GTEST_DECLARE_string_(name) \
|
||||||
|
namespace testing { \
|
||||||
|
GTEST_API_ extern ::std::string GTEST_FLAG(name); \
|
||||||
|
} static_assert(true, "no-op to require trailing semicolon")
|
||||||
|
|
||||||
// Macros for defining flags.
|
// Macros for defining flags.
|
||||||
# define GTEST_DEFINE_bool_(name, default_val, doc) \
|
#define GTEST_DEFINE_bool_(name, default_val, doc) \
|
||||||
GTEST_API_ bool GTEST_FLAG(name) = (default_val)
|
namespace testing { \
|
||||||
# define GTEST_DEFINE_int32_(name, default_val, doc) \
|
GTEST_API_ bool GTEST_FLAG(name) = (default_val); \
|
||||||
GTEST_API_ std::int32_t GTEST_FLAG(name) = (default_val)
|
} static_assert(true, "no-op to require trailing semicolon")
|
||||||
# define GTEST_DEFINE_string_(name, default_val, doc) \
|
#define GTEST_DEFINE_int32_(name, default_val, doc) \
|
||||||
GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val)
|
namespace testing { \
|
||||||
|
GTEST_API_ std::int32_t GTEST_FLAG(name) = (default_val); \
|
||||||
|
} static_assert(true, "no-op to require trailing semicolon")
|
||||||
|
#define GTEST_DEFINE_string_(name, default_val, doc) \
|
||||||
|
namespace testing { \
|
||||||
|
GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val); \
|
||||||
|
} static_assert(true, "no-op to require trailing semicolon")
|
||||||
|
|
||||||
#endif // !defined(GTEST_DECLARE_bool_)
|
#endif // !defined(GTEST_DECLARE_bool_)
|
||||||
|
|
||||||
|
#if !defined(GTEST_FLAG_GET)
|
||||||
|
#define GTEST_FLAG_GET(name) ::testing::GTEST_FLAG(name)
|
||||||
|
#define GTEST_FLAG_SET(name, value) (void)(::testing::GTEST_FLAG(name) = value)
|
||||||
|
#endif // !defined(GTEST_FLAG_GET)
|
||||||
|
|
||||||
// Thread annotations
|
// Thread annotations
|
||||||
#if !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_)
|
#if !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_)
|
||||||
# define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)
|
# define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)
|
||||||
@ -2308,6 +2291,7 @@ namespace testing {
|
|||||||
namespace internal {
|
namespace internal {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using Optional = ::absl::optional<T>;
|
using Optional = ::absl::optional<T>;
|
||||||
|
inline ::absl::nullopt_t Nullopt() { return ::absl::nullopt; }
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
#else
|
#else
|
||||||
@ -2321,6 +2305,7 @@ namespace testing {
|
|||||||
namespace internal {
|
namespace internal {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using Optional = ::std::optional<T>;
|
using Optional = ::std::optional<T>;
|
||||||
|
inline ::std::nullopt_t Nullopt() { return ::std::nullopt; }
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
// The case where absl is configured NOT to alias std::optional is not
|
// The case where absl is configured NOT to alias std::optional is not
|
||||||
|
@ -36,8 +36,6 @@
|
|||||||
// This header file is #included by gtest-internal.h.
|
// This header file is #included by gtest-internal.h.
|
||||||
// It should not be #included by other files.
|
// It should not be #included by other files.
|
||||||
|
|
||||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
|
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
|
||||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
|
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
|
||||||
|
|
||||||
|
@ -30,8 +30,6 @@
|
|||||||
// Type utilities needed for implementing typed and type-parameterized
|
// Type utilities needed for implementing typed and type-parameterized
|
||||||
// tests.
|
// tests.
|
||||||
|
|
||||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
|
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
|
||||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
|
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
|
||||||
|
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
# Please Note:
|
|
||||||
|
|
||||||
Files in this directory are no longer supported by the maintainers. They
|
|
||||||
represent mosty historical artifacts and supported by the community only. There
|
|
||||||
is no guarantee whatsoever that these scripts still work.
|
|
@ -1,83 +0,0 @@
|
|||||||
# Copyright 2013 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.
|
|
||||||
|
|
||||||
"""Shared utilities for writing scripts for Google Test/Mock."""
|
|
||||||
|
|
||||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
|
||||||
|
|
||||||
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
|
|
||||||
|
|
||||||
# Matches the line from 'svn info .' output that describes what SVN
|
|
||||||
# path the current local directory corresponds to. For example, in
|
|
||||||
# a googletest SVN workspace's trunk/test directory, the output will be:
|
|
||||||
#
|
|
||||||
# URL: https://googletest.googlecode.com/svn/trunk/test
|
|
||||||
_SVN_INFO_URL_RE = re.compile(r'^URL: https://(\w+)\.googlecode\.com/svn(.*)')
|
|
||||||
|
|
||||||
|
|
||||||
def GetCommandOutput(command):
|
|
||||||
"""Runs the shell command and returns its stdout as a list of lines."""
|
|
||||||
|
|
||||||
f = os.popen(command, 'r')
|
|
||||||
lines = [line.strip() for line in f.readlines()]
|
|
||||||
f.close()
|
|
||||||
return lines
|
|
||||||
|
|
||||||
|
|
||||||
def GetSvnInfo():
|
|
||||||
"""Returns the project name and the current SVN workspace's root path."""
|
|
||||||
|
|
||||||
for line in GetCommandOutput('svn info .'):
|
|
||||||
m = _SVN_INFO_URL_RE.match(line)
|
|
||||||
if m:
|
|
||||||
project = m.group(1) # googletest or googlemock
|
|
||||||
rel_path = m.group(2)
|
|
||||||
root = os.path.realpath(rel_path.count('/') * '../')
|
|
||||||
return project, root
|
|
||||||
|
|
||||||
return None, None
|
|
||||||
|
|
||||||
|
|
||||||
def GetSvnTrunk():
|
|
||||||
"""Returns the current SVN workspace's trunk root path."""
|
|
||||||
|
|
||||||
_, root = GetSvnInfo()
|
|
||||||
return root + '/trunk' if root else None
|
|
||||||
|
|
||||||
|
|
||||||
def IsInGTestSvn():
|
|
||||||
project, _ = GetSvnInfo()
|
|
||||||
return project == 'googletest'
|
|
||||||
|
|
||||||
|
|
||||||
def IsInGMockSvn():
|
|
||||||
project, _ = GetSvnInfo()
|
|
||||||
return project == 'googlemock'
|
|
@ -1,253 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# Copyright 2009, 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.
|
|
||||||
|
|
||||||
"""fuse_gtest_files.py v0.2.0
|
|
||||||
Fuses Google Test source code into a .h file and a .cc file.
|
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
fuse_gtest_files.py [GTEST_ROOT_DIR] OUTPUT_DIR
|
|
||||||
|
|
||||||
Scans GTEST_ROOT_DIR for Google Test source code, and generates
|
|
||||||
two files: OUTPUT_DIR/gtest/gtest.h and OUTPUT_DIR/gtest/gtest-all.cc.
|
|
||||||
Then you can build your tests by adding OUTPUT_DIR to the include
|
|
||||||
search path and linking with OUTPUT_DIR/gtest/gtest-all.cc. These
|
|
||||||
two files contain everything you need to use Google Test. Hence
|
|
||||||
you can "install" Google Test by copying them to wherever you want.
|
|
||||||
|
|
||||||
GTEST_ROOT_DIR can be omitted and defaults to the parent
|
|
||||||
directory of the directory holding this script.
|
|
||||||
|
|
||||||
EXAMPLES
|
|
||||||
./fuse_gtest_files.py fused_gtest
|
|
||||||
./fuse_gtest_files.py path/to/unpacked/gtest fused_gtest
|
|
||||||
|
|
||||||
This tool is experimental. In particular, it assumes that there is no
|
|
||||||
conditional inclusion of Google Test headers. Please report any
|
|
||||||
problems to googletestframework@googlegroups.com. You can read
|
|
||||||
https://github.com/google/googletest/blob/master/googletest/docs/advanced.md for
|
|
||||||
more information.
|
|
||||||
"""
|
|
||||||
|
|
||||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
|
||||||
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
try:
|
|
||||||
from sets import Set as set # For Python 2.3 compatibility
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
import sys
|
|
||||||
|
|
||||||
# We assume that this file is in the scripts/ directory in the Google
|
|
||||||
# Test root directory.
|
|
||||||
DEFAULT_GTEST_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..')
|
|
||||||
|
|
||||||
# Regex for matching '#include "gtest/..."'.
|
|
||||||
INCLUDE_GTEST_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(gtest/.+)"')
|
|
||||||
|
|
||||||
# Regex for matching '#include "src/..."'.
|
|
||||||
INCLUDE_SRC_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(src/.+)"')
|
|
||||||
|
|
||||||
# Where to find the source seed files.
|
|
||||||
GTEST_H_SEED = 'include/gtest/gtest.h'
|
|
||||||
GTEST_SPI_H_SEED = 'include/gtest/gtest-spi.h'
|
|
||||||
GTEST_ALL_CC_SEED = 'src/gtest-all.cc'
|
|
||||||
|
|
||||||
# Where to put the generated files.
|
|
||||||
GTEST_H_OUTPUT = 'gtest/gtest.h'
|
|
||||||
GTEST_ALL_CC_OUTPUT = 'gtest/gtest-all.cc'
|
|
||||||
|
|
||||||
|
|
||||||
def VerifyFileExists(directory, relative_path):
|
|
||||||
"""Verifies that the given file exists; aborts on failure.
|
|
||||||
|
|
||||||
relative_path is the file path relative to the given directory.
|
|
||||||
"""
|
|
||||||
|
|
||||||
if not os.path.isfile(os.path.join(directory, relative_path)):
|
|
||||||
print('ERROR: Cannot find %s in directory %s.' % (relative_path,
|
|
||||||
directory))
|
|
||||||
print('Please either specify a valid project root directory '
|
|
||||||
'or omit it on the command line.')
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
def ValidateGTestRootDir(gtest_root):
|
|
||||||
"""Makes sure gtest_root points to a valid gtest root directory.
|
|
||||||
|
|
||||||
The function aborts the program on failure.
|
|
||||||
"""
|
|
||||||
|
|
||||||
VerifyFileExists(gtest_root, GTEST_H_SEED)
|
|
||||||
VerifyFileExists(gtest_root, GTEST_ALL_CC_SEED)
|
|
||||||
|
|
||||||
|
|
||||||
def VerifyOutputFile(output_dir, relative_path):
|
|
||||||
"""Verifies that the given output file path is valid.
|
|
||||||
|
|
||||||
relative_path is relative to the output_dir directory.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Makes sure the output file either doesn't exist or can be overwritten.
|
|
||||||
output_file = os.path.join(output_dir, relative_path)
|
|
||||||
if os.path.exists(output_file):
|
|
||||||
# TODO(wan@google.com): The following user-interaction doesn't
|
|
||||||
# work with automated processes. We should provide a way for the
|
|
||||||
# Makefile to force overwriting the files.
|
|
||||||
print('%s already exists in directory %s - overwrite it? (y/N) ' %
|
|
||||||
(relative_path, output_dir))
|
|
||||||
answer = sys.stdin.readline().strip()
|
|
||||||
if answer not in ['y', 'Y']:
|
|
||||||
print('ABORTED.')
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# Makes sure the directory holding the output file exists; creates
|
|
||||||
# it and all its ancestors if necessary.
|
|
||||||
parent_directory = os.path.dirname(output_file)
|
|
||||||
if not os.path.isdir(parent_directory):
|
|
||||||
os.makedirs(parent_directory)
|
|
||||||
|
|
||||||
|
|
||||||
def ValidateOutputDir(output_dir):
|
|
||||||
"""Makes sure output_dir points to a valid output directory.
|
|
||||||
|
|
||||||
The function aborts the program on failure.
|
|
||||||
"""
|
|
||||||
|
|
||||||
VerifyOutputFile(output_dir, GTEST_H_OUTPUT)
|
|
||||||
VerifyOutputFile(output_dir, GTEST_ALL_CC_OUTPUT)
|
|
||||||
|
|
||||||
|
|
||||||
def FuseGTestH(gtest_root, output_dir):
|
|
||||||
"""Scans folder gtest_root to generate gtest/gtest.h in output_dir."""
|
|
||||||
|
|
||||||
output_file = open(os.path.join(output_dir, GTEST_H_OUTPUT), 'w')
|
|
||||||
processed_files = set() # Holds all gtest headers we've processed.
|
|
||||||
|
|
||||||
def ProcessFile(gtest_header_path):
|
|
||||||
"""Processes the given gtest header file."""
|
|
||||||
|
|
||||||
# We don't process the same header twice.
|
|
||||||
if gtest_header_path in processed_files:
|
|
||||||
return
|
|
||||||
|
|
||||||
processed_files.add(gtest_header_path)
|
|
||||||
|
|
||||||
# Reads each line in the given gtest header.
|
|
||||||
for line in open(os.path.join(gtest_root, gtest_header_path), 'r'):
|
|
||||||
m = INCLUDE_GTEST_FILE_REGEX.match(line)
|
|
||||||
if m:
|
|
||||||
# It's '#include "gtest/..."' - let's process it recursively.
|
|
||||||
ProcessFile('include/' + m.group(1))
|
|
||||||
else:
|
|
||||||
# Otherwise we copy the line unchanged to the output file.
|
|
||||||
output_file.write(line)
|
|
||||||
|
|
||||||
ProcessFile(GTEST_H_SEED)
|
|
||||||
output_file.close()
|
|
||||||
|
|
||||||
|
|
||||||
def FuseGTestAllCcToFile(gtest_root, output_file):
|
|
||||||
"""Scans folder gtest_root to generate gtest/gtest-all.cc in output_file."""
|
|
||||||
|
|
||||||
processed_files = set()
|
|
||||||
|
|
||||||
def ProcessFile(gtest_source_file):
|
|
||||||
"""Processes the given gtest source file."""
|
|
||||||
|
|
||||||
# We don't process the same #included file twice.
|
|
||||||
if gtest_source_file in processed_files:
|
|
||||||
return
|
|
||||||
|
|
||||||
processed_files.add(gtest_source_file)
|
|
||||||
|
|
||||||
# Reads each line in the given gtest source file.
|
|
||||||
for line in open(os.path.join(gtest_root, gtest_source_file), 'r'):
|
|
||||||
m = INCLUDE_GTEST_FILE_REGEX.match(line)
|
|
||||||
if m:
|
|
||||||
if 'include/' + m.group(1) == GTEST_SPI_H_SEED:
|
|
||||||
# It's '#include "gtest/gtest-spi.h"'. This file is not
|
|
||||||
# #included by "gtest/gtest.h", so we need to process it.
|
|
||||||
ProcessFile(GTEST_SPI_H_SEED)
|
|
||||||
else:
|
|
||||||
# It's '#include "gtest/foo.h"' where foo is not gtest-spi.
|
|
||||||
# We treat it as '#include "gtest/gtest.h"', as all other
|
|
||||||
# gtest headers are being fused into gtest.h and cannot be
|
|
||||||
# #included directly.
|
|
||||||
|
|
||||||
# There is no need to #include "gtest/gtest.h" more than once.
|
|
||||||
if not GTEST_H_SEED in processed_files:
|
|
||||||
processed_files.add(GTEST_H_SEED)
|
|
||||||
output_file.write('#include "%s"\n' % (GTEST_H_OUTPUT,))
|
|
||||||
else:
|
|
||||||
m = INCLUDE_SRC_FILE_REGEX.match(line)
|
|
||||||
if m:
|
|
||||||
# It's '#include "src/foo"' - let's process it recursively.
|
|
||||||
ProcessFile(m.group(1))
|
|
||||||
else:
|
|
||||||
output_file.write(line)
|
|
||||||
|
|
||||||
ProcessFile(GTEST_ALL_CC_SEED)
|
|
||||||
|
|
||||||
|
|
||||||
def FuseGTestAllCc(gtest_root, output_dir):
|
|
||||||
"""Scans folder gtest_root to generate gtest/gtest-all.cc in output_dir."""
|
|
||||||
|
|
||||||
output_file = open(os.path.join(output_dir, GTEST_ALL_CC_OUTPUT), 'w')
|
|
||||||
FuseGTestAllCcToFile(gtest_root, output_file)
|
|
||||||
output_file.close()
|
|
||||||
|
|
||||||
|
|
||||||
def FuseGTest(gtest_root, output_dir):
|
|
||||||
"""Fuses gtest.h and gtest-all.cc."""
|
|
||||||
|
|
||||||
ValidateGTestRootDir(gtest_root)
|
|
||||||
ValidateOutputDir(output_dir)
|
|
||||||
|
|
||||||
FuseGTestH(gtest_root, output_dir)
|
|
||||||
FuseGTestAllCc(gtest_root, output_dir)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
argc = len(sys.argv)
|
|
||||||
if argc == 2:
|
|
||||||
# fuse_gtest_files.py OUTPUT_DIR
|
|
||||||
FuseGTest(DEFAULT_GTEST_ROOT_DIR, sys.argv[1])
|
|
||||||
elif argc == 3:
|
|
||||||
# fuse_gtest_files.py GTEST_ROOT_DIR OUTPUT_DIR
|
|
||||||
FuseGTest(sys.argv[1], sys.argv[2])
|
|
||||||
else:
|
|
||||||
print(__doc__)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
@ -1,733 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# Copyright 2006, 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.
|
|
||||||
|
|
||||||
"""gen_gtest_pred_impl.py v0.1
|
|
||||||
|
|
||||||
Generates the implementation of Google Test predicate assertions and
|
|
||||||
accompanying tests.
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
|
|
||||||
gen_gtest_pred_impl.py MAX_ARITY
|
|
||||||
|
|
||||||
where MAX_ARITY is a positive integer.
|
|
||||||
|
|
||||||
The command generates the implementation of up-to MAX_ARITY-ary
|
|
||||||
predicate assertions, and writes it to file gtest_pred_impl.h in the
|
|
||||||
directory where the script is. It also generates the accompanying
|
|
||||||
unit test in file gtest_pred_impl_unittest.cc.
|
|
||||||
"""
|
|
||||||
|
|
||||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
|
|
||||||
# Where this script is.
|
|
||||||
SCRIPT_DIR = os.path.dirname(sys.argv[0])
|
|
||||||
|
|
||||||
# Where to store the generated header.
|
|
||||||
HEADER = os.path.join(SCRIPT_DIR, '../include/gtest/gtest_pred_impl.h')
|
|
||||||
|
|
||||||
# Where to store the generated unit test.
|
|
||||||
UNIT_TEST = os.path.join(SCRIPT_DIR, '../test/gtest_pred_impl_unittest.cc')
|
|
||||||
|
|
||||||
|
|
||||||
def HeaderPreamble(n):
|
|
||||||
"""Returns the preamble for the header file.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
n: the maximum arity of the predicate macros to be generated.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# A map that defines the values used in the preamble template.
|
|
||||||
DEFS = {
|
|
||||||
'today' : time.strftime('%m/%d/%Y'),
|
|
||||||
'year' : time.strftime('%Y'),
|
|
||||||
'command' : '%s %s' % (os.path.basename(sys.argv[0]), n),
|
|
||||||
'n' : n
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
"""// Copyright 2006, 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.
|
|
||||||
|
|
||||||
// This file is AUTOMATICALLY GENERATED on %(today)s by command
|
|
||||||
// '%(command)s'. DO NOT EDIT BY HAND!
|
|
||||||
//
|
|
||||||
// Implements a family of generic predicate assertion macros.
|
|
||||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
|
||||||
#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
|
||||||
|
|
||||||
namespace testing {
|
|
||||||
|
|
||||||
// This header implements a family of generic predicate assertion
|
|
||||||
// macros:
|
|
||||||
//
|
|
||||||
// ASSERT_PRED_FORMAT1(pred_format, v1)
|
|
||||||
// ASSERT_PRED_FORMAT2(pred_format, v1, v2)
|
|
||||||
// ...
|
|
||||||
//
|
|
||||||
// where pred_format is a function or functor that takes n (in the
|
|
||||||
// case of ASSERT_PRED_FORMATn) values and their source expression
|
|
||||||
// text, and returns a testing::AssertionResult. See the definition
|
|
||||||
// of ASSERT_EQ in gtest.h for an example.
|
|
||||||
//
|
|
||||||
// If you don't care about formatting, you can use the more
|
|
||||||
// restrictive version:
|
|
||||||
//
|
|
||||||
// ASSERT_PRED1(pred, v1)
|
|
||||||
// ASSERT_PRED2(pred, v1, v2)
|
|
||||||
// ...
|
|
||||||
//
|
|
||||||
// where pred is an n-ary function or functor that returns bool,
|
|
||||||
// and the values v1, v2, ..., must support the << operator for
|
|
||||||
// streaming to std::ostream.
|
|
||||||
//
|
|
||||||
// We also define the EXPECT_* variations.
|
|
||||||
//
|
|
||||||
// For now we only support predicates whose arity is at most %(n)s.
|
|
||||||
// Please email googletestframework@googlegroups.com if you need
|
|
||||||
// support for higher arities.
|
|
||||||
|
|
||||||
// GTEST_ASSERT_ is the basic statement to which all of the assertions
|
|
||||||
// in this file reduce. Don't use this in your code.
|
|
||||||
|
|
||||||
#define GTEST_ASSERT_(expression, on_failure) \\
|
|
||||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\
|
|
||||||
if (const ::testing::AssertionResult gtest_ar = (expression)) \\
|
|
||||||
; \\
|
|
||||||
else \\
|
|
||||||
on_failure(gtest_ar.failure_message())
|
|
||||||
""" % DEFS)
|
|
||||||
|
|
||||||
|
|
||||||
def Arity(n):
|
|
||||||
"""Returns the English name of the given arity."""
|
|
||||||
|
|
||||||
if n < 0:
|
|
||||||
return None
|
|
||||||
elif n <= 3:
|
|
||||||
return ['nullary', 'unary', 'binary', 'ternary'][n]
|
|
||||||
else:
|
|
||||||
return '%s-ary' % n
|
|
||||||
|
|
||||||
|
|
||||||
def Title(word):
|
|
||||||
"""Returns the given word in title case. The difference between
|
|
||||||
this and string's title() method is that Title('4-ary') is '4-ary'
|
|
||||||
while '4-ary'.title() is '4-Ary'."""
|
|
||||||
|
|
||||||
return word[0].upper() + word[1:]
|
|
||||||
|
|
||||||
|
|
||||||
def OneTo(n):
|
|
||||||
"""Returns the list [1, 2, 3, ..., n]."""
|
|
||||||
|
|
||||||
return range(1, n + 1)
|
|
||||||
|
|
||||||
|
|
||||||
def Iter(n, format, sep=''):
|
|
||||||
"""Given a positive integer n, a format string that contains 0 or
|
|
||||||
more '%s' format specs, and optionally a separator string, returns
|
|
||||||
the join of n strings, each formatted with the format string on an
|
|
||||||
iterator ranged from 1 to n.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
Iter(3, 'v%s', sep=', ') returns 'v1, v2, v3'.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# How many '%s' specs are in format?
|
|
||||||
spec_count = len(format.split('%s')) - 1
|
|
||||||
return sep.join([format % (spec_count * (i,)) for i in OneTo(n)])
|
|
||||||
|
|
||||||
|
|
||||||
def ImplementationForArity(n):
|
|
||||||
"""Returns the implementation of n-ary predicate assertions."""
|
|
||||||
|
|
||||||
# A map the defines the values used in the implementation template.
|
|
||||||
DEFS = {
|
|
||||||
'n' : str(n),
|
|
||||||
'vs' : Iter(n, 'v%s', sep=', '),
|
|
||||||
'vts' : Iter(n, '#v%s', sep=', '),
|
|
||||||
'arity' : Arity(n),
|
|
||||||
'Arity' : Title(Arity(n))
|
|
||||||
}
|
|
||||||
|
|
||||||
impl = """
|
|
||||||
|
|
||||||
// Helper function for implementing {EXPECT|ASSERT}_PRED%(n)s. Don't use
|
|
||||||
// this in your code.
|
|
||||||
template <typename Pred""" % DEFS
|
|
||||||
|
|
||||||
impl += Iter(n, """,
|
|
||||||
typename T%s""")
|
|
||||||
|
|
||||||
impl += """>
|
|
||||||
AssertionResult AssertPred%(n)sHelper(const char* pred_text""" % DEFS
|
|
||||||
|
|
||||||
impl += Iter(n, """,
|
|
||||||
const char* e%s""")
|
|
||||||
|
|
||||||
impl += """,
|
|
||||||
Pred pred"""
|
|
||||||
|
|
||||||
impl += Iter(n, """,
|
|
||||||
const T%s& v%s""")
|
|
||||||
|
|
||||||
impl += """) {
|
|
||||||
if (pred(%(vs)s)) return AssertionSuccess();
|
|
||||||
|
|
||||||
""" % DEFS
|
|
||||||
|
|
||||||
impl += ' return AssertionFailure() << pred_text << "("'
|
|
||||||
|
|
||||||
impl += Iter(n, """
|
|
||||||
<< e%s""", sep=' << ", "')
|
|
||||||
|
|
||||||
impl += ' << ") evaluates to false, where"'
|
|
||||||
|
|
||||||
impl += Iter(
|
|
||||||
n, """
|
|
||||||
<< "\\n" << e%s << " evaluates to " << ::testing::PrintToString(v%s)"""
|
|
||||||
)
|
|
||||||
|
|
||||||
impl += """;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT%(n)s.
|
|
||||||
// Don't use this in your code.
|
|
||||||
#define GTEST_PRED_FORMAT%(n)s_(pred_format, %(vs)s, on_failure)\\
|
|
||||||
GTEST_ASSERT_(pred_format(%(vts)s, %(vs)s), \\
|
|
||||||
on_failure)
|
|
||||||
|
|
||||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED%(n)s. Don't use
|
|
||||||
// this in your code.
|
|
||||||
#define GTEST_PRED%(n)s_(pred, %(vs)s, on_failure)\\
|
|
||||||
GTEST_ASSERT_(::testing::AssertPred%(n)sHelper(#pred""" % DEFS
|
|
||||||
|
|
||||||
impl += Iter(n, """, \\
|
|
||||||
#v%s""")
|
|
||||||
|
|
||||||
impl += """, \\
|
|
||||||
pred"""
|
|
||||||
|
|
||||||
impl += Iter(n, """, \\
|
|
||||||
v%s""")
|
|
||||||
|
|
||||||
impl += """), on_failure)
|
|
||||||
|
|
||||||
// %(Arity)s predicate assertion macros.
|
|
||||||
#define EXPECT_PRED_FORMAT%(n)s(pred_format, %(vs)s) \\
|
|
||||||
GTEST_PRED_FORMAT%(n)s_(pred_format, %(vs)s, GTEST_NONFATAL_FAILURE_)
|
|
||||||
#define EXPECT_PRED%(n)s(pred, %(vs)s) \\
|
|
||||||
GTEST_PRED%(n)s_(pred, %(vs)s, GTEST_NONFATAL_FAILURE_)
|
|
||||||
#define ASSERT_PRED_FORMAT%(n)s(pred_format, %(vs)s) \\
|
|
||||||
GTEST_PRED_FORMAT%(n)s_(pred_format, %(vs)s, GTEST_FATAL_FAILURE_)
|
|
||||||
#define ASSERT_PRED%(n)s(pred, %(vs)s) \\
|
|
||||||
GTEST_PRED%(n)s_(pred, %(vs)s, GTEST_FATAL_FAILURE_)
|
|
||||||
|
|
||||||
""" % DEFS
|
|
||||||
|
|
||||||
return impl
|
|
||||||
|
|
||||||
|
|
||||||
def HeaderPostamble():
|
|
||||||
"""Returns the postamble for the header file."""
|
|
||||||
|
|
||||||
return """
|
|
||||||
|
|
||||||
} // namespace testing
|
|
||||||
|
|
||||||
#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def GenerateFile(path, content):
|
|
||||||
"""Given a file path and a content string
|
|
||||||
overwrites it with the given content.
|
|
||||||
"""
|
|
||||||
print 'Updating file %s . . .' % path
|
|
||||||
f = file(path, 'w+')
|
|
||||||
print >>f, content,
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
print 'File %s has been updated.' % path
|
|
||||||
|
|
||||||
|
|
||||||
def GenerateHeader(n):
|
|
||||||
"""Given the maximum arity n, updates the header file that implements
|
|
||||||
the predicate assertions.
|
|
||||||
"""
|
|
||||||
GenerateFile(HEADER,
|
|
||||||
HeaderPreamble(n)
|
|
||||||
+ ''.join([ImplementationForArity(i) for i in OneTo(n)])
|
|
||||||
+ HeaderPostamble())
|
|
||||||
|
|
||||||
|
|
||||||
def UnitTestPreamble():
|
|
||||||
"""Returns the preamble for the unit test file."""
|
|
||||||
|
|
||||||
# A map that defines the values used in the preamble template.
|
|
||||||
DEFS = {
|
|
||||||
'today' : time.strftime('%m/%d/%Y'),
|
|
||||||
'year' : time.strftime('%Y'),
|
|
||||||
'command' : '%s %s' % (os.path.basename(sys.argv[0]), sys.argv[1]),
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
"""// Copyright 2006, 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.
|
|
||||||
|
|
||||||
// This file is AUTOMATICALLY GENERATED on %(today)s by command
|
|
||||||
// '%(command)s'. DO NOT EDIT BY HAND!
|
|
||||||
|
|
||||||
// Regression test for gtest_pred_impl.h
|
|
||||||
//
|
|
||||||
// This file is generated by a script and quite long. If you intend to
|
|
||||||
// learn how Google Test works by reading its unit tests, read
|
|
||||||
// gtest_unittest.cc instead.
|
|
||||||
//
|
|
||||||
// This is intended as a regression test for the Google Test predicate
|
|
||||||
// assertions. We compile it as part of the gtest_unittest target
|
|
||||||
// only to keep the implementation tidy and compact, as it is quite
|
|
||||||
// involved to set up the stage for testing Google Test using Google
|
|
||||||
// Test itself.
|
|
||||||
//
|
|
||||||
// Currently, gtest_unittest takes ~11 seconds to run in the testing
|
|
||||||
// daemon. In the future, if it grows too large and needs much more
|
|
||||||
// time to finish, we should consider separating this file into a
|
|
||||||
// stand-alone regression test.
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
|
||||||
#include "gtest/gtest-spi.h"
|
|
||||||
|
|
||||||
// A user-defined data type.
|
|
||||||
struct Bool {
|
|
||||||
explicit Bool(int val) : value(val != 0) {}
|
|
||||||
|
|
||||||
bool operator>(int n) const { return value > Bool(n).value; }
|
|
||||||
|
|
||||||
Bool operator+(const Bool& rhs) const { return Bool(value + rhs.value); }
|
|
||||||
|
|
||||||
bool operator==(const Bool& rhs) const { return value == rhs.value; }
|
|
||||||
|
|
||||||
bool value;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Enables Bool to be used in assertions.
|
|
||||||
std::ostream& operator<<(std::ostream& os, const Bool& x) {
|
|
||||||
return os << (x.value ? "true" : "false");
|
|
||||||
}
|
|
||||||
|
|
||||||
""" % DEFS)
|
|
||||||
|
|
||||||
|
|
||||||
def TestsForArity(n):
|
|
||||||
"""Returns the tests for n-ary predicate assertions."""
|
|
||||||
|
|
||||||
# A map that defines the values used in the template for the tests.
|
|
||||||
DEFS = {
|
|
||||||
'n' : n,
|
|
||||||
'es' : Iter(n, 'e%s', sep=', '),
|
|
||||||
'vs' : Iter(n, 'v%s', sep=', '),
|
|
||||||
'vts' : Iter(n, '#v%s', sep=', '),
|
|
||||||
'tvs' : Iter(n, 'T%s v%s', sep=', '),
|
|
||||||
'int_vs' : Iter(n, 'int v%s', sep=', '),
|
|
||||||
'Bool_vs' : Iter(n, 'Bool v%s', sep=', '),
|
|
||||||
'types' : Iter(n, 'typename T%s', sep=', '),
|
|
||||||
'v_sum' : Iter(n, 'v%s', sep=' + '),
|
|
||||||
'arity' : Arity(n),
|
|
||||||
'Arity' : Title(Arity(n)),
|
|
||||||
}
|
|
||||||
|
|
||||||
tests = (
|
|
||||||
"""// Sample functions/functors for testing %(arity)s predicate assertions.
|
|
||||||
|
|
||||||
// A %(arity)s predicate function.
|
|
||||||
template <%(types)s>
|
|
||||||
bool PredFunction%(n)s(%(tvs)s) {
|
|
||||||
return %(v_sum)s > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The following two functions are needed because a compiler doesn't have
|
|
||||||
// a context yet to know which template function must be instantiated.
|
|
||||||
bool PredFunction%(n)sInt(%(int_vs)s) {
|
|
||||||
return %(v_sum)s > 0;
|
|
||||||
}
|
|
||||||
bool PredFunction%(n)sBool(%(Bool_vs)s) {
|
|
||||||
return %(v_sum)s > 0;
|
|
||||||
}
|
|
||||||
""" % DEFS)
|
|
||||||
|
|
||||||
tests += """
|
|
||||||
// A %(arity)s predicate functor.
|
|
||||||
struct PredFunctor%(n)s {
|
|
||||||
template <%(types)s>
|
|
||||||
bool operator()(""" % DEFS
|
|
||||||
|
|
||||||
tests += Iter(n, 'const T%s& v%s', sep=""",
|
|
||||||
""")
|
|
||||||
|
|
||||||
tests += """) {
|
|
||||||
return %(v_sum)s > 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
""" % DEFS
|
|
||||||
|
|
||||||
tests += """
|
|
||||||
// A %(arity)s predicate-formatter function.
|
|
||||||
template <%(types)s>
|
|
||||||
testing::AssertionResult PredFormatFunction%(n)s(""" % DEFS
|
|
||||||
|
|
||||||
tests += Iter(n, 'const char* e%s', sep=""",
|
|
||||||
""")
|
|
||||||
|
|
||||||
tests += Iter(n, """,
|
|
||||||
const T%s& v%s""")
|
|
||||||
|
|
||||||
tests += """) {
|
|
||||||
if (PredFunction%(n)s(%(vs)s))
|
|
||||||
return testing::AssertionSuccess();
|
|
||||||
|
|
||||||
return testing::AssertionFailure()
|
|
||||||
<< """ % DEFS
|
|
||||||
|
|
||||||
tests += Iter(n, 'e%s', sep=' << " + " << ')
|
|
||||||
|
|
||||||
tests += """
|
|
||||||
<< " is expected to be positive, but evaluates to "
|
|
||||||
<< %(v_sum)s << ".";
|
|
||||||
}
|
|
||||||
""" % DEFS
|
|
||||||
|
|
||||||
tests += """
|
|
||||||
// A %(arity)s predicate-formatter functor.
|
|
||||||
struct PredFormatFunctor%(n)s {
|
|
||||||
template <%(types)s>
|
|
||||||
testing::AssertionResult operator()(""" % DEFS
|
|
||||||
|
|
||||||
tests += Iter(n, 'const char* e%s', sep=""",
|
|
||||||
""")
|
|
||||||
|
|
||||||
tests += Iter(n, """,
|
|
||||||
const T%s& v%s""")
|
|
||||||
|
|
||||||
tests += """) const {
|
|
||||||
return PredFormatFunction%(n)s(%(es)s, %(vs)s);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
""" % DEFS
|
|
||||||
|
|
||||||
tests += """
|
|
||||||
// Tests for {EXPECT|ASSERT}_PRED_FORMAT%(n)s.
|
|
||||||
|
|
||||||
class Predicate%(n)sTest : public testing::Test {
|
|
||||||
protected:
|
|
||||||
void SetUp() override {
|
|
||||||
expected_to_finish_ = true;
|
|
||||||
finished_ = false;""" % DEFS
|
|
||||||
|
|
||||||
tests += """
|
|
||||||
""" + Iter(n, 'n%s_ = ') + """0;
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|
|
||||||
tests += """
|
|
||||||
void TearDown() override {
|
|
||||||
// Verifies that each of the predicate's arguments was evaluated
|
|
||||||
// exactly once."""
|
|
||||||
|
|
||||||
tests += ''.join(["""
|
|
||||||
EXPECT_EQ(1, n%s_) <<
|
|
||||||
"The predicate assertion didn't evaluate argument %s "
|
|
||||||
"exactly once.";""" % (i, i + 1) for i in OneTo(n)])
|
|
||||||
|
|
||||||
tests += """
|
|
||||||
|
|
||||||
// Verifies that the control flow in the test function is expected.
|
|
||||||
if (expected_to_finish_ && !finished_) {
|
|
||||||
FAIL() << "The predicate assertion unexpactedly aborted the test.";
|
|
||||||
} else if (!expected_to_finish_ && finished_) {
|
|
||||||
FAIL() << "The failed predicate assertion didn't abort the test "
|
|
||||||
"as expected.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// true if and only if the test function is expected to run to finish.
|
|
||||||
static bool expected_to_finish_;
|
|
||||||
|
|
||||||
// true if and only if the test function did run to finish.
|
|
||||||
static bool finished_;
|
|
||||||
""" % DEFS
|
|
||||||
|
|
||||||
tests += Iter(n, """
|
|
||||||
static int n%s_;""")
|
|
||||||
|
|
||||||
tests += """
|
|
||||||
};
|
|
||||||
|
|
||||||
bool Predicate%(n)sTest::expected_to_finish_;
|
|
||||||
bool Predicate%(n)sTest::finished_;
|
|
||||||
""" % DEFS
|
|
||||||
|
|
||||||
tests += Iter(n, """int Predicate%%(n)sTest::n%s_;
|
|
||||||
""") % DEFS
|
|
||||||
|
|
||||||
tests += """
|
|
||||||
typedef Predicate%(n)sTest EXPECT_PRED_FORMAT%(n)sTest;
|
|
||||||
typedef Predicate%(n)sTest ASSERT_PRED_FORMAT%(n)sTest;
|
|
||||||
typedef Predicate%(n)sTest EXPECT_PRED%(n)sTest;
|
|
||||||
typedef Predicate%(n)sTest ASSERT_PRED%(n)sTest;
|
|
||||||
""" % DEFS
|
|
||||||
|
|
||||||
def GenTest(use_format, use_assert, expect_failure,
|
|
||||||
use_functor, use_user_type):
|
|
||||||
"""Returns the test for a predicate assertion macro.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
use_format: true if and only if the assertion is a *_PRED_FORMAT*.
|
|
||||||
use_assert: true if and only if the assertion is a ASSERT_*.
|
|
||||||
expect_failure: true if and only if the assertion is expected to fail.
|
|
||||||
use_functor: true if and only if the first argument of the assertion is
|
|
||||||
a functor (as opposed to a function)
|
|
||||||
use_user_type: true if and only if the predicate functor/function takes
|
|
||||||
argument(s) of a user-defined type.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
GenTest(1, 0, 0, 1, 0) returns a test that tests the behavior
|
|
||||||
of a successful EXPECT_PRED_FORMATn() that takes a functor
|
|
||||||
whose arguments have built-in types."""
|
|
||||||
|
|
||||||
if use_assert:
|
|
||||||
assrt = 'ASSERT' # 'assert' is reserved, so we cannot use
|
|
||||||
# that identifier here.
|
|
||||||
else:
|
|
||||||
assrt = 'EXPECT'
|
|
||||||
|
|
||||||
assertion = assrt + '_PRED'
|
|
||||||
|
|
||||||
if use_format:
|
|
||||||
pred_format = 'PredFormat'
|
|
||||||
assertion += '_FORMAT'
|
|
||||||
else:
|
|
||||||
pred_format = 'Pred'
|
|
||||||
|
|
||||||
assertion += '%(n)s' % DEFS
|
|
||||||
|
|
||||||
if use_functor:
|
|
||||||
pred_format_type = 'functor'
|
|
||||||
pred_format += 'Functor%(n)s()'
|
|
||||||
else:
|
|
||||||
pred_format_type = 'function'
|
|
||||||
pred_format += 'Function%(n)s'
|
|
||||||
if not use_format:
|
|
||||||
if use_user_type:
|
|
||||||
pred_format += 'Bool'
|
|
||||||
else:
|
|
||||||
pred_format += 'Int'
|
|
||||||
|
|
||||||
test_name = pred_format_type.title()
|
|
||||||
|
|
||||||
if use_user_type:
|
|
||||||
arg_type = 'user-defined type (Bool)'
|
|
||||||
test_name += 'OnUserType'
|
|
||||||
if expect_failure:
|
|
||||||
arg = 'Bool(n%s_++)'
|
|
||||||
else:
|
|
||||||
arg = 'Bool(++n%s_)'
|
|
||||||
else:
|
|
||||||
arg_type = 'built-in type (int)'
|
|
||||||
test_name += 'OnBuiltInType'
|
|
||||||
if expect_failure:
|
|
||||||
arg = 'n%s_++'
|
|
||||||
else:
|
|
||||||
arg = '++n%s_'
|
|
||||||
|
|
||||||
if expect_failure:
|
|
||||||
successful_or_failed = 'failed'
|
|
||||||
expected_or_not = 'expected.'
|
|
||||||
test_name += 'Failure'
|
|
||||||
else:
|
|
||||||
successful_or_failed = 'successful'
|
|
||||||
expected_or_not = 'UNEXPECTED!'
|
|
||||||
test_name += 'Success'
|
|
||||||
|
|
||||||
# A map that defines the values used in the test template.
|
|
||||||
defs = DEFS.copy()
|
|
||||||
defs.update({
|
|
||||||
'assert' : assrt,
|
|
||||||
'assertion' : assertion,
|
|
||||||
'test_name' : test_name,
|
|
||||||
'pf_type' : pred_format_type,
|
|
||||||
'pf' : pred_format,
|
|
||||||
'arg_type' : arg_type,
|
|
||||||
'arg' : arg,
|
|
||||||
'successful' : successful_or_failed,
|
|
||||||
'expected' : expected_or_not,
|
|
||||||
})
|
|
||||||
|
|
||||||
test = """
|
|
||||||
// Tests a %(successful)s %(assertion)s where the
|
|
||||||
// predicate-formatter is a %(pf_type)s on a %(arg_type)s.
|
|
||||||
TEST_F(%(assertion)sTest, %(test_name)s) {""" % defs
|
|
||||||
|
|
||||||
indent = (len(assertion) + 3)*' '
|
|
||||||
extra_indent = ''
|
|
||||||
|
|
||||||
if expect_failure:
|
|
||||||
extra_indent = ' '
|
|
||||||
if use_assert:
|
|
||||||
test += """
|
|
||||||
expected_to_finish_ = false;
|
|
||||||
EXPECT_FATAL_FAILURE({ // NOLINT"""
|
|
||||||
else:
|
|
||||||
test += """
|
|
||||||
EXPECT_NONFATAL_FAILURE({ // NOLINT"""
|
|
||||||
|
|
||||||
test += '\n' + extra_indent + """ %(assertion)s(%(pf)s""" % defs
|
|
||||||
|
|
||||||
test = test % defs
|
|
||||||
test += Iter(n, ',\n' + indent + extra_indent + '%(arg)s' % defs)
|
|
||||||
test += ');\n' + extra_indent + ' finished_ = true;\n'
|
|
||||||
|
|
||||||
if expect_failure:
|
|
||||||
test += ' }, "");\n'
|
|
||||||
|
|
||||||
test += '}\n'
|
|
||||||
return test
|
|
||||||
|
|
||||||
# Generates tests for all 2**6 = 64 combinations.
|
|
||||||
tests += ''.join([GenTest(use_format, use_assert, expect_failure,
|
|
||||||
use_functor, use_user_type)
|
|
||||||
for use_format in [0, 1]
|
|
||||||
for use_assert in [0, 1]
|
|
||||||
for expect_failure in [0, 1]
|
|
||||||
for use_functor in [0, 1]
|
|
||||||
for use_user_type in [0, 1]
|
|
||||||
])
|
|
||||||
|
|
||||||
return tests
|
|
||||||
|
|
||||||
|
|
||||||
def UnitTestPostamble():
|
|
||||||
"""Returns the postamble for the tests."""
|
|
||||||
|
|
||||||
return ''
|
|
||||||
|
|
||||||
|
|
||||||
def GenerateUnitTest(n):
|
|
||||||
"""Returns the tests for up-to n-ary predicate assertions."""
|
|
||||||
|
|
||||||
GenerateFile(UNIT_TEST,
|
|
||||||
UnitTestPreamble()
|
|
||||||
+ ''.join([TestsForArity(i) for i in OneTo(n)])
|
|
||||||
+ UnitTestPostamble())
|
|
||||||
|
|
||||||
|
|
||||||
def _Main():
|
|
||||||
"""The entry point of the script. Generates the header file and its
|
|
||||||
unit test."""
|
|
||||||
|
|
||||||
if len(sys.argv) != 2:
|
|
||||||
print __doc__
|
|
||||||
print 'Author: ' + __author__
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
n = int(sys.argv[1])
|
|
||||||
GenerateHeader(n)
|
|
||||||
GenerateUnitTest(n)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
_Main()
|
|
@ -1,274 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# These variables are automatically filled in by the configure script.
|
|
||||||
name="@PACKAGE_TARNAME@"
|
|
||||||
version="@PACKAGE_VERSION@"
|
|
||||||
|
|
||||||
show_usage()
|
|
||||||
{
|
|
||||||
echo "Usage: gtest-config [OPTIONS...]"
|
|
||||||
}
|
|
||||||
|
|
||||||
show_help()
|
|
||||||
{
|
|
||||||
show_usage
|
|
||||||
cat <<\EOF
|
|
||||||
|
|
||||||
The `gtest-config' script provides access to the necessary compile and linking
|
|
||||||
flags to connect with Google C++ Testing Framework, both in a build prior to
|
|
||||||
installation, and on the system proper after installation. The installation
|
|
||||||
overrides may be issued in combination with any other queries, but will only
|
|
||||||
affect installation queries if called on a built but not installed gtest. The
|
|
||||||
installation queries may not be issued with any other types of queries, and
|
|
||||||
only one installation query may be made at a time. The version queries and
|
|
||||||
compiler flag queries may be combined as desired but not mixed. Different
|
|
||||||
version queries are always combined with logical "and" semantics, and only the
|
|
||||||
last of any particular query is used while all previous ones ignored. All
|
|
||||||
versions must be specified as a sequence of numbers separated by periods.
|
|
||||||
Compiler flag queries output the union of the sets of flags when combined.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
gtest-config --min-version=1.0 || echo "Insufficient Google Test version."
|
|
||||||
|
|
||||||
g++ $(gtest-config --cppflags --cxxflags) -o foo.o -c foo.cpp
|
|
||||||
g++ $(gtest-config --ldflags --libs) -o foo foo.o
|
|
||||||
|
|
||||||
# When using a built but not installed Google Test:
|
|
||||||
g++ $(../../my_gtest_build/scripts/gtest-config ...) ...
|
|
||||||
|
|
||||||
# When using an installed Google Test, but with installation overrides:
|
|
||||||
export GTEST_PREFIX="/opt"
|
|
||||||
g++ $(gtest-config --libdir="/opt/lib64" ...) ...
|
|
||||||
|
|
||||||
Help:
|
|
||||||
--usage brief usage information
|
|
||||||
--help display this help message
|
|
||||||
|
|
||||||
Installation Overrides:
|
|
||||||
--prefix=<dir> overrides the installation prefix
|
|
||||||
--exec-prefix=<dir> overrides the executable installation prefix
|
|
||||||
--libdir=<dir> overrides the library installation prefix
|
|
||||||
--includedir=<dir> overrides the header file installation prefix
|
|
||||||
|
|
||||||
Installation Queries:
|
|
||||||
--prefix installation prefix
|
|
||||||
--exec-prefix executable installation prefix
|
|
||||||
--libdir library installation directory
|
|
||||||
--includedir header file installation directory
|
|
||||||
--version the version of the Google Test installation
|
|
||||||
|
|
||||||
Version Queries:
|
|
||||||
--min-version=VERSION return 0 if the version is at least VERSION
|
|
||||||
--exact-version=VERSION return 0 if the version is exactly VERSION
|
|
||||||
--max-version=VERSION return 0 if the version is at most VERSION
|
|
||||||
|
|
||||||
Compilation Flag Queries:
|
|
||||||
--cppflags compile flags specific to the C-like preprocessors
|
|
||||||
--cxxflags compile flags appropriate for C++ programs
|
|
||||||
--ldflags linker flags
|
|
||||||
--libs libraries for linking
|
|
||||||
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
# This function bounds our version with a min and a max. It uses some clever
|
|
||||||
# POSIX-compliant variable expansion to portably do all the work in the shell
|
|
||||||
# and avoid any dependency on a particular "sed" or "awk" implementation.
|
|
||||||
# Notable is that it will only ever compare the first 3 components of versions.
|
|
||||||
# Further components will be cleanly stripped off. All versions must be
|
|
||||||
# unadorned, so "v1.0" will *not* work. The minimum version must be in $1, and
|
|
||||||
# the max in $2. TODO(chandlerc@google.com): If this ever breaks, we should
|
|
||||||
# investigate expanding this via autom4te from AS_VERSION_COMPARE rather than
|
|
||||||
# continuing to maintain our own shell version.
|
|
||||||
check_versions()
|
|
||||||
{
|
|
||||||
major_version=${version%%.*}
|
|
||||||
minor_version="0"
|
|
||||||
point_version="0"
|
|
||||||
if test "${version#*.}" != "${version}"; then
|
|
||||||
minor_version=${version#*.}
|
|
||||||
minor_version=${minor_version%%.*}
|
|
||||||
fi
|
|
||||||
if test "${version#*.*.}" != "${version}"; then
|
|
||||||
point_version=${version#*.*.}
|
|
||||||
point_version=${point_version%%.*}
|
|
||||||
fi
|
|
||||||
|
|
||||||
min_version="$1"
|
|
||||||
min_major_version=${min_version%%.*}
|
|
||||||
min_minor_version="0"
|
|
||||||
min_point_version="0"
|
|
||||||
if test "${min_version#*.}" != "${min_version}"; then
|
|
||||||
min_minor_version=${min_version#*.}
|
|
||||||
min_minor_version=${min_minor_version%%.*}
|
|
||||||
fi
|
|
||||||
if test "${min_version#*.*.}" != "${min_version}"; then
|
|
||||||
min_point_version=${min_version#*.*.}
|
|
||||||
min_point_version=${min_point_version%%.*}
|
|
||||||
fi
|
|
||||||
|
|
||||||
max_version="$2"
|
|
||||||
max_major_version=${max_version%%.*}
|
|
||||||
max_minor_version="0"
|
|
||||||
max_point_version="0"
|
|
||||||
if test "${max_version#*.}" != "${max_version}"; then
|
|
||||||
max_minor_version=${max_version#*.}
|
|
||||||
max_minor_version=${max_minor_version%%.*}
|
|
||||||
fi
|
|
||||||
if test "${max_version#*.*.}" != "${max_version}"; then
|
|
||||||
max_point_version=${max_version#*.*.}
|
|
||||||
max_point_version=${max_point_version%%.*}
|
|
||||||
fi
|
|
||||||
|
|
||||||
test $(($major_version)) -lt $(($min_major_version)) && exit 1
|
|
||||||
if test $(($major_version)) -eq $(($min_major_version)); then
|
|
||||||
test $(($minor_version)) -lt $(($min_minor_version)) && exit 1
|
|
||||||
if test $(($minor_version)) -eq $(($min_minor_version)); then
|
|
||||||
test $(($point_version)) -lt $(($min_point_version)) && exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
test $(($major_version)) -gt $(($max_major_version)) && exit 1
|
|
||||||
if test $(($major_version)) -eq $(($max_major_version)); then
|
|
||||||
test $(($minor_version)) -gt $(($max_minor_version)) && exit 1
|
|
||||||
if test $(($minor_version)) -eq $(($max_minor_version)); then
|
|
||||||
test $(($point_version)) -gt $(($max_point_version)) && exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
# Show the usage line when no arguments are specified.
|
|
||||||
if test $# -eq 0; then
|
|
||||||
show_usage
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
while test $# -gt 0; do
|
|
||||||
case $1 in
|
|
||||||
--usage) show_usage; exit 0;;
|
|
||||||
--help) show_help; exit 0;;
|
|
||||||
|
|
||||||
# Installation overrides
|
|
||||||
--prefix=*) GTEST_PREFIX=${1#--prefix=};;
|
|
||||||
--exec-prefix=*) GTEST_EXEC_PREFIX=${1#--exec-prefix=};;
|
|
||||||
--libdir=*) GTEST_LIBDIR=${1#--libdir=};;
|
|
||||||
--includedir=*) GTEST_INCLUDEDIR=${1#--includedir=};;
|
|
||||||
|
|
||||||
# Installation queries
|
|
||||||
--prefix|--exec-prefix|--libdir|--includedir|--version)
|
|
||||||
if test -n "${do_query}"; then
|
|
||||||
show_usage
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
do_query=${1#--}
|
|
||||||
;;
|
|
||||||
|
|
||||||
# Version checking
|
|
||||||
--min-version=*)
|
|
||||||
do_check_versions=yes
|
|
||||||
min_version=${1#--min-version=}
|
|
||||||
;;
|
|
||||||
--max-version=*)
|
|
||||||
do_check_versions=yes
|
|
||||||
max_version=${1#--max-version=}
|
|
||||||
;;
|
|
||||||
--exact-version=*)
|
|
||||||
do_check_versions=yes
|
|
||||||
exact_version=${1#--exact-version=}
|
|
||||||
;;
|
|
||||||
|
|
||||||
# Compiler flag output
|
|
||||||
--cppflags) echo_cppflags=yes;;
|
|
||||||
--cxxflags) echo_cxxflags=yes;;
|
|
||||||
--ldflags) echo_ldflags=yes;;
|
|
||||||
--libs) echo_libs=yes;;
|
|
||||||
|
|
||||||
# Everything else is an error
|
|
||||||
*) show_usage; exit 1;;
|
|
||||||
esac
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
|
|
||||||
# These have defaults filled in by the configure script but can also be
|
|
||||||
# overridden by environment variables or command line parameters.
|
|
||||||
prefix="${GTEST_PREFIX:-@prefix@}"
|
|
||||||
exec_prefix="${GTEST_EXEC_PREFIX:-@exec_prefix@}"
|
|
||||||
libdir="${GTEST_LIBDIR:-@libdir@}"
|
|
||||||
includedir="${GTEST_INCLUDEDIR:-@includedir@}"
|
|
||||||
|
|
||||||
# We try and detect if our binary is not located at its installed location. If
|
|
||||||
# it's not, we provide variables pointing to the source and build tree rather
|
|
||||||
# than to the install tree. This allows building against a just-built gtest
|
|
||||||
# rather than an installed gtest.
|
|
||||||
bindir="@bindir@"
|
|
||||||
this_relative_bindir=`dirname $0`
|
|
||||||
this_bindir=`cd ${this_relative_bindir}; pwd -P`
|
|
||||||
if test "${this_bindir}" = "${this_bindir%${bindir}}"; then
|
|
||||||
# The path to the script doesn't end in the bindir sequence from Autoconf,
|
|
||||||
# assume that we are in a build tree.
|
|
||||||
build_dir=`dirname ${this_bindir}`
|
|
||||||
src_dir=`cd ${this_bindir}; cd @top_srcdir@; pwd -P`
|
|
||||||
|
|
||||||
# TODO(chandlerc@google.com): This is a dangerous dependency on libtool, we
|
|
||||||
# should work to remove it, and/or remove libtool altogether, replacing it
|
|
||||||
# with direct references to the library and a link path.
|
|
||||||
gtest_libs="${build_dir}/lib/libgtest.la @PTHREAD_CFLAGS@ @PTHREAD_LIBS@"
|
|
||||||
gtest_ldflags=""
|
|
||||||
|
|
||||||
# We provide hooks to include from either the source or build dir, where the
|
|
||||||
# build dir is always preferred. This will potentially allow us to write
|
|
||||||
# build rules for generated headers and have them automatically be preferred
|
|
||||||
# over provided versions.
|
|
||||||
gtest_cppflags="-I${build_dir}/include -I${src_dir}/include"
|
|
||||||
gtest_cxxflags="@PTHREAD_CFLAGS@"
|
|
||||||
else
|
|
||||||
# We're using an installed gtest, although it may be staged under some
|
|
||||||
# prefix. Assume (as our own libraries do) that we can resolve the prefix,
|
|
||||||
# and are present in the dynamic link paths.
|
|
||||||
gtest_ldflags="-L${libdir}"
|
|
||||||
gtest_libs="-l${name} @PTHREAD_CFLAGS@ @PTHREAD_LIBS@"
|
|
||||||
gtest_cppflags="-I${includedir}"
|
|
||||||
gtest_cxxflags="@PTHREAD_CFLAGS@"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Do an installation query if requested.
|
|
||||||
if test -n "$do_query"; then
|
|
||||||
case $do_query in
|
|
||||||
prefix) echo $prefix; exit 0;;
|
|
||||||
exec-prefix) echo $exec_prefix; exit 0;;
|
|
||||||
libdir) echo $libdir; exit 0;;
|
|
||||||
includedir) echo $includedir; exit 0;;
|
|
||||||
version) echo $version; exit 0;;
|
|
||||||
*) show_usage; exit 1;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Do a version check if requested.
|
|
||||||
if test "$do_check_versions" = "yes"; then
|
|
||||||
# Make sure we didn't receive a bad combination of parameters.
|
|
||||||
test "$echo_cppflags" = "yes" && show_usage && exit 1
|
|
||||||
test "$echo_cxxflags" = "yes" && show_usage && exit 1
|
|
||||||
test "$echo_ldflags" = "yes" && show_usage && exit 1
|
|
||||||
test "$echo_libs" = "yes" && show_usage && exit 1
|
|
||||||
|
|
||||||
if test "$exact_version" != ""; then
|
|
||||||
check_versions $exact_version $exact_version
|
|
||||||
# unreachable
|
|
||||||
else
|
|
||||||
check_versions ${min_version:-0.0.0} ${max_version:-9999.9999.9999}
|
|
||||||
# unreachable
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Do the output in the correct order so that these can be used in-line of
|
|
||||||
# a compiler invocation.
|
|
||||||
output=""
|
|
||||||
test "$echo_cppflags" = "yes" && output="$output $gtest_cppflags"
|
|
||||||
test "$echo_cxxflags" = "yes" && output="$output $gtest_cxxflags"
|
|
||||||
test "$echo_ldflags" = "yes" && output="$output $gtest_ldflags"
|
|
||||||
test "$echo_libs" = "yes" && output="$output $gtest_libs"
|
|
||||||
echo $output
|
|
||||||
|
|
||||||
exit 0
|
|
@ -1,158 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# Copyright 2013 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.
|
|
||||||
|
|
||||||
"""Script for branching Google Test/Mock wiki pages for a new version.
|
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
release_docs.py NEW_RELEASE_VERSION
|
|
||||||
|
|
||||||
Google Test and Google Mock's external user documentation is in
|
|
||||||
interlinked wiki files. When we release a new version of
|
|
||||||
Google Test or Google Mock, we need to branch the wiki files
|
|
||||||
such that users of a specific version of Google Test/Mock can
|
|
||||||
look up documentation relevant for that version. This script
|
|
||||||
automates that process by:
|
|
||||||
|
|
||||||
- branching the current wiki pages (which document the
|
|
||||||
behavior of the SVN trunk head) to pages for the specified
|
|
||||||
version (e.g. branching FAQ.wiki to V2_6_FAQ.wiki when
|
|
||||||
NEW_RELEASE_VERSION is 2.6);
|
|
||||||
- updating the links in the branched files to point to the branched
|
|
||||||
version (e.g. a link in V2_6_FAQ.wiki that pointed to
|
|
||||||
Primer.wiki#Anchor will now point to V2_6_Primer.wiki#Anchor).
|
|
||||||
|
|
||||||
NOTE: NEW_RELEASE_VERSION must be a NEW version number for
|
|
||||||
which the wiki pages don't yet exist; otherwise you'll get SVN
|
|
||||||
errors like "svn: Path 'V1_7_PumpManual.wiki' is not a
|
|
||||||
directory" when running the script.
|
|
||||||
|
|
||||||
EXAMPLE
|
|
||||||
$ cd PATH/TO/GTEST_SVN_WORKSPACE/trunk
|
|
||||||
$ scripts/release_docs.py 2.6 # create wiki pages for v2.6
|
|
||||||
$ svn status # verify the file list
|
|
||||||
$ svn diff # verify the file contents
|
|
||||||
$ svn commit -m "release wiki pages for v2.6"
|
|
||||||
"""
|
|
||||||
|
|
||||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
|
||||||
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
|
|
||||||
import common
|
|
||||||
|
|
||||||
|
|
||||||
# Wiki pages that shouldn't be branched for every gtest/gmock release.
|
|
||||||
GTEST_UNVERSIONED_WIKIS = ['DevGuide.wiki']
|
|
||||||
GMOCK_UNVERSIONED_WIKIS = [
|
|
||||||
'DesignDoc.wiki',
|
|
||||||
'DevGuide.wiki',
|
|
||||||
'KnownIssues.wiki'
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def DropWikiSuffix(wiki_filename):
|
|
||||||
"""Removes the .wiki suffix (if any) from the given filename."""
|
|
||||||
|
|
||||||
return (wiki_filename[:-len('.wiki')] if wiki_filename.endswith('.wiki')
|
|
||||||
else wiki_filename)
|
|
||||||
|
|
||||||
|
|
||||||
class WikiBrancher(object):
|
|
||||||
"""Branches ..."""
|
|
||||||
|
|
||||||
def __init__(self, dot_version):
|
|
||||||
self.project, svn_root_path = common.GetSvnInfo()
|
|
||||||
if self.project not in ('googletest', 'googlemock'):
|
|
||||||
sys.exit('This script must be run in a gtest or gmock SVN workspace.')
|
|
||||||
self.wiki_dir = svn_root_path + '/wiki'
|
|
||||||
# Turn '2.6' to 'V2_6_'.
|
|
||||||
self.version_prefix = 'V' + dot_version.replace('.', '_') + '_'
|
|
||||||
self.files_to_branch = self.GetFilesToBranch()
|
|
||||||
page_names = [DropWikiSuffix(f) for f in self.files_to_branch]
|
|
||||||
# A link to Foo.wiki is in one of the following forms:
|
|
||||||
# [Foo words]
|
|
||||||
# [Foo#Anchor words]
|
|
||||||
# [http://code.google.com/.../wiki/Foo words]
|
|
||||||
# [http://code.google.com/.../wiki/Foo#Anchor words]
|
|
||||||
# We want to replace 'Foo' with 'V2_6_Foo' in the above cases.
|
|
||||||
self.search_for_re = re.compile(
|
|
||||||
# This regex matches either
|
|
||||||
# [Foo
|
|
||||||
# or
|
|
||||||
# /wiki/Foo
|
|
||||||
# followed by a space or a #, where Foo is the name of an
|
|
||||||
# unversioned wiki page.
|
|
||||||
r'(\[|/wiki/)(%s)([ #])' % '|'.join(page_names))
|
|
||||||
self.replace_with = r'\1%s\2\3' % (self.version_prefix,)
|
|
||||||
|
|
||||||
def GetFilesToBranch(self):
|
|
||||||
"""Returns a list of .wiki file names that need to be branched."""
|
|
||||||
|
|
||||||
unversioned_wikis = (GTEST_UNVERSIONED_WIKIS if self.project == 'googletest'
|
|
||||||
else GMOCK_UNVERSIONED_WIKIS)
|
|
||||||
return [f for f in os.listdir(self.wiki_dir)
|
|
||||||
if (f.endswith('.wiki') and
|
|
||||||
not re.match(r'^V\d', f) and # Excluded versioned .wiki files.
|
|
||||||
f not in unversioned_wikis)]
|
|
||||||
|
|
||||||
def BranchFiles(self):
|
|
||||||
"""Branches the .wiki files needed to be branched."""
|
|
||||||
|
|
||||||
print 'Branching %d .wiki files:' % (len(self.files_to_branch),)
|
|
||||||
os.chdir(self.wiki_dir)
|
|
||||||
for f in self.files_to_branch:
|
|
||||||
command = 'svn cp %s %s%s' % (f, self.version_prefix, f)
|
|
||||||
print command
|
|
||||||
os.system(command)
|
|
||||||
|
|
||||||
def UpdateLinksInBranchedFiles(self):
|
|
||||||
|
|
||||||
for f in self.files_to_branch:
|
|
||||||
source_file = os.path.join(self.wiki_dir, f)
|
|
||||||
versioned_file = os.path.join(self.wiki_dir, self.version_prefix + f)
|
|
||||||
print 'Updating links in %s.' % (versioned_file,)
|
|
||||||
text = file(source_file, 'r').read()
|
|
||||||
new_text = self.search_for_re.sub(self.replace_with, text)
|
|
||||||
file(versioned_file, 'w').write(new_text)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
if len(sys.argv) != 2:
|
|
||||||
sys.exit(__doc__)
|
|
||||||
|
|
||||||
brancher = WikiBrancher(sys.argv[1])
|
|
||||||
brancher.BranchFiles()
|
|
||||||
brancher.UpdateLinksInBranchedFiles()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
@ -1,32 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# Copyright 2010 Google Inc. All Rights Reserved.
|
|
||||||
|
|
||||||
"""Runs program specified in the command line with the substituted PATH.
|
|
||||||
|
|
||||||
This script is needed for to support building under Pulse which is unable
|
|
||||||
to override the existing PATH variable.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
|
|
||||||
SUBST_PATH_ENV_VAR_NAME = "SUBST_PATH"
|
|
||||||
|
|
||||||
def main():
|
|
||||||
if SUBST_PATH_ENV_VAR_NAME in os.environ:
|
|
||||||
os.environ["PATH"] = os.environ[SUBST_PATH_ENV_VAR_NAME]
|
|
||||||
|
|
||||||
exit_code = subprocess.Popen(sys.argv[1:]).wait()
|
|
||||||
|
|
||||||
# exit_code is negative (-signal) if the process has been terminated by
|
|
||||||
# a signal. Returning negative exit code is not portable and so we return
|
|
||||||
# 100 instead.
|
|
||||||
if exit_code < 0:
|
|
||||||
exit_code = 100
|
|
||||||
|
|
||||||
sys.exit(exit_code)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
@ -1,59 +0,0 @@
|
|||||||
# A Makefile for fusing Google Test and building a sample test against it.
|
|
||||||
#
|
|
||||||
# SYNOPSIS:
|
|
||||||
#
|
|
||||||
# make [all] - makes everything.
|
|
||||||
# make TARGET - makes the given target.
|
|
||||||
# make check - makes everything and runs the built sample test.
|
|
||||||
# make clean - removes all files generated by make.
|
|
||||||
|
|
||||||
# Points to the root of fused Google Test, relative to where this file is.
|
|
||||||
FUSED_GTEST_DIR = output
|
|
||||||
|
|
||||||
# Paths to the fused gtest files.
|
|
||||||
FUSED_GTEST_H = $(FUSED_GTEST_DIR)/gtest/gtest.h
|
|
||||||
FUSED_GTEST_ALL_CC = $(FUSED_GTEST_DIR)/gtest/gtest-all.cc
|
|
||||||
|
|
||||||
# Where to find the sample test.
|
|
||||||
SAMPLE_DIR = ../../samples
|
|
||||||
|
|
||||||
# Where to find gtest_main.cc.
|
|
||||||
GTEST_MAIN_CC = ../../src/gtest_main.cc
|
|
||||||
|
|
||||||
# Flags passed to the preprocessor.
|
|
||||||
# We have no idea here whether pthreads is available in the system, so
|
|
||||||
# disable its use.
|
|
||||||
CPPFLAGS += -I$(FUSED_GTEST_DIR) -DGTEST_HAS_PTHREAD=0
|
|
||||||
|
|
||||||
# Flags passed to the C++ compiler.
|
|
||||||
CXXFLAGS += -g
|
|
||||||
|
|
||||||
all : sample1_unittest
|
|
||||||
|
|
||||||
check : all
|
|
||||||
./sample1_unittest
|
|
||||||
|
|
||||||
clean :
|
|
||||||
rm -rf $(FUSED_GTEST_DIR) sample1_unittest *.o
|
|
||||||
|
|
||||||
$(FUSED_GTEST_H) :
|
|
||||||
../fuse_gtest_files.py $(FUSED_GTEST_DIR)
|
|
||||||
|
|
||||||
$(FUSED_GTEST_ALL_CC) :
|
|
||||||
../fuse_gtest_files.py $(FUSED_GTEST_DIR)
|
|
||||||
|
|
||||||
gtest-all.o : $(FUSED_GTEST_H) $(FUSED_GTEST_ALL_CC)
|
|
||||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(FUSED_GTEST_DIR)/gtest/gtest-all.cc
|
|
||||||
|
|
||||||
gtest_main.o : $(FUSED_GTEST_H) $(GTEST_MAIN_CC)
|
|
||||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(GTEST_MAIN_CC)
|
|
||||||
|
|
||||||
sample1.o : $(SAMPLE_DIR)/sample1.cc $(SAMPLE_DIR)/sample1.h
|
|
||||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SAMPLE_DIR)/sample1.cc
|
|
||||||
|
|
||||||
sample1_unittest.o : $(SAMPLE_DIR)/sample1_unittest.cc \
|
|
||||||
$(SAMPLE_DIR)/sample1.h $(FUSED_GTEST_H)
|
|
||||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SAMPLE_DIR)/sample1_unittest.cc
|
|
||||||
|
|
||||||
sample1_unittest : sample1.o sample1_unittest.o gtest-all.o gtest_main.o
|
|
||||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $^ -o $@
|
|
File diff suppressed because it is too large
Load Diff
@ -1,78 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# Copyright 2009, 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.
|
|
||||||
|
|
||||||
"""upload_gtest.py v0.1.0 -- uploads a Google Test patch for review.
|
|
||||||
|
|
||||||
This simple wrapper passes all command line flags and
|
|
||||||
--cc=googletestframework@googlegroups.com to upload.py.
|
|
||||||
|
|
||||||
USAGE: upload_gtest.py [options for upload.py]
|
|
||||||
"""
|
|
||||||
|
|
||||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
CC_FLAG = '--cc='
|
|
||||||
GTEST_GROUP = 'googletestframework@googlegroups.com'
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
# Finds the path to upload.py, assuming it is in the same directory
|
|
||||||
# as this file.
|
|
||||||
my_dir = os.path.dirname(os.path.abspath(__file__))
|
|
||||||
upload_py_path = os.path.join(my_dir, 'upload.py')
|
|
||||||
|
|
||||||
# Adds Google Test discussion group to the cc line if it's not there
|
|
||||||
# already.
|
|
||||||
upload_py_argv = [upload_py_path]
|
|
||||||
found_cc_flag = False
|
|
||||||
for arg in sys.argv[1:]:
|
|
||||||
if arg.startswith(CC_FLAG):
|
|
||||||
found_cc_flag = True
|
|
||||||
cc_line = arg[len(CC_FLAG):]
|
|
||||||
cc_list = [addr for addr in cc_line.split(',') if addr]
|
|
||||||
if GTEST_GROUP not in cc_list:
|
|
||||||
cc_list.append(GTEST_GROUP)
|
|
||||||
upload_py_argv.append(CC_FLAG + ','.join(cc_list))
|
|
||||||
else:
|
|
||||||
upload_py_argv.append(arg)
|
|
||||||
|
|
||||||
if not found_cc_flag:
|
|
||||||
upload_py_argv.append(CC_FLAG + GTEST_GROUP)
|
|
||||||
|
|
||||||
# Invokes upload.py with the modified command line flags.
|
|
||||||
os.execv(upload_py_path, upload_py_argv)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
@ -96,9 +96,12 @@ namespace testing {
|
|||||||
// used internally at Google, is "threadsafe".
|
// used internally at Google, is "threadsafe".
|
||||||
static const char kDefaultDeathTestStyle[] = GTEST_DEFAULT_DEATH_TEST_STYLE;
|
static const char kDefaultDeathTestStyle[] = GTEST_DEFAULT_DEATH_TEST_STYLE;
|
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
GTEST_DEFINE_string_(
|
GTEST_DEFINE_string_(
|
||||||
death_test_style,
|
death_test_style,
|
||||||
internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle),
|
testing::internal::StringFromGTestEnv("death_test_style",
|
||||||
|
testing::kDefaultDeathTestStyle),
|
||||||
"Indicates how to run a death test in a forked child process: "
|
"Indicates how to run a death test in a forked child process: "
|
||||||
"\"threadsafe\" (child process re-executes the test binary "
|
"\"threadsafe\" (child process re-executes the test binary "
|
||||||
"from the beginning, running only the specific death test) or "
|
"from the beginning, running only the specific death test) or "
|
||||||
@ -107,7 +110,7 @@ GTEST_DEFINE_string_(
|
|||||||
|
|
||||||
GTEST_DEFINE_bool_(
|
GTEST_DEFINE_bool_(
|
||||||
death_test_use_fork,
|
death_test_use_fork,
|
||||||
internal::BoolFromGTestEnv("death_test_use_fork", false),
|
testing::internal::BoolFromGTestEnv("death_test_use_fork", false),
|
||||||
"Instructs to use fork()/_exit() instead of clone() in death tests. "
|
"Instructs to use fork()/_exit() instead of clone() in death tests. "
|
||||||
"Ignored and always uses fork() on POSIX systems where clone() is not "
|
"Ignored and always uses fork() on POSIX systems where clone() is not "
|
||||||
"implemented. Useful when running under valgrind or similar tools if "
|
"implemented. Useful when running under valgrind or similar tools if "
|
||||||
@ -117,7 +120,6 @@ GTEST_DEFINE_bool_(
|
|||||||
"work in 99% of the cases. Once valgrind is fixed, this flag will "
|
"work in 99% of the cases. Once valgrind is fixed, this flag will "
|
||||||
"most likely be removed.");
|
"most likely be removed.");
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
GTEST_DEFINE_string_(
|
GTEST_DEFINE_string_(
|
||||||
internal_run_death_test, "",
|
internal_run_death_test, "",
|
||||||
"Indicates the file, line number, temporal index of "
|
"Indicates the file, line number, temporal index of "
|
||||||
@ -126,7 +128,8 @@ GTEST_DEFINE_string_(
|
|||||||
"the '|' characters. This flag is specified if and only if the "
|
"the '|' characters. This flag is specified if and only if the "
|
||||||
"current process is a sub-process launched for running a thread-safe "
|
"current process is a sub-process launched for running a thread-safe "
|
||||||
"death test. FOR INTERNAL USE ONLY.");
|
"death test. FOR INTERNAL USE ONLY.");
|
||||||
} // namespace internal
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
#if GTEST_HAS_DEATH_TEST
|
#if GTEST_HAS_DEATH_TEST
|
||||||
|
|
||||||
@ -148,12 +151,12 @@ bool InDeathTestChild() {
|
|||||||
|
|
||||||
// On Windows and Fuchsia, death tests are thread-safe regardless of the value
|
// On Windows and Fuchsia, death tests are thread-safe regardless of the value
|
||||||
// of the death_test_style flag.
|
// of the death_test_style flag.
|
||||||
return !GTEST_FLAG(internal_run_death_test).empty();
|
return !GTEST_FLAG_GET(internal_run_death_test).empty();
|
||||||
|
|
||||||
# else
|
# else
|
||||||
|
|
||||||
if (GTEST_FLAG(death_test_style) == "threadsafe")
|
if (GTEST_FLAG_GET(death_test_style) == "threadsafe")
|
||||||
return !GTEST_FLAG(internal_run_death_test).empty();
|
return !GTEST_FLAG_GET(internal_run_death_test).empty();
|
||||||
else
|
else
|
||||||
return g_in_fast_death_test_child;
|
return g_in_fast_death_test_child;
|
||||||
#endif
|
#endif
|
||||||
@ -756,18 +759,18 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
|
|||||||
nullptr)); // The even is unnamed.
|
nullptr)); // The even is unnamed.
|
||||||
GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != nullptr);
|
GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != nullptr);
|
||||||
const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
|
const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
|
||||||
kFilterFlag + "=" + info->test_suite_name() +
|
"filter=" + info->test_suite_name() + "." +
|
||||||
"." + info->name();
|
info->name();
|
||||||
const std::string internal_flag =
|
const std::string internal_flag =
|
||||||
std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag +
|
std::string("--") + GTEST_FLAG_PREFIX_ +
|
||||||
"=" + file_ + "|" + StreamableToString(line_) + "|" +
|
"internal_run_death_test=" + file_ + "|" + StreamableToString(line_) +
|
||||||
StreamableToString(death_test_index) + "|" +
|
"|" + StreamableToString(death_test_index) + "|" +
|
||||||
StreamableToString(static_cast<unsigned int>(::GetCurrentProcessId())) +
|
StreamableToString(static_cast<unsigned int>(::GetCurrentProcessId())) +
|
||||||
// size_t has the same width as pointers on both 32-bit and 64-bit
|
// size_t has the same width as pointers on both 32-bit and 64-bit
|
||||||
// Windows platforms.
|
// Windows platforms.
|
||||||
// See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx.
|
// See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx.
|
||||||
"|" + StreamableToString(reinterpret_cast<size_t>(write_handle)) +
|
"|" + StreamableToString(reinterpret_cast<size_t>(write_handle)) + "|" +
|
||||||
"|" + StreamableToString(reinterpret_cast<size_t>(event_handle_.Get()));
|
StreamableToString(reinterpret_cast<size_t>(event_handle_.Get()));
|
||||||
|
|
||||||
char executable_path[_MAX_PATH + 1]; // NOLINT
|
char executable_path[_MAX_PATH + 1]; // NOLINT
|
||||||
GTEST_DEATH_TEST_CHECK_(_MAX_PATH + 1 != ::GetModuleFileNameA(nullptr,
|
GTEST_DEATH_TEST_CHECK_(_MAX_PATH + 1 != ::GetModuleFileNameA(nullptr,
|
||||||
@ -796,8 +799,8 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
|
|||||||
GTEST_DEATH_TEST_CHECK_(
|
GTEST_DEATH_TEST_CHECK_(
|
||||||
::CreateProcessA(
|
::CreateProcessA(
|
||||||
executable_path, const_cast<char*>(command_line.c_str()),
|
executable_path, const_cast<char*>(command_line.c_str()),
|
||||||
nullptr, // Retuned process handle is not inheritable.
|
nullptr, // Returned process handle is not inheritable.
|
||||||
nullptr, // Retuned thread handle is not inheritable.
|
nullptr, // Returned thread handle is not inheritable.
|
||||||
TRUE, // Child inherits all inheritable handles (for write_handle_).
|
TRUE, // Child inherits all inheritable handles (for write_handle_).
|
||||||
0x0, // Default creation flags.
|
0x0, // Default creation flags.
|
||||||
nullptr, // Inherit the parent's environment.
|
nullptr, // Inherit the parent's environment.
|
||||||
@ -987,8 +990,8 @@ DeathTest::TestRole FuchsiaDeathTest::AssumeRole() {
|
|||||||
|
|
||||||
// Build the child process command line.
|
// Build the child process command line.
|
||||||
const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
|
const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
|
||||||
kFilterFlag + "=" + info->test_suite_name() +
|
"filter=" + info->test_suite_name() + "." +
|
||||||
"." + info->name();
|
info->name();
|
||||||
const std::string internal_flag =
|
const std::string internal_flag =
|
||||||
std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "="
|
std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "="
|
||||||
+ file_ + "|"
|
+ file_ + "|"
|
||||||
@ -1351,7 +1354,7 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
|
|||||||
# endif // GTEST_OS_LINUX
|
# endif // GTEST_OS_LINUX
|
||||||
|
|
||||||
# if GTEST_HAS_CLONE
|
# if GTEST_HAS_CLONE
|
||||||
const bool use_fork = GTEST_FLAG(death_test_use_fork);
|
const bool use_fork = GTEST_FLAG_GET(death_test_use_fork);
|
||||||
|
|
||||||
if (!use_fork) {
|
if (!use_fork) {
|
||||||
static const bool stack_grows_down = StackGrowsDown();
|
static const bool stack_grows_down = StackGrowsDown();
|
||||||
@ -1420,13 +1423,13 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() {
|
|||||||
GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1);
|
GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1);
|
||||||
|
|
||||||
const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
|
const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
|
||||||
kFilterFlag + "=" + info->test_suite_name() +
|
"filter=" + info->test_suite_name() + "." +
|
||||||
"." + info->name();
|
info->name();
|
||||||
const std::string internal_flag =
|
const std::string internal_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
|
||||||
std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "="
|
"internal_run_death_test=" + file_ + "|" +
|
||||||
+ file_ + "|" + StreamableToString(line_) + "|"
|
StreamableToString(line_) + "|" +
|
||||||
+ StreamableToString(death_test_index) + "|"
|
StreamableToString(death_test_index) + "|" +
|
||||||
+ StreamableToString(pipe_fd[1]);
|
StreamableToString(pipe_fd[1]);
|
||||||
Arguments args;
|
Arguments args;
|
||||||
args.AddArguments(GetArgvsForDeathTestChildProcess());
|
args.AddArguments(GetArgvsForDeathTestChildProcess());
|
||||||
args.AddArgument(filter_flag.c_str());
|
args.AddArgument(filter_flag.c_str());
|
||||||
@ -1482,32 +1485,32 @@ bool DefaultDeathTestFactory::Create(const char* statement,
|
|||||||
|
|
||||||
# if GTEST_OS_WINDOWS
|
# if GTEST_OS_WINDOWS
|
||||||
|
|
||||||
if (GTEST_FLAG(death_test_style) == "threadsafe" ||
|
if (GTEST_FLAG_GET(death_test_style) == "threadsafe" ||
|
||||||
GTEST_FLAG(death_test_style) == "fast") {
|
GTEST_FLAG_GET(death_test_style) == "fast") {
|
||||||
*test = new WindowsDeathTest(statement, std::move(matcher), file, line);
|
*test = new WindowsDeathTest(statement, std::move(matcher), file, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
# elif GTEST_OS_FUCHSIA
|
# elif GTEST_OS_FUCHSIA
|
||||||
|
|
||||||
if (GTEST_FLAG(death_test_style) == "threadsafe" ||
|
if (GTEST_FLAG_GET(death_test_style) == "threadsafe" ||
|
||||||
GTEST_FLAG(death_test_style) == "fast") {
|
GTEST_FLAG_GET(death_test_style) == "fast") {
|
||||||
*test = new FuchsiaDeathTest(statement, std::move(matcher), file, line);
|
*test = new FuchsiaDeathTest(statement, std::move(matcher), file, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
# else
|
# else
|
||||||
|
|
||||||
if (GTEST_FLAG(death_test_style) == "threadsafe") {
|
if (GTEST_FLAG_GET(death_test_style) == "threadsafe") {
|
||||||
*test = new ExecDeathTest(statement, std::move(matcher), file, line);
|
*test = new ExecDeathTest(statement, std::move(matcher), file, line);
|
||||||
} else if (GTEST_FLAG(death_test_style) == "fast") {
|
} else if (GTEST_FLAG_GET(death_test_style) == "fast") {
|
||||||
*test = new NoExecDeathTest(statement, std::move(matcher));
|
*test = new NoExecDeathTest(statement, std::move(matcher));
|
||||||
}
|
}
|
||||||
|
|
||||||
# endif // GTEST_OS_WINDOWS
|
# endif // GTEST_OS_WINDOWS
|
||||||
|
|
||||||
else { // NOLINT - this is more readable than unbalanced brackets inside #if.
|
else { // NOLINT - this is more readable than unbalanced brackets inside #if.
|
||||||
DeathTest::set_last_death_test_message(
|
DeathTest::set_last_death_test_message("Unknown death test style \"" +
|
||||||
"Unknown death test style \"" + GTEST_FLAG(death_test_style)
|
GTEST_FLAG_GET(death_test_style) +
|
||||||
+ "\" encountered");
|
"\" encountered");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1584,14 +1587,14 @@ static int GetStatusFileDescriptor(unsigned int parent_process_id,
|
|||||||
// initialized from the GTEST_FLAG(internal_run_death_test) flag if
|
// initialized from the GTEST_FLAG(internal_run_death_test) flag if
|
||||||
// the flag is specified; otherwise returns NULL.
|
// the flag is specified; otherwise returns NULL.
|
||||||
InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
|
InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
|
||||||
if (GTEST_FLAG(internal_run_death_test) == "") return nullptr;
|
if (GTEST_FLAG_GET(internal_run_death_test) == "") return nullptr;
|
||||||
|
|
||||||
// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we
|
// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we
|
||||||
// can use it here.
|
// can use it here.
|
||||||
int line = -1;
|
int line = -1;
|
||||||
int index = -1;
|
int index = -1;
|
||||||
::std::vector< ::std::string> fields;
|
::std::vector< ::std::string> fields;
|
||||||
SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields);
|
SplitString(GTEST_FLAG_GET(internal_run_death_test), '|', &fields);
|
||||||
int write_fd = -1;
|
int write_fd = -1;
|
||||||
|
|
||||||
# if GTEST_OS_WINDOWS
|
# if GTEST_OS_WINDOWS
|
||||||
@ -1607,7 +1610,7 @@ InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
|
|||||||
|| !ParseNaturalNumber(fields[4], &write_handle_as_size_t)
|
|| !ParseNaturalNumber(fields[4], &write_handle_as_size_t)
|
||||||
|| !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) {
|
|| !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) {
|
||||||
DeathTestAbort("Bad --gtest_internal_run_death_test flag: " +
|
DeathTestAbort("Bad --gtest_internal_run_death_test flag: " +
|
||||||
GTEST_FLAG(internal_run_death_test));
|
GTEST_FLAG_GET(internal_run_death_test));
|
||||||
}
|
}
|
||||||
write_fd = GetStatusFileDescriptor(parent_process_id,
|
write_fd = GetStatusFileDescriptor(parent_process_id,
|
||||||
write_handle_as_size_t,
|
write_handle_as_size_t,
|
||||||
@ -1618,8 +1621,8 @@ InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
|
|||||||
if (fields.size() != 3
|
if (fields.size() != 3
|
||||||
|| !ParseNaturalNumber(fields[1], &line)
|
|| !ParseNaturalNumber(fields[1], &line)
|
||||||
|| !ParseNaturalNumber(fields[2], &index)) {
|
|| !ParseNaturalNumber(fields[2], &index)) {
|
||||||
DeathTestAbort("Bad --gtest_internal_run_death_test flag: "
|
DeathTestAbort("Bad --gtest_internal_run_death_test flag: " +
|
||||||
+ GTEST_FLAG(internal_run_death_test));
|
GTEST_FLAG_GET(internal_run_death_test));
|
||||||
}
|
}
|
||||||
|
|
||||||
# else
|
# else
|
||||||
@ -1628,8 +1631,8 @@ InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
|
|||||||
|| !ParseNaturalNumber(fields[1], &line)
|
|| !ParseNaturalNumber(fields[1], &line)
|
||||||
|| !ParseNaturalNumber(fields[2], &index)
|
|| !ParseNaturalNumber(fields[2], &index)
|
||||||
|| !ParseNaturalNumber(fields[3], &write_fd)) {
|
|| !ParseNaturalNumber(fields[3], &write_fd)) {
|
||||||
DeathTestAbort("Bad --gtest_internal_run_death_test flag: "
|
DeathTestAbort("Bad --gtest_internal_run_death_test flag: " +
|
||||||
+ GTEST_FLAG(internal_run_death_test));
|
GTEST_FLAG_GET(internal_run_death_test));
|
||||||
}
|
}
|
||||||
|
|
||||||
# endif // GTEST_OS_WINDOWS
|
# endif // GTEST_OS_WINDOWS
|
||||||
|
@ -64,8 +64,6 @@
|
|||||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||||
/* class A needs to have dll-interface to be used by clients of class B */)
|
/* class A needs to have dll-interface to be used by clients of class B */)
|
||||||
|
|
||||||
namespace testing {
|
|
||||||
|
|
||||||
// Declares the flags.
|
// Declares the flags.
|
||||||
//
|
//
|
||||||
// We don't want the users to modify this flag in the code, but want
|
// We don't want the users to modify this flag in the code, but want
|
||||||
@ -73,32 +71,13 @@ namespace testing {
|
|||||||
// declare it here as opposed to in gtest.h.
|
// declare it here as opposed to in gtest.h.
|
||||||
GTEST_DECLARE_bool_(death_test_use_fork);
|
GTEST_DECLARE_bool_(death_test_use_fork);
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// The value of GetTestTypeId() as seen from within the Google Test
|
// The value of GetTestTypeId() as seen from within the Google Test
|
||||||
// library. This is solely for testing GetTestTypeId().
|
// library. This is solely for testing GetTestTypeId().
|
||||||
GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest;
|
GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest;
|
||||||
|
|
||||||
// Names of the flags (needed for parsing Google Test flags).
|
|
||||||
const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests";
|
|
||||||
const char kBreakOnFailureFlag[] = "break_on_failure";
|
|
||||||
const char kCatchExceptionsFlag[] = "catch_exceptions";
|
|
||||||
const char kColorFlag[] = "color";
|
|
||||||
const char kFailFast[] = "fail_fast";
|
|
||||||
const char kFilterFlag[] = "filter";
|
|
||||||
const char kListTestsFlag[] = "list_tests";
|
|
||||||
const char kOutputFlag[] = "output";
|
|
||||||
const char kBriefFlag[] = "brief";
|
|
||||||
const char kPrintTimeFlag[] = "print_time";
|
|
||||||
const char kPrintUTF8Flag[] = "print_utf8";
|
|
||||||
const char kRandomSeedFlag[] = "random_seed";
|
|
||||||
const char kRepeatFlag[] = "repeat";
|
|
||||||
const char kShuffleFlag[] = "shuffle";
|
|
||||||
const char kStackTraceDepthFlag[] = "stack_trace_depth";
|
|
||||||
const char kStreamResultToFlag[] = "stream_result_to";
|
|
||||||
const char kThrowOnFailureFlag[] = "throw_on_failure";
|
|
||||||
const char kFlagfileFlag[] = "flagfile";
|
|
||||||
|
|
||||||
// A valid random seed must be in [1, kMaxRandomSeed].
|
// A valid random seed must be in [1, kMaxRandomSeed].
|
||||||
const int kMaxRandomSeed = 99999;
|
const int kMaxRandomSeed = 99999;
|
||||||
|
|
||||||
@ -125,8 +104,7 @@ GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms);
|
|||||||
//
|
//
|
||||||
// On success, stores the value of the flag in *value, and returns
|
// On success, stores the value of the flag in *value, and returns
|
||||||
// true. On failure, returns false without changing *value.
|
// true. On failure, returns false without changing *value.
|
||||||
GTEST_API_ bool ParseInt32Flag(
|
GTEST_API_ bool ParseFlag(const char* str, const char* flag, int32_t* value);
|
||||||
const char* str, const char* flag, int32_t* value);
|
|
||||||
|
|
||||||
// Returns a random seed in range [1, kMaxRandomSeed] based on the
|
// Returns a random seed in range [1, kMaxRandomSeed] based on the
|
||||||
// given --gtest_random_seed flag value.
|
// given --gtest_random_seed flag value.
|
||||||
@ -160,50 +138,54 @@ class GTestFlagSaver {
|
|||||||
public:
|
public:
|
||||||
// The c'tor.
|
// The c'tor.
|
||||||
GTestFlagSaver() {
|
GTestFlagSaver() {
|
||||||
also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests);
|
also_run_disabled_tests_ = GTEST_FLAG_GET(also_run_disabled_tests);
|
||||||
break_on_failure_ = GTEST_FLAG(break_on_failure);
|
break_on_failure_ = GTEST_FLAG_GET(break_on_failure);
|
||||||
catch_exceptions_ = GTEST_FLAG(catch_exceptions);
|
catch_exceptions_ = GTEST_FLAG_GET(catch_exceptions);
|
||||||
color_ = GTEST_FLAG(color);
|
color_ = GTEST_FLAG_GET(color);
|
||||||
death_test_style_ = GTEST_FLAG(death_test_style);
|
death_test_style_ = GTEST_FLAG_GET(death_test_style);
|
||||||
death_test_use_fork_ = GTEST_FLAG(death_test_use_fork);
|
death_test_use_fork_ = GTEST_FLAG_GET(death_test_use_fork);
|
||||||
fail_fast_ = GTEST_FLAG(fail_fast);
|
fail_fast_ = GTEST_FLAG_GET(fail_fast);
|
||||||
filter_ = GTEST_FLAG(filter);
|
filter_ = GTEST_FLAG_GET(filter);
|
||||||
internal_run_death_test_ = GTEST_FLAG(internal_run_death_test);
|
internal_run_death_test_ = GTEST_FLAG_GET(internal_run_death_test);
|
||||||
list_tests_ = GTEST_FLAG(list_tests);
|
list_tests_ = GTEST_FLAG_GET(list_tests);
|
||||||
output_ = GTEST_FLAG(output);
|
output_ = GTEST_FLAG_GET(output);
|
||||||
brief_ = GTEST_FLAG(brief);
|
brief_ = GTEST_FLAG_GET(brief);
|
||||||
print_time_ = GTEST_FLAG(print_time);
|
print_time_ = GTEST_FLAG_GET(print_time);
|
||||||
print_utf8_ = GTEST_FLAG(print_utf8);
|
print_utf8_ = GTEST_FLAG_GET(print_utf8);
|
||||||
random_seed_ = GTEST_FLAG(random_seed);
|
random_seed_ = GTEST_FLAG_GET(random_seed);
|
||||||
repeat_ = GTEST_FLAG(repeat);
|
repeat_ = GTEST_FLAG_GET(repeat);
|
||||||
shuffle_ = GTEST_FLAG(shuffle);
|
recreate_environments_when_repeating_ =
|
||||||
stack_trace_depth_ = GTEST_FLAG(stack_trace_depth);
|
GTEST_FLAG_GET(recreate_environments_when_repeating);
|
||||||
stream_result_to_ = GTEST_FLAG(stream_result_to);
|
shuffle_ = GTEST_FLAG_GET(shuffle);
|
||||||
throw_on_failure_ = GTEST_FLAG(throw_on_failure);
|
stack_trace_depth_ = GTEST_FLAG_GET(stack_trace_depth);
|
||||||
|
stream_result_to_ = GTEST_FLAG_GET(stream_result_to);
|
||||||
|
throw_on_failure_ = GTEST_FLAG_GET(throw_on_failure);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS.
|
// The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS.
|
||||||
~GTestFlagSaver() {
|
~GTestFlagSaver() {
|
||||||
GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_;
|
GTEST_FLAG_SET(also_run_disabled_tests, also_run_disabled_tests_);
|
||||||
GTEST_FLAG(break_on_failure) = break_on_failure_;
|
GTEST_FLAG_SET(break_on_failure, break_on_failure_);
|
||||||
GTEST_FLAG(catch_exceptions) = catch_exceptions_;
|
GTEST_FLAG_SET(catch_exceptions, catch_exceptions_);
|
||||||
GTEST_FLAG(color) = color_;
|
GTEST_FLAG_SET(color, color_);
|
||||||
GTEST_FLAG(death_test_style) = death_test_style_;
|
GTEST_FLAG_SET(death_test_style, death_test_style_);
|
||||||
GTEST_FLAG(death_test_use_fork) = death_test_use_fork_;
|
GTEST_FLAG_SET(death_test_use_fork, death_test_use_fork_);
|
||||||
GTEST_FLAG(filter) = filter_;
|
GTEST_FLAG_SET(filter, filter_);
|
||||||
GTEST_FLAG(fail_fast) = fail_fast_;
|
GTEST_FLAG_SET(fail_fast, fail_fast_);
|
||||||
GTEST_FLAG(internal_run_death_test) = internal_run_death_test_;
|
GTEST_FLAG_SET(internal_run_death_test, internal_run_death_test_);
|
||||||
GTEST_FLAG(list_tests) = list_tests_;
|
GTEST_FLAG_SET(list_tests, list_tests_);
|
||||||
GTEST_FLAG(output) = output_;
|
GTEST_FLAG_SET(output, output_);
|
||||||
GTEST_FLAG(brief) = brief_;
|
GTEST_FLAG_SET(brief, brief_);
|
||||||
GTEST_FLAG(print_time) = print_time_;
|
GTEST_FLAG_SET(print_time, print_time_);
|
||||||
GTEST_FLAG(print_utf8) = print_utf8_;
|
GTEST_FLAG_SET(print_utf8, print_utf8_);
|
||||||
GTEST_FLAG(random_seed) = random_seed_;
|
GTEST_FLAG_SET(random_seed, random_seed_);
|
||||||
GTEST_FLAG(repeat) = repeat_;
|
GTEST_FLAG_SET(repeat, repeat_);
|
||||||
GTEST_FLAG(shuffle) = shuffle_;
|
GTEST_FLAG_SET(recreate_environments_when_repeating,
|
||||||
GTEST_FLAG(stack_trace_depth) = stack_trace_depth_;
|
recreate_environments_when_repeating_);
|
||||||
GTEST_FLAG(stream_result_to) = stream_result_to_;
|
GTEST_FLAG_SET(shuffle, shuffle_);
|
||||||
GTEST_FLAG(throw_on_failure) = throw_on_failure_;
|
GTEST_FLAG_SET(stack_trace_depth, stack_trace_depth_);
|
||||||
|
GTEST_FLAG_SET(stream_result_to, stream_result_to_);
|
||||||
|
GTEST_FLAG_SET(throw_on_failure, throw_on_failure_);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -224,6 +206,7 @@ class GTestFlagSaver {
|
|||||||
bool print_utf8_;
|
bool print_utf8_;
|
||||||
int32_t random_seed_;
|
int32_t random_seed_;
|
||||||
int32_t repeat_;
|
int32_t repeat_;
|
||||||
|
bool recreate_environments_when_repeating_;
|
||||||
bool shuffle_;
|
bool shuffle_;
|
||||||
int32_t stack_trace_depth_;
|
int32_t stack_trace_depth_;
|
||||||
std::string stream_result_to_;
|
std::string stream_result_to_;
|
||||||
@ -290,7 +273,7 @@ inline int CountIf(const Container& c, Predicate predicate) {
|
|||||||
// Implemented as an explicit loop since std::count_if() in libCstd on
|
// Implemented as an explicit loop since std::count_if() in libCstd on
|
||||||
// Solaris has a non-standard signature.
|
// Solaris has a non-standard signature.
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) {
|
for (auto it = c.begin(); it != c.end(); ++it) {
|
||||||
if (predicate(*it))
|
if (predicate(*it))
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ const int kStdOutFileno = STDOUT_FILENO;
|
|||||||
const int kStdErrFileno = STDERR_FILENO;
|
const int kStdErrFileno = STDERR_FILENO;
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
#if GTEST_OS_LINUX
|
#if GTEST_OS_LINUX || GTEST_OS_GNU_HURD
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -280,10 +280,6 @@ size_t GetThreadCount() {
|
|||||||
|
|
||||||
#if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS
|
#if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS
|
||||||
|
|
||||||
void SleepMilliseconds(int n) {
|
|
||||||
::Sleep(static_cast<DWORD>(n));
|
|
||||||
}
|
|
||||||
|
|
||||||
AutoHandle::AutoHandle()
|
AutoHandle::AutoHandle()
|
||||||
: handle_(INVALID_HANDLE_VALUE) {}
|
: handle_(INVALID_HANDLE_VALUE) {}
|
||||||
|
|
||||||
@ -322,23 +318,6 @@ bool AutoHandle::IsCloseable() const {
|
|||||||
return handle_ != nullptr && handle_ != INVALID_HANDLE_VALUE;
|
return handle_ != nullptr && handle_ != INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Notification::Notification()
|
|
||||||
: event_(::CreateEvent(nullptr, // Default security attributes.
|
|
||||||
TRUE, // Do not reset automatically.
|
|
||||||
FALSE, // Initially unset.
|
|
||||||
nullptr)) { // Anonymous event.
|
|
||||||
GTEST_CHECK_(event_.Get() != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Notification::Notify() {
|
|
||||||
GTEST_CHECK_(::SetEvent(event_.Get()) != FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Notification::WaitForNotification() {
|
|
||||||
GTEST_CHECK_(
|
|
||||||
::WaitForSingleObject(event_.Get(), INFINITE) == WAIT_OBJECT_0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Mutex::Mutex()
|
Mutex::Mutex()
|
||||||
: owner_thread_id_(0),
|
: owner_thread_id_(0),
|
||||||
type_(kDynamic),
|
type_(kDynamic),
|
||||||
@ -650,7 +629,8 @@ class ThreadLocalRegistryImpl {
|
|||||||
&ThreadLocalRegistryImpl::WatcherThreadFunc,
|
&ThreadLocalRegistryImpl::WatcherThreadFunc,
|
||||||
reinterpret_cast<LPVOID>(new ThreadIdAndHandle(thread_id, thread)),
|
reinterpret_cast<LPVOID>(new ThreadIdAndHandle(thread_id, thread)),
|
||||||
CREATE_SUSPENDED, &watcher_thread_id);
|
CREATE_SUSPENDED, &watcher_thread_id);
|
||||||
GTEST_CHECK_(watcher_thread != nullptr);
|
GTEST_CHECK_(watcher_thread != nullptr)
|
||||||
|
<< "CreateThread failed with error " << ::GetLastError() << ".";
|
||||||
// Give the watcher thread the same priority as ours to avoid being
|
// Give the watcher thread the same priority as ours to avoid being
|
||||||
// blocked by it.
|
// blocked by it.
|
||||||
::SetThreadPriority(watcher_thread,
|
::SetThreadPriority(watcher_thread,
|
||||||
|
@ -304,6 +304,51 @@ void PrintTo(char32_t c, ::std::ostream* os) {
|
|||||||
<< static_cast<uint32_t>(c);
|
<< static_cast<uint32_t>(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gcc/clang __{u,}int128_t
|
||||||
|
#if defined(__SIZEOF_INT128__)
|
||||||
|
void PrintTo(__uint128_t v, ::std::ostream* os) {
|
||||||
|
if (v == 0) {
|
||||||
|
*os << "0";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffer large enough for ceil(log10(2^128))==39 and the null terminator
|
||||||
|
char buf[40];
|
||||||
|
char* p = buf + sizeof(buf);
|
||||||
|
|
||||||
|
// Some configurations have a __uint128_t, but no support for built in
|
||||||
|
// division. Do manual long division instead.
|
||||||
|
|
||||||
|
uint64_t high = static_cast<uint64_t>(v >> 64);
|
||||||
|
uint64_t low = static_cast<uint64_t>(v);
|
||||||
|
|
||||||
|
*--p = 0;
|
||||||
|
while (high != 0 || low != 0) {
|
||||||
|
uint64_t high_mod = high % 10;
|
||||||
|
high = high / 10;
|
||||||
|
// This is the long division algorithm specialized for a divisor of 10 and
|
||||||
|
// only two elements.
|
||||||
|
// Notable values:
|
||||||
|
// 2^64 / 10 == 1844674407370955161
|
||||||
|
// 2^64 % 10 == 6
|
||||||
|
const uint64_t carry = 6 * high_mod + low % 10;
|
||||||
|
low = low / 10 + high_mod * 1844674407370955161 + carry / 10;
|
||||||
|
|
||||||
|
char digit = static_cast<char>(carry % 10);
|
||||||
|
*--p = '0' + digit;
|
||||||
|
}
|
||||||
|
*os << p;
|
||||||
|
}
|
||||||
|
void PrintTo(__int128_t v, ::std::ostream* os) {
|
||||||
|
__uint128_t uv = static_cast<__uint128_t>(v);
|
||||||
|
if (v < 0) {
|
||||||
|
*os << "-";
|
||||||
|
uv = -uv;
|
||||||
|
}
|
||||||
|
PrintTo(uv, os);
|
||||||
|
}
|
||||||
|
#endif // __SIZEOF_INT128__
|
||||||
|
|
||||||
// Prints the given array of characters to the ostream. CharType must be either
|
// Prints the given array of characters to the ostream. CharType must be either
|
||||||
// char, char8_t, char16_t, char32_t, or wchar_t.
|
// char, char8_t, char16_t, char32_t, or wchar_t.
|
||||||
// The array starts at begin, the length is len, it may include '\0' characters
|
// The array starts at begin, the length is len, it may include '\0' characters
|
||||||
@ -502,7 +547,7 @@ void ConditionalPrintAsText(const char* str, size_t length, ostream* os) {
|
|||||||
|
|
||||||
void PrintStringTo(const ::std::string& s, ostream* os) {
|
void PrintStringTo(const ::std::string& s, ostream* os) {
|
||||||
if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) {
|
if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) {
|
||||||
if (GTEST_FLAG(print_utf8)) {
|
if (GTEST_FLAG_GET(print_utf8)) {
|
||||||
ConditionalPrintAsText(s.data(), s.size(), os);
|
ConditionalPrintAsText(s.data(), s.size(), os);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,7 @@ const char kStackTraceMarker[] = "\nStack trace:\n";
|
|||||||
// is specified on the command line.
|
// is specified on the command line.
|
||||||
bool g_help_flag = false;
|
bool g_help_flag = false;
|
||||||
|
|
||||||
// Utilty function to Open File for Writing
|
// Utility function to Open File for Writing
|
||||||
static FILE* OpenFileForWriting(const std::string& output_file) {
|
static FILE* OpenFileForWriting(const std::string& output_file) {
|
||||||
FILE* fileout = nullptr;
|
FILE* fileout = nullptr;
|
||||||
FilePath output_file_path(output_file);
|
FilePath output_file_path(output_file);
|
||||||
@ -216,28 +216,33 @@ static bool GetDefaultFailFast() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
GTEST_DEFINE_bool_(
|
GTEST_DEFINE_bool_(
|
||||||
fail_fast, internal::BoolFromGTestEnv("fail_fast", GetDefaultFailFast()),
|
fail_fast,
|
||||||
|
testing::internal::BoolFromGTestEnv("fail_fast",
|
||||||
|
testing::GetDefaultFailFast()),
|
||||||
"True if and only if a test failure should stop further test execution.");
|
"True if and only if a test failure should stop further test execution.");
|
||||||
|
|
||||||
GTEST_DEFINE_bool_(
|
GTEST_DEFINE_bool_(
|
||||||
also_run_disabled_tests,
|
also_run_disabled_tests,
|
||||||
internal::BoolFromGTestEnv("also_run_disabled_tests", false),
|
testing::internal::BoolFromGTestEnv("also_run_disabled_tests", false),
|
||||||
"Run disabled tests too, in addition to the tests normally being run.");
|
"Run disabled tests too, in addition to the tests normally being run.");
|
||||||
|
|
||||||
GTEST_DEFINE_bool_(
|
GTEST_DEFINE_bool_(
|
||||||
break_on_failure, internal::BoolFromGTestEnv("break_on_failure", false),
|
break_on_failure,
|
||||||
|
testing::internal::BoolFromGTestEnv("break_on_failure", false),
|
||||||
"True if and only if a failed assertion should be a debugger "
|
"True if and only if a failed assertion should be a debugger "
|
||||||
"break-point.");
|
"break-point.");
|
||||||
|
|
||||||
GTEST_DEFINE_bool_(catch_exceptions,
|
GTEST_DEFINE_bool_(catch_exceptions,
|
||||||
internal::BoolFromGTestEnv("catch_exceptions", true),
|
testing::internal::BoolFromGTestEnv("catch_exceptions",
|
||||||
|
true),
|
||||||
"True if and only if " GTEST_NAME_
|
"True if and only if " GTEST_NAME_
|
||||||
" should catch exceptions and treat them as test failures.");
|
" should catch exceptions and treat them as test failures.");
|
||||||
|
|
||||||
GTEST_DEFINE_string_(
|
GTEST_DEFINE_string_(
|
||||||
color,
|
color, testing::internal::StringFromGTestEnv("color", "auto"),
|
||||||
internal::StringFromGTestEnv("color", "auto"),
|
|
||||||
"Whether to use colors in the output. Valid values: yes, no, "
|
"Whether to use colors in the output. Valid values: yes, no, "
|
||||||
"and auto. 'auto' means to use colors if the output is "
|
"and auto. 'auto' means to use colors if the output is "
|
||||||
"being sent to a terminal and the TERM environment variable "
|
"being sent to a terminal and the TERM environment variable "
|
||||||
@ -245,7 +250,8 @@ GTEST_DEFINE_string_(
|
|||||||
|
|
||||||
GTEST_DEFINE_string_(
|
GTEST_DEFINE_string_(
|
||||||
filter,
|
filter,
|
||||||
internal::StringFromGTestEnv("filter", GetDefaultFilter()),
|
testing::internal::StringFromGTestEnv("filter",
|
||||||
|
testing::GetDefaultFilter()),
|
||||||
"A colon-separated list of glob (not regex) patterns "
|
"A colon-separated list of glob (not regex) patterns "
|
||||||
"for filtering the tests to run, optionally followed by a "
|
"for filtering the tests to run, optionally followed by a "
|
||||||
"'-' and a : separated list of negative patterns (tests to "
|
"'-' and a : separated list of negative patterns (tests to "
|
||||||
@ -254,8 +260,10 @@ GTEST_DEFINE_string_(
|
|||||||
|
|
||||||
GTEST_DEFINE_bool_(
|
GTEST_DEFINE_bool_(
|
||||||
install_failure_signal_handler,
|
install_failure_signal_handler,
|
||||||
internal::BoolFromGTestEnv("install_failure_signal_handler", false),
|
testing::internal::BoolFromGTestEnv("install_failure_signal_handler",
|
||||||
"If true and supported on the current platform, " GTEST_NAME_ " should "
|
false),
|
||||||
|
"If true and supported on the current platform, " GTEST_NAME_
|
||||||
|
" should "
|
||||||
"install a signal handler that dumps debugging information when fatal "
|
"install a signal handler that dumps debugging information when fatal "
|
||||||
"signals are raised.");
|
"signals are raised.");
|
||||||
|
|
||||||
@ -269,8 +277,8 @@ GTEST_DEFINE_bool_(list_tests, false,
|
|||||||
// ''
|
// ''
|
||||||
GTEST_DEFINE_string_(
|
GTEST_DEFINE_string_(
|
||||||
output,
|
output,
|
||||||
internal::StringFromGTestEnv("output",
|
testing::internal::StringFromGTestEnv(
|
||||||
internal::OutputFlagAlsoCheckEnvVar().c_str()),
|
"output", testing::internal::OutputFlagAlsoCheckEnvVar().c_str()),
|
||||||
"A format (defaults to \"xml\" but can be specified to be \"json\"), "
|
"A format (defaults to \"xml\" but can be specified to be \"json\"), "
|
||||||
"optionally followed by a colon and an output file name or directory. "
|
"optionally followed by a colon and an output file name or directory. "
|
||||||
"A directory is indicated by a trailing pathname separator. "
|
"A directory is indicated by a trailing pathname separator. "
|
||||||
@ -281,65 +289,79 @@ GTEST_DEFINE_string_(
|
|||||||
"digits.");
|
"digits.");
|
||||||
|
|
||||||
GTEST_DEFINE_bool_(
|
GTEST_DEFINE_bool_(
|
||||||
brief, internal::BoolFromGTestEnv("brief", false),
|
brief, testing::internal::BoolFromGTestEnv("brief", false),
|
||||||
"True if only test failures should be displayed in text output.");
|
"True if only test failures should be displayed in text output.");
|
||||||
|
|
||||||
GTEST_DEFINE_bool_(print_time, internal::BoolFromGTestEnv("print_time", true),
|
GTEST_DEFINE_bool_(print_time,
|
||||||
|
testing::internal::BoolFromGTestEnv("print_time", true),
|
||||||
"True if and only if " GTEST_NAME_
|
"True if and only if " GTEST_NAME_
|
||||||
" should display elapsed time in text output.");
|
" should display elapsed time in text output.");
|
||||||
|
|
||||||
GTEST_DEFINE_bool_(print_utf8, internal::BoolFromGTestEnv("print_utf8", true),
|
GTEST_DEFINE_bool_(print_utf8,
|
||||||
|
testing::internal::BoolFromGTestEnv("print_utf8", true),
|
||||||
"True if and only if " GTEST_NAME_
|
"True if and only if " GTEST_NAME_
|
||||||
" prints UTF8 characters as text.");
|
" prints UTF8 characters as text.");
|
||||||
|
|
||||||
GTEST_DEFINE_int32_(
|
GTEST_DEFINE_int32_(
|
||||||
random_seed,
|
random_seed, testing::internal::Int32FromGTestEnv("random_seed", 0),
|
||||||
internal::Int32FromGTestEnv("random_seed", 0),
|
|
||||||
"Random number seed to use when shuffling test orders. Must be in range "
|
"Random number seed to use when shuffling test orders. Must be in range "
|
||||||
"[1, 99999], or 0 to use a seed based on the current time.");
|
"[1, 99999], or 0 to use a seed based on the current time.");
|
||||||
|
|
||||||
GTEST_DEFINE_int32_(
|
GTEST_DEFINE_int32_(
|
||||||
repeat,
|
repeat, testing::internal::Int32FromGTestEnv("repeat", 1),
|
||||||
internal::Int32FromGTestEnv("repeat", 1),
|
|
||||||
"How many times to repeat each test. Specify a negative number "
|
"How many times to repeat each test. Specify a negative number "
|
||||||
"for repeating forever. Useful for shaking out flaky tests.");
|
"for repeating forever. Useful for shaking out flaky tests.");
|
||||||
|
|
||||||
|
GTEST_DEFINE_bool_(
|
||||||
|
recreate_environments_when_repeating,
|
||||||
|
testing::internal::BoolFromGTestEnv("recreate_environments_when_repeating",
|
||||||
|
true),
|
||||||
|
"Controls whether global test environments are recreated for each repeat "
|
||||||
|
"of the tests. If set to false the global test environments are only set "
|
||||||
|
"up once, for the first iteration, and only torn down once, for the last. "
|
||||||
|
"Useful for shaking out flaky tests with stable, expensive test "
|
||||||
|
"environments. If --gtest_repeat is set to a negative number, meaning "
|
||||||
|
"there is no last run, the environments will always be recreated to avoid "
|
||||||
|
"leaks.");
|
||||||
|
|
||||||
GTEST_DEFINE_bool_(show_internal_stack_frames, false,
|
GTEST_DEFINE_bool_(show_internal_stack_frames, false,
|
||||||
"True if and only if " GTEST_NAME_
|
"True if and only if " GTEST_NAME_
|
||||||
" should include internal stack frames when "
|
" should include internal stack frames when "
|
||||||
"printing test failure stack traces.");
|
"printing test failure stack traces.");
|
||||||
|
|
||||||
GTEST_DEFINE_bool_(shuffle, internal::BoolFromGTestEnv("shuffle", false),
|
GTEST_DEFINE_bool_(shuffle,
|
||||||
|
testing::internal::BoolFromGTestEnv("shuffle", false),
|
||||||
"True if and only if " GTEST_NAME_
|
"True if and only if " GTEST_NAME_
|
||||||
" should randomize tests' order on every run.");
|
" should randomize tests' order on every run.");
|
||||||
|
|
||||||
GTEST_DEFINE_int32_(
|
GTEST_DEFINE_int32_(
|
||||||
stack_trace_depth,
|
stack_trace_depth,
|
||||||
internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth),
|
testing::internal::Int32FromGTestEnv("stack_trace_depth",
|
||||||
|
testing::kMaxStackTraceDepth),
|
||||||
"The maximum number of stack frames to print when an "
|
"The maximum number of stack frames to print when an "
|
||||||
"assertion fails. The valid range is 0 through 100, inclusive.");
|
"assertion fails. The valid range is 0 through 100, inclusive.");
|
||||||
|
|
||||||
GTEST_DEFINE_string_(
|
GTEST_DEFINE_string_(
|
||||||
stream_result_to,
|
stream_result_to,
|
||||||
internal::StringFromGTestEnv("stream_result_to", ""),
|
testing::internal::StringFromGTestEnv("stream_result_to", ""),
|
||||||
"This flag specifies the host name and the port number on which to stream "
|
"This flag specifies the host name and the port number on which to stream "
|
||||||
"test results. Example: \"localhost:555\". The flag is effective only on "
|
"test results. Example: \"localhost:555\". The flag is effective only on "
|
||||||
"Linux.");
|
"Linux.");
|
||||||
|
|
||||||
GTEST_DEFINE_bool_(
|
GTEST_DEFINE_bool_(
|
||||||
throw_on_failure,
|
throw_on_failure,
|
||||||
internal::BoolFromGTestEnv("throw_on_failure", false),
|
testing::internal::BoolFromGTestEnv("throw_on_failure", false),
|
||||||
"When this flag is specified, a failed assertion will throw an exception "
|
"When this flag is specified, a failed assertion will throw an exception "
|
||||||
"if exceptions are enabled or exit the program with a non-zero code "
|
"if exceptions are enabled or exit the program with a non-zero code "
|
||||||
"otherwise. For use with an external test framework.");
|
"otherwise. For use with an external test framework.");
|
||||||
|
|
||||||
#if GTEST_USE_OWN_FLAGFILE_FLAG_
|
#if GTEST_USE_OWN_FLAGFILE_FLAG_
|
||||||
GTEST_DEFINE_string_(
|
GTEST_DEFINE_string_(
|
||||||
flagfile,
|
flagfile, testing::internal::StringFromGTestEnv("flagfile", ""),
|
||||||
internal::StringFromGTestEnv("flagfile", ""),
|
|
||||||
"This flag specifies the flagfile to read command-line flags from.");
|
"This flag specifies the flagfile to read command-line flags from.");
|
||||||
#endif // GTEST_USE_OWN_FLAGFILE_FLAG_
|
#endif // GTEST_USE_OWN_FLAGFILE_FLAG_
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// Generates a random number from [0, range), using a Linear
|
// Generates a random number from [0, range), using a Linear
|
||||||
@ -421,7 +443,7 @@ void AssertHelper::operator=(const Message& message) const {
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// When TEST_P is found without a matching INSTANTIATE_TEST_SUITE_P
|
// When TEST_P is found without a matching INSTANTIATE_TEST_SUITE_P
|
||||||
// to creates test cases for it, a syntetic test case is
|
// to creates test cases for it, a synthetic test case is
|
||||||
// inserted to report ether an error or a log message.
|
// inserted to report ether an error or a log message.
|
||||||
//
|
//
|
||||||
// This configuration bit will likely be removed at some point.
|
// This configuration bit will likely be removed at some point.
|
||||||
@ -606,7 +628,8 @@ FilePath GetCurrentExecutableName() {
|
|||||||
|
|
||||||
// Returns the output format, or "" for normal printed output.
|
// Returns the output format, or "" for normal printed output.
|
||||||
std::string UnitTestOptions::GetOutputFormat() {
|
std::string UnitTestOptions::GetOutputFormat() {
|
||||||
const char* const gtest_output_flag = GTEST_FLAG(output).c_str();
|
std::string s = GTEST_FLAG_GET(output);
|
||||||
|
const char* const gtest_output_flag = s.c_str();
|
||||||
const char* const colon = strchr(gtest_output_flag, ':');
|
const char* const colon = strchr(gtest_output_flag, ':');
|
||||||
return (colon == nullptr)
|
return (colon == nullptr)
|
||||||
? std::string(gtest_output_flag)
|
? std::string(gtest_output_flag)
|
||||||
@ -617,7 +640,8 @@ std::string UnitTestOptions::GetOutputFormat() {
|
|||||||
// Returns the name of the requested output file, or the default if none
|
// Returns the name of the requested output file, or the default if none
|
||||||
// was explicitly specified.
|
// was explicitly specified.
|
||||||
std::string UnitTestOptions::GetAbsolutePathToOutputFile() {
|
std::string UnitTestOptions::GetAbsolutePathToOutputFile() {
|
||||||
const char* const gtest_output_flag = GTEST_FLAG(output).c_str();
|
std::string s = GTEST_FLAG_GET(output);
|
||||||
|
const char* const gtest_output_flag = s.c_str();
|
||||||
|
|
||||||
std::string format = GetOutputFormat();
|
std::string format = GetOutputFormat();
|
||||||
if (format.empty())
|
if (format.empty())
|
||||||
@ -732,12 +756,13 @@ bool UnitTestOptions::FilterMatchesTest(const std::string& test_suite_name,
|
|||||||
|
|
||||||
// Split --gtest_filter at '-', if there is one, to separate into
|
// Split --gtest_filter at '-', if there is one, to separate into
|
||||||
// positive filter and negative filter portions
|
// positive filter and negative filter portions
|
||||||
const char* const p = GTEST_FLAG(filter).c_str();
|
std::string str = GTEST_FLAG_GET(filter);
|
||||||
|
const char* const p = str.c_str();
|
||||||
const char* const dash = strchr(p, '-');
|
const char* const dash = strchr(p, '-');
|
||||||
std::string positive;
|
std::string positive;
|
||||||
std::string negative;
|
std::string negative;
|
||||||
if (dash == nullptr) {
|
if (dash == nullptr) {
|
||||||
positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter
|
positive = str.c_str(); // Whole string is a positive filter
|
||||||
negative = "";
|
negative = "";
|
||||||
} else {
|
} else {
|
||||||
positive = std::string(p, dash); // Everything up to the dash
|
positive = std::string(p, dash); // Everything up to the dash
|
||||||
@ -771,7 +796,7 @@ int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) {
|
|||||||
|
|
||||||
bool should_handle = true;
|
bool should_handle = true;
|
||||||
|
|
||||||
if (!GTEST_FLAG(catch_exceptions))
|
if (!GTEST_FLAG_GET(catch_exceptions))
|
||||||
should_handle = false;
|
should_handle = false;
|
||||||
else if (exception_code == EXCEPTION_BREAKPOINT)
|
else if (exception_code == EXCEPTION_BREAKPOINT)
|
||||||
should_handle = false;
|
should_handle = false;
|
||||||
@ -1024,11 +1049,10 @@ int UnitTestImpl::test_to_run_count() const {
|
|||||||
// trace but Bar() and CurrentOsStackTraceExceptTop() won't.
|
// trace but Bar() and CurrentOsStackTraceExceptTop() won't.
|
||||||
std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) {
|
std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) {
|
||||||
return os_stack_trace_getter()->CurrentStackTrace(
|
return os_stack_trace_getter()->CurrentStackTrace(
|
||||||
static_cast<int>(GTEST_FLAG(stack_trace_depth)),
|
static_cast<int>(GTEST_FLAG_GET(stack_trace_depth)), skip_count + 1
|
||||||
skip_count + 1
|
|
||||||
// Skips the user-specified number of frames plus this function
|
// Skips the user-specified number of frames plus this function
|
||||||
// itself.
|
// itself.
|
||||||
); // NOLINT
|
); // NOLINT
|
||||||
}
|
}
|
||||||
|
|
||||||
// A helper class for measuring elapsed times.
|
// A helper class for measuring elapsed times.
|
||||||
@ -2623,7 +2647,7 @@ Result HandleExceptionsInMethodIfSupported(
|
|||||||
// try {
|
// try {
|
||||||
// // Perform the test method.
|
// // Perform the test method.
|
||||||
// } catch (...) {
|
// } catch (...) {
|
||||||
// if (GTEST_FLAG(catch_exceptions))
|
// if (GTEST_FLAG_GET(catch_exceptions))
|
||||||
// // Report the exception as failure.
|
// // Report the exception as failure.
|
||||||
// else
|
// else
|
||||||
// throw; // Re-throws the original exception.
|
// throw; // Re-throws the original exception.
|
||||||
@ -2831,20 +2855,20 @@ void UnitTestImpl::RegisterParameterizedTests() {
|
|||||||
// Creates the test object, runs it, records its result, and then
|
// Creates the test object, runs it, records its result, and then
|
||||||
// deletes it.
|
// deletes it.
|
||||||
void TestInfo::Run() {
|
void TestInfo::Run() {
|
||||||
if (!should_run_) return;
|
TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
|
||||||
|
if (!should_run_) {
|
||||||
|
if (is_disabled_) repeater->OnTestDisabled(*this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Tells UnitTest where to store test result.
|
// Tells UnitTest where to store test result.
|
||||||
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
|
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
|
||||||
impl->set_current_test_info(this);
|
impl->set_current_test_info(this);
|
||||||
|
|
||||||
TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
|
|
||||||
|
|
||||||
// Notifies the unit test event listeners that a test is about to start.
|
// Notifies the unit test event listeners that a test is about to start.
|
||||||
repeater->OnTestStart(*this);
|
repeater->OnTestStart(*this);
|
||||||
|
|
||||||
result_.set_start_timestamp(internal::GetTimeInMillis());
|
result_.set_start_timestamp(internal::GetTimeInMillis());
|
||||||
internal::Timer timer;
|
internal::Timer timer;
|
||||||
|
|
||||||
impl->os_stack_trace_getter()->UponLeavingGTest();
|
impl->os_stack_trace_getter()->UponLeavingGTest();
|
||||||
|
|
||||||
// Creates the test object.
|
// Creates the test object.
|
||||||
@ -3009,11 +3033,18 @@ void TestSuite::Run() {
|
|||||||
internal::HandleExceptionsInMethodIfSupported(
|
internal::HandleExceptionsInMethodIfSupported(
|
||||||
this, &TestSuite::RunSetUpTestSuite, "SetUpTestSuite()");
|
this, &TestSuite::RunSetUpTestSuite, "SetUpTestSuite()");
|
||||||
|
|
||||||
|
const bool skip_all = ad_hoc_test_result().Failed();
|
||||||
|
|
||||||
start_timestamp_ = internal::GetTimeInMillis();
|
start_timestamp_ = internal::GetTimeInMillis();
|
||||||
internal::Timer timer;
|
internal::Timer timer;
|
||||||
for (int i = 0; i < total_test_count(); i++) {
|
for (int i = 0; i < total_test_count(); i++) {
|
||||||
GetMutableTestInfo(i)->Run();
|
if (skip_all) {
|
||||||
if (GTEST_FLAG(fail_fast) && GetMutableTestInfo(i)->result()->Failed()) {
|
GetMutableTestInfo(i)->Skip();
|
||||||
|
} else {
|
||||||
|
GetMutableTestInfo(i)->Run();
|
||||||
|
}
|
||||||
|
if (GTEST_FLAG_GET(fail_fast) &&
|
||||||
|
GetMutableTestInfo(i)->result()->Failed()) {
|
||||||
for (int j = i + 1; j < total_test_count(); j++) {
|
for (int j = i + 1; j < total_test_count(); j++) {
|
||||||
GetMutableTestInfo(j)->Skip();
|
GetMutableTestInfo(j)->Skip();
|
||||||
}
|
}
|
||||||
@ -3232,7 +3263,8 @@ static const char* GetAnsiColorCode(GTestColor color) {
|
|||||||
|
|
||||||
// Returns true if and only if Google Test should use colors in the output.
|
// Returns true if and only if Google Test should use colors in the output.
|
||||||
bool ShouldUseColor(bool stdout_is_tty) {
|
bool ShouldUseColor(bool stdout_is_tty) {
|
||||||
const char* const gtest_color = GTEST_FLAG(color).c_str();
|
std::string c = GTEST_FLAG_GET(color);
|
||||||
|
const char* const gtest_color = c.c_str();
|
||||||
|
|
||||||
if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) {
|
if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) {
|
||||||
#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW
|
#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW
|
||||||
@ -3364,6 +3396,7 @@ class PrettyUnitTestResultPrinter : public TestEventListener {
|
|||||||
#endif // OnTestCaseStart
|
#endif // OnTestCaseStart
|
||||||
|
|
||||||
void OnTestStart(const TestInfo& test_info) override;
|
void OnTestStart(const TestInfo& test_info) override;
|
||||||
|
void OnTestDisabled(const TestInfo& test_info) override;
|
||||||
|
|
||||||
void OnTestPartResult(const TestPartResult& result) override;
|
void OnTestPartResult(const TestPartResult& result) override;
|
||||||
void OnTestEnd(const TestInfo& test_info) override;
|
void OnTestEnd(const TestInfo& test_info) override;
|
||||||
@ -3387,10 +3420,11 @@ class PrettyUnitTestResultPrinter : public TestEventListener {
|
|||||||
// Fired before each iteration of tests starts.
|
// Fired before each iteration of tests starts.
|
||||||
void PrettyUnitTestResultPrinter::OnTestIterationStart(
|
void PrettyUnitTestResultPrinter::OnTestIterationStart(
|
||||||
const UnitTest& unit_test, int iteration) {
|
const UnitTest& unit_test, int iteration) {
|
||||||
if (GTEST_FLAG(repeat) != 1)
|
if (GTEST_FLAG_GET(repeat) != 1)
|
||||||
printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1);
|
printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1);
|
||||||
|
|
||||||
const char* const filter = GTEST_FLAG(filter).c_str();
|
std::string f = GTEST_FLAG_GET(filter);
|
||||||
|
const char* const filter = f.c_str();
|
||||||
|
|
||||||
// Prints the filter if it's not *. This reminds the user that some
|
// Prints the filter if it's not *. This reminds the user that some
|
||||||
// tests may be skipped.
|
// tests may be skipped.
|
||||||
@ -3406,7 +3440,7 @@ void PrettyUnitTestResultPrinter::OnTestIterationStart(
|
|||||||
internal::posix::GetEnv(kTestTotalShards));
|
internal::posix::GetEnv(kTestTotalShards));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GTEST_FLAG(shuffle)) {
|
if (GTEST_FLAG_GET(shuffle)) {
|
||||||
ColoredPrintf(GTestColor::kYellow,
|
ColoredPrintf(GTestColor::kYellow,
|
||||||
"Note: Randomizing tests' orders with a seed of %d .\n",
|
"Note: Randomizing tests' orders with a seed of %d .\n",
|
||||||
unit_test.random_seed());
|
unit_test.random_seed());
|
||||||
@ -3462,6 +3496,13 @@ void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) {
|
|||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrettyUnitTestResultPrinter::OnTestDisabled(const TestInfo& test_info) {
|
||||||
|
ColoredPrintf(GTestColor::kYellow, "[ DISABLED ] ");
|
||||||
|
PrintTestName(test_info.test_suite_name(), test_info.name());
|
||||||
|
printf("\n");
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
// Called after an assertion failure.
|
// Called after an assertion failure.
|
||||||
void PrettyUnitTestResultPrinter::OnTestPartResult(
|
void PrettyUnitTestResultPrinter::OnTestPartResult(
|
||||||
const TestPartResult& result) {
|
const TestPartResult& result) {
|
||||||
@ -3489,7 +3530,7 @@ void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {
|
|||||||
if (test_info.result()->Failed())
|
if (test_info.result()->Failed())
|
||||||
PrintFullTestCommentIfPresent(test_info);
|
PrintFullTestCommentIfPresent(test_info);
|
||||||
|
|
||||||
if (GTEST_FLAG(print_time)) {
|
if (GTEST_FLAG_GET(print_time)) {
|
||||||
printf(" (%s ms)\n", internal::StreamableToString(
|
printf(" (%s ms)\n", internal::StreamableToString(
|
||||||
test_info.result()->elapsed_time()).c_str());
|
test_info.result()->elapsed_time()).c_str());
|
||||||
} else {
|
} else {
|
||||||
@ -3500,7 +3541,7 @@ void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {
|
|||||||
|
|
||||||
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) {
|
void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) {
|
||||||
if (!GTEST_FLAG(print_time)) return;
|
if (!GTEST_FLAG_GET(print_time)) return;
|
||||||
|
|
||||||
const std::string counts =
|
const std::string counts =
|
||||||
FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
|
FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
|
||||||
@ -3511,7 +3552,7 @@ void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) {
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void PrettyUnitTestResultPrinter::OnTestSuiteEnd(const TestSuite& test_suite) {
|
void PrettyUnitTestResultPrinter::OnTestSuiteEnd(const TestSuite& test_suite) {
|
||||||
if (!GTEST_FLAG(print_time)) return;
|
if (!GTEST_FLAG_GET(print_time)) return;
|
||||||
|
|
||||||
const std::string counts =
|
const std::string counts =
|
||||||
FormatCountableNoun(test_suite.test_to_run_count(), "test", "tests");
|
FormatCountableNoun(test_suite.test_to_run_count(), "test", "tests");
|
||||||
@ -3607,7 +3648,7 @@ void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
|
|||||||
printf("%s from %s ran.",
|
printf("%s from %s ran.",
|
||||||
FormatTestCount(unit_test.test_to_run_count()).c_str(),
|
FormatTestCount(unit_test.test_to_run_count()).c_str(),
|
||||||
FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str());
|
FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str());
|
||||||
if (GTEST_FLAG(print_time)) {
|
if (GTEST_FLAG_GET(print_time)) {
|
||||||
printf(" (%s ms total)",
|
printf(" (%s ms total)",
|
||||||
internal::StreamableToString(unit_test.elapsed_time()).c_str());
|
internal::StreamableToString(unit_test.elapsed_time()).c_str());
|
||||||
}
|
}
|
||||||
@ -3628,7 +3669,7 @@ void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int num_disabled = unit_test.reportable_disabled_test_count();
|
int num_disabled = unit_test.reportable_disabled_test_count();
|
||||||
if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) {
|
if (num_disabled && !GTEST_FLAG_GET(also_run_disabled_tests)) {
|
||||||
if (unit_test.Passed()) {
|
if (unit_test.Passed()) {
|
||||||
printf("\n"); // Add a spacer if no FAILURE banner is displayed.
|
printf("\n"); // Add a spacer if no FAILURE banner is displayed.
|
||||||
}
|
}
|
||||||
@ -3664,6 +3705,7 @@ class BriefUnitTestResultPrinter : public TestEventListener {
|
|||||||
#endif // OnTestCaseStart
|
#endif // OnTestCaseStart
|
||||||
|
|
||||||
void OnTestStart(const TestInfo& /*test_info*/) override {}
|
void OnTestStart(const TestInfo& /*test_info*/) override {}
|
||||||
|
void OnTestDisabled(const TestInfo& /*test_info*/) override {}
|
||||||
|
|
||||||
void OnTestPartResult(const TestPartResult& result) override;
|
void OnTestPartResult(const TestPartResult& result) override;
|
||||||
void OnTestEnd(const TestInfo& test_info) override;
|
void OnTestEnd(const TestInfo& test_info) override;
|
||||||
@ -3700,7 +3742,7 @@ void BriefUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {
|
|||||||
PrintTestName(test_info.test_suite_name(), test_info.name());
|
PrintTestName(test_info.test_suite_name(), test_info.name());
|
||||||
PrintFullTestCommentIfPresent(test_info);
|
PrintFullTestCommentIfPresent(test_info);
|
||||||
|
|
||||||
if (GTEST_FLAG(print_time)) {
|
if (GTEST_FLAG_GET(print_time)) {
|
||||||
printf(" (%s ms)\n",
|
printf(" (%s ms)\n",
|
||||||
internal::StreamableToString(test_info.result()->elapsed_time())
|
internal::StreamableToString(test_info.result()->elapsed_time())
|
||||||
.c_str());
|
.c_str());
|
||||||
@ -3717,7 +3759,7 @@ void BriefUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
|
|||||||
printf("%s from %s ran.",
|
printf("%s from %s ran.",
|
||||||
FormatTestCount(unit_test.test_to_run_count()).c_str(),
|
FormatTestCount(unit_test.test_to_run_count()).c_str(),
|
||||||
FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str());
|
FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str());
|
||||||
if (GTEST_FLAG(print_time)) {
|
if (GTEST_FLAG_GET(print_time)) {
|
||||||
printf(" (%s ms total)",
|
printf(" (%s ms total)",
|
||||||
internal::StreamableToString(unit_test.elapsed_time()).c_str());
|
internal::StreamableToString(unit_test.elapsed_time()).c_str());
|
||||||
}
|
}
|
||||||
@ -3732,7 +3774,7 @@ void BriefUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int num_disabled = unit_test.reportable_disabled_test_count();
|
int num_disabled = unit_test.reportable_disabled_test_count();
|
||||||
if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) {
|
if (num_disabled && !GTEST_FLAG_GET(also_run_disabled_tests)) {
|
||||||
if (unit_test.Passed()) {
|
if (unit_test.Passed()) {
|
||||||
printf("\n"); // Add a spacer if no FAILURE banner is displayed.
|
printf("\n"); // Add a spacer if no FAILURE banner is displayed.
|
||||||
}
|
}
|
||||||
@ -3770,6 +3812,7 @@ class TestEventRepeater : public TestEventListener {
|
|||||||
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
void OnTestSuiteStart(const TestSuite& parameter) override;
|
void OnTestSuiteStart(const TestSuite& parameter) override;
|
||||||
void OnTestStart(const TestInfo& test_info) override;
|
void OnTestStart(const TestInfo& test_info) override;
|
||||||
|
void OnTestDisabled(const TestInfo& test_info) override;
|
||||||
void OnTestPartResult(const TestPartResult& result) override;
|
void OnTestPartResult(const TestPartResult& result) override;
|
||||||
void OnTestEnd(const TestInfo& test_info) override;
|
void OnTestEnd(const TestInfo& test_info) override;
|
||||||
// Legacy API is deprecated but still available
|
// Legacy API is deprecated but still available
|
||||||
@ -3840,6 +3883,7 @@ GTEST_REPEATER_METHOD_(OnTestCaseStart, TestSuite)
|
|||||||
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
GTEST_REPEATER_METHOD_(OnTestSuiteStart, TestSuite)
|
GTEST_REPEATER_METHOD_(OnTestSuiteStart, TestSuite)
|
||||||
GTEST_REPEATER_METHOD_(OnTestStart, TestInfo)
|
GTEST_REPEATER_METHOD_(OnTestStart, TestInfo)
|
||||||
|
GTEST_REPEATER_METHOD_(OnTestDisabled, TestInfo)
|
||||||
GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult)
|
GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult)
|
||||||
GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest)
|
GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest)
|
||||||
GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest)
|
GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest)
|
||||||
@ -3890,12 +3934,13 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener {
|
|||||||
private:
|
private:
|
||||||
// Is c a whitespace character that is normalized to a space character
|
// Is c a whitespace character that is normalized to a space character
|
||||||
// when it appears in an XML attribute value?
|
// when it appears in an XML attribute value?
|
||||||
static bool IsNormalizableWhitespace(char c) {
|
static bool IsNormalizableWhitespace(unsigned char c) {
|
||||||
return c == 0x9 || c == 0xA || c == 0xD;
|
return c == '\t' || c == '\n' || c == '\r';
|
||||||
}
|
}
|
||||||
|
|
||||||
// May c appear in a well-formed XML document?
|
// May c appear in a well-formed XML document?
|
||||||
static bool IsValidXmlCharacter(char c) {
|
// https://www.w3.org/TR/REC-xml/#charsets
|
||||||
|
static bool IsValidXmlCharacter(unsigned char c) {
|
||||||
return IsNormalizableWhitespace(c) || c >= 0x20;
|
return IsNormalizableWhitespace(c) || c >= 0x20;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4064,7 +4109,6 @@ std::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(
|
|||||||
|
|
||||||
// The following routines generate an XML representation of a UnitTest
|
// The following routines generate an XML representation of a UnitTest
|
||||||
// object.
|
// object.
|
||||||
// GOOGLETEST_CM0009 DO NOT DELETE
|
|
||||||
//
|
//
|
||||||
// This is how Google Test concepts map to the DTD:
|
// This is how Google Test concepts map to the DTD:
|
||||||
//
|
//
|
||||||
@ -4216,7 +4260,7 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
|
|||||||
OutputXmlAttribute(stream, kTestsuite, "type_param",
|
OutputXmlAttribute(stream, kTestsuite, "type_param",
|
||||||
test_info.type_param());
|
test_info.type_param());
|
||||||
}
|
}
|
||||||
if (GTEST_FLAG(list_tests)) {
|
if (GTEST_FLAG_GET(list_tests)) {
|
||||||
OutputXmlAttribute(stream, kTestsuite, "file", test_info.file());
|
OutputXmlAttribute(stream, kTestsuite, "file", test_info.file());
|
||||||
OutputXmlAttribute(stream, kTestsuite, "line",
|
OutputXmlAttribute(stream, kTestsuite, "line",
|
||||||
StreamableToString(test_info.line()));
|
StreamableToString(test_info.line()));
|
||||||
@ -4295,7 +4339,7 @@ void XmlUnitTestResultPrinter::PrintXmlTestSuite(std::ostream* stream,
|
|||||||
OutputXmlAttribute(stream, kTestsuite, "name", test_suite.name());
|
OutputXmlAttribute(stream, kTestsuite, "name", test_suite.name());
|
||||||
OutputXmlAttribute(stream, kTestsuite, "tests",
|
OutputXmlAttribute(stream, kTestsuite, "tests",
|
||||||
StreamableToString(test_suite.reportable_test_count()));
|
StreamableToString(test_suite.reportable_test_count()));
|
||||||
if (!GTEST_FLAG(list_tests)) {
|
if (!GTEST_FLAG_GET(list_tests)) {
|
||||||
OutputXmlAttribute(stream, kTestsuite, "failures",
|
OutputXmlAttribute(stream, kTestsuite, "failures",
|
||||||
StreamableToString(test_suite.failed_test_count()));
|
StreamableToString(test_suite.failed_test_count()));
|
||||||
OutputXmlAttribute(
|
OutputXmlAttribute(
|
||||||
@ -4343,7 +4387,7 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream,
|
|||||||
stream, kTestsuites, "timestamp",
|
stream, kTestsuites, "timestamp",
|
||||||
FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp()));
|
FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp()));
|
||||||
|
|
||||||
if (GTEST_FLAG(shuffle)) {
|
if (GTEST_FLAG_GET(shuffle)) {
|
||||||
OutputXmlAttribute(stream, kTestsuites, "random_seed",
|
OutputXmlAttribute(stream, kTestsuites, "random_seed",
|
||||||
StreamableToString(unit_test.random_seed()));
|
StreamableToString(unit_test.random_seed()));
|
||||||
}
|
}
|
||||||
@ -4410,15 +4454,15 @@ void XmlUnitTestResultPrinter::OutputXmlTestProperties(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
*stream << "<" << kProperties << ">\n";
|
*stream << " <" << kProperties << ">\n";
|
||||||
for (int i = 0; i < result.test_property_count(); ++i) {
|
for (int i = 0; i < result.test_property_count(); ++i) {
|
||||||
const TestProperty& property = result.GetTestProperty(i);
|
const TestProperty& property = result.GetTestProperty(i);
|
||||||
*stream << "<" << kProperty;
|
*stream << " <" << kProperty;
|
||||||
*stream << " name=\"" << EscapeXmlAttribute(property.key()) << "\"";
|
*stream << " name=\"" << EscapeXmlAttribute(property.key()) << "\"";
|
||||||
*stream << " value=\"" << EscapeXmlAttribute(property.value()) << "\"";
|
*stream << " value=\"" << EscapeXmlAttribute(property.value()) << "\"";
|
||||||
*stream << "/>\n";
|
*stream << "/>\n";
|
||||||
}
|
}
|
||||||
*stream << "</" << kProperties << ">\n";
|
*stream << " </" << kProperties << ">\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// End XmlUnitTestResultPrinter
|
// End XmlUnitTestResultPrinter
|
||||||
@ -4620,7 +4664,7 @@ void JsonUnitTestResultPrinter::OutputJsonTestSuiteForTestResult(
|
|||||||
*stream << Indent(4) << "{\n";
|
*stream << Indent(4) << "{\n";
|
||||||
OutputJsonKey(stream, "testsuite", "name", "NonTestSuiteFailure", Indent(6));
|
OutputJsonKey(stream, "testsuite", "name", "NonTestSuiteFailure", Indent(6));
|
||||||
OutputJsonKey(stream, "testsuite", "tests", 1, Indent(6));
|
OutputJsonKey(stream, "testsuite", "tests", 1, Indent(6));
|
||||||
if (!GTEST_FLAG(list_tests)) {
|
if (!GTEST_FLAG_GET(list_tests)) {
|
||||||
OutputJsonKey(stream, "testsuite", "failures", 1, Indent(6));
|
OutputJsonKey(stream, "testsuite", "failures", 1, Indent(6));
|
||||||
OutputJsonKey(stream, "testsuite", "disabled", 0, Indent(6));
|
OutputJsonKey(stream, "testsuite", "disabled", 0, Indent(6));
|
||||||
OutputJsonKey(stream, "testsuite", "skipped", 0, Indent(6));
|
OutputJsonKey(stream, "testsuite", "skipped", 0, Indent(6));
|
||||||
@ -4674,7 +4718,7 @@ void JsonUnitTestResultPrinter::OutputJsonTestInfo(::std::ostream* stream,
|
|||||||
OutputJsonKey(stream, kTestsuite, "type_param", test_info.type_param(),
|
OutputJsonKey(stream, kTestsuite, "type_param", test_info.type_param(),
|
||||||
kIndent);
|
kIndent);
|
||||||
}
|
}
|
||||||
if (GTEST_FLAG(list_tests)) {
|
if (GTEST_FLAG_GET(list_tests)) {
|
||||||
OutputJsonKey(stream, kTestsuite, "file", test_info.file(), kIndent);
|
OutputJsonKey(stream, kTestsuite, "file", test_info.file(), kIndent);
|
||||||
OutputJsonKey(stream, kTestsuite, "line", test_info.line(), kIndent, false);
|
OutputJsonKey(stream, kTestsuite, "line", test_info.line(), kIndent, false);
|
||||||
*stream << "\n" << Indent(8) << "}";
|
*stream << "\n" << Indent(8) << "}";
|
||||||
@ -4738,7 +4782,7 @@ void JsonUnitTestResultPrinter::PrintJsonTestSuite(
|
|||||||
OutputJsonKey(stream, kTestsuite, "name", test_suite.name(), kIndent);
|
OutputJsonKey(stream, kTestsuite, "name", test_suite.name(), kIndent);
|
||||||
OutputJsonKey(stream, kTestsuite, "tests", test_suite.reportable_test_count(),
|
OutputJsonKey(stream, kTestsuite, "tests", test_suite.reportable_test_count(),
|
||||||
kIndent);
|
kIndent);
|
||||||
if (!GTEST_FLAG(list_tests)) {
|
if (!GTEST_FLAG_GET(list_tests)) {
|
||||||
OutputJsonKey(stream, kTestsuite, "failures",
|
OutputJsonKey(stream, kTestsuite, "failures",
|
||||||
test_suite.failed_test_count(), kIndent);
|
test_suite.failed_test_count(), kIndent);
|
||||||
OutputJsonKey(stream, kTestsuite, "disabled",
|
OutputJsonKey(stream, kTestsuite, "disabled",
|
||||||
@ -4785,7 +4829,7 @@ void JsonUnitTestResultPrinter::PrintJsonUnitTest(std::ostream* stream,
|
|||||||
OutputJsonKey(stream, kTestsuites, "disabled",
|
OutputJsonKey(stream, kTestsuites, "disabled",
|
||||||
unit_test.reportable_disabled_test_count(), kIndent);
|
unit_test.reportable_disabled_test_count(), kIndent);
|
||||||
OutputJsonKey(stream, kTestsuites, "errors", 0, kIndent);
|
OutputJsonKey(stream, kTestsuites, "errors", 0, kIndent);
|
||||||
if (GTEST_FLAG(shuffle)) {
|
if (GTEST_FLAG_GET(shuffle)) {
|
||||||
OutputJsonKey(stream, kTestsuites, "random_seed", unit_test.random_seed(),
|
OutputJsonKey(stream, kTestsuites, "random_seed", unit_test.random_seed(),
|
||||||
kIndent);
|
kIndent);
|
||||||
}
|
}
|
||||||
@ -4962,7 +5006,7 @@ std::string OsStackTraceGetter::CurrentStackTrace(int max_depth, int skip_count)
|
|||||||
|
|
||||||
for (int i = 0; i < raw_stack_size; ++i) {
|
for (int i = 0; i < raw_stack_size; ++i) {
|
||||||
if (raw_stack[i] == caller_frame &&
|
if (raw_stack[i] == caller_frame &&
|
||||||
!GTEST_FLAG(show_internal_stack_frames)) {
|
!GTEST_FLAG_GET(show_internal_stack_frames)) {
|
||||||
// Add a marker to the trace and stop adding frames.
|
// Add a marker to the trace and stop adding frames.
|
||||||
absl::StrAppend(&result, kElidedFramesMarker, "\n");
|
absl::StrAppend(&result, kElidedFramesMarker, "\n");
|
||||||
break;
|
break;
|
||||||
@ -5012,7 +5056,7 @@ class ScopedPrematureExitFile {
|
|||||||
// create the file with a single "0" character in it. I/O
|
// create the file with a single "0" character in it. I/O
|
||||||
// errors are ignored as there's nothing better we can do and we
|
// errors are ignored as there's nothing better we can do and we
|
||||||
// don't want to fail the test because of this.
|
// don't want to fail the test because of this.
|
||||||
FILE* pfile = posix::FOpen(premature_exit_filepath, "w");
|
FILE* pfile = posix::FOpen(premature_exit_filepath_.c_str(), "w");
|
||||||
fwrite("0", 1, 1, pfile);
|
fwrite("0", 1, 1, pfile);
|
||||||
fclose(pfile);
|
fclose(pfile);
|
||||||
}
|
}
|
||||||
@ -5314,7 +5358,7 @@ void UnitTest::AddTestPartResult(
|
|||||||
// in the code (perhaps in order to use Google Test assertions
|
// in the code (perhaps in order to use Google Test assertions
|
||||||
// with another testing framework) and specify the former on the
|
// with another testing framework) and specify the former on the
|
||||||
// command line for debugging.
|
// command line for debugging.
|
||||||
if (GTEST_FLAG(break_on_failure)) {
|
if (GTEST_FLAG_GET(break_on_failure)) {
|
||||||
#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT
|
#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT
|
||||||
// Using DebugBreak on Windows allows gtest to still break into a debugger
|
// Using DebugBreak on Windows allows gtest to still break into a debugger
|
||||||
// when a failure happens and both the --gtest_break_on_failure and
|
// when a failure happens and both the --gtest_break_on_failure and
|
||||||
@ -5331,7 +5375,7 @@ void UnitTest::AddTestPartResult(
|
|||||||
// portability: some debuggers don't correctly trap abort().
|
// portability: some debuggers don't correctly trap abort().
|
||||||
*static_cast<volatile int*>(nullptr) = 1;
|
*static_cast<volatile int*>(nullptr) = 1;
|
||||||
#endif // GTEST_OS_WINDOWS
|
#endif // GTEST_OS_WINDOWS
|
||||||
} else if (GTEST_FLAG(throw_on_failure)) {
|
} else if (GTEST_FLAG_GET(throw_on_failure)) {
|
||||||
#if GTEST_HAS_EXCEPTIONS
|
#if GTEST_HAS_EXCEPTIONS
|
||||||
throw internal::GoogleTestFailureException(result);
|
throw internal::GoogleTestFailureException(result);
|
||||||
#else
|
#else
|
||||||
@ -5360,7 +5404,7 @@ void UnitTest::RecordProperty(const std::string& key,
|
|||||||
// from the main thread.
|
// from the main thread.
|
||||||
int UnitTest::Run() {
|
int UnitTest::Run() {
|
||||||
const bool in_death_test_child_process =
|
const bool in_death_test_child_process =
|
||||||
internal::GTEST_FLAG(internal_run_death_test).length() > 0;
|
GTEST_FLAG_GET(internal_run_death_test).length() > 0;
|
||||||
|
|
||||||
// Google Test implements this protocol for catching that a test
|
// Google Test implements this protocol for catching that a test
|
||||||
// program exits before returning control to Google Test:
|
// program exits before returning control to Google Test:
|
||||||
@ -5390,7 +5434,7 @@ int UnitTest::Run() {
|
|||||||
|
|
||||||
// Captures the value of GTEST_FLAG(catch_exceptions). This value will be
|
// Captures the value of GTEST_FLAG(catch_exceptions). This value will be
|
||||||
// used for the duration of the program.
|
// used for the duration of the program.
|
||||||
impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions));
|
impl()->set_catch_exceptions(GTEST_FLAG_GET(catch_exceptions));
|
||||||
|
|
||||||
#if GTEST_OS_WINDOWS
|
#if GTEST_OS_WINDOWS
|
||||||
// Either the user wants Google Test to catch exceptions thrown by the
|
// Either the user wants Google Test to catch exceptions thrown by the
|
||||||
@ -5417,7 +5461,7 @@ int UnitTest::Run() {
|
|||||||
// this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement
|
// this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement
|
||||||
// executed. Google Test will notify the user of any unexpected
|
// executed. Google Test will notify the user of any unexpected
|
||||||
// failure via stderr.
|
// failure via stderr.
|
||||||
if (!GTEST_FLAG(break_on_failure))
|
if (!GTEST_FLAG_GET(break_on_failure))
|
||||||
_set_abort_behavior(
|
_set_abort_behavior(
|
||||||
0x0, // Clear the following flags:
|
0x0, // Clear the following flags:
|
||||||
_WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump.
|
_WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump.
|
||||||
@ -5599,7 +5643,7 @@ void UnitTestImpl::ConfigureXmlOutput() {
|
|||||||
// Initializes event listeners for streaming test results in string form.
|
// Initializes event listeners for streaming test results in string form.
|
||||||
// Must not be called before InitGoogleTest.
|
// Must not be called before InitGoogleTest.
|
||||||
void UnitTestImpl::ConfigureStreamingOutput() {
|
void UnitTestImpl::ConfigureStreamingOutput() {
|
||||||
const std::string& target = GTEST_FLAG(stream_result_to);
|
const std::string& target = GTEST_FLAG_GET(stream_result_to);
|
||||||
if (!target.empty()) {
|
if (!target.empty()) {
|
||||||
const size_t pos = target.find(':');
|
const size_t pos = target.find(':');
|
||||||
if (pos != std::string::npos) {
|
if (pos != std::string::npos) {
|
||||||
@ -5642,7 +5686,7 @@ void UnitTestImpl::PostFlagParsingInit() {
|
|||||||
// to shut down the default XML output before invoking RUN_ALL_TESTS.
|
// to shut down the default XML output before invoking RUN_ALL_TESTS.
|
||||||
ConfigureXmlOutput();
|
ConfigureXmlOutput();
|
||||||
|
|
||||||
if (GTEST_FLAG(brief)) {
|
if (GTEST_FLAG_GET(brief)) {
|
||||||
listeners()->SetDefaultResultPrinter(new BriefUnitTestResultPrinter);
|
listeners()->SetDefaultResultPrinter(new BriefUnitTestResultPrinter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5652,7 +5696,7 @@ void UnitTestImpl::PostFlagParsingInit() {
|
|||||||
#endif // GTEST_CAN_STREAM_RESULTS_
|
#endif // GTEST_CAN_STREAM_RESULTS_
|
||||||
|
|
||||||
#if GTEST_HAS_ABSL
|
#if GTEST_HAS_ABSL
|
||||||
if (GTEST_FLAG(install_failure_signal_handler)) {
|
if (GTEST_FLAG_GET(install_failure_signal_handler)) {
|
||||||
absl::FailureSignalHandlerOptions options;
|
absl::FailureSignalHandlerOptions options;
|
||||||
absl::InstallFailureSignalHandler(options);
|
absl::InstallFailureSignalHandler(options);
|
||||||
}
|
}
|
||||||
@ -5785,14 +5829,15 @@ bool UnitTestImpl::RunAllTests() {
|
|||||||
: IGNORE_SHARDING_PROTOCOL) > 0;
|
: IGNORE_SHARDING_PROTOCOL) > 0;
|
||||||
|
|
||||||
// Lists the tests and exits if the --gtest_list_tests flag was specified.
|
// Lists the tests and exits if the --gtest_list_tests flag was specified.
|
||||||
if (GTEST_FLAG(list_tests)) {
|
if (GTEST_FLAG_GET(list_tests)) {
|
||||||
// This must be called *after* FilterTests() has been called.
|
// This must be called *after* FilterTests() has been called.
|
||||||
ListTestsMatchingFilter();
|
ListTestsMatchingFilter();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
random_seed_ = GTEST_FLAG(shuffle) ?
|
random_seed_ = GTEST_FLAG_GET(shuffle)
|
||||||
GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0;
|
? GetRandomSeedFromFlag(GTEST_FLAG_GET(random_seed))
|
||||||
|
: 0;
|
||||||
|
|
||||||
// True if and only if at least one test has failed.
|
// True if and only if at least one test has failed.
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
@ -5804,9 +5849,21 @@ bool UnitTestImpl::RunAllTests() {
|
|||||||
|
|
||||||
// How many times to repeat the tests? We don't want to repeat them
|
// How many times to repeat the tests? We don't want to repeat them
|
||||||
// when we are inside the subprocess of a death test.
|
// when we are inside the subprocess of a death test.
|
||||||
const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat);
|
const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG_GET(repeat);
|
||||||
|
|
||||||
// Repeats forever if the repeat count is negative.
|
// Repeats forever if the repeat count is negative.
|
||||||
const bool gtest_repeat_forever = repeat < 0;
|
const bool gtest_repeat_forever = repeat < 0;
|
||||||
|
|
||||||
|
// Should test environments be set up and torn down for each repeat, or only
|
||||||
|
// set up on the first and torn down on the last iteration? If there is no
|
||||||
|
// "last" iteration because the tests will repeat forever, always recreate the
|
||||||
|
// environments to avoid leaks in case one of the environments is using
|
||||||
|
// resources that are external to this process. Without this check there would
|
||||||
|
// be no way to clean up those external resources automatically.
|
||||||
|
const bool recreate_environments_when_repeating =
|
||||||
|
GTEST_FLAG_GET(recreate_environments_when_repeating) ||
|
||||||
|
gtest_repeat_forever;
|
||||||
|
|
||||||
for (int i = 0; gtest_repeat_forever || i != repeat; i++) {
|
for (int i = 0; gtest_repeat_forever || i != repeat; i++) {
|
||||||
// We want to preserve failures generated by ad-hoc test
|
// We want to preserve failures generated by ad-hoc test
|
||||||
// assertions executed before RUN_ALL_TESTS().
|
// assertions executed before RUN_ALL_TESTS().
|
||||||
@ -5815,7 +5872,7 @@ bool UnitTestImpl::RunAllTests() {
|
|||||||
Timer timer;
|
Timer timer;
|
||||||
|
|
||||||
// Shuffles test suites and tests if requested.
|
// Shuffles test suites and tests if requested.
|
||||||
if (has_tests_to_run && GTEST_FLAG(shuffle)) {
|
if (has_tests_to_run && GTEST_FLAG_GET(shuffle)) {
|
||||||
random()->Reseed(static_cast<uint32_t>(random_seed_));
|
random()->Reseed(static_cast<uint32_t>(random_seed_));
|
||||||
// This should be done before calling OnTestIterationStart(),
|
// This should be done before calling OnTestIterationStart(),
|
||||||
// such that a test event listener can see the actual test order
|
// such that a test event listener can see the actual test order
|
||||||
@ -5828,10 +5885,13 @@ bool UnitTestImpl::RunAllTests() {
|
|||||||
|
|
||||||
// Runs each test suite if there is at least one test to run.
|
// Runs each test suite if there is at least one test to run.
|
||||||
if (has_tests_to_run) {
|
if (has_tests_to_run) {
|
||||||
// Sets up all environments beforehand.
|
// Sets up all environments beforehand. If test environments aren't
|
||||||
repeater->OnEnvironmentsSetUpStart(*parent_);
|
// recreated for each iteration, only do so on the first iteration.
|
||||||
ForEach(environments_, SetUpEnvironment);
|
if (i == 0 || recreate_environments_when_repeating) {
|
||||||
repeater->OnEnvironmentsSetUpEnd(*parent_);
|
repeater->OnEnvironmentsSetUpStart(*parent_);
|
||||||
|
ForEach(environments_, SetUpEnvironment);
|
||||||
|
repeater->OnEnvironmentsSetUpEnd(*parent_);
|
||||||
|
}
|
||||||
|
|
||||||
// Runs the tests only if there was no fatal failure or skip triggered
|
// Runs the tests only if there was no fatal failure or skip triggered
|
||||||
// during global set-up.
|
// during global set-up.
|
||||||
@ -5853,7 +5913,7 @@ bool UnitTestImpl::RunAllTests() {
|
|||||||
for (int test_index = 0; test_index < total_test_suite_count();
|
for (int test_index = 0; test_index < total_test_suite_count();
|
||||||
test_index++) {
|
test_index++) {
|
||||||
GetMutableSuiteCase(test_index)->Run();
|
GetMutableSuiteCase(test_index)->Run();
|
||||||
if (GTEST_FLAG(fail_fast) &&
|
if (GTEST_FLAG_GET(fail_fast) &&
|
||||||
GetMutableSuiteCase(test_index)->Failed()) {
|
GetMutableSuiteCase(test_index)->Failed()) {
|
||||||
for (int j = test_index + 1; j < total_test_suite_count(); j++) {
|
for (int j = test_index + 1; j < total_test_suite_count(); j++) {
|
||||||
GetMutableSuiteCase(j)->Skip();
|
GetMutableSuiteCase(j)->Skip();
|
||||||
@ -5871,11 +5931,15 @@ bool UnitTestImpl::RunAllTests() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tears down all environments in reverse order afterwards.
|
// Tears down all environments in reverse order afterwards. If test
|
||||||
repeater->OnEnvironmentsTearDownStart(*parent_);
|
// environments aren't recreated for each iteration, only do so on the
|
||||||
std::for_each(environments_.rbegin(), environments_.rend(),
|
// last iteration.
|
||||||
TearDownEnvironment);
|
if (i == repeat - 1 || recreate_environments_when_repeating) {
|
||||||
repeater->OnEnvironmentsTearDownEnd(*parent_);
|
repeater->OnEnvironmentsTearDownStart(*parent_);
|
||||||
|
std::for_each(environments_.rbegin(), environments_.rend(),
|
||||||
|
TearDownEnvironment);
|
||||||
|
repeater->OnEnvironmentsTearDownEnd(*parent_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
elapsed_time_ = timer.Elapsed();
|
elapsed_time_ = timer.Elapsed();
|
||||||
@ -5896,7 +5960,7 @@ bool UnitTestImpl::RunAllTests() {
|
|||||||
// (it's always safe to unshuffle the tests).
|
// (it's always safe to unshuffle the tests).
|
||||||
UnshuffleTests();
|
UnshuffleTests();
|
||||||
|
|
||||||
if (GTEST_FLAG(shuffle)) {
|
if (GTEST_FLAG_GET(shuffle)) {
|
||||||
// Picks a new random seed for each iteration.
|
// Picks a new random seed for each iteration.
|
||||||
random_seed_ = GetNextRandomSeed(random_seed_);
|
random_seed_ = GetNextRandomSeed(random_seed_);
|
||||||
}
|
}
|
||||||
@ -6053,7 +6117,7 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
|
|||||||
test_info->matches_filter_ = matches_filter;
|
test_info->matches_filter_ = matches_filter;
|
||||||
|
|
||||||
const bool is_runnable =
|
const bool is_runnable =
|
||||||
(GTEST_FLAG(also_run_disabled_tests) || !is_disabled) &&
|
(GTEST_FLAG_GET(also_run_disabled_tests) || !is_disabled) &&
|
||||||
matches_filter;
|
matches_filter;
|
||||||
|
|
||||||
const bool is_in_another_shard =
|
const bool is_in_another_shard =
|
||||||
@ -6264,13 +6328,14 @@ bool SkipPrefix(const char* prefix, const char** pstr) {
|
|||||||
// part can be omitted.
|
// part can be omitted.
|
||||||
//
|
//
|
||||||
// Returns the value of the flag, or NULL if the parsing failed.
|
// Returns the value of the flag, or NULL if the parsing failed.
|
||||||
static const char* ParseFlagValue(const char* str, const char* flag,
|
static const char* ParseFlagValue(const char* str, const char* flag_name,
|
||||||
bool def_optional) {
|
bool def_optional) {
|
||||||
// str and flag must not be NULL.
|
// str and flag must not be NULL.
|
||||||
if (str == nullptr || flag == nullptr) return nullptr;
|
if (str == nullptr || flag_name == nullptr) return nullptr;
|
||||||
|
|
||||||
// The flag must start with "--" followed by GTEST_FLAG_PREFIX_.
|
// The flag must start with "--" followed by GTEST_FLAG_PREFIX_.
|
||||||
const std::string flag_str = std::string("--") + GTEST_FLAG_PREFIX_ + flag;
|
const std::string flag_str =
|
||||||
|
std::string("--") + GTEST_FLAG_PREFIX_ + flag_name;
|
||||||
const size_t flag_len = flag_str.length();
|
const size_t flag_len = flag_str.length();
|
||||||
if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr;
|
if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr;
|
||||||
|
|
||||||
@ -6301,9 +6366,9 @@ static const char* ParseFlagValue(const char* str, const char* flag,
|
|||||||
//
|
//
|
||||||
// On success, stores the value of the flag in *value, and returns
|
// On success, stores the value of the flag in *value, and returns
|
||||||
// true. On failure, returns false without changing *value.
|
// true. On failure, returns false without changing *value.
|
||||||
static bool ParseBoolFlag(const char* str, const char* flag, bool* value) {
|
static bool ParseFlag(const char* str, const char* flag_name, bool* value) {
|
||||||
// Gets the value of the flag as a string.
|
// Gets the value of the flag as a string.
|
||||||
const char* const value_str = ParseFlagValue(str, flag, true);
|
const char* const value_str = ParseFlagValue(str, flag_name, true);
|
||||||
|
|
||||||
// Aborts if the parsing failed.
|
// Aborts if the parsing failed.
|
||||||
if (value_str == nullptr) return false;
|
if (value_str == nullptr) return false;
|
||||||
@ -6317,16 +6382,16 @@ static bool ParseBoolFlag(const char* str, const char* flag, bool* value) {
|
|||||||
//
|
//
|
||||||
// On success, stores the value of the flag in *value, and returns
|
// On success, stores the value of the flag in *value, and returns
|
||||||
// true. On failure, returns false without changing *value.
|
// true. On failure, returns false without changing *value.
|
||||||
bool ParseInt32Flag(const char* str, const char* flag, int32_t* value) {
|
bool ParseFlag(const char* str, const char* flag_name, int32_t* value) {
|
||||||
// Gets the value of the flag as a string.
|
// Gets the value of the flag as a string.
|
||||||
const char* const value_str = ParseFlagValue(str, flag, false);
|
const char* const value_str = ParseFlagValue(str, flag_name, false);
|
||||||
|
|
||||||
// Aborts if the parsing failed.
|
// Aborts if the parsing failed.
|
||||||
if (value_str == nullptr) return false;
|
if (value_str == nullptr) return false;
|
||||||
|
|
||||||
// Sets *value to the value of the flag.
|
// Sets *value to the value of the flag.
|
||||||
return ParseInt32(Message() << "The value of flag --" << flag,
|
return ParseInt32(Message() << "The value of flag --" << flag_name, value_str,
|
||||||
value_str, value);
|
value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parses a string for a string flag, in the form of "--flag=value".
|
// Parses a string for a string flag, in the form of "--flag=value".
|
||||||
@ -6334,9 +6399,9 @@ bool ParseInt32Flag(const char* str, const char* flag, int32_t* value) {
|
|||||||
// On success, stores the value of the flag in *value, and returns
|
// On success, stores the value of the flag in *value, and returns
|
||||||
// true. On failure, returns false without changing *value.
|
// true. On failure, returns false without changing *value.
|
||||||
template <typename String>
|
template <typename String>
|
||||||
static bool ParseStringFlag(const char* str, const char* flag, String* value) {
|
static bool ParseFlag(const char* str, const char* flag_name, String* value) {
|
||||||
// Gets the value of the flag as a string.
|
// Gets the value of the flag as a string.
|
||||||
const char* const value_str = ParseFlagValue(str, flag, false);
|
const char* const value_str = ParseFlagValue(str, flag_name, false);
|
||||||
|
|
||||||
// Aborts if the parsing failed.
|
// Aborts if the parsing failed.
|
||||||
if (value_str == nullptr) return false;
|
if (value_str == nullptr) return false;
|
||||||
@ -6437,6 +6502,10 @@ static const char kColorEncodedHelpMessage[] =
|
|||||||
"random_seed=@Y[NUMBER]@D\n"
|
"random_seed=@Y[NUMBER]@D\n"
|
||||||
" Random number seed to use for shuffling test orders (between 1 and\n"
|
" Random number seed to use for shuffling test orders (between 1 and\n"
|
||||||
" 99999, or 0 to use a seed based on the current time).\n"
|
" 99999, or 0 to use a seed based on the current time).\n"
|
||||||
|
" @G--" GTEST_FLAG_PREFIX_
|
||||||
|
"recreate_environments_when_repeating@D\n"
|
||||||
|
" Sets up and tears down the global test environment on each repeat\n"
|
||||||
|
" of the test.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Test Output:\n"
|
"Test Output:\n"
|
||||||
" @G--" GTEST_FLAG_PREFIX_
|
" @G--" GTEST_FLAG_PREFIX_
|
||||||
@ -6497,41 +6566,44 @@ static const char kColorEncodedHelpMessage[] =
|
|||||||
"@G<" GTEST_DEV_EMAIL_ ">@D.\n";
|
"@G<" GTEST_DEV_EMAIL_ ">@D.\n";
|
||||||
|
|
||||||
static bool ParseGoogleTestFlag(const char* const arg) {
|
static bool ParseGoogleTestFlag(const char* const arg) {
|
||||||
return ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag,
|
#define GTEST_INTERNAL_PARSE_FLAG(flag_name) \
|
||||||
>EST_FLAG(also_run_disabled_tests)) ||
|
do { \
|
||||||
ParseBoolFlag(arg, kBreakOnFailureFlag,
|
auto value = GTEST_FLAG_GET(flag_name); \
|
||||||
>EST_FLAG(break_on_failure)) ||
|
if (ParseFlag(arg, #flag_name, &value)) { \
|
||||||
ParseBoolFlag(arg, kCatchExceptionsFlag,
|
GTEST_FLAG_SET(flag_name, value); \
|
||||||
>EST_FLAG(catch_exceptions)) ||
|
return true; \
|
||||||
ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) ||
|
} \
|
||||||
ParseStringFlag(arg, kDeathTestStyleFlag,
|
} while (false)
|
||||||
>EST_FLAG(death_test_style)) ||
|
|
||||||
ParseBoolFlag(arg, kDeathTestUseFork,
|
GTEST_INTERNAL_PARSE_FLAG(also_run_disabled_tests);
|
||||||
>EST_FLAG(death_test_use_fork)) ||
|
GTEST_INTERNAL_PARSE_FLAG(break_on_failure);
|
||||||
ParseBoolFlag(arg, kFailFast, >EST_FLAG(fail_fast)) ||
|
GTEST_INTERNAL_PARSE_FLAG(catch_exceptions);
|
||||||
ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) ||
|
GTEST_INTERNAL_PARSE_FLAG(color);
|
||||||
ParseStringFlag(arg, kInternalRunDeathTestFlag,
|
GTEST_INTERNAL_PARSE_FLAG(death_test_style);
|
||||||
>EST_FLAG(internal_run_death_test)) ||
|
GTEST_INTERNAL_PARSE_FLAG(death_test_use_fork);
|
||||||
ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) ||
|
GTEST_INTERNAL_PARSE_FLAG(fail_fast);
|
||||||
ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) ||
|
GTEST_INTERNAL_PARSE_FLAG(filter);
|
||||||
ParseBoolFlag(arg, kBriefFlag, >EST_FLAG(brief)) ||
|
GTEST_INTERNAL_PARSE_FLAG(internal_run_death_test);
|
||||||
ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) ||
|
GTEST_INTERNAL_PARSE_FLAG(list_tests);
|
||||||
ParseBoolFlag(arg, kPrintUTF8Flag, >EST_FLAG(print_utf8)) ||
|
GTEST_INTERNAL_PARSE_FLAG(output);
|
||||||
ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) ||
|
GTEST_INTERNAL_PARSE_FLAG(brief);
|
||||||
ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) ||
|
GTEST_INTERNAL_PARSE_FLAG(print_time);
|
||||||
ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) ||
|
GTEST_INTERNAL_PARSE_FLAG(print_utf8);
|
||||||
ParseInt32Flag(arg, kStackTraceDepthFlag,
|
GTEST_INTERNAL_PARSE_FLAG(random_seed);
|
||||||
>EST_FLAG(stack_trace_depth)) ||
|
GTEST_INTERNAL_PARSE_FLAG(repeat);
|
||||||
ParseStringFlag(arg, kStreamResultToFlag,
|
GTEST_INTERNAL_PARSE_FLAG(recreate_environments_when_repeating);
|
||||||
>EST_FLAG(stream_result_to)) ||
|
GTEST_INTERNAL_PARSE_FLAG(shuffle);
|
||||||
ParseBoolFlag(arg, kThrowOnFailureFlag, >EST_FLAG(throw_on_failure));
|
GTEST_INTERNAL_PARSE_FLAG(stack_trace_depth);
|
||||||
|
GTEST_INTERNAL_PARSE_FLAG(stream_result_to);
|
||||||
|
GTEST_INTERNAL_PARSE_FLAG(throw_on_failure);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GTEST_USE_OWN_FLAGFILE_FLAG_
|
#if GTEST_USE_OWN_FLAGFILE_FLAG_
|
||||||
static void LoadFlagsFromFile(const std::string& path) {
|
static void LoadFlagsFromFile(const std::string& path) {
|
||||||
FILE* flagfile = posix::FOpen(path.c_str(), "r");
|
FILE* flagfile = posix::FOpen(path.c_str(), "r");
|
||||||
if (!flagfile) {
|
if (!flagfile) {
|
||||||
GTEST_LOG_(FATAL) << "Unable to open file \"" << GTEST_FLAG(flagfile)
|
GTEST_LOG_(FATAL) << "Unable to open file \"" << GTEST_FLAG_GET(flagfile)
|
||||||
<< "\"";
|
<< "\"";
|
||||||
}
|
}
|
||||||
std::string contents(ReadEntireFile(flagfile));
|
std::string contents(ReadEntireFile(flagfile));
|
||||||
@ -6552,20 +6624,20 @@ static void LoadFlagsFromFile(const std::string& path) {
|
|||||||
// instantiated to either char or wchar_t.
|
// instantiated to either char or wchar_t.
|
||||||
template <typename CharType>
|
template <typename CharType>
|
||||||
void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
|
void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
|
||||||
|
std::string flagfile_value;
|
||||||
for (int i = 1; i < *argc; i++) {
|
for (int i = 1; i < *argc; i++) {
|
||||||
const std::string arg_string = StreamableToString(argv[i]);
|
const std::string arg_string = StreamableToString(argv[i]);
|
||||||
const char* const arg = arg_string.c_str();
|
const char* const arg = arg_string.c_str();
|
||||||
|
|
||||||
using internal::ParseBoolFlag;
|
using internal::ParseFlag;
|
||||||
using internal::ParseInt32Flag;
|
|
||||||
using internal::ParseStringFlag;
|
|
||||||
|
|
||||||
bool remove_flag = false;
|
bool remove_flag = false;
|
||||||
if (ParseGoogleTestFlag(arg)) {
|
if (ParseGoogleTestFlag(arg)) {
|
||||||
remove_flag = true;
|
remove_flag = true;
|
||||||
#if GTEST_USE_OWN_FLAGFILE_FLAG_
|
#if GTEST_USE_OWN_FLAGFILE_FLAG_
|
||||||
} else if (ParseStringFlag(arg, kFlagfileFlag, >EST_FLAG(flagfile))) {
|
} else if (ParseFlag(arg, "flagfile", &flagfile_value)) {
|
||||||
LoadFlagsFromFile(GTEST_FLAG(flagfile));
|
GTEST_FLAG_SET(flagfile, flagfile_value);
|
||||||
|
LoadFlagsFromFile(flagfile_value);
|
||||||
remove_flag = true;
|
remove_flag = true;
|
||||||
#endif // GTEST_USE_OWN_FLAGFILE_FLAG_
|
#endif // GTEST_USE_OWN_FLAGFILE_FLAG_
|
||||||
} else if (arg_string == "--help" || arg_string == "-h" ||
|
} else if (arg_string == "--help" || arg_string == "-h" ||
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
#
|
#
|
||||||
# Bazel BUILD for The Google C++ Testing Framework (Google Test)
|
# Bazel BUILD for The Google C++ Testing Framework (Google Test)
|
||||||
|
|
||||||
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test")
|
|
||||||
load("@rules_python//python:defs.bzl", "py_library", "py_test")
|
load("@rules_python//python:defs.bzl", "py_library", "py_test")
|
||||||
|
|
||||||
licenses(["notice"])
|
licenses(["notice"])
|
||||||
@ -95,6 +94,7 @@ cc_test(
|
|||||||
"googletest/test",
|
"googletest/test",
|
||||||
],
|
],
|
||||||
linkopts = select({
|
linkopts = select({
|
||||||
|
"//:qnx": [],
|
||||||
"//:windows": [],
|
"//:windows": [],
|
||||||
"//conditions:default": ["-pthread"],
|
"//conditions:default": ["-pthread"],
|
||||||
}),
|
}),
|
||||||
|
@ -147,19 +147,19 @@ class CatchCxxExceptionsTest(gtest_test_utils.TestCase):
|
|||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
'CxxExceptionInConstructorTest::TearDownTestSuite() '
|
'CxxExceptionInConstructorTest::TearDownTestSuite() '
|
||||||
'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT)
|
'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT)
|
||||||
self.assertTrue(
|
self.assertFalse(
|
||||||
'CxxExceptionInSetUpTestSuiteTest constructor '
|
'CxxExceptionInSetUpTestSuiteTest constructor '
|
||||||
'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT)
|
'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT)
|
||||||
self.assertTrue(
|
self.assertFalse(
|
||||||
'CxxExceptionInSetUpTestSuiteTest destructor '
|
'CxxExceptionInSetUpTestSuiteTest destructor '
|
||||||
'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT)
|
'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT)
|
||||||
self.assertTrue(
|
self.assertFalse(
|
||||||
'CxxExceptionInSetUpTestSuiteTest::SetUp() '
|
'CxxExceptionInSetUpTestSuiteTest::SetUp() '
|
||||||
'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT)
|
'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT)
|
||||||
self.assertTrue(
|
self.assertFalse(
|
||||||
'CxxExceptionInSetUpTestSuiteTest::TearDown() '
|
'CxxExceptionInSetUpTestSuiteTest::TearDown() '
|
||||||
'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT)
|
'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT)
|
||||||
self.assertTrue(
|
self.assertFalse(
|
||||||
'CxxExceptionInSetUpTestSuiteTest test body '
|
'CxxExceptionInSetUpTestSuiteTest test body '
|
||||||
'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT)
|
'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT)
|
||||||
|
|
||||||
|
@ -370,14 +370,14 @@ TEST_F(TestForDeathTest, SwitchStatement) {
|
|||||||
// Tests that a static member function can be used in a "fast" style
|
// Tests that a static member function can be used in a "fast" style
|
||||||
// death test.
|
// death test.
|
||||||
TEST_F(TestForDeathTest, StaticMemberFunctionFastStyle) {
|
TEST_F(TestForDeathTest, StaticMemberFunctionFastStyle) {
|
||||||
testing::GTEST_FLAG(death_test_style) = "fast";
|
GTEST_FLAG_SET(death_test_style, "fast");
|
||||||
ASSERT_DEATH(StaticMemberFunction(), "death.*StaticMember");
|
ASSERT_DEATH(StaticMemberFunction(), "death.*StaticMember");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that a method of the test fixture can be used in a "fast"
|
// Tests that a method of the test fixture can be used in a "fast"
|
||||||
// style death test.
|
// style death test.
|
||||||
TEST_F(TestForDeathTest, MemberFunctionFastStyle) {
|
TEST_F(TestForDeathTest, MemberFunctionFastStyle) {
|
||||||
testing::GTEST_FLAG(death_test_style) = "fast";
|
GTEST_FLAG_SET(death_test_style, "fast");
|
||||||
should_die_ = true;
|
should_die_ = true;
|
||||||
EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction");
|
EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction");
|
||||||
}
|
}
|
||||||
@ -387,7 +387,7 @@ void ChangeToRootDir() { posix::ChDir(GTEST_PATH_SEP_); }
|
|||||||
// Tests that death tests work even if the current directory has been
|
// Tests that death tests work even if the current directory has been
|
||||||
// changed.
|
// changed.
|
||||||
TEST_F(TestForDeathTest, FastDeathTestInChangedDir) {
|
TEST_F(TestForDeathTest, FastDeathTestInChangedDir) {
|
||||||
testing::GTEST_FLAG(death_test_style) = "fast";
|
GTEST_FLAG_SET(death_test_style, "fast");
|
||||||
|
|
||||||
ChangeToRootDir();
|
ChangeToRootDir();
|
||||||
EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), "");
|
EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), "");
|
||||||
@ -432,7 +432,7 @@ void DisableSigprofActionAndTimer(struct sigaction* old_signal_action) {
|
|||||||
|
|
||||||
// Tests that death tests work when SIGPROF handler and timer are set.
|
// Tests that death tests work when SIGPROF handler and timer are set.
|
||||||
TEST_F(TestForDeathTest, FastSigprofActionSet) {
|
TEST_F(TestForDeathTest, FastSigprofActionSet) {
|
||||||
testing::GTEST_FLAG(death_test_style) = "fast";
|
GTEST_FLAG_SET(death_test_style, "fast");
|
||||||
SetSigprofActionAndTimer();
|
SetSigprofActionAndTimer();
|
||||||
EXPECT_DEATH(_exit(1), "");
|
EXPECT_DEATH(_exit(1), "");
|
||||||
struct sigaction old_signal_action;
|
struct sigaction old_signal_action;
|
||||||
@ -441,7 +441,7 @@ TEST_F(TestForDeathTest, FastSigprofActionSet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestForDeathTest, ThreadSafeSigprofActionSet) {
|
TEST_F(TestForDeathTest, ThreadSafeSigprofActionSet) {
|
||||||
testing::GTEST_FLAG(death_test_style) = "threadsafe";
|
GTEST_FLAG_SET(death_test_style, "threadsafe");
|
||||||
SetSigprofActionAndTimer();
|
SetSigprofActionAndTimer();
|
||||||
EXPECT_DEATH(_exit(1), "");
|
EXPECT_DEATH(_exit(1), "");
|
||||||
struct sigaction old_signal_action;
|
struct sigaction old_signal_action;
|
||||||
@ -453,25 +453,25 @@ TEST_F(TestForDeathTest, ThreadSafeSigprofActionSet) {
|
|||||||
// Repeats a representative sample of death tests in the "threadsafe" style:
|
// Repeats a representative sample of death tests in the "threadsafe" style:
|
||||||
|
|
||||||
TEST_F(TestForDeathTest, StaticMemberFunctionThreadsafeStyle) {
|
TEST_F(TestForDeathTest, StaticMemberFunctionThreadsafeStyle) {
|
||||||
testing::GTEST_FLAG(death_test_style) = "threadsafe";
|
GTEST_FLAG_SET(death_test_style, "threadsafe");
|
||||||
ASSERT_DEATH(StaticMemberFunction(), "death.*StaticMember");
|
ASSERT_DEATH(StaticMemberFunction(), "death.*StaticMember");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestForDeathTest, MemberFunctionThreadsafeStyle) {
|
TEST_F(TestForDeathTest, MemberFunctionThreadsafeStyle) {
|
||||||
testing::GTEST_FLAG(death_test_style) = "threadsafe";
|
GTEST_FLAG_SET(death_test_style, "threadsafe");
|
||||||
should_die_ = true;
|
should_die_ = true;
|
||||||
EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction");
|
EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestForDeathTest, ThreadsafeDeathTestInLoop) {
|
TEST_F(TestForDeathTest, ThreadsafeDeathTestInLoop) {
|
||||||
testing::GTEST_FLAG(death_test_style) = "threadsafe";
|
GTEST_FLAG_SET(death_test_style, "threadsafe");
|
||||||
|
|
||||||
for (int i = 0; i < 3; ++i)
|
for (int i = 0; i < 3; ++i)
|
||||||
EXPECT_EXIT(_exit(i), testing::ExitedWithCode(i), "") << ": i = " << i;
|
EXPECT_EXIT(_exit(i), testing::ExitedWithCode(i), "") << ": i = " << i;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestForDeathTest, ThreadsafeDeathTestInChangedDir) {
|
TEST_F(TestForDeathTest, ThreadsafeDeathTestInChangedDir) {
|
||||||
testing::GTEST_FLAG(death_test_style) = "threadsafe";
|
GTEST_FLAG_SET(death_test_style, "threadsafe");
|
||||||
|
|
||||||
ChangeToRootDir();
|
ChangeToRootDir();
|
||||||
EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), "");
|
EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), "");
|
||||||
@ -481,9 +481,9 @@ TEST_F(TestForDeathTest, ThreadsafeDeathTestInChangedDir) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestForDeathTest, MixedStyles) {
|
TEST_F(TestForDeathTest, MixedStyles) {
|
||||||
testing::GTEST_FLAG(death_test_style) = "threadsafe";
|
GTEST_FLAG_SET(death_test_style, "threadsafe");
|
||||||
EXPECT_DEATH(_exit(1), "");
|
EXPECT_DEATH(_exit(1), "");
|
||||||
testing::GTEST_FLAG(death_test_style) = "fast";
|
GTEST_FLAG_SET(death_test_style, "fast");
|
||||||
EXPECT_DEATH(_exit(1), "");
|
EXPECT_DEATH(_exit(1), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -496,8 +496,8 @@ void SetPthreadFlag() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) {
|
TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) {
|
||||||
if (!testing::GTEST_FLAG(death_test_use_fork)) {
|
if (!GTEST_FLAG_GET(death_test_use_fork)) {
|
||||||
testing::GTEST_FLAG(death_test_style) = "threadsafe";
|
GTEST_FLAG_SET(death_test_style, "threadsafe");
|
||||||
pthread_flag = false;
|
pthread_flag = false;
|
||||||
ASSERT_EQ(0, pthread_atfork(&SetPthreadFlag, nullptr, nullptr));
|
ASSERT_EQ(0, pthread_atfork(&SetPthreadFlag, nullptr, nullptr));
|
||||||
ASSERT_DEATH(_exit(1), "");
|
ASSERT_DEATH(_exit(1), "");
|
||||||
@ -740,10 +740,12 @@ TEST(PopUpDeathTest, DoesNotShowPopUpOnAbort) {
|
|||||||
"any pop-up dialogs.\n");
|
"any pop-up dialogs.\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
EXPECT_DEATH({
|
EXPECT_DEATH(
|
||||||
testing::GTEST_FLAG(catch_exceptions) = false;
|
{
|
||||||
abort();
|
GTEST_FLAG_SET(catch_exceptions, false);
|
||||||
}, "");
|
abort();
|
||||||
|
},
|
||||||
|
"");
|
||||||
}
|
}
|
||||||
# endif // GTEST_OS_WINDOWS
|
# endif // GTEST_OS_WINDOWS
|
||||||
|
|
||||||
@ -874,19 +876,19 @@ TEST_F(TestForDeathTest, ExitMacros) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestForDeathTest, ExitMacrosUsingFork) {
|
TEST_F(TestForDeathTest, ExitMacrosUsingFork) {
|
||||||
testing::GTEST_FLAG(death_test_use_fork) = true;
|
GTEST_FLAG_SET(death_test_use_fork, true);
|
||||||
TestExitMacros();
|
TestExitMacros();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestForDeathTest, InvalidStyle) {
|
TEST_F(TestForDeathTest, InvalidStyle) {
|
||||||
testing::GTEST_FLAG(death_test_style) = "rococo";
|
GTEST_FLAG_SET(death_test_style, "rococo");
|
||||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||||
EXPECT_DEATH(_exit(0), "") << "This failure is expected.";
|
EXPECT_DEATH(_exit(0), "") << "This failure is expected.";
|
||||||
}, "This failure is expected.");
|
}, "This failure is expected.");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestForDeathTest, DeathTestFailedOutput) {
|
TEST_F(TestForDeathTest, DeathTestFailedOutput) {
|
||||||
testing::GTEST_FLAG(death_test_style) = "fast";
|
GTEST_FLAG_SET(death_test_style, "fast");
|
||||||
EXPECT_NONFATAL_FAILURE(
|
EXPECT_NONFATAL_FAILURE(
|
||||||
EXPECT_DEATH(DieWithMessage("death\n"),
|
EXPECT_DEATH(DieWithMessage("death\n"),
|
||||||
"expected message"),
|
"expected message"),
|
||||||
@ -895,7 +897,7 @@ TEST_F(TestForDeathTest, DeathTestFailedOutput) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestForDeathTest, DeathTestUnexpectedReturnOutput) {
|
TEST_F(TestForDeathTest, DeathTestUnexpectedReturnOutput) {
|
||||||
testing::GTEST_FLAG(death_test_style) = "fast";
|
GTEST_FLAG_SET(death_test_style, "fast");
|
||||||
EXPECT_NONFATAL_FAILURE(
|
EXPECT_NONFATAL_FAILURE(
|
||||||
EXPECT_DEATH({
|
EXPECT_DEATH({
|
||||||
fprintf(stderr, "returning\n");
|
fprintf(stderr, "returning\n");
|
||||||
@ -908,7 +910,7 @@ TEST_F(TestForDeathTest, DeathTestUnexpectedReturnOutput) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestForDeathTest, DeathTestBadExitCodeOutput) {
|
TEST_F(TestForDeathTest, DeathTestBadExitCodeOutput) {
|
||||||
testing::GTEST_FLAG(death_test_style) = "fast";
|
GTEST_FLAG_SET(death_test_style, "fast");
|
||||||
EXPECT_NONFATAL_FAILURE(
|
EXPECT_NONFATAL_FAILURE(
|
||||||
EXPECT_EXIT(DieWithMessage("exiting with rc 1\n"),
|
EXPECT_EXIT(DieWithMessage("exiting with rc 1\n"),
|
||||||
testing::ExitedWithCode(3),
|
testing::ExitedWithCode(3),
|
||||||
@ -920,7 +922,7 @@ TEST_F(TestForDeathTest, DeathTestBadExitCodeOutput) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestForDeathTest, DeathTestMultiLineMatchFail) {
|
TEST_F(TestForDeathTest, DeathTestMultiLineMatchFail) {
|
||||||
testing::GTEST_FLAG(death_test_style) = "fast";
|
GTEST_FLAG_SET(death_test_style, "fast");
|
||||||
EXPECT_NONFATAL_FAILURE(
|
EXPECT_NONFATAL_FAILURE(
|
||||||
EXPECT_DEATH(DieWithMessage("line 1\nline 2\nline 3\n"),
|
EXPECT_DEATH(DieWithMessage("line 1\nline 2\nline 3\n"),
|
||||||
"line 1\nxyz\nline 3\n"),
|
"line 1\nxyz\nline 3\n"),
|
||||||
@ -931,7 +933,7 @@ TEST_F(TestForDeathTest, DeathTestMultiLineMatchFail) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestForDeathTest, DeathTestMultiLineMatchPass) {
|
TEST_F(TestForDeathTest, DeathTestMultiLineMatchPass) {
|
||||||
testing::GTEST_FLAG(death_test_style) = "fast";
|
GTEST_FLAG_SET(death_test_style, "fast");
|
||||||
EXPECT_DEATH(DieWithMessage("line 1\nline 2\nline 3\n"),
|
EXPECT_DEATH(DieWithMessage("line 1\nline 2\nline 3\n"),
|
||||||
"line 1\nline 2\nline 3\n");
|
"line 1\nline 2\nline 3\n");
|
||||||
}
|
}
|
||||||
@ -1358,7 +1360,7 @@ TEST(ConditionalDeathMacrosDeathTest, ExpectsDeathWhenDeathTestsAvailable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInFastStyle) {
|
TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInFastStyle) {
|
||||||
testing::GTEST_FLAG(death_test_style) = "fast";
|
GTEST_FLAG_SET(death_test_style, "fast");
|
||||||
EXPECT_FALSE(InDeathTestChild());
|
EXPECT_FALSE(InDeathTestChild());
|
||||||
EXPECT_DEATH({
|
EXPECT_DEATH({
|
||||||
fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside");
|
fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside");
|
||||||
@ -1368,7 +1370,7 @@ TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInFastStyle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInThreadSafeStyle) {
|
TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInThreadSafeStyle) {
|
||||||
testing::GTEST_FLAG(death_test_style) = "threadsafe";
|
GTEST_FLAG_SET(death_test_style, "threadsafe");
|
||||||
EXPECT_FALSE(InDeathTestChild());
|
EXPECT_FALSE(InDeathTestChild());
|
||||||
EXPECT_DEATH({
|
EXPECT_DEATH({
|
||||||
fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside");
|
fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside");
|
||||||
|
@ -53,7 +53,7 @@ TEST(CxxExceptionDeathTest, ExceptionIsFailure) {
|
|||||||
} catch (...) { // NOLINT
|
} catch (...) { // NOLINT
|
||||||
FAIL() << "An exception escaped a death test macro invocation "
|
FAIL() << "An exception escaped a death test macro invocation "
|
||||||
<< "with catch_exceptions "
|
<< "with catch_exceptions "
|
||||||
<< (testing::GTEST_FLAG(catch_exceptions) ? "enabled" : "disabled");
|
<< (GTEST_FLAG_GET(catch_exceptions) ? "enabled" : "disabled");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ TEST(CxxExceptionDeathTest, PrintsMessageForStdExceptions) {
|
|||||||
TEST(SehExceptionDeasTest, CatchExceptionsDoesNotInterfere) {
|
TEST(SehExceptionDeasTest, CatchExceptionsDoesNotInterfere) {
|
||||||
EXPECT_DEATH(RaiseException(42, 0x0, 0, NULL), "")
|
EXPECT_DEATH(RaiseException(42, 0x0, 0, NULL), "")
|
||||||
<< "with catch_exceptions "
|
<< "with catch_exceptions "
|
||||||
<< (testing::GTEST_FLAG(catch_exceptions) ? "enabled" : "disabled");
|
<< (GTEST_FLAG_GET(catch_exceptions) ? "enabled" : "disabled");
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
@ -87,6 +87,6 @@ TEST(SehExceptionDeasTest, CatchExceptionsDoesNotInterfere) {
|
|||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
testing::InitGoogleTest(&argc, argv);
|
testing::InitGoogleTest(&argc, argv);
|
||||||
testing::GTEST_FLAG(catch_exceptions) = GTEST_ENABLE_CATCH_EXCEPTIONS_ != 0;
|
GTEST_FLAG_SET(catch_exceptions, GTEST_ENABLE_CATCH_EXCEPTIONS_ != 0);
|
||||||
return RUN_ALL_TESTS();
|
return RUN_ALL_TESTS();
|
||||||
}
|
}
|
||||||
|
@ -48,67 +48,67 @@ TEST(GTestEnvVarTest, Dummy) {
|
|||||||
|
|
||||||
void PrintFlag(const char* flag) {
|
void PrintFlag(const char* flag) {
|
||||||
if (strcmp(flag, "break_on_failure") == 0) {
|
if (strcmp(flag, "break_on_failure") == 0) {
|
||||||
cout << GTEST_FLAG(break_on_failure);
|
cout << GTEST_FLAG_GET(break_on_failure);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(flag, "catch_exceptions") == 0) {
|
if (strcmp(flag, "catch_exceptions") == 0) {
|
||||||
cout << GTEST_FLAG(catch_exceptions);
|
cout << GTEST_FLAG_GET(catch_exceptions);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(flag, "color") == 0) {
|
if (strcmp(flag, "color") == 0) {
|
||||||
cout << GTEST_FLAG(color);
|
cout << GTEST_FLAG_GET(color);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(flag, "death_test_style") == 0) {
|
if (strcmp(flag, "death_test_style") == 0) {
|
||||||
cout << GTEST_FLAG(death_test_style);
|
cout << GTEST_FLAG_GET(death_test_style);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(flag, "death_test_use_fork") == 0) {
|
if (strcmp(flag, "death_test_use_fork") == 0) {
|
||||||
cout << GTEST_FLAG(death_test_use_fork);
|
cout << GTEST_FLAG_GET(death_test_use_fork);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(flag, "fail_fast") == 0) {
|
if (strcmp(flag, "fail_fast") == 0) {
|
||||||
cout << GTEST_FLAG(fail_fast);
|
cout << GTEST_FLAG_GET(fail_fast);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(flag, "filter") == 0) {
|
if (strcmp(flag, "filter") == 0) {
|
||||||
cout << GTEST_FLAG(filter);
|
cout << GTEST_FLAG_GET(filter);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(flag, "output") == 0) {
|
if (strcmp(flag, "output") == 0) {
|
||||||
cout << GTEST_FLAG(output);
|
cout << GTEST_FLAG_GET(output);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(flag, "brief") == 0) {
|
if (strcmp(flag, "brief") == 0) {
|
||||||
cout << GTEST_FLAG(brief);
|
cout << GTEST_FLAG_GET(brief);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(flag, "print_time") == 0) {
|
if (strcmp(flag, "print_time") == 0) {
|
||||||
cout << GTEST_FLAG(print_time);
|
cout << GTEST_FLAG_GET(print_time);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(flag, "repeat") == 0) {
|
if (strcmp(flag, "repeat") == 0) {
|
||||||
cout << GTEST_FLAG(repeat);
|
cout << GTEST_FLAG_GET(repeat);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(flag, "stack_trace_depth") == 0) {
|
if (strcmp(flag, "stack_trace_depth") == 0) {
|
||||||
cout << GTEST_FLAG(stack_trace_depth);
|
cout << GTEST_FLAG_GET(stack_trace_depth);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(flag, "throw_on_failure") == 0) {
|
if (strcmp(flag, "throw_on_failure") == 0) {
|
||||||
cout << GTEST_FLAG(throw_on_failure);
|
cout << GTEST_FLAG_GET(throw_on_failure);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user