Compare commits
No commits in common. "main" and "release-1.11.0" have entirely different histories.
main
...
release-1.
21
BUILD.bazel
21
BUILD.bazel
@ -30,32 +30,19 @@
|
||||
#
|
||||
# Bazel Build for Google C++ Testing Framework(Google Test)
|
||||
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
exports_files(["LICENSE"])
|
||||
|
||||
config_setting(
|
||||
name = "qnx",
|
||||
constraint_values = ["@platforms//os:qnx"],
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name = "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(
|
||||
name = "msvc_compiler",
|
||||
flag_values = {
|
||||
@ -99,7 +86,6 @@ cc_library(
|
||||
"googlemock/include/gmock/*.h",
|
||||
]),
|
||||
copts = select({
|
||||
":qnx": [],
|
||||
":windows": [],
|
||||
"//conditions:default": ["-pthread"],
|
||||
}),
|
||||
@ -118,10 +104,7 @@ cc_library(
|
||||
"googletest/include",
|
||||
],
|
||||
linkopts = select({
|
||||
":qnx": ["-lregex"],
|
||||
":windows": [],
|
||||
":freebsd": ["-lm", "-pthread"],
|
||||
":openbsd": ["-lm", "-pthread"],
|
||||
"//conditions:default": ["-pthread"],
|
||||
}),
|
||||
deps = select({
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Note: CMake support is community-based. The maintainers do not use CMake
|
||||
# internally.
|
||||
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
if (POLICY CMP0048)
|
||||
cmake_policy(SET CMP0048 NEW)
|
||||
@ -10,8 +10,10 @@ endif (POLICY CMP0048)
|
||||
project(googletest-distribution)
|
||||
set(GOOGLETEST_VERSION 1.11.0)
|
||||
|
||||
if(NOT CYGWIN AND NOT MSYS AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL QNX)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
if (CMAKE_VERSION VERSION_GREATER "3.0.2")
|
||||
if(NOT CYGWIN AND NOT MSYS AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL QNX)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
enable_testing()
|
||||
|
@ -36,8 +36,7 @@ PR is acceptable as an alternative.
|
||||
This ensures that work isn't being duplicated and communicating your plan
|
||||
early also generally leads to better patches.
|
||||
4. If your proposed change is accepted, and you haven't already done so, sign a
|
||||
Contributor License Agreement
|
||||
([see details above](#contributor-license-agreements)).
|
||||
Contributor License Agreement (see details above).
|
||||
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
|
||||
you are contributing.
|
||||
|
@ -34,7 +34,6 @@ Manuel Klimek <klimek@google.com>
|
||||
Mario Tanev <radix@google.com>
|
||||
Mark Paskin
|
||||
Markus Heule <markus.heule@gmail.com>
|
||||
Martijn Vels <mvels@google.com>
|
||||
Matthew Simmons <simmonmt@acm.org>
|
||||
Mika Raento <mikie@iki.fi>
|
||||
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
|
||||
GitHub Pages rather than directly in the repository.
|
||||
|
||||
#### Release 1.11.0
|
||||
#### Release 1.10.x
|
||||
|
||||
[Release 1.11.0](https://github.com/google/googletest/releases/tag/release-1.11.0)
|
||||
[Release 1.10.x](https://github.com/google/googletest/releases/tag/release-1.10.0)
|
||||
is now available.
|
||||
|
||||
#### Coming Soon
|
||||
@ -109,8 +109,8 @@ Windows and Linux platforms.
|
||||
|
||||
[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
|
||||
displays a list of test failures. Clicking on one shows failure text. GoogleTest
|
||||
UI is written in C#.
|
||||
displays a list of test failures. Clicking on one shows failure text. Google
|
||||
Test UI is written in C#.
|
||||
|
||||
[GTest TAP Listener](https://github.com/kinow/gtest-tap-listener) is an event
|
||||
listener for GoogleTest that implements the
|
||||
|
19
WORKSPACE
19
WORKSPACE
@ -4,14 +4,21 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
|
||||
http_archive(
|
||||
name = "com_google_absl",
|
||||
sha256 = "aeba534f7307e36fe084b452299e49b97420667a8d28102cf9a0daeed340b859",
|
||||
strip_prefix = "abseil-cpp-7971fb358ae376e016d2d4fc9327aad95659b25e",
|
||||
urls = ["https://github.com/abseil/abseil-cpp/archive/7971fb358ae376e016d2d4fc9327aad95659b25e.zip"], # 2021-05-20T02:59:16Z
|
||||
strip_prefix = "abseil-cpp-7971fb358ae376e016d2d4fc9327aad95659b25e",
|
||||
sha256 = "aeba534f7307e36fe084b452299e49b97420667a8d28102cf9a0daeed340b859",
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "rules_python",
|
||||
sha256 = "98b3c592faea9636ac8444bfd9de7f3fb4c60590932d6e6ac5946e3f8dbd5ff6",
|
||||
strip_prefix = "rules_python-ed6cc8f2c3692a6a7f013ff8bc185ba77eb9b4d2",
|
||||
urls = ["https://github.com/bazelbuild/rules_python/archive/ed6cc8f2c3692a6a7f013ff8bc185ba77eb9b4d2.zip"], # 2021-05-17T00:24:16Z
|
||||
name = "rules_cc",
|
||||
urls = ["https://github.com/bazelbuild/rules_cc/archive/68cb652a71e7e7e2858c50593e5a9e3b94e5b9a9.zip"], # 2021-05-14T14:51:14Z
|
||||
strip_prefix = "rules_cc-68cb652a71e7e7e2858c50593e5a9e3b94e5b9a9",
|
||||
sha256 = "1e19e9a3bc3d4ee91d7fcad00653485ee6c798efbbf9588d40b34cbfbded143d",
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
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:20210617"
|
||||
readonly LINUX_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20210525"
|
||||
readonly LINUX_GCC_FLOOR_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-floor:20201015"
|
||||
|
||||
if [[ -z ${GTEST_ROOT:-} ]]; then
|
||||
GTEST_ROOT="$(realpath $(dirname ${0})/..)"
|
||||
|
121
docs/advanced.md
121
docs/advanced.md
@ -157,11 +157,8 @@ that can be used in the predicate assertion macro
|
||||
example:
|
||||
|
||||
```c++
|
||||
using ::testing::FloatLE;
|
||||
using ::testing::DoubleLE;
|
||||
...
|
||||
EXPECT_PRED_FORMAT2(FloatLE, val1, val2);
|
||||
EXPECT_PRED_FORMAT2(DoubleLE, val1, val2);
|
||||
EXPECT_PRED_FORMAT2(testing::FloatLE, val1, val2);
|
||||
EXPECT_PRED_FORMAT2(testing::DoubleLE, val1, val2);
|
||||
```
|
||||
|
||||
The above code verifies that `val1` is less than, or approximately equal to,
|
||||
@ -205,9 +202,10 @@ You can call the function
|
||||
|
||||
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
|
||||
fail to compile, the compiler error message will say that `T1 and T2 are not the
|
||||
same type` and most likely (depending on the compiler) show you the actual
|
||||
values of `T1` and `T2`. This is mainly useful inside template code.
|
||||
fail to compile, the compiler error message will say that
|
||||
`T1 and T2 are not the same type` and most likely (depending on the compiler)
|
||||
show you the actual values of `T1` and `T2`. This is mainly useful inside
|
||||
template code.
|
||||
|
||||
**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
|
||||
@ -385,10 +383,10 @@ EXPECT_TRUE(IsCorrectBarIntVector(bar_ints))
|
||||
## Death Tests
|
||||
|
||||
In many applications, there are assertions that can cause application failure if
|
||||
a condition is not met. These consistency checks, which ensure that the program
|
||||
is in a known good state, are there to fail at the earliest possible time after
|
||||
some program state is corrupted. If the assertion checks the wrong condition,
|
||||
then the program may proceed in an erroneous state, which could lead to memory
|
||||
a condition is not met. These sanity checks, which ensure that the program is in
|
||||
a known good state, are there to fail at the earliest possible time after some
|
||||
program state is corrupted. If the assertion checks the wrong condition, 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
|
||||
such assertion statements work as expected.
|
||||
|
||||
@ -560,7 +558,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:
|
||||
|
||||
```c++
|
||||
GTEST_FLAG_SET(death_test_style, "threadsafe")
|
||||
testing::FLAGS_gtest_death_test_style="threadsafe"
|
||||
```
|
||||
|
||||
You can do this in `main()` to set the style for all death tests in the binary,
|
||||
@ -570,12 +568,12 @@ restored afterwards, so you need not do that yourself. For example:
|
||||
```c++
|
||||
int main(int argc, char** argv) {
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
GTEST_FLAG_SET(death_test_style, "fast");
|
||||
testing::FLAGS_gtest_death_test_style = "fast";
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
TEST(MyDeathTest, TestOne) {
|
||||
GTEST_FLAG_SET(death_test_style, "threadsafe");
|
||||
testing::FLAGS_gtest_death_test_style = "threadsafe";
|
||||
// This test is run in the "threadsafe" style:
|
||||
ASSERT_DEATH(ThisShouldDie(), "");
|
||||
}
|
||||
@ -612,14 +610,15 @@ 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
|
||||
handlers registered with `pthread_atfork(3)`.
|
||||
|
||||
|
||||
## Using Assertions in Sub-routines
|
||||
|
||||
{: .callout .note}
|
||||
Note: If you want to put a series of test assertions in a subroutine to check
|
||||
for a complex condition, consider using
|
||||
[a custom GMock matcher](gmock_cook_book.md#NewMatchers) instead. This lets you
|
||||
provide a more readable error message in case of failure and avoid all of the
|
||||
issues described below.
|
||||
[a custom GMock matcher](gmock_cook_book.md#NewMatchers)
|
||||
instead. This lets you provide a more readable error message in case of failure
|
||||
and avoid all of the issues described below.
|
||||
|
||||
### Adding Traces to Assertions
|
||||
|
||||
@ -632,7 +631,6 @@ the `SCOPED_TRACE` macro or the `ScopedTrace` utility:
|
||||
```c++
|
||||
SCOPED_TRACE(message);
|
||||
```
|
||||
|
||||
```c++
|
||||
ScopedTrace trace("file_path", line_number, message);
|
||||
```
|
||||
@ -890,12 +888,6 @@ 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
|
||||
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:
|
||||
|
||||
```c++
|
||||
@ -905,10 +897,7 @@ class FooTest : public testing::Test {
|
||||
// Called before the first test in this test suite.
|
||||
// Can be omitted if not needed.
|
||||
static void SetUpTestSuite() {
|
||||
// Avoid reallocating static objects if called in subclasses of FooTest.
|
||||
if (shared_resource_ == nullptr) {
|
||||
shared_resource_ = new ...;
|
||||
}
|
||||
shared_resource_ = new ...;
|
||||
}
|
||||
|
||||
// Per-test-suite tear-down.
|
||||
@ -1492,8 +1481,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
|
||||
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, you can use
|
||||
`"gtest/gtest-spi.h"` contains some constructs to do this. After #including this header,
|
||||
you can use
|
||||
|
||||
```c++
|
||||
EXPECT_FATAL_FAILURE(statement, substring);
|
||||
@ -1597,14 +1586,12 @@ void RegisterMyTests(const std::vector<int>& values) {
|
||||
}
|
||||
...
|
||||
int main(int argc, char** argv) {
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
std::vector<int> values_to_test = LoadValuesFromConfig();
|
||||
RegisterMyTests(values_to_test);
|
||||
...
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
```
|
||||
|
||||
## Getting the Current Test's Name
|
||||
|
||||
Sometimes a function may need to know the name of the currently running test.
|
||||
@ -1829,7 +1816,8 @@ 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
|
||||
test execution upon first failure (trading improved latency for completeness).
|
||||
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 found.
|
||||
the test runner will stop execution as soon as the first test failure is
|
||||
found.
|
||||
|
||||
#### Temporarily Disabling Tests
|
||||
|
||||
@ -1923,58 +1911,6 @@ time.
|
||||
If you combine this with `--gtest_repeat=N`, googletest will pick a different
|
||||
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
|
||||
|
||||
#### Colored Terminal Output
|
||||
@ -2029,6 +1965,8 @@ 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`
|
||||
environment variable to `0`.
|
||||
|
||||
|
||||
|
||||
#### Generating an XML Report
|
||||
|
||||
googletest can emit a detailed XML report to a file in addition to its normal
|
||||
@ -2315,11 +2253,12 @@ IMPORTANT: The exact format of the JSON document is subject to change.
|
||||
|
||||
#### Detecting Test Premature Exit
|
||||
|
||||
Google Test implements the _premature-exit-file_ protocol for test runners to
|
||||
catch any kind of unexpected exits of test programs. Upon start, Google Test
|
||||
creates the file which will be automatically deleted after all work has been
|
||||
finished. Then, the test runner can check if this file exists. In case the file
|
||||
remains undeleted, the inspected test has exited prematurely.
|
||||
Google Test implements the _premature-exit-file_ protocol for test runners
|
||||
to catch any kind of unexpected exits of test programs. Upon start,
|
||||
Google Test creates the file which will be automatically deleted after
|
||||
all work has been finished. Then, the test runner can check if this file
|
||||
exists. In case the file remains undeleted, the inspected test has exited
|
||||
prematurely.
|
||||
|
||||
This feature is enabled only if the `TEST_PREMATURE_EXIT_FILE` environment
|
||||
variable has been set.
|
||||
|
@ -410,6 +410,7 @@ C++ is case-sensitive. Did you spell it as `Setup()`?
|
||||
Similarly, sometimes people spell `SetUpTestSuite()` as `SetupTestSuite()` and
|
||||
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.
|
||||
|
||||
You don't have to. Instead of
|
||||
|
@ -230,7 +230,7 @@ class MockFunction<R(A1, ..., An)> {
|
||||
};
|
||||
```
|
||||
|
||||
See this [recipe](gmock_cook_book.md#UsingCheckPoints) for one application of
|
||||
See this [recipe](gmock_cook_book.md#using-check-points) for one application of
|
||||
it.
|
||||
|
||||
## 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.
|
||||
|
||||
Therefore, if you have some complex matcher that you want to use again and
|
||||
again, there is no need to build it every time. Just assign it to a matcher
|
||||
again, there is no need to build it everytime. Just assign it to a matcher
|
||||
variable and use that variable repeatedly! For example,
|
||||
|
||||
```cpp
|
||||
@ -1754,7 +1754,7 @@ specifies the following DAG (where `s1` is `A -> B`, and `s2` is `A -> C -> D`):
|
||||
|
|
||||
A ---|
|
||||
|
|
||||
+---> C ---> D
|
||||
+---> C ---> D
|
||||
```
|
||||
|
||||
This means that A must occur before B and C, and C must occur before D. There's
|
||||
@ -1980,7 +1980,6 @@ If the mock method also needs to return a value as well, you can chain
|
||||
|
||||
```cpp
|
||||
using ::testing::_;
|
||||
using ::testing::DoAll;
|
||||
using ::testing::Return;
|
||||
using ::testing::SetArgPointee;
|
||||
|
||||
@ -2034,7 +2033,10 @@ class MockRolodex : public Rolodex {
|
||||
}
|
||||
...
|
||||
MockRolodex rolodex;
|
||||
vector<string> names = {"George", "John", "Thomas"};
|
||||
vector<string> names;
|
||||
names.push_back("George");
|
||||
names.push_back("John");
|
||||
names.push_back("Thomas");
|
||||
EXPECT_CALL(rolodex, GetNames(_))
|
||||
.WillOnce(SetArrayArgument<0>(names.begin(), names.end()));
|
||||
```
|
||||
@ -2602,7 +2604,7 @@ efficient. When the last action that references the implementation object dies,
|
||||
the implementation object will be deleted.
|
||||
|
||||
If you have some complex action that you want to use again and again, you may
|
||||
not have to build it from scratch every time. If the action doesn't have an
|
||||
not have to build it from scratch everytime. If the action doesn't have an
|
||||
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
|
||||
variable repeatedly. For example:
|
||||
@ -4189,7 +4191,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
|
||||
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,
|
||||
but must be invocable with exactly one template argument, which is the result
|
||||
but must be invokable 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
|
||||
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()`.).
|
||||
|
||||
What can we do inside `WillOnce()` besides `Return()`? You can return a
|
||||
reference using `ReturnRef(`*`variable`*`)`, or invoke a pre-defined function,
|
||||
among [others](gmock_cook_book.md#using-actions).
|
||||
reference using `ReturnRef(*variable*)`, or invoke a pre-defined function, among
|
||||
[others](gmock_cook_book.md#using-actions).
|
||||
|
||||
**Important note:** The `EXPECT_CALL()` statement evaluates the action clause
|
||||
only once, even though the action may be performed many times. Therefore you
|
||||
|
@ -105,7 +105,7 @@ includedir=/usr/include
|
||||
|
||||
Name: gtest
|
||||
Description: GoogleTest (without main() function)
|
||||
Version: 1.11.0
|
||||
Version: 1.10.0
|
||||
URL: https://github.com/google/googletest
|
||||
Libs: -L${libdir} -lgtest -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
|
||||
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 any
|
||||
underscores (`_`). A test's *full name* consists of its containing test suite
|
||||
and its individual name. Tests from different test suites can have the same
|
||||
suite. Both names must be valid C++ identifiers, and they should not contain
|
||||
any underscores (`_`). A test's *full name* consists of its containing test suite and
|
||||
its individual name. Tests from different test suites can have the same
|
||||
individual name.
|
||||
|
||||
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`".
|
||||
|
||||
For each test defined with `TEST_F()`, googletest will create a *fresh* test
|
||||
fixture at runtime, immediately initialize it via `SetUp()`, run the test, clean
|
||||
up by calling `TearDown()`, and then delete the test fixture. Note that
|
||||
fixture at runtime, immediately initialize it via `SetUp()`, run the test,
|
||||
clean 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
|
||||
googletest always deletes a test fixture before it creates the next one.
|
||||
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
|
||||
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 different
|
||||
test suites, or even different source files.
|
||||
`RUN_ALL_TESTS()` runs *all tests* in your link unit--they can be from
|
||||
different test suites, or even different source files.
|
||||
|
||||
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
|
||||
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 the
|
||||
[AdvancedGuide](advanced.md). You **must** call this function before calling
|
||||
control a test program's behavior via various flags, which we'll cover in
|
||||
the [AdvancedGuide](advanced.md). You **must** call this function before calling
|
||||
`RUN_ALL_TESTS()`, or the flags won't be properly initialized.
|
||||
|
||||
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.
|
||||
|
||||
If you don't already have Bazel installed, see the
|
||||
[Bazel installation guide](https://docs.bazel.build/versions/main/install.html).
|
||||
[Bazel installation guide](https://docs.bazel.build/versions/master/install.html).
|
||||
|
||||
{: .callout .note}
|
||||
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
|
||||
|
||||
A
|
||||
[Bazel workspace](https://docs.bazel.build/versions/main/build-ref.html#workspace)
|
||||
[Bazel workspace](https://docs.bazel.build/versions/master/build-ref.html#workspace)
|
||||
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
|
||||
`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
|
||||
recommended way to depend on GoogleTest is to use a
|
||||
[Bazel external dependency](https://docs.bazel.build/versions/main/external.html)
|
||||
[Bazel external dependency](https://docs.bazel.build/versions/master/external.html)
|
||||
via the
|
||||
[`http_archive` rule](https://docs.bazel.build/versions/main/repo/http.html#http_archive).
|
||||
[`http_archive` rule](https://docs.bazel.build/versions/master/repo/http.html#http_archive).
|
||||
To do this, in the root directory of your workspace (`my_workspace/`), create a
|
||||
file named `WORKSPACE` with the following contents:
|
||||
|
||||
@ -62,6 +62,18 @@ as a ZIP archive from GitHub. In the above example,
|
||||
GoogleTest version to use; we recommend updating the hash often to point to the
|
||||
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.
|
||||
|
||||
## Create and run a binary
|
||||
@ -92,6 +104,8 @@ To build the code, create a file named `BUILD` in the same directory with the
|
||||
following contents:
|
||||
|
||||
```
|
||||
load("@rules_cc//cc:defs.bzl", "cc_test")
|
||||
|
||||
cc_test(
|
||||
name = "hello_test",
|
||||
size = "small",
|
||||
@ -104,7 +118,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`
|
||||
file (`@com_google_googletest`). For more information about Bazel `BUILD` files,
|
||||
see the
|
||||
[Bazel C++ Tutorial](https://docs.bazel.build/versions/main/tutorial/cpp.html).
|
||||
[Bazel C++ Tutorial](https://docs.bazel.build/versions/master/tutorial/cpp.html).
|
||||
|
||||
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
|
||||
|
||||
| Action | Description |
|
||||
| | |
|
||||
| :-------------------------------- | :-------------------------------------------- |
|
||||
| `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. |
|
||||
@ -20,7 +20,7 @@ provided by GoogleTest. All actions are defined in the `::testing` namespace.
|
||||
|
||||
## Side Effects
|
||||
|
||||
| Action | Description |
|
||||
| | |
|
||||
| :--------------------------------- | :-------------------------------------- |
|
||||
| `Assign(&variable, value)` | Assign `value` to variable. |
|
||||
| `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`,
|
||||
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(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. |
|
||||
@ -86,7 +86,7 @@ value, and `foo` by reference.
|
||||
|
||||
## Default Action
|
||||
|
||||
| Action | Description |
|
||||
| Matcher | Description |
|
||||
| :------------ | :----------------------------------------------------- |
|
||||
| `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
|
||||
|
||||
| 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. |
|
||||
| `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
|
||||
|
||||
| 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_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,17 +88,16 @@ The `argument` can be either a C string or a C++ string object:
|
||||
|
||||
| Matcher | Description |
|
||||
| :---------------------- | :------------------------------------------------- |
|
||||
| `ContainsRegex(string)` | `argument` matches the given regular expression. |
|
||||
| `EndsWith(suffix)` | `argument` ends with string `suffix`. |
|
||||
| `HasSubstr(string)` | `argument` contains `string` as a sub-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. |
|
||||
| `StartsWith(prefix)` | `argument` starts with string `prefix`. |
|
||||
| `StrCaseEq(string)` | `argument` is equal to `string`, ignoring case. |
|
||||
| `StrCaseNe(string)` | `argument` is not equal to `string`, ignoring case. |
|
||||
| `StrEq(string)` | `argument` is 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(string)` | `argument` matches the given regular expression. |
|
||||
| `EndsWith(suffix)` | `argument` ends with string `suffix`. |
|
||||
| `HasSubstr(string)` | `argument` contains `string` as a sub-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. |
|
||||
| `StartsWith(prefix)` | `argument` starts with string `prefix`. |
|
||||
| `StrCaseEq(string)` | `argument` is equal to `string`, ignoring case. |
|
||||
| `StrCaseNe(string)` | `argument` is not equal to `string`, ignoring case. |
|
||||
| `StrEq(string)` | `argument` is equal to `string`. |
|
||||
| `StrNe(string)` | `argument` is not equal to `string`. |
|
||||
|
||||
`ContainsRegex()` and `MatchesRegex()` take ownership of the `RE` object. They
|
||||
use the regular expression syntax defined
|
||||
@ -117,7 +116,6 @@ 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. |
|
||||
| `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).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. |
|
||||
| `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. |
|
||||
@ -148,6 +146,7 @@ messages, you can use:
|
||||
one might write:
|
||||
|
||||
```cpp
|
||||
using ::std::get;
|
||||
MATCHER(FooEq, "") {
|
||||
return std::get<0>(arg).Equals(std::get<1>(arg));
|
||||
}
|
||||
@ -238,7 +237,6 @@ 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`. |
|
||||
| `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`. |
|
||||
| `Conditional(cond, m1, m2)` | Matches matcher `m1` if `cond` evaluates to true, else matches `m2`.|
|
||||
|
||||
## Adapters for Matchers
|
||||
|
||||
@ -261,7 +259,7 @@ which must be a permanent callback.
|
||||
|
||||
## Defining Matchers
|
||||
|
||||
| Macro | Description |
|
||||
| Matcher | Description |
|
||||
| :----------------------------------- | :------------------------------------ |
|
||||
| `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`. |
|
||||
|
@ -36,9 +36,13 @@ endif()
|
||||
# as ${gmock_SOURCE_DIR} and to the root binary directory as
|
||||
# ${gmock_BINARY_DIR}.
|
||||
# Language "C" is required for find_package(Threads).
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
cmake_policy(SET CMP0048 NEW)
|
||||
project(gmock VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)
|
||||
if (CMAKE_VERSION VERSION_LESS 3.0)
|
||||
project(gmock CXX C)
|
||||
else()
|
||||
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)
|
||||
set_up_hermetic_build()
|
||||
|
@ -35,6 +35,10 @@ Details and examples can be found here:
|
||||
* [gMock Cookbook](https://google.github.io/googletest/gmock_cook_book.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
|
||||
[GoogleTest C++ testing framework](http://github.com/google/googletest/) and a
|
||||
subject to the same requirements.
|
||||
|
@ -125,6 +125,8 @@
|
||||
// To learn more about using these macros, please search for 'ACTION' on
|
||||
// https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md
|
||||
|
||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
|
||||
|
||||
|
@ -34,6 +34,8 @@
|
||||
// cardinalities can be defined by the user implementing the
|
||||
// CardinalityInterface interface if necessary.
|
||||
|
||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
||||
|
||||
|
@ -31,6 +31,8 @@
|
||||
//
|
||||
// This file implements MOCK_METHOD.
|
||||
|
||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
|
||||
|
||||
@ -62,39 +64,6 @@ 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
|
||||
|
||||
// The style guide prohibits "using" statements in a namespace scope
|
||||
@ -117,18 +86,17 @@ using internal::FunctionMocker;
|
||||
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_3(_Ret, _MethodName, _Args) \
|
||||
GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, ())
|
||||
|
||||
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, _Spec) \
|
||||
GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Args); \
|
||||
GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Spec); \
|
||||
GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE( \
|
||||
GMOCK_PP_NARG0 _Args, GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)); \
|
||||
GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \
|
||||
GMOCK_INTERNAL_MOCK_METHOD_IMPL( \
|
||||
GMOCK_PP_NARG0 _Args, _MethodName, GMOCK_INTERNAL_HAS_CONST(_Spec), \
|
||||
GMOCK_INTERNAL_HAS_OVERRIDE(_Spec), GMOCK_INTERNAL_HAS_FINAL(_Spec), \
|
||||
GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Spec), \
|
||||
GMOCK_INTERNAL_GET_CALLTYPE_SPEC(_Spec), \
|
||||
GMOCK_INTERNAL_GET_REF_SPEC(_Spec), \
|
||||
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, _Spec) \
|
||||
GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Args); \
|
||||
GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Spec); \
|
||||
GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE( \
|
||||
GMOCK_PP_NARG0 _Args, GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)); \
|
||||
GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \
|
||||
GMOCK_INTERNAL_MOCK_METHOD_IMPL( \
|
||||
GMOCK_PP_NARG0 _Args, _MethodName, GMOCK_INTERNAL_HAS_CONST(_Spec), \
|
||||
GMOCK_INTERNAL_HAS_OVERRIDE(_Spec), GMOCK_INTERNAL_HAS_FINAL(_Spec), \
|
||||
GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Spec), \
|
||||
GMOCK_INTERNAL_GET_CALLTYPE(_Spec), GMOCK_INTERNAL_GET_REF_SPEC(_Spec), \
|
||||
(GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)))
|
||||
|
||||
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_5(...) \
|
||||
@ -202,7 +170,7 @@ using internal::FunctionMocker;
|
||||
|
||||
#define GMOCK_INTERNAL_EXPAND(...) __VA_ARGS__
|
||||
|
||||
// Valid modifiers.
|
||||
// Five Valid modifiers.
|
||||
#define GMOCK_INTERNAL_HAS_CONST(_Tuple) \
|
||||
GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_CONST, ~, _Tuple))
|
||||
|
||||
@ -221,14 +189,6 @@ using internal::FunctionMocker;
|
||||
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _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) \
|
||||
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_REF_SPEC_IF_REF, ~, _Tuple)
|
||||
|
||||
@ -236,25 +196,19 @@ using internal::FunctionMocker;
|
||||
GMOCK_PP_IF(GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)), \
|
||||
GMOCK_PP_CAT(GMOCK_INTERNAL_UNPACK_, _elem), )
|
||||
|
||||
#ifdef GMOCK_INTERNAL_STRICT_SPEC_ASSERT
|
||||
#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem) \
|
||||
static_assert( \
|
||||
::testing::internal::ValidateSpec(GMOCK_PP_STRINGIZE(_elem)), \
|
||||
"Token \'" GMOCK_PP_STRINGIZE( \
|
||||
_elem) "\' cannot be recognized as a valid specification " \
|
||||
"modifier. Is a ',' missing?");
|
||||
#else
|
||||
#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem) \
|
||||
static_assert( \
|
||||
(GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem)) + \
|
||||
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( \
|
||||
#define GMOCK_INTERNAL_GET_CALLTYPE(_Tuple) \
|
||||
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_CALLTYPE_IMPL, ~, _Tuple)
|
||||
|
||||
#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem) \
|
||||
static_assert( \
|
||||
(GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem)) + \
|
||||
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_INTERNAL_IS_CALLTYPE(_elem)) == 1, \
|
||||
GMOCK_PP_STRINGIZE( \
|
||||
_elem) " cannot be recognized as a valid specification modifier.");
|
||||
#endif // GMOCK_INTERNAL_STRICT_SPEC_ASSERT
|
||||
|
||||
// Modifiers implementation.
|
||||
#define GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem) \
|
||||
@ -284,12 +238,26 @@ using internal::FunctionMocker;
|
||||
|
||||
#define GMOCK_INTERNAL_UNPACK_ref(x) x
|
||||
|
||||
#define GMOCK_INTERNAL_DETECT_CALLTYPE(_i, _, _elem) \
|
||||
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_CALLTYPE_I_, _elem)
|
||||
#define GMOCK_INTERNAL_GET_CALLTYPE_IMPL(_i, _, _elem) \
|
||||
GMOCK_PP_IF(GMOCK_INTERNAL_IS_CALLTYPE(_elem), \
|
||||
GMOCK_INTERNAL_GET_VALUE_CALLTYPE, GMOCK_PP_EMPTY) \
|
||||
(_elem)
|
||||
|
||||
#define GMOCK_INTERNAL_DETECT_CALLTYPE_I_Calltype ,
|
||||
// TODO(iserna): GMOCK_INTERNAL_IS_CALLTYPE and
|
||||
// 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_UNPACK_Calltype(...) __VA_ARGS__
|
||||
#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE(_arg) \
|
||||
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
|
||||
// would normally need to be specified in a different way. For example, a method
|
||||
|
@ -250,6 +250,8 @@
|
||||
// See googletest/include/gtest/gtest-matchers.h for the definition of class
|
||||
// Matcher, class MatcherInterface, and others.
|
||||
|
||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
|
||||
|
||||
@ -1122,45 +1124,6 @@ class EndsWithMatcher {
|
||||
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
|
||||
// using one of the ==, <=, <, etc, operators. The two fields being
|
||||
// compared don't have to have the same type.
|
||||
@ -1442,30 +1405,6 @@ class AnyOfMatcherImpl : public MatcherInterface<const T&> {
|
||||
template <typename... 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().
|
||||
template <template <class> class MatcherImpl, typename T>
|
||||
class SomeOfArrayMatcher {
|
||||
@ -2425,6 +2364,7 @@ class ContainerEqMatcher {
|
||||
typedef internal::StlContainerView<
|
||||
typename std::remove_const<LhsContainer>::type>
|
||||
LhsView;
|
||||
typedef typename LhsView::type LhsStlContainer;
|
||||
StlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);
|
||||
if (lhs_stl_container == expected_)
|
||||
return true;
|
||||
@ -2433,7 +2373,8 @@ class ContainerEqMatcher {
|
||||
if (os != nullptr) {
|
||||
// Something is different. Check for extra values first.
|
||||
bool printed_header = false;
|
||||
for (auto it = lhs_stl_container.begin();
|
||||
for (typename LhsStlContainer::const_iterator it =
|
||||
lhs_stl_container.begin();
|
||||
it != lhs_stl_container.end(); ++it) {
|
||||
if (internal::ArrayAwareFind(expected_.begin(), expected_.end(), *it) ==
|
||||
expected_.end()) {
|
||||
@ -2449,7 +2390,7 @@ class ContainerEqMatcher {
|
||||
|
||||
// Now check for missing values.
|
||||
bool printed_header2 = false;
|
||||
for (auto it = expected_.begin();
|
||||
for (typename StlContainer::const_iterator it = expected_.begin();
|
||||
it != expected_.end(); ++it) {
|
||||
if (internal::ArrayAwareFind(
|
||||
lhs_stl_container.begin(), lhs_stl_container.end(), *it) ==
|
||||
@ -2633,14 +2574,14 @@ class PointwiseMatcher {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto left = lhs_stl_container.begin();
|
||||
auto right = rhs_.begin();
|
||||
typename LhsStlContainer::const_iterator left = lhs_stl_container.begin();
|
||||
typename RhsStlContainer::const_iterator right = rhs_.begin();
|
||||
for (size_t i = 0; i != actual_size; ++i, ++left, ++right) {
|
||||
if (listener->IsInterested()) {
|
||||
StringMatchResultListener inner_listener;
|
||||
// Create InnerMatcherArg as a temporarily object to avoid it outlives
|
||||
// *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(
|
||||
InnerMatcherArg(ImplicitCast_<const LhsValue&>(*left),
|
||||
ImplicitCast_<const RhsValue&>(*right)),
|
||||
@ -2697,7 +2638,7 @@ class QuantifierMatcherImpl : public MatcherInterface<Container> {
|
||||
MatchResultListener* listener) const {
|
||||
StlContainerReference stl_container = View::ConstReference(container);
|
||||
size_t i = 0;
|
||||
for (auto it = stl_container.begin();
|
||||
for (typename StlContainer::const_iterator it = stl_container.begin();
|
||||
it != stl_container.end(); ++it, ++i) {
|
||||
StringMatchResultListener inner_listener;
|
||||
const bool matches = inner_matcher_.MatchAndExplain(*it, &inner_listener);
|
||||
@ -2712,54 +2653,6 @@ class QuantifierMatcherImpl : public MatcherInterface<Container> {
|
||||
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:
|
||||
const Matcher<const Element&> inner_matcher_;
|
||||
};
|
||||
@ -2816,58 +2709,6 @@ 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).
|
||||
template <typename M>
|
||||
class ContainsMatcher {
|
||||
@ -2875,15 +2716,11 @@ class ContainsMatcher {
|
||||
explicit ContainsMatcher(M m) : inner_matcher_(m) {}
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const { // NOLINT
|
||||
operator Matcher<Container>() const {
|
||||
return Matcher<Container>(
|
||||
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:
|
||||
const M inner_matcher_;
|
||||
};
|
||||
@ -2895,7 +2732,7 @@ class EachMatcher {
|
||||
explicit EachMatcher(M m) : inner_matcher_(m) {}
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const { // NOLINT
|
||||
operator Matcher<Container>() const {
|
||||
return Matcher<Container>(
|
||||
new EachMatcherImpl<const Container&>(inner_matcher_));
|
||||
}
|
||||
@ -3398,7 +3235,7 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> {
|
||||
// explanations[i] is the explanation of the element at index i.
|
||||
::std::vector<std::string> explanations(count());
|
||||
StlContainerReference stl_container = View::ConstReference(container);
|
||||
auto it = stl_container.begin();
|
||||
typename StlContainer::const_iterator it = stl_container.begin();
|
||||
size_t exam_pos = 0;
|
||||
bool mismatch_found = false; // Have we found a mismatched element yet?
|
||||
|
||||
@ -3591,6 +3428,7 @@ class UnorderedElementsAreMatcherImpl
|
||||
typedef internal::StlContainerView<RawContainer> View;
|
||||
typedef typename View::type StlContainer;
|
||||
typedef typename View::const_reference StlContainerReference;
|
||||
typedef typename StlContainer::const_iterator StlContainerConstIterator;
|
||||
typedef typename StlContainer::value_type Element;
|
||||
|
||||
template <typename InputIter>
|
||||
@ -4143,26 +3981,26 @@ ElementsAreArray(Iter first, Iter last) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline auto ElementsAreArray(const T* pointer, size_t count)
|
||||
-> decltype(ElementsAreArray(pointer, pointer + count)) {
|
||||
inline internal::ElementsAreArrayMatcher<T> ElementsAreArray(
|
||||
const T* pointer, size_t count) {
|
||||
return ElementsAreArray(pointer, pointer + count);
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
inline auto ElementsAreArray(const T (&array)[N])
|
||||
-> decltype(ElementsAreArray(array, N)) {
|
||||
inline internal::ElementsAreArrayMatcher<T> ElementsAreArray(
|
||||
const T (&array)[N]) {
|
||||
return ElementsAreArray(array, N);
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
inline auto ElementsAreArray(const Container& container)
|
||||
-> decltype(ElementsAreArray(container.begin(), container.end())) {
|
||||
inline internal::ElementsAreArrayMatcher<typename Container::value_type>
|
||||
ElementsAreArray(const Container& container) {
|
||||
return ElementsAreArray(container.begin(), container.end());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline auto ElementsAreArray(::std::initializer_list<T> xs)
|
||||
-> decltype(ElementsAreArray(xs.begin(), xs.end())) {
|
||||
inline internal::ElementsAreArrayMatcher<T>
|
||||
ElementsAreArray(::std::initializer_list<T> xs) {
|
||||
return ElementsAreArray(xs.begin(), xs.end());
|
||||
}
|
||||
|
||||
@ -4757,7 +4595,7 @@ UnorderedPointwise(const Tuple2Matcher& tuple2_matcher,
|
||||
|
||||
// Create a matcher for each element in rhs_container.
|
||||
::std::vector<internal::BoundSecondMatcher<Tuple2Matcher, Second> > matchers;
|
||||
for (auto it = rhs_stl_container.begin();
|
||||
for (typename RhsStlContainer::const_iterator it = rhs_stl_container.begin();
|
||||
it != rhs_stl_container.end(); ++it) {
|
||||
matchers.push_back(
|
||||
internal::MatcherBindSecond(tuple2_matcher, *it));
|
||||
@ -4777,6 +4615,7 @@ UnorderedPointwise(const Tuple2Matcher& tuple2_matcher,
|
||||
return UnorderedPointwise(tuple2_matcher, std::vector<T>(rhs));
|
||||
}
|
||||
|
||||
|
||||
// Matches an STL-style container or a native array that contains at
|
||||
// least one element matching the given value or matcher.
|
||||
//
|
||||
@ -4786,7 +4625,7 @@ UnorderedPointwise(const Tuple2Matcher& tuple2_matcher,
|
||||
// page_ids.insert(1);
|
||||
// EXPECT_THAT(page_ids, Contains(1));
|
||||
// EXPECT_THAT(page_ids, Contains(Gt(2)));
|
||||
// EXPECT_THAT(page_ids, Not(Contains(4))); // See below for Times(0)
|
||||
// EXPECT_THAT(page_ids, Not(Contains(4)));
|
||||
//
|
||||
// ::std::map<int, size_t> page_lengths;
|
||||
// page_lengths[1] = 100;
|
||||
@ -4795,19 +4634,6 @@ UnorderedPointwise(const Tuple2Matcher& tuple2_matcher,
|
||||
//
|
||||
// const char* user_ids[] = { "joe", "mike", "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>
|
||||
inline internal::ContainsMatcher<M> Contains(M matcher) {
|
||||
return internal::ContainsMatcher<M>(matcher);
|
||||
@ -4934,7 +4760,7 @@ inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(
|
||||
// Matches an STL-style container or a native array that contains only
|
||||
// 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.
|
||||
//
|
||||
// Examples:
|
||||
@ -4984,18 +4810,6 @@ Pair(FirstMatcher first_matcher, SecondMatcher second_matcher) {
|
||||
}
|
||||
|
||||
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.
|
||||
// These include those that support `get<I>(obj)`, and when structured bindings
|
||||
// are enabled any class that supports them.
|
||||
@ -5022,14 +4836,6 @@ inline internal::AddressMatcher<InnerMatcher> Address(
|
||||
const 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
|
||||
|
||||
// Returns a predicate that is satisfied by anything that matches the
|
||||
@ -5266,8 +5072,7 @@ class WithWhatMatcherImpl {
|
||||
|
||||
template <typename Err>
|
||||
bool MatchAndExplain(const Err& err, MatchResultListener* listener) const {
|
||||
*listener << "which contains .what() (of value = " << err.what()
|
||||
<< ") that ";
|
||||
*listener << "which contains .what() that ";
|
||||
return matcher_.MatchAndExplain(err.what(), listener);
|
||||
}
|
||||
|
||||
@ -5422,7 +5227,7 @@ PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> ThrowsMessage(
|
||||
#define EXPECT_THAT(value, matcher) EXPECT_PRED_FORMAT1(\
|
||||
::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
|
||||
|
||||
// MATCHER* macros itself are listed below.
|
||||
// MATCHER* macroses itself are listed below.
|
||||
#define MATCHER(name, description) \
|
||||
class name##Matcher \
|
||||
: public ::testing::internal::MatcherBaseImpl<name##Matcher> { \
|
||||
@ -5443,7 +5248,6 @@ PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> ThrowsMessage(
|
||||
\
|
||||
private: \
|
||||
::std::string FormatDescription(bool negation) const { \
|
||||
/* NOLINTNEXTLINE readability-redundant-string-init */ \
|
||||
::std::string gmock_description = (description); \
|
||||
if (!gmock_description.empty()) { \
|
||||
return gmock_description; \
|
||||
|
@ -32,6 +32,8 @@
|
||||
//
|
||||
// This file implements some commonly used variadic actions.
|
||||
|
||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
||||
|
||||
|
@ -35,6 +35,8 @@
|
||||
// Note that tests are implemented in gmock-matchers_test.cc rather than
|
||||
// gmock-more-matchers-test.cc.
|
||||
|
||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_
|
||||
|
||||
|
@ -58,6 +58,8 @@
|
||||
// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
|
||||
// supported.
|
||||
|
||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
|
||||
|
||||
|
@ -56,6 +56,8 @@
|
||||
// where all clauses are optional, and .InSequence()/.After()/
|
||||
// .WillOnce() can appear any number of times.
|
||||
|
||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
|
||||
|
||||
@ -888,7 +890,7 @@ class GTEST_API_ ExpectationBase {
|
||||
mutable Mutex mutex_; // Protects action_count_checked_.
|
||||
}; // class ExpectationBase
|
||||
|
||||
// Implements an expectation for the given function type.
|
||||
// Impements an expectation for the given function type.
|
||||
template <typename F>
|
||||
class TypedExpectation : public ExpectationBase {
|
||||
public:
|
||||
@ -1508,7 +1510,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
||||
|
||||
// Performs the default action of this mock function on the given
|
||||
// arguments and returns the result. Asserts (or throws if
|
||||
// exceptions are enabled) with a helpful call description if there
|
||||
// exceptions are enabled) with a helpful call descrption if there
|
||||
// is no valid return value. This method doesn't depend on the
|
||||
// mutable state of this object, and thus can be called concurrently
|
||||
// without locking.
|
||||
|
@ -32,6 +32,8 @@
|
||||
//
|
||||
// This is the main header file a user should include.
|
||||
|
||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_
|
||||
|
||||
@ -63,13 +65,13 @@
|
||||
#include "gmock/gmock-nice-strict.h"
|
||||
#include "gmock/internal/gmock-internal-utils.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Declares Google Mock flags that we want a user to use programmatically.
|
||||
GMOCK_DECLARE_bool_(catch_leaked_mocks);
|
||||
GMOCK_DECLARE_string_(verbose);
|
||||
GMOCK_DECLARE_int32_(default_mock_behavior);
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Initializes Google Mock. This must be called before running the
|
||||
// tests. In particular, it parses the command line for the flags
|
||||
// that Google Mock recognizes. Whenever a Google Mock flag is seen,
|
||||
|
@ -14,5 +14,3 @@ The following macros can be defined:
|
||||
* `GMOCK_DEFINE_bool_(name, default_val, doc)`
|
||||
* `GMOCK_DEFINE_int32_(name, default_val, doc)`
|
||||
* `GMOCK_DEFINE_string_(name, default_val, doc)`
|
||||
* `GMOCK_FLAG_GET(flag_name)`
|
||||
* `GMOCK_FLAG_SET(flag_name, value)`
|
||||
|
@ -1,3 +1,5 @@
|
||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
|
||||
|
||||
|
@ -28,6 +28,8 @@
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Injection point for custom user configurations. See README for details
|
||||
//
|
||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
|
||||
|
@ -31,6 +31,8 @@
|
||||
//
|
||||
// ** Custom implementation starts here **
|
||||
|
||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
|
||||
|
||||
|
@ -34,6 +34,8 @@
|
||||
// Mock. They are subject to change without notice, so please DO NOT
|
||||
// USE THEM IN USER CODE.
|
||||
|
||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
||||
|
||||
@ -279,7 +281,7 @@ class WithoutMatchers {
|
||||
GTEST_API_ WithoutMatchers GetWithoutMatchers();
|
||||
|
||||
// Disable MSVC warnings for infinite recursion, since in this case the
|
||||
// recursion is unreachable.
|
||||
// the recursion is unreachable.
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4717)
|
||||
@ -447,8 +449,6 @@ struct Function<R(Args...)> {
|
||||
template <typename R, typename... Args>
|
||||
constexpr size_t Function<R(Args...)>::ArgumentCount;
|
||||
|
||||
bool Base64Unescape(const std::string& encoded, std::string* decoded);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
@ -35,6 +35,8 @@
|
||||
// end with _ are part of Google Mock's public API and can be used by
|
||||
// code outside Google Mock.
|
||||
|
||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||
|
||||
@ -67,37 +69,19 @@
|
||||
#if !defined(GMOCK_DECLARE_bool_)
|
||||
|
||||
// Macros for declaring flags.
|
||||
#define GMOCK_DECLARE_bool_(name) \
|
||||
namespace testing { \
|
||||
GTEST_API_ extern bool 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")
|
||||
# define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name)
|
||||
# define GMOCK_DECLARE_int32_(name) extern GTEST_API_ int32_t GMOCK_FLAG(name)
|
||||
# define GMOCK_DECLARE_string_(name) \
|
||||
extern GTEST_API_ ::std::string GMOCK_FLAG(name)
|
||||
|
||||
// Macros for defining flags.
|
||||
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||
namespace testing { \
|
||||
GTEST_API_ bool GMOCK_FLAG(name) = (default_val); \
|
||||
} static_assert(true, "no-op to require trailing semicolon")
|
||||
#define GMOCK_DEFINE_int32_(name, default_val, doc) \
|
||||
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")
|
||||
# define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||
GTEST_API_ bool GMOCK_FLAG(name) = (default_val)
|
||||
# define GMOCK_DEFINE_int32_(name, default_val, doc) \
|
||||
GTEST_API_ int32_t GMOCK_FLAG(name) = (default_val)
|
||||
# define GMOCK_DEFINE_string_(name, default_val, doc) \
|
||||
GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val)
|
||||
|
||||
#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_
|
||||
|
5
googlemock/scripts/README.md
Normal file
5
googlemock/scripts/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# 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.
|
256
googlemock/scripts/fuse_gmock_files.py
Executable file
256
googlemock/scripts/fuse_gmock_files.py
Executable file
@ -0,0 +1,256 @@
|
||||
#!/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()
|
203
googlemock/scripts/generator/LICENSE
Normal file
203
googlemock/scripts/generator/LICENSE
Normal file
@ -0,0 +1,203 @@
|
||||
|
||||
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.
|
34
googlemock/scripts/generator/README
Normal file
34
googlemock/scripts/generator/README
Normal file
@ -0,0 +1,34 @@
|
||||
|
||||
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.
|
115
googlemock/scripts/generator/README.cppclean
Normal file
115
googlemock/scripts/generator/README.cppclean
Normal file
@ -0,0 +1,115 @@
|
||||
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)
|
0
googlemock/scripts/generator/cpp/__init__.py
Executable file
0
googlemock/scripts/generator/cpp/__init__.py
Executable file
1773
googlemock/scripts/generator/cpp/ast.py
Executable file
1773
googlemock/scripts/generator/cpp/ast.py
Executable file
File diff suppressed because it is too large
Load Diff
247
googlemock/scripts/generator/cpp/gmock_class.py
Executable file
247
googlemock/scripts/generator/cpp/gmock_class.py
Executable file
@ -0,0 +1,247 @@
|
||||
#!/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)
|
570
googlemock/scripts/generator/cpp/gmock_class_test.py
Executable file
570
googlemock/scripts/generator/cpp/gmock_class_test.py
Executable file
@ -0,0 +1,570 @@
|
||||
#!/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()
|
56
googlemock/scripts/generator/cpp/keywords.py
Executable file
56
googlemock/scripts/generator/cpp/keywords.py
Executable file
@ -0,0 +1,56 @@
|
||||
#!/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
|
284
googlemock/scripts/generator/cpp/tokenize.py
Executable file
284
googlemock/scripts/generator/cpp/tokenize.py
Executable file
@ -0,0 +1,284 @@
|
||||
#!/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)
|
37
googlemock/scripts/generator/cpp/utils.py
Executable file
37
googlemock/scripts/generator/cpp/utils.py
Executable file
@ -0,0 +1,37 @@
|
||||
#!/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
|
30
googlemock/scripts/generator/gmock_gen.py
Executable file
30
googlemock/scripts/generator/gmock_gen.py
Executable file
@ -0,0 +1,30 @@
|
||||
#!/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,14 +37,8 @@
|
||||
#include "gmock/internal/gmock-internal-utils.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include <array>
|
||||
#include <cctype>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
#include "gtest/gtest.h"
|
||||
@ -132,10 +126,10 @@ static GTEST_DEFINE_STATIC_MUTEX_(g_log_mutex);
|
||||
// Returns true if and only if a log with the given severity is visible
|
||||
// according to the --gmock_verbose flag.
|
||||
GTEST_API_ bool LogIsVisible(LogSeverity severity) {
|
||||
if (GMOCK_FLAG_GET(verbose) == kInfoVerbosity) {
|
||||
if (GMOCK_FLAG(verbose) == kInfoVerbosity) {
|
||||
// Always show the log if --gmock_verbose=info.
|
||||
return true;
|
||||
} else if (GMOCK_FLAG_GET(verbose) == kErrorVerbosity) {
|
||||
} else if (GMOCK_FLAG(verbose) == kErrorVerbosity) {
|
||||
// Always hide it if --gmock_verbose=error.
|
||||
return false;
|
||||
} else {
|
||||
@ -202,53 +196,5 @@ GTEST_API_ void IllegalDoDefault(const char* file, int line) {
|
||||
"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 testing
|
||||
|
@ -264,10 +264,10 @@ void ExpectationBase::UntypedTimes(const Cardinality& a_cardinality) {
|
||||
".Times() cannot appear "
|
||||
"more than once in an EXPECT_CALL().");
|
||||
} else {
|
||||
ExpectSpecProperty(
|
||||
last_clause_ < kTimes,
|
||||
".Times() may only appear *before* .InSequence(), .WillOnce(), "
|
||||
".WillRepeatedly(), or .RetiresonSaturation(), not after.");
|
||||
ExpectSpecProperty(last_clause_ < kTimes,
|
||||
".Times() cannot appear after "
|
||||
".InSequence(), .WillOnce(), .WillRepeatedly(), "
|
||||
"or .RetiresOnSaturation().");
|
||||
}
|
||||
last_clause_ = kTimes;
|
||||
|
||||
@ -283,7 +283,7 @@ GTEST_API_ ThreadLocal<Sequence*> g_gmock_implicit_sequence;
|
||||
void ReportUninterestingCall(CallReaction reaction, const std::string& msg) {
|
||||
// Include a stack trace only if --gmock_verbose=info is specified.
|
||||
const int stack_frames_to_skip =
|
||||
GMOCK_FLAG_GET(verbose) == kInfoVerbosity ? 3 : -1;
|
||||
GMOCK_FLAG(verbose) == kInfoVerbosity ? 3 : -1;
|
||||
switch (reaction) {
|
||||
case kAllow:
|
||||
Log(kInfo, msg, stack_frames_to_skip);
|
||||
@ -613,7 +613,8 @@ class MockObjectRegistry {
|
||||
// object alive. Therefore we report any living object as test
|
||||
// failure, unless the user explicitly asked us to ignore it.
|
||||
~MockObjectRegistry() {
|
||||
if (!GMOCK_FLAG_GET(catch_leaked_mocks)) return;
|
||||
if (!GMOCK_FLAG(catch_leaked_mocks))
|
||||
return;
|
||||
|
||||
int leaked_count = 0;
|
||||
for (StateMap::const_iterator it = states_.begin(); it != states_.end();
|
||||
@ -715,10 +716,9 @@ internal::CallReaction Mock::GetReactionOnUninterestingCalls(
|
||||
const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
return (g_uninteresting_call_reaction.count(mock_obj) == 0)
|
||||
? internal::intToCallReaction(
|
||||
GMOCK_FLAG_GET(default_mock_behavior))
|
||||
: g_uninteresting_call_reaction[mock_obj];
|
||||
return (g_uninteresting_call_reaction.count(mock_obj) == 0) ?
|
||||
internal::intToCallReaction(GMOCK_FLAG(default_mock_behavior)) :
|
||||
g_uninteresting_call_reaction[mock_obj];
|
||||
}
|
||||
|
||||
// Tells Google Mock to ignore mock_obj when checking for leaked mock
|
||||
|
@ -31,11 +31,13 @@
|
||||
#include "gmock/gmock.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
GMOCK_DEFINE_bool_(catch_leaked_mocks, true,
|
||||
"true if and only if Google Mock should report leaked "
|
||||
"mock objects as failures.");
|
||||
|
||||
GMOCK_DEFINE_string_(verbose, testing::internal::kWarningVerbosity,
|
||||
GMOCK_DEFINE_string_(verbose, internal::kWarningVerbosity,
|
||||
"Controls how verbose Google Mock's output is."
|
||||
" Valid values:\n"
|
||||
" info - prints all messages.\n"
|
||||
@ -49,7 +51,6 @@ GMOCK_DEFINE_int32_(default_mock_behavior, 1,
|
||||
" 1 - by default, mocks act as NaggyMocks.\n"
|
||||
" 2 - by default, mocks act as StrictMocks.");
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Parses a string as a command line flag. The string should have the
|
||||
@ -58,18 +59,18 @@ namespace internal {
|
||||
//
|
||||
// Returns the value of the flag, or NULL if the parsing failed.
|
||||
static const char* ParseGoogleMockFlagValue(const char* str,
|
||||
const char* flag_name,
|
||||
const char* flag,
|
||||
bool def_optional) {
|
||||
// str and flag must not be NULL.
|
||||
if (str == nullptr || flag_name == nullptr) return nullptr;
|
||||
if (str == nullptr || flag == nullptr) return nullptr;
|
||||
|
||||
// The flag must start with "--gmock_".
|
||||
const std::string flag_name_str = std::string("--gmock_") + flag_name;
|
||||
const size_t flag_name_len = flag_name_str.length();
|
||||
if (strncmp(str, flag_name_str.c_str(), flag_name_len) != 0) return nullptr;
|
||||
const std::string flag_str = std::string("--gmock_") + flag;
|
||||
const size_t flag_len = flag_str.length();
|
||||
if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr;
|
||||
|
||||
// Skips the flag name.
|
||||
const char* flag_end = str + flag_name_len;
|
||||
const char* flag_end = str + flag_len;
|
||||
|
||||
// When def_optional is true, it's OK to not have a "=value" part.
|
||||
if (def_optional && (flag_end[0] == '\0')) {
|
||||
@ -90,10 +91,10 @@ static const char* ParseGoogleMockFlagValue(const char* str,
|
||||
//
|
||||
// On success, stores the value of the flag in *value, and returns
|
||||
// true. On failure, returns false without changing *value.
|
||||
static bool ParseGoogleMockFlag(const char* str, const char* flag_name,
|
||||
bool* value) {
|
||||
static bool ParseGoogleMockBoolFlag(const char* str, const char* flag,
|
||||
bool* value) {
|
||||
// Gets the value of the flag as a string.
|
||||
const char* const value_str = ParseGoogleMockFlagValue(str, flag_name, true);
|
||||
const char* const value_str = ParseGoogleMockFlagValue(str, flag, true);
|
||||
|
||||
// Aborts if the parsing failed.
|
||||
if (value_str == nullptr) return false;
|
||||
@ -109,10 +110,10 @@ static bool ParseGoogleMockFlag(const char* str, const char* flag_name,
|
||||
// On success, stores the value of the flag in *value, and returns
|
||||
// true. On failure, returns false without changing *value.
|
||||
template <typename String>
|
||||
static bool ParseGoogleMockFlag(const char* str, const char* flag_name,
|
||||
String* value) {
|
||||
static bool ParseGoogleMockStringFlag(const char* str, const char* flag,
|
||||
String* value) {
|
||||
// Gets the value of the flag as a string.
|
||||
const char* const value_str = ParseGoogleMockFlagValue(str, flag_name, false);
|
||||
const char* const value_str = ParseGoogleMockFlagValue(str, flag, false);
|
||||
|
||||
// Aborts if the parsing failed.
|
||||
if (value_str == nullptr) return false;
|
||||
@ -122,17 +123,17 @@ static bool ParseGoogleMockFlag(const char* str, const char* flag_name,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ParseGoogleMockFlag(const char* str, const char* flag_name,
|
||||
int32_t* value) {
|
||||
static bool ParseGoogleMockIntFlag(const char* str, const char* flag,
|
||||
int32_t* value) {
|
||||
// Gets the value of the flag as a string.
|
||||
const char* const value_str = ParseGoogleMockFlagValue(str, flag_name, true);
|
||||
const char* const value_str = ParseGoogleMockFlagValue(str, flag, true);
|
||||
|
||||
// Aborts if the parsing failed.
|
||||
if (value_str == nullptr) return false;
|
||||
|
||||
// Sets *value to the value of the flag.
|
||||
return ParseInt32(Message() << "The value of flag --" << flag_name, value_str,
|
||||
value);
|
||||
return ParseInt32(Message() << "The value of flag --" << flag,
|
||||
value_str, value);
|
||||
}
|
||||
|
||||
// The internal implementation of InitGoogleMock().
|
||||
@ -151,22 +152,11 @@ void InitGoogleMockImpl(int* argc, CharType** argv) {
|
||||
const char* const arg = arg_string.c_str();
|
||||
|
||||
// Do we see a Google Mock flag?
|
||||
bool found_gmock_flag = false;
|
||||
|
||||
#define GMOCK_INTERNAL_PARSE_FLAG(flag_name) \
|
||||
if (!found_gmock_flag) { \
|
||||
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) {
|
||||
if (ParseGoogleMockBoolFlag(arg, "catch_leaked_mocks",
|
||||
&GMOCK_FLAG(catch_leaked_mocks)) ||
|
||||
ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose)) ||
|
||||
ParseGoogleMockIntFlag(arg, "default_mock_behavior",
|
||||
&GMOCK_FLAG(default_mock_behavior))) {
|
||||
// Yes. Shift the remainder of the argv list left by one. Note
|
||||
// that argv has (*argc + 1) elements, the last one always being
|
||||
// NULL. The following loop moves the trailing NULL element as
|
||||
|
@ -30,6 +30,7 @@
|
||||
#
|
||||
# Bazel Build for Google C++ Testing Framework(Google Test)-googlemock
|
||||
|
||||
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test")
|
||||
load("@rules_python//python:defs.bzl", "py_library", "py_test")
|
||||
|
||||
licenses(["notice"])
|
||||
@ -40,7 +41,6 @@ cc_test(
|
||||
size = "small",
|
||||
srcs = glob(include = ["gmock-*.cc"]),
|
||||
linkopts = select({
|
||||
"//:qnx": [],
|
||||
"//:windows": [],
|
||||
"//conditions:default": ["-pthread"],
|
||||
}),
|
||||
|
@ -384,7 +384,7 @@ TEST(ActionInterfaceTest, MakeAction) {
|
||||
EXPECT_EQ(5, action.Perform(std::make_tuple(true, 5)));
|
||||
}
|
||||
|
||||
// Tests that Action<F> can be constructed from a pointer to
|
||||
// Tests that Action<F> can be contructed from a pointer to
|
||||
// ActionInterface<F>.
|
||||
TEST(ActionTest, CanBeConstructedFromActionInterface) {
|
||||
Action<MyGlobalFunction> action(new MyActionImpl);
|
||||
|
@ -361,27 +361,27 @@ TEST(ExpectTest, FailsNonfatallyOnFalse) {
|
||||
|
||||
class LogIsVisibleTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override { original_verbose_ = GMOCK_FLAG_GET(verbose); }
|
||||
void SetUp() override { original_verbose_ = GMOCK_FLAG(verbose); }
|
||||
|
||||
void TearDown() override { GMOCK_FLAG_SET(verbose, original_verbose_); }
|
||||
void TearDown() override { GMOCK_FLAG(verbose) = original_verbose_; }
|
||||
|
||||
std::string original_verbose_;
|
||||
};
|
||||
|
||||
TEST_F(LogIsVisibleTest, AlwaysReturnsTrueIfVerbosityIsInfo) {
|
||||
GMOCK_FLAG_SET(verbose, kInfoVerbosity);
|
||||
GMOCK_FLAG(verbose) = kInfoVerbosity;
|
||||
EXPECT_TRUE(LogIsVisible(kInfo));
|
||||
EXPECT_TRUE(LogIsVisible(kWarning));
|
||||
}
|
||||
|
||||
TEST_F(LogIsVisibleTest, AlwaysReturnsFalseIfVerbosityIsError) {
|
||||
GMOCK_FLAG_SET(verbose, kErrorVerbosity);
|
||||
GMOCK_FLAG(verbose) = kErrorVerbosity;
|
||||
EXPECT_FALSE(LogIsVisible(kInfo));
|
||||
EXPECT_FALSE(LogIsVisible(kWarning));
|
||||
}
|
||||
|
||||
TEST_F(LogIsVisibleTest, WorksWhenVerbosityIsWarning) {
|
||||
GMOCK_FLAG_SET(verbose, kWarningVerbosity);
|
||||
GMOCK_FLAG(verbose) = kWarningVerbosity;
|
||||
EXPECT_FALSE(LogIsVisible(kInfo));
|
||||
EXPECT_TRUE(LogIsVisible(kWarning));
|
||||
}
|
||||
@ -394,8 +394,8 @@ TEST_F(LogIsVisibleTest, WorksWhenVerbosityIsWarning) {
|
||||
// and log severity.
|
||||
void TestLogWithSeverity(const std::string& verbosity, LogSeverity severity,
|
||||
bool should_print) {
|
||||
const std::string old_flag = GMOCK_FLAG_GET(verbose);
|
||||
GMOCK_FLAG_SET(verbose, verbosity);
|
||||
const std::string old_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = verbosity;
|
||||
CaptureStdout();
|
||||
Log(severity, "Test log.\n", 0);
|
||||
if (should_print) {
|
||||
@ -407,18 +407,18 @@ void TestLogWithSeverity(const std::string& verbosity, LogSeverity severity,
|
||||
} else {
|
||||
EXPECT_STREQ("", GetCapturedStdout().c_str());
|
||||
}
|
||||
GMOCK_FLAG_SET(verbose, old_flag);
|
||||
GMOCK_FLAG(verbose) = old_flag;
|
||||
}
|
||||
|
||||
// Tests that when the stack_frames_to_skip parameter is negative,
|
||||
// Log() doesn't include the stack trace in the output.
|
||||
TEST(LogTest, NoStackTraceWhenStackFramesToSkipIsNegative) {
|
||||
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||
GMOCK_FLAG_SET(verbose, kInfoVerbosity);
|
||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = kInfoVerbosity;
|
||||
CaptureStdout();
|
||||
Log(kInfo, "Test log.\n", -1);
|
||||
EXPECT_STREQ("\nTest log.\n", GetCapturedStdout().c_str());
|
||||
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||
GMOCK_FLAG(verbose) = saved_flag;
|
||||
}
|
||||
|
||||
struct MockStackTraceGetter : testing::internal::OsStackTraceGetterInterface {
|
||||
@ -440,8 +440,7 @@ TEST(LogTest, NoSkippingStackFrameInOptMode) {
|
||||
const std::string log = GetCapturedStdout();
|
||||
|
||||
std::string expected_trace =
|
||||
(testing::Message() << GTEST_FLAG_GET(stack_trace_depth) << "::")
|
||||
.GetString();
|
||||
(testing::Message() << GTEST_FLAG(stack_trace_depth) << "::").GetString();
|
||||
std::string expected_message =
|
||||
"\nGMOCK WARNING:\n"
|
||||
"Test log.\n"
|
||||
@ -499,11 +498,11 @@ TEST(LogTest, OnlyWarningsArePrintedWhenVerbosityIsInvalid) {
|
||||
// Verifies that Log() behaves correctly for the given verbosity level
|
||||
// and log severity.
|
||||
std::string GrabOutput(void(*logger)(), const char* verbosity) {
|
||||
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||
GMOCK_FLAG_SET(verbose, verbosity);
|
||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = verbosity;
|
||||
CaptureStdout();
|
||||
logger();
|
||||
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||
GMOCK_FLAG(verbose) = saved_flag;
|
||||
return GetCapturedStdout();
|
||||
}
|
||||
|
||||
@ -716,46 +715,6 @@ TEST(FunctionTest, LongArgumentList) {
|
||||
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 internal
|
||||
} // namespace testing
|
||||
|
@ -114,32 +114,31 @@ std::vector<std::unique_ptr<int>> MakeUniquePtrs(const std::vector<int>& ints) {
|
||||
}
|
||||
|
||||
// For testing ExplainMatchResultTo().
|
||||
template <typename T = int>
|
||||
class GreaterThanMatcher : public MatcherInterface<T> {
|
||||
class GreaterThanMatcher : public MatcherInterface<int> {
|
||||
public:
|
||||
explicit GreaterThanMatcher(T rhs) : rhs_(rhs) {}
|
||||
explicit GreaterThanMatcher(int rhs) : rhs_(rhs) {}
|
||||
|
||||
void DescribeTo(ostream* os) const override { *os << "is > " << rhs_; }
|
||||
|
||||
bool MatchAndExplain(T lhs, MatchResultListener* listener) const override {
|
||||
if (lhs > rhs_) {
|
||||
*listener << "which is " << (lhs - rhs_) << " more than " << rhs_;
|
||||
} else if (lhs == rhs_) {
|
||||
bool MatchAndExplain(int lhs, MatchResultListener* listener) const override {
|
||||
const int diff = lhs - rhs_;
|
||||
if (diff > 0) {
|
||||
*listener << "which is " << diff << " more than " << rhs_;
|
||||
} else if (diff == 0) {
|
||||
*listener << "which is the same as " << rhs_;
|
||||
} else {
|
||||
*listener << "which is " << (rhs_ - lhs) << " less than " << rhs_;
|
||||
*listener << "which is " << -diff << " less than " << rhs_;
|
||||
}
|
||||
|
||||
return lhs > rhs_;
|
||||
}
|
||||
|
||||
private:
|
||||
const T rhs_;
|
||||
int rhs_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
Matcher<T> GreaterThan(T n) {
|
||||
return MakeMatcher(new GreaterThanMatcher<T>(n));
|
||||
Matcher<int> GreaterThan(int n) {
|
||||
return MakeMatcher(new GreaterThanMatcher(n));
|
||||
}
|
||||
|
||||
std::string OfType(const std::string& type_name) {
|
||||
@ -1866,33 +1865,6 @@ TEST(EndsWithTest, CanDescribeSelf) {
|
||||
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().
|
||||
|
||||
TEST(MatchesRegexTest, MatchesStringMatchingGivenRegex) {
|
||||
@ -2799,34 +2771,6 @@ TEST(AnyOfTest, VariadicMatchesWhenAnyMatches) {
|
||||
"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
|
||||
TEST(ElementsAreTest, HugeMatcher) {
|
||||
vector<int> test_vector{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||
@ -5424,14 +5368,12 @@ class Streamlike {
|
||||
}
|
||||
|
||||
private:
|
||||
class ConstIter {
|
||||
class ConstIter : public std::iterator<std::input_iterator_tag,
|
||||
value_type,
|
||||
ptrdiff_t,
|
||||
const value_type*,
|
||||
const value_type&> {
|
||||
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,
|
||||
typename std::list<value_type>::iterator pos)
|
||||
: s_(s), pos_(pos) {}
|
||||
@ -6385,7 +6327,7 @@ TEST_P(BipartiteRandomTest, LargerNets) {
|
||||
int iters = GetParam().second;
|
||||
MatchMatrix graph(static_cast<size_t>(nodes), static_cast<size_t>(nodes));
|
||||
|
||||
auto seed = static_cast<uint32_t>(GTEST_FLAG_GET(random_seed));
|
||||
auto seed = static_cast<uint32_t>(GTEST_FLAG(random_seed));
|
||||
if (seed == 0) {
|
||||
seed = static_cast<uint32_t>(time(nullptr));
|
||||
}
|
||||
@ -7289,7 +7231,7 @@ TEST(ElementsAreTest, CanDescribeNegationOfExpectingNoElement) {
|
||||
EXPECT_EQ("isn't empty", DescribeNegation(m));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, CanDescribeNegationOfExpectingOneElement) {
|
||||
TEST(ElementsAreTest, CanDescribeNegationOfExpectingOneElment) {
|
||||
Matcher<const list<int>&> m = ElementsAre(Gt(5));
|
||||
EXPECT_EQ(
|
||||
"doesn't have 1 element, or\n"
|
||||
@ -8081,7 +8023,6 @@ TEST(ContainsTest, ListMatchesWhenElementIsInContainer) {
|
||||
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(1));
|
||||
EXPECT_THAT(some_list, Contains(Gt(2.5)));
|
||||
EXPECT_THAT(some_list, Contains(Eq(2.0f)));
|
||||
@ -8206,79 +8147,6 @@ TEST(ContainsTest, WorksForTwoDimensionalNativeArray) {
|
||||
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) {
|
||||
// Iterator
|
||||
std::vector<int> v0{};
|
||||
@ -8407,7 +8275,7 @@ TEST(AnyOfArrayTest, ExplainsMatchResultCorrectly) {
|
||||
// Explain with matchers
|
||||
const Matcher<int> g1 = AnyOfArray({GreaterThan(1)});
|
||||
const Matcher<int> g2 = AnyOfArray({GreaterThan(1), GreaterThan(2)});
|
||||
// Explains the first positive match and all prior negative matches...
|
||||
// Explains the first positiv match and all prior negative matches...
|
||||
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 1 more than 1", Explain(g1, 2));
|
||||
@ -8517,12 +8385,6 @@ TEST(ThrowsTest, Examples) {
|
||||
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) {
|
||||
EXPECT_THAT(std::function<void()>([]() { throw std::exception(); }),
|
||||
Throws<std::exception>());
|
||||
@ -8638,6 +8500,15 @@ TEST_P(ThrowsPredicateTest, FailWrongTypeNonStd) {
|
||||
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) {
|
||||
Matcher<std::function<void()>> matcher = GetParam();
|
||||
StringMatchResultListener listener;
|
||||
|
@ -50,6 +50,7 @@ class Mock {
|
||||
namespace testing {
|
||||
namespace gmock_nice_strict_test {
|
||||
|
||||
using testing::GMOCK_FLAG(verbose);
|
||||
using testing::HasSubstr;
|
||||
using testing::NaggyMock;
|
||||
using testing::NiceMock;
|
||||
@ -139,8 +140,8 @@ class MockBaz {
|
||||
|
||||
// Tests that a raw mock generates warnings for uninteresting calls.
|
||||
TEST(RawMockTest, WarningForUninterestingCall) {
|
||||
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||
GMOCK_FLAG_SET(verbose, "warning");
|
||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = "warning";
|
||||
|
||||
MockFoo raw_foo;
|
||||
|
||||
@ -150,14 +151,14 @@ TEST(RawMockTest, WarningForUninterestingCall) {
|
||||
EXPECT_THAT(GetCapturedStdout(),
|
||||
HasSubstr("Uninteresting mock function call"));
|
||||
|
||||
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||
GMOCK_FLAG(verbose) = saved_flag;
|
||||
}
|
||||
|
||||
// Tests that a raw mock generates warnings for uninteresting calls
|
||||
// that delete the mock object.
|
||||
TEST(RawMockTest, WarningForUninterestingCallAfterDeath) {
|
||||
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||
GMOCK_FLAG_SET(verbose, "warning");
|
||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = "warning";
|
||||
|
||||
MockFoo* const raw_foo = new MockFoo;
|
||||
|
||||
@ -169,7 +170,7 @@ TEST(RawMockTest, WarningForUninterestingCallAfterDeath) {
|
||||
EXPECT_THAT(GetCapturedStdout(),
|
||||
HasSubstr("Uninteresting mock function call"));
|
||||
|
||||
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||
GMOCK_FLAG(verbose) = saved_flag;
|
||||
}
|
||||
|
||||
// Tests that a raw mock generates informational logs for
|
||||
@ -177,14 +178,14 @@ TEST(RawMockTest, WarningForUninterestingCallAfterDeath) {
|
||||
TEST(RawMockTest, InfoForUninterestingCall) {
|
||||
MockFoo raw_foo;
|
||||
|
||||
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||
GMOCK_FLAG_SET(verbose, "info");
|
||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = "info";
|
||||
CaptureStdout();
|
||||
raw_foo.DoThis();
|
||||
EXPECT_THAT(GetCapturedStdout(),
|
||||
HasSubstr("Uninteresting mock function call"));
|
||||
|
||||
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||
GMOCK_FLAG(verbose) = saved_flag;
|
||||
}
|
||||
|
||||
TEST(RawMockTest, IsNaggy_IsNice_IsStrict) {
|
||||
@ -222,14 +223,14 @@ TEST(NiceMockTest, NoWarningForUninterestingCallAfterDeath) {
|
||||
TEST(NiceMockTest, InfoForUninterestingCall) {
|
||||
NiceMock<MockFoo> nice_foo;
|
||||
|
||||
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||
GMOCK_FLAG_SET(verbose, "info");
|
||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = "info";
|
||||
CaptureStdout();
|
||||
nice_foo.DoThis();
|
||||
EXPECT_THAT(GetCapturedStdout(),
|
||||
HasSubstr("Uninteresting mock function call"));
|
||||
|
||||
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||
GMOCK_FLAG(verbose) = saved_flag;
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_STREAM_REDIRECTION
|
||||
@ -325,8 +326,8 @@ TEST(NiceMockTest, IsNaggy_IsNice_IsStrict) {
|
||||
|
||||
// Tests that a naggy mock generates warnings for uninteresting calls.
|
||||
TEST(NaggyMockTest, WarningForUninterestingCall) {
|
||||
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||
GMOCK_FLAG_SET(verbose, "warning");
|
||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = "warning";
|
||||
|
||||
NaggyMock<MockFoo> naggy_foo;
|
||||
|
||||
@ -336,14 +337,14 @@ TEST(NaggyMockTest, WarningForUninterestingCall) {
|
||||
EXPECT_THAT(GetCapturedStdout(),
|
||||
HasSubstr("Uninteresting mock function call"));
|
||||
|
||||
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||
GMOCK_FLAG(verbose) = saved_flag;
|
||||
}
|
||||
|
||||
// Tests that a naggy mock generates a warning for an uninteresting call
|
||||
// that deletes the mock object.
|
||||
TEST(NaggyMockTest, WarningForUninterestingCallAfterDeath) {
|
||||
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||
GMOCK_FLAG_SET(verbose, "warning");
|
||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = "warning";
|
||||
|
||||
NaggyMock<MockFoo>* const naggy_foo = new NaggyMock<MockFoo>;
|
||||
|
||||
@ -355,7 +356,7 @@ TEST(NaggyMockTest, WarningForUninterestingCallAfterDeath) {
|
||||
EXPECT_THAT(GetCapturedStdout(),
|
||||
HasSubstr("Uninteresting mock function call"));
|
||||
|
||||
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||
GMOCK_FLAG(verbose) = saved_flag;
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_STREAM_REDIRECTION
|
||||
@ -418,8 +419,8 @@ TEST(NaggyMockTest, AcceptsClassNamedMock) {
|
||||
}
|
||||
|
||||
TEST(NaggyMockTest, IsNaggyInDestructor) {
|
||||
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
|
||||
GMOCK_FLAG_SET(verbose, "warning");
|
||||
const std::string saved_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = "warning";
|
||||
CaptureStdout();
|
||||
|
||||
{
|
||||
@ -430,7 +431,7 @@ TEST(NaggyMockTest, IsNaggyInDestructor) {
|
||||
EXPECT_THAT(GetCapturedStdout(),
|
||||
HasSubstr("Uninteresting mock function call"));
|
||||
|
||||
GMOCK_FLAG_SET(verbose, saved_flag);
|
||||
GMOCK_FLAG(verbose) = saved_flag;
|
||||
}
|
||||
|
||||
TEST(NaggyMockTest, IsNaggy_IsNice_IsStrict) {
|
||||
|
@ -76,6 +76,7 @@ using testing::DoDefault;
|
||||
using testing::Eq;
|
||||
using testing::Expectation;
|
||||
using testing::ExpectationSet;
|
||||
using testing::GMOCK_FLAG(verbose);
|
||||
using testing::Gt;
|
||||
using testing::IgnoreResult;
|
||||
using testing::InSequence;
|
||||
@ -390,7 +391,7 @@ TEST(ExpectCallSyntaxTest, TimesMustBeBeforeInSequence) {
|
||||
EXPECT_CALL(a, DoA(1))
|
||||
.InSequence(s)
|
||||
.Times(1);
|
||||
}, ".Times() may only appear *before* ");
|
||||
}, ".Times() cannot appear after ");
|
||||
|
||||
a.DoA(1);
|
||||
}
|
||||
@ -695,9 +696,9 @@ TEST(ExpectCallSyntaxTest, WarnsOnTooFewActions) {
|
||||
}
|
||||
|
||||
TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
|
||||
int original_behavior = GMOCK_FLAG_GET(default_mock_behavior);
|
||||
int original_behavior = testing::GMOCK_FLAG(default_mock_behavior);
|
||||
|
||||
GMOCK_FLAG_SET(default_mock_behavior, kAllow);
|
||||
testing::GMOCK_FLAG(default_mock_behavior) = kAllow;
|
||||
CaptureStdout();
|
||||
{
|
||||
MockA a;
|
||||
@ -706,7 +707,7 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
|
||||
std::string output = GetCapturedStdout();
|
||||
EXPECT_TRUE(output.empty()) << output;
|
||||
|
||||
GMOCK_FLAG_SET(default_mock_behavior, kWarn);
|
||||
testing::GMOCK_FLAG(default_mock_behavior) = kWarn;
|
||||
CaptureStdout();
|
||||
{
|
||||
MockA a;
|
||||
@ -717,14 +718,14 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call",
|
||||
warning_output);
|
||||
|
||||
GMOCK_FLAG_SET(default_mock_behavior, kFail);
|
||||
testing::GMOCK_FLAG(default_mock_behavior) = kFail;
|
||||
EXPECT_NONFATAL_FAILURE({
|
||||
MockA a;
|
||||
a.DoA(0);
|
||||
}, "Uninteresting mock function call");
|
||||
|
||||
// Out of bounds values are converted to kWarn
|
||||
GMOCK_FLAG_SET(default_mock_behavior, -1);
|
||||
testing::GMOCK_FLAG(default_mock_behavior) = -1;
|
||||
CaptureStdout();
|
||||
{
|
||||
MockA a;
|
||||
@ -734,7 +735,7 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "GMOCK WARNING", warning_output);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call",
|
||||
warning_output);
|
||||
GMOCK_FLAG_SET(default_mock_behavior, 3);
|
||||
testing::GMOCK_FLAG(default_mock_behavior) = 3;
|
||||
CaptureStdout();
|
||||
{
|
||||
MockA a;
|
||||
@ -745,7 +746,7 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call",
|
||||
warning_output);
|
||||
|
||||
GMOCK_FLAG_SET(default_mock_behavior, original_behavior);
|
||||
testing::GMOCK_FLAG(default_mock_behavior) = original_behavior;
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_STREAM_REDIRECTION
|
||||
@ -2023,10 +2024,10 @@ class MockC {
|
||||
class VerboseFlagPreservingFixture : public testing::Test {
|
||||
protected:
|
||||
VerboseFlagPreservingFixture()
|
||||
: saved_verbose_flag_(GMOCK_FLAG_GET(verbose)) {}
|
||||
: saved_verbose_flag_(GMOCK_FLAG(verbose)) {}
|
||||
|
||||
~VerboseFlagPreservingFixture() override {
|
||||
GMOCK_FLAG_SET(verbose, saved_verbose_flag_);
|
||||
GMOCK_FLAG(verbose) = saved_verbose_flag_;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -2042,7 +2043,7 @@ class VerboseFlagPreservingFixture : public testing::Test {
|
||||
// --gmock_verbose=warning is specified.
|
||||
TEST(FunctionCallMessageTest,
|
||||
UninterestingCallOnNaggyMockGeneratesNoStackTraceWhenVerboseWarning) {
|
||||
GMOCK_FLAG_SET(verbose, kWarningVerbosity);
|
||||
GMOCK_FLAG(verbose) = kWarningVerbosity;
|
||||
NaggyMock<MockC> c;
|
||||
CaptureStdout();
|
||||
c.VoidMethod(false, 5, "Hi", nullptr, Printable(), Unprintable());
|
||||
@ -2056,7 +2057,7 @@ TEST(FunctionCallMessageTest,
|
||||
// --gmock_verbose=info is specified.
|
||||
TEST(FunctionCallMessageTest,
|
||||
UninterestingCallOnNaggyMockGeneratesFyiWithStackTraceWhenVerboseInfo) {
|
||||
GMOCK_FLAG_SET(verbose, kInfoVerbosity);
|
||||
GMOCK_FLAG(verbose) = kInfoVerbosity;
|
||||
NaggyMock<MockC> c;
|
||||
CaptureStdout();
|
||||
c.VoidMethod(false, 5, "Hi", nullptr, Printable(), Unprintable());
|
||||
@ -2212,7 +2213,7 @@ class GMockVerboseFlagTest : public VerboseFlagPreservingFixture {
|
||||
// Tests that --gmock_verbose=info causes both expected and
|
||||
// uninteresting calls to be reported.
|
||||
TEST_F(GMockVerboseFlagTest, Info) {
|
||||
GMOCK_FLAG_SET(verbose, kInfoVerbosity);
|
||||
GMOCK_FLAG(verbose) = kInfoVerbosity;
|
||||
TestExpectedCall(true);
|
||||
TestUninterestingCallOnNaggyMock(true);
|
||||
}
|
||||
@ -2220,7 +2221,7 @@ TEST_F(GMockVerboseFlagTest, Info) {
|
||||
// Tests that --gmock_verbose=warning causes uninteresting calls to be
|
||||
// reported.
|
||||
TEST_F(GMockVerboseFlagTest, Warning) {
|
||||
GMOCK_FLAG_SET(verbose, kWarningVerbosity);
|
||||
GMOCK_FLAG(verbose) = kWarningVerbosity;
|
||||
TestExpectedCall(false);
|
||||
TestUninterestingCallOnNaggyMock(true);
|
||||
}
|
||||
@ -2228,7 +2229,7 @@ TEST_F(GMockVerboseFlagTest, Warning) {
|
||||
// Tests that --gmock_verbose=warning causes neither expected nor
|
||||
// uninteresting calls to be reported.
|
||||
TEST_F(GMockVerboseFlagTest, Error) {
|
||||
GMOCK_FLAG_SET(verbose, kErrorVerbosity);
|
||||
GMOCK_FLAG(verbose) = kErrorVerbosity;
|
||||
TestExpectedCall(false);
|
||||
TestUninterestingCallOnNaggyMock(false);
|
||||
}
|
||||
@ -2236,7 +2237,7 @@ TEST_F(GMockVerboseFlagTest, Error) {
|
||||
// Tests that --gmock_verbose=SOME_INVALID_VALUE has the same effect
|
||||
// as --gmock_verbose=warning.
|
||||
TEST_F(GMockVerboseFlagTest, InvalidFlagIsTreatedAsWarning) {
|
||||
GMOCK_FLAG_SET(verbose, "invalid"); // Treated as "warning".
|
||||
GMOCK_FLAG(verbose) = "invalid"; // Treated as "warning".
|
||||
TestExpectedCall(false);
|
||||
TestUninterestingCallOnNaggyMock(true);
|
||||
}
|
||||
@ -2269,21 +2270,21 @@ class GMockLogTest : public VerboseFlagPreservingFixture {
|
||||
};
|
||||
|
||||
TEST_F(GMockLogTest, DoesNotPrintGoodCallInternallyIfVerbosityIsWarning) {
|
||||
GMOCK_FLAG_SET(verbose, kWarningVerbosity);
|
||||
GMOCK_FLAG(verbose) = kWarningVerbosity;
|
||||
EXPECT_CALL(helper_, Foo(_))
|
||||
.WillOnce(Return(PrintMeNot()));
|
||||
helper_.Foo(PrintMeNot()); // This is an expected call.
|
||||
}
|
||||
|
||||
TEST_F(GMockLogTest, DoesNotPrintGoodCallInternallyIfVerbosityIsError) {
|
||||
GMOCK_FLAG_SET(verbose, kErrorVerbosity);
|
||||
GMOCK_FLAG(verbose) = kErrorVerbosity;
|
||||
EXPECT_CALL(helper_, Foo(_))
|
||||
.WillOnce(Return(PrintMeNot()));
|
||||
helper_.Foo(PrintMeNot()); // This is an expected call.
|
||||
}
|
||||
|
||||
TEST_F(GMockLogTest, DoesNotPrintWarningInternallyIfVerbosityIsError) {
|
||||
GMOCK_FLAG_SET(verbose, kErrorVerbosity);
|
||||
GMOCK_FLAG(verbose) = kErrorVerbosity;
|
||||
ON_CALL(helper_, Foo(_))
|
||||
.WillByDefault(Return(PrintMeNot()));
|
||||
helper_.Foo(PrintMeNot()); // This should generate a warning.
|
||||
@ -2767,8 +2768,8 @@ int main(int argc, char **argv) {
|
||||
testing::InitGoogleMock(&argc, argv);
|
||||
// Ensures that the tests pass no matter what value of
|
||||
// --gmock_catch_leaked_mocks and --gmock_verbose the user specifies.
|
||||
GMOCK_FLAG_SET(catch_leaked_mocks, true);
|
||||
GMOCK_FLAG_SET(verbose, testing::internal::kWarningVerbosity);
|
||||
testing::GMOCK_FLAG(catch_leaked_mocks) = true;
|
||||
testing::GMOCK_FLAG(verbose) = testing::internal::kWarningVerbosity;
|
||||
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
@ -72,21 +72,21 @@ class GMockOutputTest : public testing::Test {
|
||||
};
|
||||
|
||||
TEST_F(GMockOutputTest, ExpectedCall) {
|
||||
GMOCK_FLAG_SET(verbose, "info");
|
||||
testing::GMOCK_FLAG(verbose) = "info";
|
||||
|
||||
EXPECT_CALL(foo_, Bar2(0, _));
|
||||
foo_.Bar2(0, 0); // Expected call
|
||||
|
||||
GMOCK_FLAG_SET(verbose, "warning");
|
||||
testing::GMOCK_FLAG(verbose) = "warning";
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, ExpectedCallToVoidFunction) {
|
||||
GMOCK_FLAG_SET(verbose, "info");
|
||||
testing::GMOCK_FLAG(verbose) = "info";
|
||||
|
||||
EXPECT_CALL(foo_, Bar3(0, _));
|
||||
foo_.Bar3(0, 0); // Expected call
|
||||
|
||||
GMOCK_FLAG_SET(verbose, "warning");
|
||||
testing::GMOCK_FLAG(verbose) = "warning";
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, ExplicitActionsRunOut) {
|
||||
@ -297,8 +297,8 @@ int main(int argc, char **argv) {
|
||||
testing::InitGoogleMock(&argc, argv);
|
||||
// Ensures that the tests pass no matter what value of
|
||||
// --gmock_catch_leaked_mocks and --gmock_verbose the user specifies.
|
||||
GMOCK_FLAG_SET(catch_leaked_mocks, true);
|
||||
GMOCK_FLAG_SET(verbose, "warning");
|
||||
testing::GMOCK_FLAG(catch_leaked_mocks) = true;
|
||||
testing::GMOCK_FLAG(verbose) = "warning";
|
||||
|
||||
TestCatchesLeakedMocksInAdHocTests();
|
||||
return RUN_ALL_TESTS();
|
||||
|
@ -40,6 +40,8 @@
|
||||
|
||||
#if !defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
||||
|
||||
using testing::GMOCK_FLAG(default_mock_behavior);
|
||||
using testing::GMOCK_FLAG(verbose);
|
||||
using testing::InitGoogleMock;
|
||||
|
||||
// Verifies that calling InitGoogleMock() on argv results in new_argv,
|
||||
@ -47,7 +49,7 @@ using testing::InitGoogleMock;
|
||||
template <typename Char, int M, int N>
|
||||
void TestInitGoogleMock(const Char* (&argv)[M], const Char* (&new_argv)[N],
|
||||
const ::std::string& expected_gmock_verbose) {
|
||||
const ::std::string old_verbose = GMOCK_FLAG_GET(verbose);
|
||||
const ::std::string old_verbose = GMOCK_FLAG(verbose);
|
||||
|
||||
int argc = M - 1;
|
||||
InitGoogleMock(&argc, const_cast<Char**>(argv));
|
||||
@ -57,8 +59,8 @@ void TestInitGoogleMock(const Char* (&argv)[M], const Char* (&new_argv)[N],
|
||||
EXPECT_STREQ(new_argv[i], argv[i]);
|
||||
}
|
||||
|
||||
EXPECT_EQ(expected_gmock_verbose, GMOCK_FLAG_GET(verbose));
|
||||
GMOCK_FLAG_SET(verbose, old_verbose); // Restores the gmock_verbose flag.
|
||||
EXPECT_EQ(expected_gmock_verbose, GMOCK_FLAG(verbose).c_str());
|
||||
GMOCK_FLAG(verbose) = old_verbose; // Restores the gmock_verbose flag.
|
||||
}
|
||||
|
||||
TEST(InitGoogleMockTest, ParsesInvalidCommandLine) {
|
||||
@ -66,7 +68,7 @@ TEST(InitGoogleMockTest, ParsesInvalidCommandLine) {
|
||||
|
||||
const char* new_argv[] = {nullptr};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG_GET(verbose));
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
||||
}
|
||||
|
||||
TEST(InitGoogleMockTest, ParsesEmptyCommandLine) {
|
||||
@ -74,7 +76,7 @@ TEST(InitGoogleMockTest, ParsesEmptyCommandLine) {
|
||||
|
||||
const char* new_argv[] = {"foo.exe", nullptr};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG_GET(verbose));
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
||||
}
|
||||
|
||||
TEST(InitGoogleMockTest, ParsesSingleFlag) {
|
||||
@ -86,16 +88,16 @@ TEST(InitGoogleMockTest, ParsesSingleFlag) {
|
||||
}
|
||||
|
||||
TEST(InitGoogleMockTest, ParsesMultipleFlags) {
|
||||
int old_default_behavior = GMOCK_FLAG_GET(default_mock_behavior);
|
||||
int old_default_behavior = GMOCK_FLAG(default_mock_behavior);
|
||||
const wchar_t* argv[] = {L"foo.exe", L"--gmock_verbose=info",
|
||||
L"--gmock_default_mock_behavior=2", nullptr};
|
||||
|
||||
const wchar_t* new_argv[] = {L"foo.exe", nullptr};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, "info");
|
||||
EXPECT_EQ(2, GMOCK_FLAG_GET(default_mock_behavior));
|
||||
EXPECT_EQ(2, GMOCK_FLAG(default_mock_behavior));
|
||||
EXPECT_NE(2, old_default_behavior);
|
||||
GMOCK_FLAG_SET(default_mock_behavior, old_default_behavior);
|
||||
GMOCK_FLAG(default_mock_behavior) = old_default_behavior;
|
||||
}
|
||||
|
||||
TEST(InitGoogleMockTest, ParsesUnrecognizedFlag) {
|
||||
@ -103,7 +105,7 @@ TEST(InitGoogleMockTest, ParsesUnrecognizedFlag) {
|
||||
|
||||
const char* new_argv[] = {"foo.exe", "--non_gmock_flag=blah", nullptr};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG_GET(verbose));
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
||||
}
|
||||
|
||||
TEST(InitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
|
||||
@ -120,7 +122,7 @@ TEST(WideInitGoogleMockTest, ParsesInvalidCommandLine) {
|
||||
|
||||
const wchar_t* new_argv[] = {nullptr};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG_GET(verbose));
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
||||
}
|
||||
|
||||
TEST(WideInitGoogleMockTest, ParsesEmptyCommandLine) {
|
||||
@ -128,7 +130,7 @@ TEST(WideInitGoogleMockTest, ParsesEmptyCommandLine) {
|
||||
|
||||
const wchar_t* new_argv[] = {L"foo.exe", nullptr};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG_GET(verbose));
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
||||
}
|
||||
|
||||
TEST(WideInitGoogleMockTest, ParsesSingleFlag) {
|
||||
@ -140,16 +142,16 @@ TEST(WideInitGoogleMockTest, ParsesSingleFlag) {
|
||||
}
|
||||
|
||||
TEST(WideInitGoogleMockTest, ParsesMultipleFlags) {
|
||||
int old_default_behavior = GMOCK_FLAG_GET(default_mock_behavior);
|
||||
int old_default_behavior = GMOCK_FLAG(default_mock_behavior);
|
||||
const wchar_t* argv[] = {L"foo.exe", L"--gmock_verbose=info",
|
||||
L"--gmock_default_mock_behavior=2", nullptr};
|
||||
|
||||
const wchar_t* new_argv[] = {L"foo.exe", nullptr};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, "info");
|
||||
EXPECT_EQ(2, GMOCK_FLAG_GET(default_mock_behavior));
|
||||
EXPECT_EQ(2, GMOCK_FLAG(default_mock_behavior));
|
||||
EXPECT_NE(2, old_default_behavior);
|
||||
GMOCK_FLAG_SET(default_mock_behavior, old_default_behavior);
|
||||
GMOCK_FLAG(default_mock_behavior) = old_default_behavior;
|
||||
}
|
||||
|
||||
TEST(WideInitGoogleMockTest, ParsesUnrecognizedFlag) {
|
||||
@ -157,7 +159,7 @@ TEST(WideInitGoogleMockTest, ParsesUnrecognizedFlag) {
|
||||
|
||||
const wchar_t* new_argv[] = {L"foo.exe", L"--non_gmock_flag=blah", nullptr};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG_GET(verbose));
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
||||
}
|
||||
|
||||
TEST(WideInitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
|
||||
@ -173,7 +175,7 @@ TEST(WideInitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
|
||||
|
||||
// Makes sure Google Mock flags can be accessed in code.
|
||||
TEST(FlagTest, IsAccessibleInCode) {
|
||||
bool dummy =
|
||||
GMOCK_FLAG_GET(catch_leaked_mocks) && GMOCK_FLAG_GET(verbose) == "";
|
||||
bool dummy = testing::GMOCK_FLAG(catch_leaked_mocks) &&
|
||||
testing::GMOCK_FLAG(verbose) == "";
|
||||
(void)dummy; // Avoids the "unused local variable" warning.
|
||||
}
|
||||
|
@ -46,9 +46,14 @@ endif()
|
||||
|
||||
# Project version:
|
||||
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
cmake_policy(SET CMP0048 NEW)
|
||||
project(gtest VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)
|
||||
if (CMAKE_VERSION VERSION_LESS 3.0)
|
||||
project(gtest CXX C)
|
||||
set(PROJECT_VERSION ${GOOGLETEST_VERSION})
|
||||
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
|
||||
cmake_policy(SET CMP0063 NEW)
|
||||
|
@ -25,7 +25,7 @@ When building GoogleTest as a standalone project, the typical workflow starts
|
||||
with
|
||||
|
||||
```
|
||||
git clone https://github.com/google/googletest.git -b release-1.11.0
|
||||
git clone https://github.com/google/googletest.git -b release-1.10.0
|
||||
cd googletest # Main directory of the cloned repository.
|
||||
mkdir build # Create a directory to hold the build output.
|
||||
cd build
|
||||
@ -203,9 +203,7 @@ add
|
||||
-DGTEST_DONT_DEFINE_FOO=1
|
||||
|
||||
to the compiler flags to tell GoogleTest to change the macro's name from `FOO`
|
||||
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
|
||||
to `GTEST_FOO`. Currently `FOO` can be `FAIL`, `SUCCEED`, or `TEST`. For
|
||||
example, with `-DGTEST_DONT_DEFINE_TEST=1`, you'll need to write
|
||||
|
||||
GTEST_TEST(SomeTest, DoesThis) { ... }
|
||||
|
@ -84,13 +84,13 @@ macro(config_compiler_and_linker)
|
||||
# Ensure MSVC treats source files as UTF-8 encoded.
|
||||
set(cxx_base_flags "${cxx_base_flags} -utf-8")
|
||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
set(cxx_base_flags "-Wall -Wshadow -Wconversion")
|
||||
set(cxx_base_flags "-Wall -Wshadow -Werror -Wconversion")
|
||||
set(cxx_exception_flags "-fexceptions")
|
||||
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_no_rtti_flags "-fno-rtti")
|
||||
elseif (CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(cxx_base_flags "-Wall -Wshadow")
|
||||
set(cxx_base_flags "-Wall -Wshadow -Werror")
|
||||
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0)
|
||||
set(cxx_base_flags "${cxx_base_flags} -Wno-error=dangling-else")
|
||||
endif()
|
||||
|
@ -33,12 +33,15 @@
|
||||
// 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
|
||||
// directly.
|
||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
||||
|
||||
#include "gtest/internal/gtest-death-test-internal.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
// 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
|
||||
// from the start, running only a single death test, or "fast",
|
||||
@ -46,8 +49,6 @@
|
||||
// after forking.
|
||||
GTEST_DECLARE_string_(death_test_style);
|
||||
|
||||
namespace testing {
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
|
||||
namespace internal {
|
||||
@ -102,6 +103,7 @@ GTEST_API_ bool InDeathTestChild();
|
||||
//
|
||||
// On the regular expressions used in death tests:
|
||||
//
|
||||
// GOOGLETEST_CM0005 DO NOT DELETE
|
||||
// On POSIX-compliant systems (*nix), we use the <regex.h> library,
|
||||
// which uses the POSIX extended regex syntax.
|
||||
//
|
||||
@ -202,6 +204,7 @@ class GTEST_API_ ExitedWithCode {
|
||||
# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
|
||||
// Tests that an exit code describes an exit due to termination by a
|
||||
// given signal.
|
||||
// GOOGLETEST_CM0006 DO NOT DELETE
|
||||
class GTEST_API_ KilledBySignal {
|
||||
public:
|
||||
explicit KilledBySignal(int signum);
|
||||
|
@ -42,6 +42,8 @@
|
||||
// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user
|
||||
// program!
|
||||
|
||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
|
||||
|
||||
|
@ -29,6 +29,8 @@
|
||||
//
|
||||
// Macros and functions for implementing parameterized tests
|
||||
// in Google C++ Testing and Mocking Framework (Google Test)
|
||||
//
|
||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
||||
|
||||
|
@ -95,6 +95,8 @@
|
||||
// being defined as many user-defined container types don't have
|
||||
// value_type.
|
||||
|
||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
||||
|
||||
@ -358,7 +360,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_(wchar_t);
|
||||
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t);
|
||||
#ifdef __cpp_lib_char8_t
|
||||
#ifdef __cpp_char8_t
|
||||
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char8_t);
|
||||
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char8_t);
|
||||
#endif
|
||||
@ -477,12 +479,6 @@ inline void PrintTo(char8_t c, ::std::ostream* os) {
|
||||
}
|
||||
#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.
|
||||
GTEST_API_ void PrintTo(const char* s, ::std::ostream* os);
|
||||
inline void PrintTo(char* s, ::std::ostream* os) {
|
||||
@ -591,12 +587,6 @@ inline void PrintTo(internal::StringView sp, ::std::ostream* os) {
|
||||
|
||||
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>
|
||||
void PrintTo(std::reference_wrapper<T> ref, ::std::ostream* os) {
|
||||
UniversalPrinter<T&>::Print(ref.get(), os);
|
||||
@ -754,14 +744,6 @@ 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
|
||||
|
||||
#if GTEST_INTERNAL_HAS_VARIANT
|
||||
|
@ -31,6 +31,8 @@
|
||||
// Utilities for testing Google Test itself and code that uses Google Test
|
||||
// (e.g. frameworks built on top of Google Test).
|
||||
|
||||
// GOOGLETEST_CM0004 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_
|
||||
|
||||
|
@ -26,6 +26,8 @@
|
||||
// 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.
|
||||
//
|
||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
||||
|
@ -27,6 +27,8 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// 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_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
|
||||
|
||||
|
@ -47,6 +47,8 @@
|
||||
// registration from Barthelemy Dagenais' (barthelemy@prologique.com)
|
||||
// easyUnit framework.
|
||||
|
||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_H_
|
||||
|
||||
@ -71,6 +73,17 @@
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||
/* 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.
|
||||
|
||||
// This flag temporary enables the disabled tests.
|
||||
@ -125,12 +138,6 @@ GTEST_DECLARE_int32_(random_seed);
|
||||
// is 1. If the value is -1 the tests are repeating forever.
|
||||
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
|
||||
// stack frames in failure stack traces.
|
||||
GTEST_DECLARE_bool_(show_internal_stack_frames);
|
||||
@ -156,16 +163,6 @@ GTEST_DECLARE_string_(stream_result_to);
|
||||
GTEST_DECLARE_string_(flagfile);
|
||||
#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.
|
||||
const int kMaxStackTraceDepth = 100;
|
||||
|
||||
@ -1123,9 +1120,6 @@ class TestEventListener {
|
||||
// Fired before the test starts.
|
||||
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.
|
||||
// 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.
|
||||
@ -1175,7 +1169,6 @@ class EmptyTestEventListener : public TestEventListener {
|
||||
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
|
||||
void OnTestStart(const TestInfo& /*test_info*/) override {}
|
||||
void OnTestDisabled(const TestInfo& /*test_info*/) override {}
|
||||
void OnTestPartResult(const TestPartResult& /*test_part_result*/) override {}
|
||||
void OnTestEnd(const TestInfo& /*test_info*/) override {}
|
||||
void OnTestSuiteEnd(const TestSuite& /*test_suite*/) override {}
|
||||
@ -2385,12 +2378,13 @@ constexpr bool StaticAssertTypeEq() noexcept {
|
||||
// EXPECT_EQ(a_.size(), 0);
|
||||
// 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, \
|
||||
::testing::internal::GetTypeId<test_fixture>())
|
||||
#if !GTEST_DONT_DEFINE_TEST_F
|
||||
#define TEST_F(test_fixture, test_name) GTEST_TEST_F(test_fixture, test_name)
|
||||
#endif
|
||||
#endif // !GTEST_DONT_DEFINE_TEST
|
||||
|
||||
// Returns a path to temporary directory.
|
||||
// Tries to determine an appropriate directory for the platform.
|
||||
@ -2451,7 +2445,6 @@ GTEST_API_ std::string TempDir();
|
||||
// }
|
||||
// ...
|
||||
// int main(int argc, char** argv) {
|
||||
// ::testing::InitGoogleTest(&argc, argv);
|
||||
// std::vector<int> values_to_test = LoadValuesFromConfig();
|
||||
// RegisterMyTests(values_to_test);
|
||||
// ...
|
||||
|
@ -27,10 +27,11 @@
|
||||
// (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 07/21/2021 by command
|
||||
// This file is AUTOMATICALLY GENERATED on 01/02/2019 by command
|
||||
// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND!
|
||||
//
|
||||
// Implements a family of generic predicate assertion macros.
|
||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
//
|
||||
// Google C++ Testing and Mocking Framework definitions useful in production code.
|
||||
// GOOGLETEST_CM0003 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_
|
||||
|
@ -26,8 +26,6 @@ The following macros can be defined:
|
||||
* `GTEST_DEFINE_bool_(name, default_val, doc)`
|
||||
* `GTEST_DEFINE_int32_(name, default_val, doc)`
|
||||
* `GTEST_DEFINE_string_(name, default_val, doc)`
|
||||
* `GTEST_FLAG_GET(flag_name)`
|
||||
* `GTEST_FLAG_SET(flag_name, value)`
|
||||
|
||||
### Logging:
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
//
|
||||
// This header file defines internal utilities needed for implementing
|
||||
// death tests. They are subject to change without notice.
|
||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
||||
@ -41,11 +42,11 @@
|
||||
#include <stdio.h>
|
||||
#include <memory>
|
||||
|
||||
GTEST_DECLARE_string_(internal_run_death_test);
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
GTEST_DECLARE_string_(internal_run_death_test);
|
||||
|
||||
// Names of the flags (needed for parsing Google Test flags).
|
||||
const char kDeathTestStyleFlag[] = "death_test_style";
|
||||
const char kDeathTestUseFork[] = "death_test_use_fork";
|
||||
@ -235,6 +236,8 @@ inline Matcher<const ::std::string&> MakeDeathTestMatcher(
|
||||
gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
|
||||
break; \
|
||||
} \
|
||||
default: \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} else \
|
||||
|
@ -35,6 +35,8 @@
|
||||
// This file is #included in gtest/internal/gtest-internal.h.
|
||||
// Do not include this header file separately!
|
||||
|
||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||
|
||||
|
@ -32,6 +32,8 @@
|
||||
// This header file declares functions and macros used internally by
|
||||
// Google Test. They are subject to change without notice.
|
||||
|
||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
|
||||
|
||||
@ -508,11 +510,11 @@ inline SetUpTearDownSuiteFuncType GetNotDefaultOrNull(
|
||||
|
||||
template <typename T>
|
||||
// Note that SuiteApiResolver inherits from T because
|
||||
// SetUpTestSuite()/TearDownTestSuite() could be protected. This way
|
||||
// SetUpTestSuite()/TearDownTestSuite() could be protected. Ths way
|
||||
// SuiteApiResolver can access them.
|
||||
struct SuiteApiResolver : T {
|
||||
// testing::Test is only forward declared at this point. So we make it a
|
||||
// dependent class for the compiler to be OK with it.
|
||||
// dependend class for the compiler to be OK with it.
|
||||
using Test =
|
||||
typename std::conditional<sizeof(T) != 0, ::testing::Test, void>::type;
|
||||
|
||||
|
@ -30,6 +30,8 @@
|
||||
|
||||
// Type and function utilities for implementing parameterized tests.
|
||||
|
||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
|
||||
|
||||
|
@ -78,8 +78,6 @@
|
||||
# define GTEST_OS_FREEBSD 1
|
||||
#elif defined __Fuchsia__
|
||||
# define GTEST_OS_FUCHSIA 1
|
||||
#elif defined(__GNU__)
|
||||
# define GTEST_OS_GNU_HURD 1
|
||||
#elif defined(__GLIBC__) && defined(__FreeBSD_kernel__)
|
||||
# define GTEST_OS_GNU_KFREEBSD 1
|
||||
#elif defined __linux__
|
||||
|
@ -38,6 +38,8 @@
|
||||
// files are expected to #include this. Therefore, it cannot #include
|
||||
// any other Google Test header.
|
||||
|
||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
|
||||
|
||||
@ -114,7 +116,6 @@
|
||||
// GTEST_OS_DRAGONFLY - DragonFlyBSD
|
||||
// GTEST_OS_FREEBSD - FreeBSD
|
||||
// GTEST_OS_FUCHSIA - Fuchsia
|
||||
// GTEST_OS_GNU_HURD - GNU/Hurd
|
||||
// GTEST_OS_GNU_KFREEBSD - GNU/kFreeBSD
|
||||
// GTEST_OS_HAIKU - Haiku
|
||||
// GTEST_OS_HPUX - HP-UX
|
||||
@ -166,6 +167,7 @@
|
||||
// GTEST_HAS_TYPED_TEST - typed tests
|
||||
// GTEST_HAS_TYPED_TEST_P - type-parameterized tests
|
||||
// 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_HAS_POSIX_RE (see above) which users can
|
||||
// define themselves.
|
||||
@ -217,6 +219,7 @@
|
||||
// Regular expressions:
|
||||
// RE - a simple regular expression class using the POSIX
|
||||
// Extended Regular Expression syntax on UNIX-like platforms
|
||||
// GOOGLETEST_CM0008 DO NOT DELETE
|
||||
// or a reduced regular exception syntax on other
|
||||
// platforms, including Windows.
|
||||
// Logging:
|
||||
@ -260,17 +263,9 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <cerrno>
|
||||
// #include <condition_variable> // Guarded by GTEST_IS_THREADSAFE below
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <locale>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
// #include <mutex> // Guarded by GTEST_IS_THREADSAFE below
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
# include <sys/types.h>
|
||||
@ -282,6 +277,13 @@
|
||||
# include <TargetConditionals.h>
|
||||
#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/gtest-port-arch.h"
|
||||
|
||||
@ -545,7 +547,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
||||
(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_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_OPENBSD || \
|
||||
GTEST_OS_HAIKU || GTEST_OS_GNU_HURD)
|
||||
GTEST_OS_HAIKU)
|
||||
#endif // GTEST_HAS_PTHREAD
|
||||
|
||||
#if GTEST_HAS_PTHREAD
|
||||
@ -605,8 +607,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
||||
(GTEST_OS_WINDOWS_DESKTOP && _MSC_VER) || GTEST_OS_WINDOWS_MINGW || \
|
||||
GTEST_OS_AIX || GTEST_OS_HPUX || GTEST_OS_OPENBSD || GTEST_OS_QNX || \
|
||||
GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA || \
|
||||
GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_HAIKU || \
|
||||
GTEST_OS_GNU_HURD)
|
||||
GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_HAIKU)
|
||||
# define GTEST_HAS_DEATH_TEST 1
|
||||
#endif
|
||||
|
||||
@ -626,8 +627,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
||||
|
||||
// Determines whether test results can be streamed to a socket.
|
||||
#if GTEST_OS_LINUX || GTEST_OS_GNU_KFREEBSD || GTEST_OS_DRAGONFLY || \
|
||||
GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_OPENBSD || \
|
||||
GTEST_OS_GNU_HURD
|
||||
GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_OPENBSD
|
||||
# define GTEST_CAN_STREAM_RESULTS_ 1
|
||||
#endif
|
||||
|
||||
@ -758,12 +758,6 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
||||
|
||||
#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
|
||||
// are guarded by #ifndef to give embedders a chance to define GTEST_API_ in
|
||||
// gtest/internal/custom/gtest-port.h
|
||||
@ -1001,7 +995,7 @@ inline void FlushInfoLog() { fflush(nullptr); }
|
||||
//
|
||||
// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition
|
||||
// is not satisfied.
|
||||
// Synopsis:
|
||||
// Synopsys:
|
||||
// GTEST_CHECK_(boolean_condition);
|
||||
// or
|
||||
// GTEST_CHECK_(boolean_condition) << "Additional message";
|
||||
@ -1056,7 +1050,7 @@ struct ConstRef<T&> { typedef T& type; };
|
||||
// const Foo*). When you use ImplicitCast_, the compiler checks that
|
||||
// the cast is safe. Such explicit ImplicitCast_s are necessary in
|
||||
// surprisingly many situations where C++ demands an exact type match
|
||||
// instead of an argument type convertible to a target type.
|
||||
// instead of an argument type convertable to a target type.
|
||||
//
|
||||
// The syntax for using ImplicitCast_ is the same as for static_cast:
|
||||
//
|
||||
@ -1168,8 +1162,71 @@ void ClearInjectableArgvs();
|
||||
|
||||
// Defines synchronization primitives.
|
||||
#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.
|
||||
// Used in death tests and in threading support.
|
||||
class GTEST_API_ AutoHandle {
|
||||
@ -1198,45 +1255,23 @@ class GTEST_API_ 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
|
||||
// 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.
|
||||
// TODO(b/203539622): Replace unconditionally with absl::Notification.
|
||||
class GTEST_API_ Notification {
|
||||
public:
|
||||
Notification() : notified_(false) {}
|
||||
Notification(const Notification&) = delete;
|
||||
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_; });
|
||||
}
|
||||
Notification();
|
||||
void Notify();
|
||||
void WaitForNotification();
|
||||
|
||||
private:
|
||||
std::mutex mu_;
|
||||
std::condition_variable cv_;
|
||||
bool notified_;
|
||||
AutoHandle event_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification);
|
||||
};
|
||||
# endif // GTEST_HAS_NOTIFICATION_
|
||||
|
||||
@ -2178,40 +2213,22 @@ using TimeInMillis = int64_t; // Represents time in milliseconds.
|
||||
# define GTEST_FLAG_SAVER_ ::testing::internal::GTestFlagSaver
|
||||
|
||||
// Macros for declaring flags.
|
||||
#define GTEST_DECLARE_bool_(name) \
|
||||
namespace testing { \
|
||||
GTEST_API_ extern bool GTEST_FLAG(name); \
|
||||
} static_assert(true, "no-op to require trailing semicolon")
|
||||
#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")
|
||||
# define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name)
|
||||
# define GTEST_DECLARE_int32_(name) \
|
||||
GTEST_API_ extern std::int32_t GTEST_FLAG(name)
|
||||
# define GTEST_DECLARE_string_(name) \
|
||||
GTEST_API_ extern ::std::string GTEST_FLAG(name)
|
||||
|
||||
// Macros for defining flags.
|
||||
#define GTEST_DEFINE_bool_(name, default_val, doc) \
|
||||
namespace testing { \
|
||||
GTEST_API_ bool GTEST_FLAG(name) = (default_val); \
|
||||
} static_assert(true, "no-op to require trailing semicolon")
|
||||
#define GTEST_DEFINE_int32_(name, default_val, doc) \
|
||||
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")
|
||||
# define GTEST_DEFINE_bool_(name, default_val, doc) \
|
||||
GTEST_API_ bool GTEST_FLAG(name) = (default_val)
|
||||
# define GTEST_DEFINE_int32_(name, default_val, doc) \
|
||||
GTEST_API_ std::int32_t GTEST_FLAG(name) = (default_val)
|
||||
# define GTEST_DEFINE_string_(name, default_val, doc) \
|
||||
GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val)
|
||||
|
||||
#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
|
||||
#if !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_)
|
||||
# define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)
|
||||
@ -2291,7 +2308,6 @@ namespace testing {
|
||||
namespace internal {
|
||||
template <typename T>
|
||||
using Optional = ::absl::optional<T>;
|
||||
inline ::absl::nullopt_t Nullopt() { return ::absl::nullopt; }
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
#else
|
||||
@ -2305,7 +2321,6 @@ namespace testing {
|
||||
namespace internal {
|
||||
template <typename T>
|
||||
using Optional = ::std::optional<T>;
|
||||
inline ::std::nullopt_t Nullopt() { return ::std::nullopt; }
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
// The case where absl is configured NOT to alias std::optional is not
|
||||
|
@ -36,6 +36,8 @@
|
||||
// This header file is #included by gtest-internal.h.
|
||||
// It should not be #included by other files.
|
||||
|
||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
|
||||
|
||||
|
@ -30,6 +30,8 @@
|
||||
// Type utilities needed for implementing typed and type-parameterized
|
||||
// tests.
|
||||
|
||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
|
||||
|
||||
|
5
googletest/scripts/README.md
Normal file
5
googletest/scripts/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# 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.
|
83
googletest/scripts/common.py
Normal file
83
googletest/scripts/common.py
Normal file
@ -0,0 +1,83 @@
|
||||
# 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'
|
253
googletest/scripts/fuse_gtest_files.py
Executable file
253
googletest/scripts/fuse_gtest_files.py
Executable file
@ -0,0 +1,253 @@
|
||||
#!/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()
|
733
googletest/scripts/gen_gtest_pred_impl.py
Executable file
733
googletest/scripts/gen_gtest_pred_impl.py
Executable file
@ -0,0 +1,733 @@
|
||||
#!/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()
|
274
googletest/scripts/gtest-config.in
Executable file
274
googletest/scripts/gtest-config.in
Executable file
@ -0,0 +1,274 @@
|
||||
#!/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
|
158
googletest/scripts/release_docs.py
Executable file
158
googletest/scripts/release_docs.py
Executable file
@ -0,0 +1,158 @@
|
||||
#!/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()
|
32
googletest/scripts/run_with_path.py
Executable file
32
googletest/scripts/run_with_path.py
Executable file
@ -0,0 +1,32 @@
|
||||
#!/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()
|
59
googletest/scripts/test/Makefile
Normal file
59
googletest/scripts/test/Makefile
Normal file
@ -0,0 +1,59 @@
|
||||
# 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 $@
|
1402
googletest/scripts/upload.py
Executable file
1402
googletest/scripts/upload.py
Executable file
File diff suppressed because it is too large
Load Diff
78
googletest/scripts/upload_gtest.py
Executable file
78
googletest/scripts/upload_gtest.py
Executable file
@ -0,0 +1,78 @@
|
||||
#!/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,12 +96,9 @@ namespace testing {
|
||||
// used internally at Google, is "threadsafe".
|
||||
static const char kDefaultDeathTestStyle[] = GTEST_DEFAULT_DEATH_TEST_STYLE;
|
||||
|
||||
} // namespace testing
|
||||
|
||||
GTEST_DEFINE_string_(
|
||||
death_test_style,
|
||||
testing::internal::StringFromGTestEnv("death_test_style",
|
||||
testing::kDefaultDeathTestStyle),
|
||||
internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle),
|
||||
"Indicates how to run a death test in a forked child process: "
|
||||
"\"threadsafe\" (child process re-executes the test binary "
|
||||
"from the beginning, running only the specific death test) or "
|
||||
@ -110,7 +107,7 @@ GTEST_DEFINE_string_(
|
||||
|
||||
GTEST_DEFINE_bool_(
|
||||
death_test_use_fork,
|
||||
testing::internal::BoolFromGTestEnv("death_test_use_fork", false),
|
||||
internal::BoolFromGTestEnv("death_test_use_fork", false),
|
||||
"Instructs to use fork()/_exit() instead of clone() in death tests. "
|
||||
"Ignored and always uses fork() on POSIX systems where clone() is not "
|
||||
"implemented. Useful when running under valgrind or similar tools if "
|
||||
@ -120,6 +117,7 @@ GTEST_DEFINE_bool_(
|
||||
"work in 99% of the cases. Once valgrind is fixed, this flag will "
|
||||
"most likely be removed.");
|
||||
|
||||
namespace internal {
|
||||
GTEST_DEFINE_string_(
|
||||
internal_run_death_test, "",
|
||||
"Indicates the file, line number, temporal index of "
|
||||
@ -128,8 +126,7 @@ GTEST_DEFINE_string_(
|
||||
"the '|' characters. This flag is specified if and only if the "
|
||||
"current process is a sub-process launched for running a thread-safe "
|
||||
"death test. FOR INTERNAL USE ONLY.");
|
||||
|
||||
namespace testing {
|
||||
} // namespace internal
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
|
||||
@ -151,12 +148,12 @@ bool InDeathTestChild() {
|
||||
|
||||
// On Windows and Fuchsia, death tests are thread-safe regardless of the value
|
||||
// of the death_test_style flag.
|
||||
return !GTEST_FLAG_GET(internal_run_death_test).empty();
|
||||
return !GTEST_FLAG(internal_run_death_test).empty();
|
||||
|
||||
# else
|
||||
|
||||
if (GTEST_FLAG_GET(death_test_style) == "threadsafe")
|
||||
return !GTEST_FLAG_GET(internal_run_death_test).empty();
|
||||
if (GTEST_FLAG(death_test_style) == "threadsafe")
|
||||
return !GTEST_FLAG(internal_run_death_test).empty();
|
||||
else
|
||||
return g_in_fast_death_test_child;
|
||||
#endif
|
||||
@ -759,18 +756,18 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
|
||||
nullptr)); // The even is unnamed.
|
||||
GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != nullptr);
|
||||
const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
|
||||
"filter=" + info->test_suite_name() + "." +
|
||||
info->name();
|
||||
kFilterFlag + "=" + info->test_suite_name() +
|
||||
"." + info->name();
|
||||
const std::string internal_flag =
|
||||
std::string("--") + GTEST_FLAG_PREFIX_ +
|
||||
"internal_run_death_test=" + file_ + "|" + StreamableToString(line_) +
|
||||
"|" + StreamableToString(death_test_index) + "|" +
|
||||
std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag +
|
||||
"=" + file_ + "|" + StreamableToString(line_) + "|" +
|
||||
StreamableToString(death_test_index) + "|" +
|
||||
StreamableToString(static_cast<unsigned int>(::GetCurrentProcessId())) +
|
||||
// size_t has the same width as pointers on both 32-bit and 64-bit
|
||||
// Windows platforms.
|
||||
// See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx.
|
||||
"|" + StreamableToString(reinterpret_cast<size_t>(write_handle)) + "|" +
|
||||
StreamableToString(reinterpret_cast<size_t>(event_handle_.Get()));
|
||||
"|" + StreamableToString(reinterpret_cast<size_t>(write_handle)) +
|
||||
"|" + StreamableToString(reinterpret_cast<size_t>(event_handle_.Get()));
|
||||
|
||||
char executable_path[_MAX_PATH + 1]; // NOLINT
|
||||
GTEST_DEATH_TEST_CHECK_(_MAX_PATH + 1 != ::GetModuleFileNameA(nullptr,
|
||||
@ -799,8 +796,8 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
|
||||
GTEST_DEATH_TEST_CHECK_(
|
||||
::CreateProcessA(
|
||||
executable_path, const_cast<char*>(command_line.c_str()),
|
||||
nullptr, // Returned process handle is not inheritable.
|
||||
nullptr, // Returned thread handle is not inheritable.
|
||||
nullptr, // Retuned process handle is not inheritable.
|
||||
nullptr, // Retuned thread handle is not inheritable.
|
||||
TRUE, // Child inherits all inheritable handles (for write_handle_).
|
||||
0x0, // Default creation flags.
|
||||
nullptr, // Inherit the parent's environment.
|
||||
@ -990,8 +987,8 @@ DeathTest::TestRole FuchsiaDeathTest::AssumeRole() {
|
||||
|
||||
// Build the child process command line.
|
||||
const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
|
||||
"filter=" + info->test_suite_name() + "." +
|
||||
info->name();
|
||||
kFilterFlag + "=" + info->test_suite_name() +
|
||||
"." + info->name();
|
||||
const std::string internal_flag =
|
||||
std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "="
|
||||
+ file_ + "|"
|
||||
@ -1354,7 +1351,7 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
|
||||
# endif // GTEST_OS_LINUX
|
||||
|
||||
# if GTEST_HAS_CLONE
|
||||
const bool use_fork = GTEST_FLAG_GET(death_test_use_fork);
|
||||
const bool use_fork = GTEST_FLAG(death_test_use_fork);
|
||||
|
||||
if (!use_fork) {
|
||||
static const bool stack_grows_down = StackGrowsDown();
|
||||
@ -1423,13 +1420,13 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() {
|
||||
GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1);
|
||||
|
||||
const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
|
||||
"filter=" + info->test_suite_name() + "." +
|
||||
info->name();
|
||||
const std::string internal_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
|
||||
"internal_run_death_test=" + file_ + "|" +
|
||||
StreamableToString(line_) + "|" +
|
||||
StreamableToString(death_test_index) + "|" +
|
||||
StreamableToString(pipe_fd[1]);
|
||||
kFilterFlag + "=" + info->test_suite_name() +
|
||||
"." + info->name();
|
||||
const std::string internal_flag =
|
||||
std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "="
|
||||
+ file_ + "|" + StreamableToString(line_) + "|"
|
||||
+ StreamableToString(death_test_index) + "|"
|
||||
+ StreamableToString(pipe_fd[1]);
|
||||
Arguments args;
|
||||
args.AddArguments(GetArgvsForDeathTestChildProcess());
|
||||
args.AddArgument(filter_flag.c_str());
|
||||
@ -1485,32 +1482,32 @@ bool DefaultDeathTestFactory::Create(const char* statement,
|
||||
|
||||
# if GTEST_OS_WINDOWS
|
||||
|
||||
if (GTEST_FLAG_GET(death_test_style) == "threadsafe" ||
|
||||
GTEST_FLAG_GET(death_test_style) == "fast") {
|
||||
if (GTEST_FLAG(death_test_style) == "threadsafe" ||
|
||||
GTEST_FLAG(death_test_style) == "fast") {
|
||||
*test = new WindowsDeathTest(statement, std::move(matcher), file, line);
|
||||
}
|
||||
|
||||
# elif GTEST_OS_FUCHSIA
|
||||
|
||||
if (GTEST_FLAG_GET(death_test_style) == "threadsafe" ||
|
||||
GTEST_FLAG_GET(death_test_style) == "fast") {
|
||||
if (GTEST_FLAG(death_test_style) == "threadsafe" ||
|
||||
GTEST_FLAG(death_test_style) == "fast") {
|
||||
*test = new FuchsiaDeathTest(statement, std::move(matcher), file, line);
|
||||
}
|
||||
|
||||
# else
|
||||
|
||||
if (GTEST_FLAG_GET(death_test_style) == "threadsafe") {
|
||||
if (GTEST_FLAG(death_test_style) == "threadsafe") {
|
||||
*test = new ExecDeathTest(statement, std::move(matcher), file, line);
|
||||
} else if (GTEST_FLAG_GET(death_test_style) == "fast") {
|
||||
} else if (GTEST_FLAG(death_test_style) == "fast") {
|
||||
*test = new NoExecDeathTest(statement, std::move(matcher));
|
||||
}
|
||||
|
||||
# endif // GTEST_OS_WINDOWS
|
||||
|
||||
else { // NOLINT - this is more readable than unbalanced brackets inside #if.
|
||||
DeathTest::set_last_death_test_message("Unknown death test style \"" +
|
||||
GTEST_FLAG_GET(death_test_style) +
|
||||
"\" encountered");
|
||||
DeathTest::set_last_death_test_message(
|
||||
"Unknown death test style \"" + GTEST_FLAG(death_test_style)
|
||||
+ "\" encountered");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1587,14 +1584,14 @@ static int GetStatusFileDescriptor(unsigned int parent_process_id,
|
||||
// initialized from the GTEST_FLAG(internal_run_death_test) flag if
|
||||
// the flag is specified; otherwise returns NULL.
|
||||
InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
|
||||
if (GTEST_FLAG_GET(internal_run_death_test) == "") return nullptr;
|
||||
if (GTEST_FLAG(internal_run_death_test) == "") return nullptr;
|
||||
|
||||
// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we
|
||||
// can use it here.
|
||||
int line = -1;
|
||||
int index = -1;
|
||||
::std::vector< ::std::string> fields;
|
||||
SplitString(GTEST_FLAG_GET(internal_run_death_test), '|', &fields);
|
||||
SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields);
|
||||
int write_fd = -1;
|
||||
|
||||
# if GTEST_OS_WINDOWS
|
||||
@ -1610,7 +1607,7 @@ InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
|
||||
|| !ParseNaturalNumber(fields[4], &write_handle_as_size_t)
|
||||
|| !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) {
|
||||
DeathTestAbort("Bad --gtest_internal_run_death_test flag: " +
|
||||
GTEST_FLAG_GET(internal_run_death_test));
|
||||
GTEST_FLAG(internal_run_death_test));
|
||||
}
|
||||
write_fd = GetStatusFileDescriptor(parent_process_id,
|
||||
write_handle_as_size_t,
|
||||
@ -1621,8 +1618,8 @@ InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
|
||||
if (fields.size() != 3
|
||||
|| !ParseNaturalNumber(fields[1], &line)
|
||||
|| !ParseNaturalNumber(fields[2], &index)) {
|
||||
DeathTestAbort("Bad --gtest_internal_run_death_test flag: " +
|
||||
GTEST_FLAG_GET(internal_run_death_test));
|
||||
DeathTestAbort("Bad --gtest_internal_run_death_test flag: "
|
||||
+ GTEST_FLAG(internal_run_death_test));
|
||||
}
|
||||
|
||||
# else
|
||||
@ -1631,8 +1628,8 @@ InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
|
||||
|| !ParseNaturalNumber(fields[1], &line)
|
||||
|| !ParseNaturalNumber(fields[2], &index)
|
||||
|| !ParseNaturalNumber(fields[3], &write_fd)) {
|
||||
DeathTestAbort("Bad --gtest_internal_run_death_test flag: " +
|
||||
GTEST_FLAG_GET(internal_run_death_test));
|
||||
DeathTestAbort("Bad --gtest_internal_run_death_test flag: "
|
||||
+ GTEST_FLAG(internal_run_death_test));
|
||||
}
|
||||
|
||||
# endif // GTEST_OS_WINDOWS
|
||||
|
@ -64,6 +64,8 @@
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||
/* class A needs to have dll-interface to be used by clients of class B */)
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Declares the flags.
|
||||
//
|
||||
// We don't want the users to modify this flag in the code, but want
|
||||
@ -71,13 +73,32 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||
// declare it here as opposed to in gtest.h.
|
||||
GTEST_DECLARE_bool_(death_test_use_fork);
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// The value of GetTestTypeId() as seen from within the Google Test
|
||||
// library. This is solely for testing GetTestTypeId().
|
||||
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].
|
||||
const int kMaxRandomSeed = 99999;
|
||||
|
||||
@ -104,7 +125,8 @@ GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms);
|
||||
//
|
||||
// On success, stores the value of the flag in *value, and returns
|
||||
// true. On failure, returns false without changing *value.
|
||||
GTEST_API_ bool ParseFlag(const char* str, const char* flag, int32_t* value);
|
||||
GTEST_API_ bool ParseInt32Flag(
|
||||
const char* str, const char* flag, int32_t* value);
|
||||
|
||||
// Returns a random seed in range [1, kMaxRandomSeed] based on the
|
||||
// given --gtest_random_seed flag value.
|
||||
@ -138,54 +160,50 @@ class GTestFlagSaver {
|
||||
public:
|
||||
// The c'tor.
|
||||
GTestFlagSaver() {
|
||||
also_run_disabled_tests_ = GTEST_FLAG_GET(also_run_disabled_tests);
|
||||
break_on_failure_ = GTEST_FLAG_GET(break_on_failure);
|
||||
catch_exceptions_ = GTEST_FLAG_GET(catch_exceptions);
|
||||
color_ = GTEST_FLAG_GET(color);
|
||||
death_test_style_ = GTEST_FLAG_GET(death_test_style);
|
||||
death_test_use_fork_ = GTEST_FLAG_GET(death_test_use_fork);
|
||||
fail_fast_ = GTEST_FLAG_GET(fail_fast);
|
||||
filter_ = GTEST_FLAG_GET(filter);
|
||||
internal_run_death_test_ = GTEST_FLAG_GET(internal_run_death_test);
|
||||
list_tests_ = GTEST_FLAG_GET(list_tests);
|
||||
output_ = GTEST_FLAG_GET(output);
|
||||
brief_ = GTEST_FLAG_GET(brief);
|
||||
print_time_ = GTEST_FLAG_GET(print_time);
|
||||
print_utf8_ = GTEST_FLAG_GET(print_utf8);
|
||||
random_seed_ = GTEST_FLAG_GET(random_seed);
|
||||
repeat_ = GTEST_FLAG_GET(repeat);
|
||||
recreate_environments_when_repeating_ =
|
||||
GTEST_FLAG_GET(recreate_environments_when_repeating);
|
||||
shuffle_ = GTEST_FLAG_GET(shuffle);
|
||||
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);
|
||||
also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests);
|
||||
break_on_failure_ = GTEST_FLAG(break_on_failure);
|
||||
catch_exceptions_ = GTEST_FLAG(catch_exceptions);
|
||||
color_ = GTEST_FLAG(color);
|
||||
death_test_style_ = GTEST_FLAG(death_test_style);
|
||||
death_test_use_fork_ = GTEST_FLAG(death_test_use_fork);
|
||||
fail_fast_ = GTEST_FLAG(fail_fast);
|
||||
filter_ = GTEST_FLAG(filter);
|
||||
internal_run_death_test_ = GTEST_FLAG(internal_run_death_test);
|
||||
list_tests_ = GTEST_FLAG(list_tests);
|
||||
output_ = GTEST_FLAG(output);
|
||||
brief_ = GTEST_FLAG(brief);
|
||||
print_time_ = GTEST_FLAG(print_time);
|
||||
print_utf8_ = GTEST_FLAG(print_utf8);
|
||||
random_seed_ = GTEST_FLAG(random_seed);
|
||||
repeat_ = GTEST_FLAG(repeat);
|
||||
shuffle_ = GTEST_FLAG(shuffle);
|
||||
stack_trace_depth_ = GTEST_FLAG(stack_trace_depth);
|
||||
stream_result_to_ = GTEST_FLAG(stream_result_to);
|
||||
throw_on_failure_ = GTEST_FLAG(throw_on_failure);
|
||||
}
|
||||
|
||||
// The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS.
|
||||
~GTestFlagSaver() {
|
||||
GTEST_FLAG_SET(also_run_disabled_tests, also_run_disabled_tests_);
|
||||
GTEST_FLAG_SET(break_on_failure, break_on_failure_);
|
||||
GTEST_FLAG_SET(catch_exceptions, catch_exceptions_);
|
||||
GTEST_FLAG_SET(color, color_);
|
||||
GTEST_FLAG_SET(death_test_style, death_test_style_);
|
||||
GTEST_FLAG_SET(death_test_use_fork, death_test_use_fork_);
|
||||
GTEST_FLAG_SET(filter, filter_);
|
||||
GTEST_FLAG_SET(fail_fast, fail_fast_);
|
||||
GTEST_FLAG_SET(internal_run_death_test, internal_run_death_test_);
|
||||
GTEST_FLAG_SET(list_tests, list_tests_);
|
||||
GTEST_FLAG_SET(output, output_);
|
||||
GTEST_FLAG_SET(brief, brief_);
|
||||
GTEST_FLAG_SET(print_time, print_time_);
|
||||
GTEST_FLAG_SET(print_utf8, print_utf8_);
|
||||
GTEST_FLAG_SET(random_seed, random_seed_);
|
||||
GTEST_FLAG_SET(repeat, repeat_);
|
||||
GTEST_FLAG_SET(recreate_environments_when_repeating,
|
||||
recreate_environments_when_repeating_);
|
||||
GTEST_FLAG_SET(shuffle, shuffle_);
|
||||
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_);
|
||||
GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_;
|
||||
GTEST_FLAG(break_on_failure) = break_on_failure_;
|
||||
GTEST_FLAG(catch_exceptions) = catch_exceptions_;
|
||||
GTEST_FLAG(color) = color_;
|
||||
GTEST_FLAG(death_test_style) = death_test_style_;
|
||||
GTEST_FLAG(death_test_use_fork) = death_test_use_fork_;
|
||||
GTEST_FLAG(filter) = filter_;
|
||||
GTEST_FLAG(fail_fast) = fail_fast_;
|
||||
GTEST_FLAG(internal_run_death_test) = internal_run_death_test_;
|
||||
GTEST_FLAG(list_tests) = list_tests_;
|
||||
GTEST_FLAG(output) = output_;
|
||||
GTEST_FLAG(brief) = brief_;
|
||||
GTEST_FLAG(print_time) = print_time_;
|
||||
GTEST_FLAG(print_utf8) = print_utf8_;
|
||||
GTEST_FLAG(random_seed) = random_seed_;
|
||||
GTEST_FLAG(repeat) = repeat_;
|
||||
GTEST_FLAG(shuffle) = shuffle_;
|
||||
GTEST_FLAG(stack_trace_depth) = stack_trace_depth_;
|
||||
GTEST_FLAG(stream_result_to) = stream_result_to_;
|
||||
GTEST_FLAG(throw_on_failure) = throw_on_failure_;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -206,7 +224,6 @@ class GTestFlagSaver {
|
||||
bool print_utf8_;
|
||||
int32_t random_seed_;
|
||||
int32_t repeat_;
|
||||
bool recreate_environments_when_repeating_;
|
||||
bool shuffle_;
|
||||
int32_t stack_trace_depth_;
|
||||
std::string stream_result_to_;
|
||||
@ -273,7 +290,7 @@ inline int CountIf(const Container& c, Predicate predicate) {
|
||||
// Implemented as an explicit loop since std::count_if() in libCstd on
|
||||
// Solaris has a non-standard signature.
|
||||
int count = 0;
|
||||
for (auto it = c.begin(); it != c.end(); ++it) {
|
||||
for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) {
|
||||
if (predicate(*it))
|
||||
++count;
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ const int kStdOutFileno = STDOUT_FILENO;
|
||||
const int kStdErrFileno = STDERR_FILENO;
|
||||
#endif // _MSC_VER
|
||||
|
||||
#if GTEST_OS_LINUX || GTEST_OS_GNU_HURD
|
||||
#if GTEST_OS_LINUX
|
||||
|
||||
namespace {
|
||||
template <typename T>
|
||||
@ -280,6 +280,10 @@ size_t GetThreadCount() {
|
||||
|
||||
#if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS
|
||||
|
||||
void SleepMilliseconds(int n) {
|
||||
::Sleep(static_cast<DWORD>(n));
|
||||
}
|
||||
|
||||
AutoHandle::AutoHandle()
|
||||
: handle_(INVALID_HANDLE_VALUE) {}
|
||||
|
||||
@ -318,6 +322,23 @@ bool AutoHandle::IsCloseable() const {
|
||||
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()
|
||||
: owner_thread_id_(0),
|
||||
type_(kDynamic),
|
||||
@ -629,8 +650,7 @@ class ThreadLocalRegistryImpl {
|
||||
&ThreadLocalRegistryImpl::WatcherThreadFunc,
|
||||
reinterpret_cast<LPVOID>(new ThreadIdAndHandle(thread_id, thread)),
|
||||
CREATE_SUSPENDED, &watcher_thread_id);
|
||||
GTEST_CHECK_(watcher_thread != nullptr)
|
||||
<< "CreateThread failed with error " << ::GetLastError() << ".";
|
||||
GTEST_CHECK_(watcher_thread != nullptr);
|
||||
// Give the watcher thread the same priority as ours to avoid being
|
||||
// blocked by it.
|
||||
::SetThreadPriority(watcher_thread,
|
||||
|
@ -304,51 +304,6 @@ void PrintTo(char32_t c, ::std::ostream* os) {
|
||||
<< 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
|
||||
// char, char8_t, char16_t, char32_t, or wchar_t.
|
||||
// The array starts at begin, the length is len, it may include '\0' characters
|
||||
@ -547,7 +502,7 @@ void ConditionalPrintAsText(const char* str, size_t length, ostream* os) {
|
||||
|
||||
void PrintStringTo(const ::std::string& s, ostream* os) {
|
||||
if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) {
|
||||
if (GTEST_FLAG_GET(print_utf8)) {
|
||||
if (GTEST_FLAG(print_utf8)) {
|
||||
ConditionalPrintAsText(s.data(), s.size(), os);
|
||||
}
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ const char kStackTraceMarker[] = "\nStack trace:\n";
|
||||
// is specified on the command line.
|
||||
bool g_help_flag = false;
|
||||
|
||||
// Utility function to Open File for Writing
|
||||
// Utilty function to Open File for Writing
|
||||
static FILE* OpenFileForWriting(const std::string& output_file) {
|
||||
FILE* fileout = nullptr;
|
||||
FilePath output_file_path(output_file);
|
||||
@ -216,33 +216,28 @@ static bool GetDefaultFailFast() {
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
GTEST_DEFINE_bool_(
|
||||
fail_fast,
|
||||
testing::internal::BoolFromGTestEnv("fail_fast",
|
||||
testing::GetDefaultFailFast()),
|
||||
fail_fast, internal::BoolFromGTestEnv("fail_fast", GetDefaultFailFast()),
|
||||
"True if and only if a test failure should stop further test execution.");
|
||||
|
||||
GTEST_DEFINE_bool_(
|
||||
also_run_disabled_tests,
|
||||
testing::internal::BoolFromGTestEnv("also_run_disabled_tests", false),
|
||||
internal::BoolFromGTestEnv("also_run_disabled_tests", false),
|
||||
"Run disabled tests too, in addition to the tests normally being run.");
|
||||
|
||||
GTEST_DEFINE_bool_(
|
||||
break_on_failure,
|
||||
testing::internal::BoolFromGTestEnv("break_on_failure", false),
|
||||
break_on_failure, internal::BoolFromGTestEnv("break_on_failure", false),
|
||||
"True if and only if a failed assertion should be a debugger "
|
||||
"break-point.");
|
||||
|
||||
GTEST_DEFINE_bool_(catch_exceptions,
|
||||
testing::internal::BoolFromGTestEnv("catch_exceptions",
|
||||
true),
|
||||
internal::BoolFromGTestEnv("catch_exceptions", true),
|
||||
"True if and only if " GTEST_NAME_
|
||||
" should catch exceptions and treat them as test failures.");
|
||||
|
||||
GTEST_DEFINE_string_(
|
||||
color, testing::internal::StringFromGTestEnv("color", "auto"),
|
||||
color,
|
||||
internal::StringFromGTestEnv("color", "auto"),
|
||||
"Whether to use colors in the output. Valid values: yes, no, "
|
||||
"and auto. 'auto' means to use colors if the output is "
|
||||
"being sent to a terminal and the TERM environment variable "
|
||||
@ -250,8 +245,7 @@ GTEST_DEFINE_string_(
|
||||
|
||||
GTEST_DEFINE_string_(
|
||||
filter,
|
||||
testing::internal::StringFromGTestEnv("filter",
|
||||
testing::GetDefaultFilter()),
|
||||
internal::StringFromGTestEnv("filter", GetDefaultFilter()),
|
||||
"A colon-separated list of glob (not regex) patterns "
|
||||
"for filtering the tests to run, optionally followed by a "
|
||||
"'-' and a : separated list of negative patterns (tests to "
|
||||
@ -260,10 +254,8 @@ GTEST_DEFINE_string_(
|
||||
|
||||
GTEST_DEFINE_bool_(
|
||||
install_failure_signal_handler,
|
||||
testing::internal::BoolFromGTestEnv("install_failure_signal_handler",
|
||||
false),
|
||||
"If true and supported on the current platform, " GTEST_NAME_
|
||||
" should "
|
||||
internal::BoolFromGTestEnv("install_failure_signal_handler", false),
|
||||
"If true and supported on the current platform, " GTEST_NAME_ " should "
|
||||
"install a signal handler that dumps debugging information when fatal "
|
||||
"signals are raised.");
|
||||
|
||||
@ -277,8 +269,8 @@ GTEST_DEFINE_bool_(list_tests, false,
|
||||
// ''
|
||||
GTEST_DEFINE_string_(
|
||||
output,
|
||||
testing::internal::StringFromGTestEnv(
|
||||
"output", testing::internal::OutputFlagAlsoCheckEnvVar().c_str()),
|
||||
internal::StringFromGTestEnv("output",
|
||||
internal::OutputFlagAlsoCheckEnvVar().c_str()),
|
||||
"A format (defaults to \"xml\" but can be specified to be \"json\"), "
|
||||
"optionally followed by a colon and an output file name or directory. "
|
||||
"A directory is indicated by a trailing pathname separator. "
|
||||
@ -289,79 +281,65 @@ GTEST_DEFINE_string_(
|
||||
"digits.");
|
||||
|
||||
GTEST_DEFINE_bool_(
|
||||
brief, testing::internal::BoolFromGTestEnv("brief", false),
|
||||
brief, internal::BoolFromGTestEnv("brief", false),
|
||||
"True if only test failures should be displayed in text output.");
|
||||
|
||||
GTEST_DEFINE_bool_(print_time,
|
||||
testing::internal::BoolFromGTestEnv("print_time", true),
|
||||
GTEST_DEFINE_bool_(print_time, internal::BoolFromGTestEnv("print_time", true),
|
||||
"True if and only if " GTEST_NAME_
|
||||
" should display elapsed time in text output.");
|
||||
|
||||
GTEST_DEFINE_bool_(print_utf8,
|
||||
testing::internal::BoolFromGTestEnv("print_utf8", true),
|
||||
GTEST_DEFINE_bool_(print_utf8, internal::BoolFromGTestEnv("print_utf8", true),
|
||||
"True if and only if " GTEST_NAME_
|
||||
" prints UTF8 characters as text.");
|
||||
|
||||
GTEST_DEFINE_int32_(
|
||||
random_seed, testing::internal::Int32FromGTestEnv("random_seed", 0),
|
||||
random_seed,
|
||||
internal::Int32FromGTestEnv("random_seed", 0),
|
||||
"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.");
|
||||
|
||||
GTEST_DEFINE_int32_(
|
||||
repeat, testing::internal::Int32FromGTestEnv("repeat", 1),
|
||||
repeat,
|
||||
internal::Int32FromGTestEnv("repeat", 1),
|
||||
"How many times to repeat each test. Specify a negative number "
|
||||
"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,
|
||||
"True if and only if " GTEST_NAME_
|
||||
" should include internal stack frames when "
|
||||
"printing test failure stack traces.");
|
||||
|
||||
GTEST_DEFINE_bool_(shuffle,
|
||||
testing::internal::BoolFromGTestEnv("shuffle", false),
|
||||
GTEST_DEFINE_bool_(shuffle, internal::BoolFromGTestEnv("shuffle", false),
|
||||
"True if and only if " GTEST_NAME_
|
||||
" should randomize tests' order on every run.");
|
||||
|
||||
GTEST_DEFINE_int32_(
|
||||
stack_trace_depth,
|
||||
testing::internal::Int32FromGTestEnv("stack_trace_depth",
|
||||
testing::kMaxStackTraceDepth),
|
||||
internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth),
|
||||
"The maximum number of stack frames to print when an "
|
||||
"assertion fails. The valid range is 0 through 100, inclusive.");
|
||||
|
||||
GTEST_DEFINE_string_(
|
||||
stream_result_to,
|
||||
testing::internal::StringFromGTestEnv("stream_result_to", ""),
|
||||
internal::StringFromGTestEnv("stream_result_to", ""),
|
||||
"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 "
|
||||
"Linux.");
|
||||
|
||||
GTEST_DEFINE_bool_(
|
||||
throw_on_failure,
|
||||
testing::internal::BoolFromGTestEnv("throw_on_failure", false),
|
||||
internal::BoolFromGTestEnv("throw_on_failure", false),
|
||||
"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 "
|
||||
"otherwise. For use with an external test framework.");
|
||||
|
||||
#if GTEST_USE_OWN_FLAGFILE_FLAG_
|
||||
GTEST_DEFINE_string_(
|
||||
flagfile, testing::internal::StringFromGTestEnv("flagfile", ""),
|
||||
flagfile,
|
||||
internal::StringFromGTestEnv("flagfile", ""),
|
||||
"This flag specifies the flagfile to read command-line flags from.");
|
||||
#endif // GTEST_USE_OWN_FLAGFILE_FLAG_
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Generates a random number from [0, range), using a Linear
|
||||
@ -443,7 +421,7 @@ void AssertHelper::operator=(const Message& message) const {
|
||||
namespace {
|
||||
|
||||
// When TEST_P is found without a matching INSTANTIATE_TEST_SUITE_P
|
||||
// to creates test cases for it, a synthetic test case is
|
||||
// to creates test cases for it, a syntetic test case is
|
||||
// inserted to report ether an error or a log message.
|
||||
//
|
||||
// This configuration bit will likely be removed at some point.
|
||||
@ -628,8 +606,7 @@ FilePath GetCurrentExecutableName() {
|
||||
|
||||
// Returns the output format, or "" for normal printed output.
|
||||
std::string UnitTestOptions::GetOutputFormat() {
|
||||
std::string s = GTEST_FLAG_GET(output);
|
||||
const char* const gtest_output_flag = s.c_str();
|
||||
const char* const gtest_output_flag = GTEST_FLAG(output).c_str();
|
||||
const char* const colon = strchr(gtest_output_flag, ':');
|
||||
return (colon == nullptr)
|
||||
? std::string(gtest_output_flag)
|
||||
@ -640,8 +617,7 @@ std::string UnitTestOptions::GetOutputFormat() {
|
||||
// Returns the name of the requested output file, or the default if none
|
||||
// was explicitly specified.
|
||||
std::string UnitTestOptions::GetAbsolutePathToOutputFile() {
|
||||
std::string s = GTEST_FLAG_GET(output);
|
||||
const char* const gtest_output_flag = s.c_str();
|
||||
const char* const gtest_output_flag = GTEST_FLAG(output).c_str();
|
||||
|
||||
std::string format = GetOutputFormat();
|
||||
if (format.empty())
|
||||
@ -756,13 +732,12 @@ bool UnitTestOptions::FilterMatchesTest(const std::string& test_suite_name,
|
||||
|
||||
// Split --gtest_filter at '-', if there is one, to separate into
|
||||
// positive filter and negative filter portions
|
||||
std::string str = GTEST_FLAG_GET(filter);
|
||||
const char* const p = str.c_str();
|
||||
const char* const p = GTEST_FLAG(filter).c_str();
|
||||
const char* const dash = strchr(p, '-');
|
||||
std::string positive;
|
||||
std::string negative;
|
||||
if (dash == nullptr) {
|
||||
positive = str.c_str(); // Whole string is a positive filter
|
||||
positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter
|
||||
negative = "";
|
||||
} else {
|
||||
positive = std::string(p, dash); // Everything up to the dash
|
||||
@ -796,7 +771,7 @@ int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) {
|
||||
|
||||
bool should_handle = true;
|
||||
|
||||
if (!GTEST_FLAG_GET(catch_exceptions))
|
||||
if (!GTEST_FLAG(catch_exceptions))
|
||||
should_handle = false;
|
||||
else if (exception_code == EXCEPTION_BREAKPOINT)
|
||||
should_handle = false;
|
||||
@ -1049,10 +1024,11 @@ int UnitTestImpl::test_to_run_count() const {
|
||||
// trace but Bar() and CurrentOsStackTraceExceptTop() won't.
|
||||
std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) {
|
||||
return os_stack_trace_getter()->CurrentStackTrace(
|
||||
static_cast<int>(GTEST_FLAG_GET(stack_trace_depth)), skip_count + 1
|
||||
static_cast<int>(GTEST_FLAG(stack_trace_depth)),
|
||||
skip_count + 1
|
||||
// Skips the user-specified number of frames plus this function
|
||||
// itself.
|
||||
); // NOLINT
|
||||
); // NOLINT
|
||||
}
|
||||
|
||||
// A helper class for measuring elapsed times.
|
||||
@ -2647,7 +2623,7 @@ Result HandleExceptionsInMethodIfSupported(
|
||||
// try {
|
||||
// // Perform the test method.
|
||||
// } catch (...) {
|
||||
// if (GTEST_FLAG_GET(catch_exceptions))
|
||||
// if (GTEST_FLAG(catch_exceptions))
|
||||
// // Report the exception as failure.
|
||||
// else
|
||||
// throw; // Re-throws the original exception.
|
||||
@ -2855,20 +2831,20 @@ void UnitTestImpl::RegisterParameterizedTests() {
|
||||
// Creates the test object, runs it, records its result, and then
|
||||
// deletes it.
|
||||
void TestInfo::Run() {
|
||||
TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
|
||||
if (!should_run_) {
|
||||
if (is_disabled_) repeater->OnTestDisabled(*this);
|
||||
return;
|
||||
}
|
||||
if (!should_run_) return;
|
||||
|
||||
// Tells UnitTest where to store test result.
|
||||
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
|
||||
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.
|
||||
repeater->OnTestStart(*this);
|
||||
|
||||
result_.set_start_timestamp(internal::GetTimeInMillis());
|
||||
internal::Timer timer;
|
||||
|
||||
impl->os_stack_trace_getter()->UponLeavingGTest();
|
||||
|
||||
// Creates the test object.
|
||||
@ -3033,18 +3009,11 @@ void TestSuite::Run() {
|
||||
internal::HandleExceptionsInMethodIfSupported(
|
||||
this, &TestSuite::RunSetUpTestSuite, "SetUpTestSuite()");
|
||||
|
||||
const bool skip_all = ad_hoc_test_result().Failed();
|
||||
|
||||
start_timestamp_ = internal::GetTimeInMillis();
|
||||
internal::Timer timer;
|
||||
for (int i = 0; i < total_test_count(); i++) {
|
||||
if (skip_all) {
|
||||
GetMutableTestInfo(i)->Skip();
|
||||
} else {
|
||||
GetMutableTestInfo(i)->Run();
|
||||
}
|
||||
if (GTEST_FLAG_GET(fail_fast) &&
|
||||
GetMutableTestInfo(i)->result()->Failed()) {
|
||||
GetMutableTestInfo(i)->Run();
|
||||
if (GTEST_FLAG(fail_fast) && GetMutableTestInfo(i)->result()->Failed()) {
|
||||
for (int j = i + 1; j < total_test_count(); j++) {
|
||||
GetMutableTestInfo(j)->Skip();
|
||||
}
|
||||
@ -3263,8 +3232,7 @@ static const char* GetAnsiColorCode(GTestColor color) {
|
||||
|
||||
// Returns true if and only if Google Test should use colors in the output.
|
||||
bool ShouldUseColor(bool stdout_is_tty) {
|
||||
std::string c = GTEST_FLAG_GET(color);
|
||||
const char* const gtest_color = c.c_str();
|
||||
const char* const gtest_color = GTEST_FLAG(color).c_str();
|
||||
|
||||
if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) {
|
||||
#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW
|
||||
@ -3396,7 +3364,6 @@ class PrettyUnitTestResultPrinter : public TestEventListener {
|
||||
#endif // OnTestCaseStart
|
||||
|
||||
void OnTestStart(const TestInfo& test_info) override;
|
||||
void OnTestDisabled(const TestInfo& test_info) override;
|
||||
|
||||
void OnTestPartResult(const TestPartResult& result) override;
|
||||
void OnTestEnd(const TestInfo& test_info) override;
|
||||
@ -3420,11 +3387,10 @@ class PrettyUnitTestResultPrinter : public TestEventListener {
|
||||
// Fired before each iteration of tests starts.
|
||||
void PrettyUnitTestResultPrinter::OnTestIterationStart(
|
||||
const UnitTest& unit_test, int iteration) {
|
||||
if (GTEST_FLAG_GET(repeat) != 1)
|
||||
if (GTEST_FLAG(repeat) != 1)
|
||||
printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1);
|
||||
|
||||
std::string f = GTEST_FLAG_GET(filter);
|
||||
const char* const filter = f.c_str();
|
||||
const char* const filter = GTEST_FLAG(filter).c_str();
|
||||
|
||||
// Prints the filter if it's not *. This reminds the user that some
|
||||
// tests may be skipped.
|
||||
@ -3440,7 +3406,7 @@ void PrettyUnitTestResultPrinter::OnTestIterationStart(
|
||||
internal::posix::GetEnv(kTestTotalShards));
|
||||
}
|
||||
|
||||
if (GTEST_FLAG_GET(shuffle)) {
|
||||
if (GTEST_FLAG(shuffle)) {
|
||||
ColoredPrintf(GTestColor::kYellow,
|
||||
"Note: Randomizing tests' orders with a seed of %d .\n",
|
||||
unit_test.random_seed());
|
||||
@ -3496,13 +3462,6 @@ void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) {
|
||||
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.
|
||||
void PrettyUnitTestResultPrinter::OnTestPartResult(
|
||||
const TestPartResult& result) {
|
||||
@ -3530,7 +3489,7 @@ void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {
|
||||
if (test_info.result()->Failed())
|
||||
PrintFullTestCommentIfPresent(test_info);
|
||||
|
||||
if (GTEST_FLAG_GET(print_time)) {
|
||||
if (GTEST_FLAG(print_time)) {
|
||||
printf(" (%s ms)\n", internal::StreamableToString(
|
||||
test_info.result()->elapsed_time()).c_str());
|
||||
} else {
|
||||
@ -3541,7 +3500,7 @@ void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {
|
||||
|
||||
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) {
|
||||
if (!GTEST_FLAG_GET(print_time)) return;
|
||||
if (!GTEST_FLAG(print_time)) return;
|
||||
|
||||
const std::string counts =
|
||||
FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
|
||||
@ -3552,7 +3511,7 @@ void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) {
|
||||
}
|
||||
#else
|
||||
void PrettyUnitTestResultPrinter::OnTestSuiteEnd(const TestSuite& test_suite) {
|
||||
if (!GTEST_FLAG_GET(print_time)) return;
|
||||
if (!GTEST_FLAG(print_time)) return;
|
||||
|
||||
const std::string counts =
|
||||
FormatCountableNoun(test_suite.test_to_run_count(), "test", "tests");
|
||||
@ -3648,7 +3607,7 @@ void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
|
||||
printf("%s from %s ran.",
|
||||
FormatTestCount(unit_test.test_to_run_count()).c_str(),
|
||||
FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str());
|
||||
if (GTEST_FLAG_GET(print_time)) {
|
||||
if (GTEST_FLAG(print_time)) {
|
||||
printf(" (%s ms total)",
|
||||
internal::StreamableToString(unit_test.elapsed_time()).c_str());
|
||||
}
|
||||
@ -3669,7 +3628,7 @@ void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
|
||||
}
|
||||
|
||||
int num_disabled = unit_test.reportable_disabled_test_count();
|
||||
if (num_disabled && !GTEST_FLAG_GET(also_run_disabled_tests)) {
|
||||
if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) {
|
||||
if (unit_test.Passed()) {
|
||||
printf("\n"); // Add a spacer if no FAILURE banner is displayed.
|
||||
}
|
||||
@ -3705,7 +3664,6 @@ class BriefUnitTestResultPrinter : public TestEventListener {
|
||||
#endif // OnTestCaseStart
|
||||
|
||||
void OnTestStart(const TestInfo& /*test_info*/) override {}
|
||||
void OnTestDisabled(const TestInfo& /*test_info*/) override {}
|
||||
|
||||
void OnTestPartResult(const TestPartResult& result) override;
|
||||
void OnTestEnd(const TestInfo& test_info) override;
|
||||
@ -3742,7 +3700,7 @@ void BriefUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {
|
||||
PrintTestName(test_info.test_suite_name(), test_info.name());
|
||||
PrintFullTestCommentIfPresent(test_info);
|
||||
|
||||
if (GTEST_FLAG_GET(print_time)) {
|
||||
if (GTEST_FLAG(print_time)) {
|
||||
printf(" (%s ms)\n",
|
||||
internal::StreamableToString(test_info.result()->elapsed_time())
|
||||
.c_str());
|
||||
@ -3759,7 +3717,7 @@ void BriefUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
|
||||
printf("%s from %s ran.",
|
||||
FormatTestCount(unit_test.test_to_run_count()).c_str(),
|
||||
FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str());
|
||||
if (GTEST_FLAG_GET(print_time)) {
|
||||
if (GTEST_FLAG(print_time)) {
|
||||
printf(" (%s ms total)",
|
||||
internal::StreamableToString(unit_test.elapsed_time()).c_str());
|
||||
}
|
||||
@ -3774,7 +3732,7 @@ void BriefUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
|
||||
}
|
||||
|
||||
int num_disabled = unit_test.reportable_disabled_test_count();
|
||||
if (num_disabled && !GTEST_FLAG_GET(also_run_disabled_tests)) {
|
||||
if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) {
|
||||
if (unit_test.Passed()) {
|
||||
printf("\n"); // Add a spacer if no FAILURE banner is displayed.
|
||||
}
|
||||
@ -3812,7 +3770,6 @@ class TestEventRepeater : public TestEventListener {
|
||||
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
void OnTestSuiteStart(const TestSuite& parameter) override;
|
||||
void OnTestStart(const TestInfo& test_info) override;
|
||||
void OnTestDisabled(const TestInfo& test_info) override;
|
||||
void OnTestPartResult(const TestPartResult& result) override;
|
||||
void OnTestEnd(const TestInfo& test_info) override;
|
||||
// Legacy API is deprecated but still available
|
||||
@ -3883,7 +3840,6 @@ GTEST_REPEATER_METHOD_(OnTestCaseStart, TestSuite)
|
||||
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
GTEST_REPEATER_METHOD_(OnTestSuiteStart, TestSuite)
|
||||
GTEST_REPEATER_METHOD_(OnTestStart, TestInfo)
|
||||
GTEST_REPEATER_METHOD_(OnTestDisabled, TestInfo)
|
||||
GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult)
|
||||
GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest)
|
||||
GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest)
|
||||
@ -3934,13 +3890,12 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener {
|
||||
private:
|
||||
// Is c a whitespace character that is normalized to a space character
|
||||
// when it appears in an XML attribute value?
|
||||
static bool IsNormalizableWhitespace(unsigned char c) {
|
||||
return c == '\t' || c == '\n' || c == '\r';
|
||||
static bool IsNormalizableWhitespace(char c) {
|
||||
return c == 0x9 || c == 0xA || c == 0xD;
|
||||
}
|
||||
|
||||
// May c appear in a well-formed XML document?
|
||||
// https://www.w3.org/TR/REC-xml/#charsets
|
||||
static bool IsValidXmlCharacter(unsigned char c) {
|
||||
static bool IsValidXmlCharacter(char c) {
|
||||
return IsNormalizableWhitespace(c) || c >= 0x20;
|
||||
}
|
||||
|
||||
@ -4109,6 +4064,7 @@ std::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(
|
||||
|
||||
// The following routines generate an XML representation of a UnitTest
|
||||
// object.
|
||||
// GOOGLETEST_CM0009 DO NOT DELETE
|
||||
//
|
||||
// This is how Google Test concepts map to the DTD:
|
||||
//
|
||||
@ -4260,7 +4216,7 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
|
||||
OutputXmlAttribute(stream, kTestsuite, "type_param",
|
||||
test_info.type_param());
|
||||
}
|
||||
if (GTEST_FLAG_GET(list_tests)) {
|
||||
if (GTEST_FLAG(list_tests)) {
|
||||
OutputXmlAttribute(stream, kTestsuite, "file", test_info.file());
|
||||
OutputXmlAttribute(stream, kTestsuite, "line",
|
||||
StreamableToString(test_info.line()));
|
||||
@ -4339,7 +4295,7 @@ void XmlUnitTestResultPrinter::PrintXmlTestSuite(std::ostream* stream,
|
||||
OutputXmlAttribute(stream, kTestsuite, "name", test_suite.name());
|
||||
OutputXmlAttribute(stream, kTestsuite, "tests",
|
||||
StreamableToString(test_suite.reportable_test_count()));
|
||||
if (!GTEST_FLAG_GET(list_tests)) {
|
||||
if (!GTEST_FLAG(list_tests)) {
|
||||
OutputXmlAttribute(stream, kTestsuite, "failures",
|
||||
StreamableToString(test_suite.failed_test_count()));
|
||||
OutputXmlAttribute(
|
||||
@ -4387,7 +4343,7 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream,
|
||||
stream, kTestsuites, "timestamp",
|
||||
FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp()));
|
||||
|
||||
if (GTEST_FLAG_GET(shuffle)) {
|
||||
if (GTEST_FLAG(shuffle)) {
|
||||
OutputXmlAttribute(stream, kTestsuites, "random_seed",
|
||||
StreamableToString(unit_test.random_seed()));
|
||||
}
|
||||
@ -4454,15 +4410,15 @@ void XmlUnitTestResultPrinter::OutputXmlTestProperties(
|
||||
return;
|
||||
}
|
||||
|
||||
*stream << " <" << kProperties << ">\n";
|
||||
*stream << "<" << kProperties << ">\n";
|
||||
for (int i = 0; i < result.test_property_count(); ++i) {
|
||||
const TestProperty& property = result.GetTestProperty(i);
|
||||
*stream << " <" << kProperty;
|
||||
*stream << "<" << kProperty;
|
||||
*stream << " name=\"" << EscapeXmlAttribute(property.key()) << "\"";
|
||||
*stream << " value=\"" << EscapeXmlAttribute(property.value()) << "\"";
|
||||
*stream << "/>\n";
|
||||
}
|
||||
*stream << " </" << kProperties << ">\n";
|
||||
*stream << "</" << kProperties << ">\n";
|
||||
}
|
||||
|
||||
// End XmlUnitTestResultPrinter
|
||||
@ -4664,7 +4620,7 @@ void JsonUnitTestResultPrinter::OutputJsonTestSuiteForTestResult(
|
||||
*stream << Indent(4) << "{\n";
|
||||
OutputJsonKey(stream, "testsuite", "name", "NonTestSuiteFailure", Indent(6));
|
||||
OutputJsonKey(stream, "testsuite", "tests", 1, Indent(6));
|
||||
if (!GTEST_FLAG_GET(list_tests)) {
|
||||
if (!GTEST_FLAG(list_tests)) {
|
||||
OutputJsonKey(stream, "testsuite", "failures", 1, Indent(6));
|
||||
OutputJsonKey(stream, "testsuite", "disabled", 0, Indent(6));
|
||||
OutputJsonKey(stream, "testsuite", "skipped", 0, Indent(6));
|
||||
@ -4718,7 +4674,7 @@ void JsonUnitTestResultPrinter::OutputJsonTestInfo(::std::ostream* stream,
|
||||
OutputJsonKey(stream, kTestsuite, "type_param", test_info.type_param(),
|
||||
kIndent);
|
||||
}
|
||||
if (GTEST_FLAG_GET(list_tests)) {
|
||||
if (GTEST_FLAG(list_tests)) {
|
||||
OutputJsonKey(stream, kTestsuite, "file", test_info.file(), kIndent);
|
||||
OutputJsonKey(stream, kTestsuite, "line", test_info.line(), kIndent, false);
|
||||
*stream << "\n" << Indent(8) << "}";
|
||||
@ -4782,7 +4738,7 @@ void JsonUnitTestResultPrinter::PrintJsonTestSuite(
|
||||
OutputJsonKey(stream, kTestsuite, "name", test_suite.name(), kIndent);
|
||||
OutputJsonKey(stream, kTestsuite, "tests", test_suite.reportable_test_count(),
|
||||
kIndent);
|
||||
if (!GTEST_FLAG_GET(list_tests)) {
|
||||
if (!GTEST_FLAG(list_tests)) {
|
||||
OutputJsonKey(stream, kTestsuite, "failures",
|
||||
test_suite.failed_test_count(), kIndent);
|
||||
OutputJsonKey(stream, kTestsuite, "disabled",
|
||||
@ -4829,7 +4785,7 @@ void JsonUnitTestResultPrinter::PrintJsonUnitTest(std::ostream* stream,
|
||||
OutputJsonKey(stream, kTestsuites, "disabled",
|
||||
unit_test.reportable_disabled_test_count(), kIndent);
|
||||
OutputJsonKey(stream, kTestsuites, "errors", 0, kIndent);
|
||||
if (GTEST_FLAG_GET(shuffle)) {
|
||||
if (GTEST_FLAG(shuffle)) {
|
||||
OutputJsonKey(stream, kTestsuites, "random_seed", unit_test.random_seed(),
|
||||
kIndent);
|
||||
}
|
||||
@ -5006,7 +4962,7 @@ std::string OsStackTraceGetter::CurrentStackTrace(int max_depth, int skip_count)
|
||||
|
||||
for (int i = 0; i < raw_stack_size; ++i) {
|
||||
if (raw_stack[i] == caller_frame &&
|
||||
!GTEST_FLAG_GET(show_internal_stack_frames)) {
|
||||
!GTEST_FLAG(show_internal_stack_frames)) {
|
||||
// Add a marker to the trace and stop adding frames.
|
||||
absl::StrAppend(&result, kElidedFramesMarker, "\n");
|
||||
break;
|
||||
@ -5056,7 +5012,7 @@ class ScopedPrematureExitFile {
|
||||
// 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
|
||||
// don't want to fail the test because of this.
|
||||
FILE* pfile = posix::FOpen(premature_exit_filepath_.c_str(), "w");
|
||||
FILE* pfile = posix::FOpen(premature_exit_filepath, "w");
|
||||
fwrite("0", 1, 1, pfile);
|
||||
fclose(pfile);
|
||||
}
|
||||
@ -5358,7 +5314,7 @@ void UnitTest::AddTestPartResult(
|
||||
// in the code (perhaps in order to use Google Test assertions
|
||||
// with another testing framework) and specify the former on the
|
||||
// command line for debugging.
|
||||
if (GTEST_FLAG_GET(break_on_failure)) {
|
||||
if (GTEST_FLAG(break_on_failure)) {
|
||||
#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT
|
||||
// Using DebugBreak on Windows allows gtest to still break into a debugger
|
||||
// when a failure happens and both the --gtest_break_on_failure and
|
||||
@ -5375,7 +5331,7 @@ void UnitTest::AddTestPartResult(
|
||||
// portability: some debuggers don't correctly trap abort().
|
||||
*static_cast<volatile int*>(nullptr) = 1;
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
} else if (GTEST_FLAG_GET(throw_on_failure)) {
|
||||
} else if (GTEST_FLAG(throw_on_failure)) {
|
||||
#if GTEST_HAS_EXCEPTIONS
|
||||
throw internal::GoogleTestFailureException(result);
|
||||
#else
|
||||
@ -5404,7 +5360,7 @@ void UnitTest::RecordProperty(const std::string& key,
|
||||
// from the main thread.
|
||||
int UnitTest::Run() {
|
||||
const bool in_death_test_child_process =
|
||||
GTEST_FLAG_GET(internal_run_death_test).length() > 0;
|
||||
internal::GTEST_FLAG(internal_run_death_test).length() > 0;
|
||||
|
||||
// Google Test implements this protocol for catching that a test
|
||||
// program exits before returning control to Google Test:
|
||||
@ -5434,7 +5390,7 @@ int UnitTest::Run() {
|
||||
|
||||
// Captures the value of GTEST_FLAG(catch_exceptions). This value will be
|
||||
// used for the duration of the program.
|
||||
impl()->set_catch_exceptions(GTEST_FLAG_GET(catch_exceptions));
|
||||
impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions));
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
// Either the user wants Google Test to catch exceptions thrown by the
|
||||
@ -5461,7 +5417,7 @@ int UnitTest::Run() {
|
||||
// this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement
|
||||
// executed. Google Test will notify the user of any unexpected
|
||||
// failure via stderr.
|
||||
if (!GTEST_FLAG_GET(break_on_failure))
|
||||
if (!GTEST_FLAG(break_on_failure))
|
||||
_set_abort_behavior(
|
||||
0x0, // Clear the following flags:
|
||||
_WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump.
|
||||
@ -5643,7 +5599,7 @@ void UnitTestImpl::ConfigureXmlOutput() {
|
||||
// Initializes event listeners for streaming test results in string form.
|
||||
// Must not be called before InitGoogleTest.
|
||||
void UnitTestImpl::ConfigureStreamingOutput() {
|
||||
const std::string& target = GTEST_FLAG_GET(stream_result_to);
|
||||
const std::string& target = GTEST_FLAG(stream_result_to);
|
||||
if (!target.empty()) {
|
||||
const size_t pos = target.find(':');
|
||||
if (pos != std::string::npos) {
|
||||
@ -5686,7 +5642,7 @@ void UnitTestImpl::PostFlagParsingInit() {
|
||||
// to shut down the default XML output before invoking RUN_ALL_TESTS.
|
||||
ConfigureXmlOutput();
|
||||
|
||||
if (GTEST_FLAG_GET(brief)) {
|
||||
if (GTEST_FLAG(brief)) {
|
||||
listeners()->SetDefaultResultPrinter(new BriefUnitTestResultPrinter);
|
||||
}
|
||||
|
||||
@ -5696,7 +5652,7 @@ void UnitTestImpl::PostFlagParsingInit() {
|
||||
#endif // GTEST_CAN_STREAM_RESULTS_
|
||||
|
||||
#if GTEST_HAS_ABSL
|
||||
if (GTEST_FLAG_GET(install_failure_signal_handler)) {
|
||||
if (GTEST_FLAG(install_failure_signal_handler)) {
|
||||
absl::FailureSignalHandlerOptions options;
|
||||
absl::InstallFailureSignalHandler(options);
|
||||
}
|
||||
@ -5829,15 +5785,14 @@ bool UnitTestImpl::RunAllTests() {
|
||||
: IGNORE_SHARDING_PROTOCOL) > 0;
|
||||
|
||||
// Lists the tests and exits if the --gtest_list_tests flag was specified.
|
||||
if (GTEST_FLAG_GET(list_tests)) {
|
||||
if (GTEST_FLAG(list_tests)) {
|
||||
// This must be called *after* FilterTests() has been called.
|
||||
ListTestsMatchingFilter();
|
||||
return true;
|
||||
}
|
||||
|
||||
random_seed_ = GTEST_FLAG_GET(shuffle)
|
||||
? GetRandomSeedFromFlag(GTEST_FLAG_GET(random_seed))
|
||||
: 0;
|
||||
random_seed_ = GTEST_FLAG(shuffle) ?
|
||||
GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0;
|
||||
|
||||
// True if and only if at least one test has failed.
|
||||
bool failed = false;
|
||||
@ -5849,21 +5804,9 @@ bool UnitTestImpl::RunAllTests() {
|
||||
|
||||
// How many times to repeat the tests? We don't want to repeat them
|
||||
// when we are inside the subprocess of a death test.
|
||||
const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG_GET(repeat);
|
||||
|
||||
const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat);
|
||||
// Repeats forever if the repeat count is negative.
|
||||
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++) {
|
||||
// We want to preserve failures generated by ad-hoc test
|
||||
// assertions executed before RUN_ALL_TESTS().
|
||||
@ -5872,7 +5815,7 @@ bool UnitTestImpl::RunAllTests() {
|
||||
Timer timer;
|
||||
|
||||
// Shuffles test suites and tests if requested.
|
||||
if (has_tests_to_run && GTEST_FLAG_GET(shuffle)) {
|
||||
if (has_tests_to_run && GTEST_FLAG(shuffle)) {
|
||||
random()->Reseed(static_cast<uint32_t>(random_seed_));
|
||||
// This should be done before calling OnTestIterationStart(),
|
||||
// such that a test event listener can see the actual test order
|
||||
@ -5885,13 +5828,10 @@ bool UnitTestImpl::RunAllTests() {
|
||||
|
||||
// Runs each test suite if there is at least one test to run.
|
||||
if (has_tests_to_run) {
|
||||
// Sets up all environments beforehand. If test environments aren't
|
||||
// recreated for each iteration, only do so on the first iteration.
|
||||
if (i == 0 || recreate_environments_when_repeating) {
|
||||
repeater->OnEnvironmentsSetUpStart(*parent_);
|
||||
ForEach(environments_, SetUpEnvironment);
|
||||
repeater->OnEnvironmentsSetUpEnd(*parent_);
|
||||
}
|
||||
// Sets up all environments beforehand.
|
||||
repeater->OnEnvironmentsSetUpStart(*parent_);
|
||||
ForEach(environments_, SetUpEnvironment);
|
||||
repeater->OnEnvironmentsSetUpEnd(*parent_);
|
||||
|
||||
// Runs the tests only if there was no fatal failure or skip triggered
|
||||
// during global set-up.
|
||||
@ -5913,7 +5853,7 @@ bool UnitTestImpl::RunAllTests() {
|
||||
for (int test_index = 0; test_index < total_test_suite_count();
|
||||
test_index++) {
|
||||
GetMutableSuiteCase(test_index)->Run();
|
||||
if (GTEST_FLAG_GET(fail_fast) &&
|
||||
if (GTEST_FLAG(fail_fast) &&
|
||||
GetMutableSuiteCase(test_index)->Failed()) {
|
||||
for (int j = test_index + 1; j < total_test_suite_count(); j++) {
|
||||
GetMutableSuiteCase(j)->Skip();
|
||||
@ -5931,15 +5871,11 @@ bool UnitTestImpl::RunAllTests() {
|
||||
}
|
||||
}
|
||||
|
||||
// Tears down all environments in reverse order afterwards. If test
|
||||
// environments aren't recreated for each iteration, only do so on the
|
||||
// last iteration.
|
||||
if (i == repeat - 1 || recreate_environments_when_repeating) {
|
||||
repeater->OnEnvironmentsTearDownStart(*parent_);
|
||||
std::for_each(environments_.rbegin(), environments_.rend(),
|
||||
TearDownEnvironment);
|
||||
repeater->OnEnvironmentsTearDownEnd(*parent_);
|
||||
}
|
||||
// Tears down all environments in reverse order afterwards.
|
||||
repeater->OnEnvironmentsTearDownStart(*parent_);
|
||||
std::for_each(environments_.rbegin(), environments_.rend(),
|
||||
TearDownEnvironment);
|
||||
repeater->OnEnvironmentsTearDownEnd(*parent_);
|
||||
}
|
||||
|
||||
elapsed_time_ = timer.Elapsed();
|
||||
@ -5960,7 +5896,7 @@ bool UnitTestImpl::RunAllTests() {
|
||||
// (it's always safe to unshuffle the tests).
|
||||
UnshuffleTests();
|
||||
|
||||
if (GTEST_FLAG_GET(shuffle)) {
|
||||
if (GTEST_FLAG(shuffle)) {
|
||||
// Picks a new random seed for each iteration.
|
||||
random_seed_ = GetNextRandomSeed(random_seed_);
|
||||
}
|
||||
@ -6117,7 +6053,7 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
|
||||
test_info->matches_filter_ = matches_filter;
|
||||
|
||||
const bool is_runnable =
|
||||
(GTEST_FLAG_GET(also_run_disabled_tests) || !is_disabled) &&
|
||||
(GTEST_FLAG(also_run_disabled_tests) || !is_disabled) &&
|
||||
matches_filter;
|
||||
|
||||
const bool is_in_another_shard =
|
||||
@ -6328,14 +6264,13 @@ bool SkipPrefix(const char* prefix, const char** pstr) {
|
||||
// part can be omitted.
|
||||
//
|
||||
// Returns the value of the flag, or NULL if the parsing failed.
|
||||
static const char* ParseFlagValue(const char* str, const char* flag_name,
|
||||
static const char* ParseFlagValue(const char* str, const char* flag,
|
||||
bool def_optional) {
|
||||
// str and flag must not be NULL.
|
||||
if (str == nullptr || flag_name == nullptr) return nullptr;
|
||||
if (str == nullptr || flag == nullptr) return nullptr;
|
||||
|
||||
// The flag must start with "--" followed by GTEST_FLAG_PREFIX_.
|
||||
const std::string flag_str =
|
||||
std::string("--") + GTEST_FLAG_PREFIX_ + flag_name;
|
||||
const std::string flag_str = std::string("--") + GTEST_FLAG_PREFIX_ + flag;
|
||||
const size_t flag_len = flag_str.length();
|
||||
if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr;
|
||||
|
||||
@ -6366,9 +6301,9 @@ static const char* ParseFlagValue(const char* str, const char* flag_name,
|
||||
//
|
||||
// On success, stores the value of the flag in *value, and returns
|
||||
// true. On failure, returns false without changing *value.
|
||||
static bool ParseFlag(const char* str, const char* flag_name, bool* value) {
|
||||
static bool ParseBoolFlag(const char* str, const char* flag, bool* value) {
|
||||
// Gets the value of the flag as a string.
|
||||
const char* const value_str = ParseFlagValue(str, flag_name, true);
|
||||
const char* const value_str = ParseFlagValue(str, flag, true);
|
||||
|
||||
// Aborts if the parsing failed.
|
||||
if (value_str == nullptr) return false;
|
||||
@ -6382,16 +6317,16 @@ static bool ParseFlag(const char* str, const char* flag_name, bool* value) {
|
||||
//
|
||||
// On success, stores the value of the flag in *value, and returns
|
||||
// true. On failure, returns false without changing *value.
|
||||
bool ParseFlag(const char* str, const char* flag_name, int32_t* value) {
|
||||
bool ParseInt32Flag(const char* str, const char* flag, int32_t* value) {
|
||||
// Gets the value of the flag as a string.
|
||||
const char* const value_str = ParseFlagValue(str, flag_name, false);
|
||||
const char* const value_str = ParseFlagValue(str, flag, false);
|
||||
|
||||
// Aborts if the parsing failed.
|
||||
if (value_str == nullptr) return false;
|
||||
|
||||
// Sets *value to the value of the flag.
|
||||
return ParseInt32(Message() << "The value of flag --" << flag_name, value_str,
|
||||
value);
|
||||
return ParseInt32(Message() << "The value of flag --" << flag,
|
||||
value_str, value);
|
||||
}
|
||||
|
||||
// Parses a string for a string flag, in the form of "--flag=value".
|
||||
@ -6399,9 +6334,9 @@ bool ParseFlag(const char* str, const char* flag_name, int32_t* value) {
|
||||
// On success, stores the value of the flag in *value, and returns
|
||||
// true. On failure, returns false without changing *value.
|
||||
template <typename String>
|
||||
static bool ParseFlag(const char* str, const char* flag_name, String* value) {
|
||||
static bool ParseStringFlag(const char* str, const char* flag, String* value) {
|
||||
// Gets the value of the flag as a string.
|
||||
const char* const value_str = ParseFlagValue(str, flag_name, false);
|
||||
const char* const value_str = ParseFlagValue(str, flag, false);
|
||||
|
||||
// Aborts if the parsing failed.
|
||||
if (value_str == nullptr) return false;
|
||||
@ -6502,10 +6437,6 @@ static const char kColorEncodedHelpMessage[] =
|
||||
"random_seed=@Y[NUMBER]@D\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"
|
||||
" @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"
|
||||
"Test Output:\n"
|
||||
" @G--" GTEST_FLAG_PREFIX_
|
||||
@ -6566,44 +6497,41 @@ static const char kColorEncodedHelpMessage[] =
|
||||
"@G<" GTEST_DEV_EMAIL_ ">@D.\n";
|
||||
|
||||
static bool ParseGoogleTestFlag(const char* const arg) {
|
||||
#define GTEST_INTERNAL_PARSE_FLAG(flag_name) \
|
||||
do { \
|
||||
auto value = GTEST_FLAG_GET(flag_name); \
|
||||
if (ParseFlag(arg, #flag_name, &value)) { \
|
||||
GTEST_FLAG_SET(flag_name, value); \
|
||||
return true; \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
GTEST_INTERNAL_PARSE_FLAG(also_run_disabled_tests);
|
||||
GTEST_INTERNAL_PARSE_FLAG(break_on_failure);
|
||||
GTEST_INTERNAL_PARSE_FLAG(catch_exceptions);
|
||||
GTEST_INTERNAL_PARSE_FLAG(color);
|
||||
GTEST_INTERNAL_PARSE_FLAG(death_test_style);
|
||||
GTEST_INTERNAL_PARSE_FLAG(death_test_use_fork);
|
||||
GTEST_INTERNAL_PARSE_FLAG(fail_fast);
|
||||
GTEST_INTERNAL_PARSE_FLAG(filter);
|
||||
GTEST_INTERNAL_PARSE_FLAG(internal_run_death_test);
|
||||
GTEST_INTERNAL_PARSE_FLAG(list_tests);
|
||||
GTEST_INTERNAL_PARSE_FLAG(output);
|
||||
GTEST_INTERNAL_PARSE_FLAG(brief);
|
||||
GTEST_INTERNAL_PARSE_FLAG(print_time);
|
||||
GTEST_INTERNAL_PARSE_FLAG(print_utf8);
|
||||
GTEST_INTERNAL_PARSE_FLAG(random_seed);
|
||||
GTEST_INTERNAL_PARSE_FLAG(repeat);
|
||||
GTEST_INTERNAL_PARSE_FLAG(recreate_environments_when_repeating);
|
||||
GTEST_INTERNAL_PARSE_FLAG(shuffle);
|
||||
GTEST_INTERNAL_PARSE_FLAG(stack_trace_depth);
|
||||
GTEST_INTERNAL_PARSE_FLAG(stream_result_to);
|
||||
GTEST_INTERNAL_PARSE_FLAG(throw_on_failure);
|
||||
return false;
|
||||
return ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag,
|
||||
>EST_FLAG(also_run_disabled_tests)) ||
|
||||
ParseBoolFlag(arg, kBreakOnFailureFlag,
|
||||
>EST_FLAG(break_on_failure)) ||
|
||||
ParseBoolFlag(arg, kCatchExceptionsFlag,
|
||||
>EST_FLAG(catch_exceptions)) ||
|
||||
ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) ||
|
||||
ParseStringFlag(arg, kDeathTestStyleFlag,
|
||||
>EST_FLAG(death_test_style)) ||
|
||||
ParseBoolFlag(arg, kDeathTestUseFork,
|
||||
>EST_FLAG(death_test_use_fork)) ||
|
||||
ParseBoolFlag(arg, kFailFast, >EST_FLAG(fail_fast)) ||
|
||||
ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) ||
|
||||
ParseStringFlag(arg, kInternalRunDeathTestFlag,
|
||||
>EST_FLAG(internal_run_death_test)) ||
|
||||
ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) ||
|
||||
ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) ||
|
||||
ParseBoolFlag(arg, kBriefFlag, >EST_FLAG(brief)) ||
|
||||
ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) ||
|
||||
ParseBoolFlag(arg, kPrintUTF8Flag, >EST_FLAG(print_utf8)) ||
|
||||
ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) ||
|
||||
ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) ||
|
||||
ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) ||
|
||||
ParseInt32Flag(arg, kStackTraceDepthFlag,
|
||||
>EST_FLAG(stack_trace_depth)) ||
|
||||
ParseStringFlag(arg, kStreamResultToFlag,
|
||||
>EST_FLAG(stream_result_to)) ||
|
||||
ParseBoolFlag(arg, kThrowOnFailureFlag, >EST_FLAG(throw_on_failure));
|
||||
}
|
||||
|
||||
#if GTEST_USE_OWN_FLAGFILE_FLAG_
|
||||
static void LoadFlagsFromFile(const std::string& path) {
|
||||
FILE* flagfile = posix::FOpen(path.c_str(), "r");
|
||||
if (!flagfile) {
|
||||
GTEST_LOG_(FATAL) << "Unable to open file \"" << GTEST_FLAG_GET(flagfile)
|
||||
GTEST_LOG_(FATAL) << "Unable to open file \"" << GTEST_FLAG(flagfile)
|
||||
<< "\"";
|
||||
}
|
||||
std::string contents(ReadEntireFile(flagfile));
|
||||
@ -6624,20 +6552,20 @@ static void LoadFlagsFromFile(const std::string& path) {
|
||||
// instantiated to either char or wchar_t.
|
||||
template <typename CharType>
|
||||
void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
|
||||
std::string flagfile_value;
|
||||
for (int i = 1; i < *argc; i++) {
|
||||
const std::string arg_string = StreamableToString(argv[i]);
|
||||
const char* const arg = arg_string.c_str();
|
||||
|
||||
using internal::ParseFlag;
|
||||
using internal::ParseBoolFlag;
|
||||
using internal::ParseInt32Flag;
|
||||
using internal::ParseStringFlag;
|
||||
|
||||
bool remove_flag = false;
|
||||
if (ParseGoogleTestFlag(arg)) {
|
||||
remove_flag = true;
|
||||
#if GTEST_USE_OWN_FLAGFILE_FLAG_
|
||||
} else if (ParseFlag(arg, "flagfile", &flagfile_value)) {
|
||||
GTEST_FLAG_SET(flagfile, flagfile_value);
|
||||
LoadFlagsFromFile(flagfile_value);
|
||||
} else if (ParseStringFlag(arg, kFlagfileFlag, >EST_FLAG(flagfile))) {
|
||||
LoadFlagsFromFile(GTEST_FLAG(flagfile));
|
||||
remove_flag = true;
|
||||
#endif // GTEST_USE_OWN_FLAGFILE_FLAG_
|
||||
} else if (arg_string == "--help" || arg_string == "-h" ||
|
||||
|
@ -30,6 +30,7 @@
|
||||
#
|
||||
# Bazel BUILD for The Google C++ Testing Framework (Google Test)
|
||||
|
||||
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test")
|
||||
load("@rules_python//python:defs.bzl", "py_library", "py_test")
|
||||
|
||||
licenses(["notice"])
|
||||
@ -94,7 +95,6 @@ cc_test(
|
||||
"googletest/test",
|
||||
],
|
||||
linkopts = select({
|
||||
"//:qnx": [],
|
||||
"//:windows": [],
|
||||
"//conditions:default": ["-pthread"],
|
||||
}),
|
||||
|
@ -147,19 +147,19 @@ class CatchCxxExceptionsTest(gtest_test_utils.TestCase):
|
||||
self.assertTrue(
|
||||
'CxxExceptionInConstructorTest::TearDownTestSuite() '
|
||||
'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT)
|
||||
self.assertFalse(
|
||||
self.assertTrue(
|
||||
'CxxExceptionInSetUpTestSuiteTest constructor '
|
||||
'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT)
|
||||
self.assertFalse(
|
||||
self.assertTrue(
|
||||
'CxxExceptionInSetUpTestSuiteTest destructor '
|
||||
'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT)
|
||||
self.assertFalse(
|
||||
self.assertTrue(
|
||||
'CxxExceptionInSetUpTestSuiteTest::SetUp() '
|
||||
'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT)
|
||||
self.assertFalse(
|
||||
self.assertTrue(
|
||||
'CxxExceptionInSetUpTestSuiteTest::TearDown() '
|
||||
'called as expected.' in EX_BINARY_OUTPUT, EX_BINARY_OUTPUT)
|
||||
self.assertFalse(
|
||||
self.assertTrue(
|
||||
'CxxExceptionInSetUpTestSuiteTest test body '
|
||||
'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
|
||||
// death test.
|
||||
TEST_F(TestForDeathTest, StaticMemberFunctionFastStyle) {
|
||||
GTEST_FLAG_SET(death_test_style, "fast");
|
||||
testing::GTEST_FLAG(death_test_style) = "fast";
|
||||
ASSERT_DEATH(StaticMemberFunction(), "death.*StaticMember");
|
||||
}
|
||||
|
||||
// Tests that a method of the test fixture can be used in a "fast"
|
||||
// style death test.
|
||||
TEST_F(TestForDeathTest, MemberFunctionFastStyle) {
|
||||
GTEST_FLAG_SET(death_test_style, "fast");
|
||||
testing::GTEST_FLAG(death_test_style) = "fast";
|
||||
should_die_ = true;
|
||||
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
|
||||
// changed.
|
||||
TEST_F(TestForDeathTest, FastDeathTestInChangedDir) {
|
||||
GTEST_FLAG_SET(death_test_style, "fast");
|
||||
testing::GTEST_FLAG(death_test_style) = "fast";
|
||||
|
||||
ChangeToRootDir();
|
||||
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.
|
||||
TEST_F(TestForDeathTest, FastSigprofActionSet) {
|
||||
GTEST_FLAG_SET(death_test_style, "fast");
|
||||
testing::GTEST_FLAG(death_test_style) = "fast";
|
||||
SetSigprofActionAndTimer();
|
||||
EXPECT_DEATH(_exit(1), "");
|
||||
struct sigaction old_signal_action;
|
||||
@ -441,7 +441,7 @@ TEST_F(TestForDeathTest, FastSigprofActionSet) {
|
||||
}
|
||||
|
||||
TEST_F(TestForDeathTest, ThreadSafeSigprofActionSet) {
|
||||
GTEST_FLAG_SET(death_test_style, "threadsafe");
|
||||
testing::GTEST_FLAG(death_test_style) = "threadsafe";
|
||||
SetSigprofActionAndTimer();
|
||||
EXPECT_DEATH(_exit(1), "");
|
||||
struct sigaction old_signal_action;
|
||||
@ -453,25 +453,25 @@ TEST_F(TestForDeathTest, ThreadSafeSigprofActionSet) {
|
||||
// Repeats a representative sample of death tests in the "threadsafe" style:
|
||||
|
||||
TEST_F(TestForDeathTest, StaticMemberFunctionThreadsafeStyle) {
|
||||
GTEST_FLAG_SET(death_test_style, "threadsafe");
|
||||
testing::GTEST_FLAG(death_test_style) = "threadsafe";
|
||||
ASSERT_DEATH(StaticMemberFunction(), "death.*StaticMember");
|
||||
}
|
||||
|
||||
TEST_F(TestForDeathTest, MemberFunctionThreadsafeStyle) {
|
||||
GTEST_FLAG_SET(death_test_style, "threadsafe");
|
||||
testing::GTEST_FLAG(death_test_style) = "threadsafe";
|
||||
should_die_ = true;
|
||||
EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction");
|
||||
}
|
||||
|
||||
TEST_F(TestForDeathTest, ThreadsafeDeathTestInLoop) {
|
||||
GTEST_FLAG_SET(death_test_style, "threadsafe");
|
||||
testing::GTEST_FLAG(death_test_style) = "threadsafe";
|
||||
|
||||
for (int i = 0; i < 3; ++i)
|
||||
EXPECT_EXIT(_exit(i), testing::ExitedWithCode(i), "") << ": i = " << i;
|
||||
}
|
||||
|
||||
TEST_F(TestForDeathTest, ThreadsafeDeathTestInChangedDir) {
|
||||
GTEST_FLAG_SET(death_test_style, "threadsafe");
|
||||
testing::GTEST_FLAG(death_test_style) = "threadsafe";
|
||||
|
||||
ChangeToRootDir();
|
||||
EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), "");
|
||||
@ -481,9 +481,9 @@ TEST_F(TestForDeathTest, ThreadsafeDeathTestInChangedDir) {
|
||||
}
|
||||
|
||||
TEST_F(TestForDeathTest, MixedStyles) {
|
||||
GTEST_FLAG_SET(death_test_style, "threadsafe");
|
||||
testing::GTEST_FLAG(death_test_style) = "threadsafe";
|
||||
EXPECT_DEATH(_exit(1), "");
|
||||
GTEST_FLAG_SET(death_test_style, "fast");
|
||||
testing::GTEST_FLAG(death_test_style) = "fast";
|
||||
EXPECT_DEATH(_exit(1), "");
|
||||
}
|
||||
|
||||
@ -496,8 +496,8 @@ void SetPthreadFlag() {
|
||||
}
|
||||
|
||||
TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) {
|
||||
if (!GTEST_FLAG_GET(death_test_use_fork)) {
|
||||
GTEST_FLAG_SET(death_test_style, "threadsafe");
|
||||
if (!testing::GTEST_FLAG(death_test_use_fork)) {
|
||||
testing::GTEST_FLAG(death_test_style) = "threadsafe";
|
||||
pthread_flag = false;
|
||||
ASSERT_EQ(0, pthread_atfork(&SetPthreadFlag, nullptr, nullptr));
|
||||
ASSERT_DEATH(_exit(1), "");
|
||||
@ -740,12 +740,10 @@ TEST(PopUpDeathTest, DoesNotShowPopUpOnAbort) {
|
||||
"any pop-up dialogs.\n");
|
||||
fflush(stdout);
|
||||
|
||||
EXPECT_DEATH(
|
||||
{
|
||||
GTEST_FLAG_SET(catch_exceptions, false);
|
||||
abort();
|
||||
},
|
||||
"");
|
||||
EXPECT_DEATH({
|
||||
testing::GTEST_FLAG(catch_exceptions) = false;
|
||||
abort();
|
||||
}, "");
|
||||
}
|
||||
# endif // GTEST_OS_WINDOWS
|
||||
|
||||
@ -876,19 +874,19 @@ TEST_F(TestForDeathTest, ExitMacros) {
|
||||
}
|
||||
|
||||
TEST_F(TestForDeathTest, ExitMacrosUsingFork) {
|
||||
GTEST_FLAG_SET(death_test_use_fork, true);
|
||||
testing::GTEST_FLAG(death_test_use_fork) = true;
|
||||
TestExitMacros();
|
||||
}
|
||||
|
||||
TEST_F(TestForDeathTest, InvalidStyle) {
|
||||
GTEST_FLAG_SET(death_test_style, "rococo");
|
||||
testing::GTEST_FLAG(death_test_style) = "rococo";
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
EXPECT_DEATH(_exit(0), "") << "This failure is expected.";
|
||||
}, "This failure is expected.");
|
||||
}
|
||||
|
||||
TEST_F(TestForDeathTest, DeathTestFailedOutput) {
|
||||
GTEST_FLAG_SET(death_test_style, "fast");
|
||||
testing::GTEST_FLAG(death_test_style) = "fast";
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
EXPECT_DEATH(DieWithMessage("death\n"),
|
||||
"expected message"),
|
||||
@ -897,7 +895,7 @@ TEST_F(TestForDeathTest, DeathTestFailedOutput) {
|
||||
}
|
||||
|
||||
TEST_F(TestForDeathTest, DeathTestUnexpectedReturnOutput) {
|
||||
GTEST_FLAG_SET(death_test_style, "fast");
|
||||
testing::GTEST_FLAG(death_test_style) = "fast";
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
EXPECT_DEATH({
|
||||
fprintf(stderr, "returning\n");
|
||||
@ -910,7 +908,7 @@ TEST_F(TestForDeathTest, DeathTestUnexpectedReturnOutput) {
|
||||
}
|
||||
|
||||
TEST_F(TestForDeathTest, DeathTestBadExitCodeOutput) {
|
||||
GTEST_FLAG_SET(death_test_style, "fast");
|
||||
testing::GTEST_FLAG(death_test_style) = "fast";
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
EXPECT_EXIT(DieWithMessage("exiting with rc 1\n"),
|
||||
testing::ExitedWithCode(3),
|
||||
@ -922,7 +920,7 @@ TEST_F(TestForDeathTest, DeathTestBadExitCodeOutput) {
|
||||
}
|
||||
|
||||
TEST_F(TestForDeathTest, DeathTestMultiLineMatchFail) {
|
||||
GTEST_FLAG_SET(death_test_style, "fast");
|
||||
testing::GTEST_FLAG(death_test_style) = "fast";
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
EXPECT_DEATH(DieWithMessage("line 1\nline 2\nline 3\n"),
|
||||
"line 1\nxyz\nline 3\n"),
|
||||
@ -933,7 +931,7 @@ TEST_F(TestForDeathTest, DeathTestMultiLineMatchFail) {
|
||||
}
|
||||
|
||||
TEST_F(TestForDeathTest, DeathTestMultiLineMatchPass) {
|
||||
GTEST_FLAG_SET(death_test_style, "fast");
|
||||
testing::GTEST_FLAG(death_test_style) = "fast";
|
||||
EXPECT_DEATH(DieWithMessage("line 1\nline 2\nline 3\n"),
|
||||
"line 1\nline 2\nline 3\n");
|
||||
}
|
||||
@ -1360,7 +1358,7 @@ TEST(ConditionalDeathMacrosDeathTest, ExpectsDeathWhenDeathTestsAvailable) {
|
||||
}
|
||||
|
||||
TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInFastStyle) {
|
||||
GTEST_FLAG_SET(death_test_style, "fast");
|
||||
testing::GTEST_FLAG(death_test_style) = "fast";
|
||||
EXPECT_FALSE(InDeathTestChild());
|
||||
EXPECT_DEATH({
|
||||
fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside");
|
||||
@ -1370,7 +1368,7 @@ TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInFastStyle) {
|
||||
}
|
||||
|
||||
TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInThreadSafeStyle) {
|
||||
GTEST_FLAG_SET(death_test_style, "threadsafe");
|
||||
testing::GTEST_FLAG(death_test_style) = "threadsafe";
|
||||
EXPECT_FALSE(InDeathTestChild());
|
||||
EXPECT_DEATH({
|
||||
fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside");
|
||||
|
@ -53,7 +53,7 @@ TEST(CxxExceptionDeathTest, ExceptionIsFailure) {
|
||||
} catch (...) { // NOLINT
|
||||
FAIL() << "An exception escaped a death test macro invocation "
|
||||
<< "with catch_exceptions "
|
||||
<< (GTEST_FLAG_GET(catch_exceptions) ? "enabled" : "disabled");
|
||||
<< (testing::GTEST_FLAG(catch_exceptions) ? "enabled" : "disabled");
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ TEST(CxxExceptionDeathTest, PrintsMessageForStdExceptions) {
|
||||
TEST(SehExceptionDeasTest, CatchExceptionsDoesNotInterfere) {
|
||||
EXPECT_DEATH(RaiseException(42, 0x0, 0, NULL), "")
|
||||
<< "with catch_exceptions "
|
||||
<< (GTEST_FLAG_GET(catch_exceptions) ? "enabled" : "disabled");
|
||||
<< (testing::GTEST_FLAG(catch_exceptions) ? "enabled" : "disabled");
|
||||
}
|
||||
# endif
|
||||
|
||||
@ -87,6 +87,6 @@ TEST(SehExceptionDeasTest, CatchExceptionsDoesNotInterfere) {
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
GTEST_FLAG_SET(catch_exceptions, GTEST_ENABLE_CATCH_EXCEPTIONS_ != 0);
|
||||
testing::GTEST_FLAG(catch_exceptions) = GTEST_ENABLE_CATCH_EXCEPTIONS_ != 0;
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
@ -48,67 +48,67 @@ TEST(GTestEnvVarTest, Dummy) {
|
||||
|
||||
void PrintFlag(const char* flag) {
|
||||
if (strcmp(flag, "break_on_failure") == 0) {
|
||||
cout << GTEST_FLAG_GET(break_on_failure);
|
||||
cout << GTEST_FLAG(break_on_failure);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(flag, "catch_exceptions") == 0) {
|
||||
cout << GTEST_FLAG_GET(catch_exceptions);
|
||||
cout << GTEST_FLAG(catch_exceptions);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(flag, "color") == 0) {
|
||||
cout << GTEST_FLAG_GET(color);
|
||||
cout << GTEST_FLAG(color);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(flag, "death_test_style") == 0) {
|
||||
cout << GTEST_FLAG_GET(death_test_style);
|
||||
cout << GTEST_FLAG(death_test_style);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(flag, "death_test_use_fork") == 0) {
|
||||
cout << GTEST_FLAG_GET(death_test_use_fork);
|
||||
cout << GTEST_FLAG(death_test_use_fork);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(flag, "fail_fast") == 0) {
|
||||
cout << GTEST_FLAG_GET(fail_fast);
|
||||
cout << GTEST_FLAG(fail_fast);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(flag, "filter") == 0) {
|
||||
cout << GTEST_FLAG_GET(filter);
|
||||
cout << GTEST_FLAG(filter);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(flag, "output") == 0) {
|
||||
cout << GTEST_FLAG_GET(output);
|
||||
cout << GTEST_FLAG(output);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(flag, "brief") == 0) {
|
||||
cout << GTEST_FLAG_GET(brief);
|
||||
cout << GTEST_FLAG(brief);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(flag, "print_time") == 0) {
|
||||
cout << GTEST_FLAG_GET(print_time);
|
||||
cout << GTEST_FLAG(print_time);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(flag, "repeat") == 0) {
|
||||
cout << GTEST_FLAG_GET(repeat);
|
||||
cout << GTEST_FLAG(repeat);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(flag, "stack_trace_depth") == 0) {
|
||||
cout << GTEST_FLAG_GET(stack_trace_depth);
|
||||
cout << GTEST_FLAG(stack_trace_depth);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(flag, "throw_on_failure") == 0) {
|
||||
cout << GTEST_FLAG_GET(throw_on_failure);
|
||||
cout << GTEST_FLAG(throw_on_failure);
|
||||
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