aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTING.md179
-rw-r--r--README.md5
-rw-r--r--googlemock/CMakeLists.txt4
-rw-r--r--googlemock/docs/cheat_sheet.md239
-rw-r--r--googlemock/docs/cook_book.md77
-rw-r--r--googlemock/docs/for_dummies.md12
-rw-r--r--googlemock/docs/gmock_faq.md6
-rw-r--r--googlemock/include/gmock/gmock-function-mocker.h35
-rw-r--r--googletest/CMakeLists.txt2
-rw-r--r--googletest/README.md6
-rw-r--r--googletest/docs/advanced.md4
-rw-r--r--googletest/docs/faq.md4
-rw-r--r--googletest/docs/pkgconfig.md53
-rw-r--r--googletest/docs/primer.md6
-rw-r--r--googletest/docs/pump_manual.md169
-rw-r--r--googletest/include/gtest/gtest.h15
-rw-r--r--googletest/src/gtest.cc41
-rw-r--r--googletest/test/googletest-json-outfiles-test.py6
-rw-r--r--googletest/test/googletest-json-output-unittest.py880
-rwxr-xr-xgoogletest/test/gtest_xml_outfiles_test.py8
-rwxr-xr-xgoogletest/test/gtest_xml_output_unittest.py92
-rwxr-xr-xgoogletest/test/gtest_xml_test_utils.py2
22 files changed, 1030 insertions, 815 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c273fdca..3c8ad310 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -2,16 +2,16 @@
## Contributor License Agreements
-We'd love to accept your patches! Before we can take them, we
-have to jump a couple of legal hurdles.
+We'd love to accept your patches! Before we can take them, we have to jump a
+couple of legal hurdles.
Please fill out either the individual or corporate Contributor License Agreement
(CLA).
- * If you are an individual writing original source code and you're sure you
+* If you are an individual writing original source code and you're sure you
own the intellectual property, then you'll need to sign an
[individual CLA](https://developers.google.com/open-source/cla/individual).
- * If you work for a company that wants to allow you to contribute your work,
+* If you work for a company that wants to allow you to contribute your work,
then you'll need to sign a
[corporate CLA](https://developers.google.com/open-source/cla/corporate).
@@ -20,144 +20,139 @@ instructions for how to sign and return it. Once we receive it, we'll be able to
accept your pull requests.
## Are you a Googler?
-If you are a Googler, plese make an attempt to submit an internal change rather
-than a GitHub Pull Request. If you are not able to submit an internal change
-a PR is acceptable as an alternative.
+If you are a Googler, plese make an attempt to submit an internal change rather
+than a GitHub Pull Request. If you are not able to submit an internal change a
+PR is acceptable as an alternative.
## Contributing A Patch
-1. Submit an issue describing your proposed change to the
- [issue tracker](https://github.com/google/googletest).
-1. Please don't mix more than one logical change per submittal,
- because it makes the history hard to follow. If you want to make a
- change that doesn't have a corresponding issue in the issue
- tracker, please create one.
-1. Also, coordinate with team members that are listed on the issue in
- question. This ensures that work isn't being duplicated and
- communicating your plan early also generally leads to better
- patches.
-1. If your proposed change is accepted, and you haven't already done so, sign a
- Contributor License Agreement (see details above).
-1. Fork the desired repo, develop and test your code changes.
-1. Ensure that your code adheres to the existing style in the sample to which
- you are contributing.
-1. Ensure that your code has an appropriate set of unit tests which all pass.
-1. Submit a pull request.
-
-## The Google Test and Google Mock Communities ##
+1. Submit an issue describing your proposed change to the
+ [issue tracker](https://github.com/google/googletest).
+1. Please don't mix more than one logical change per submittal, because it
+ makes the history hard to follow. If you want to make a change that doesn't
+ have a corresponding issue in the issue tracker, please create one.
+1. Also, coordinate with team members that are listed on the issue in question.
+ This ensures that work isn't being duplicated and communicating your plan
+ early also generally leads to better patches.
+1. If your proposed change is accepted, and you haven't already done so, sign a
+ Contributor License Agreement (see details above).
+1. Fork the desired repo, develop and test your code changes.
+1. Ensure that your code adheres to the existing style in the sample to which
+ you are contributing.
+1. Ensure that your code has an appropriate set of unit tests which all pass.
+1. Submit a pull request.
+
+## The Google Test and Google Mock Communities
The Google Test community exists primarily through the
-[discussion group](http://groups.google.com/group/googletestframework)
-and the GitHub repository.
-Likewise, the Google Mock community exists primarily through their own
-[discussion group](http://groups.google.com/group/googlemock).
-You are definitely encouraged to contribute to the
-discussion and you can also help us to keep the effectiveness of the
-group high by following and promoting the guidelines listed here.
-
-### Please Be Friendly ###
-
-Showing courtesy and respect to others is a vital part of the Google
-culture, and we strongly encourage everyone participating in Google
-Test development to join us in accepting nothing less. Of course,
-being courteous is not the same as failing to constructively disagree
-with each other, but it does mean that we should be respectful of each
-other when enumerating the 42 technical reasons that a particular
-proposal may not be the best choice. There's never a reason to be
-antagonistic or dismissive toward anyone who is sincerely trying to
+[discussion group](http://groups.google.com/group/googletestframework) and the
+GitHub repository. Likewise, the Google Mock community exists primarily through
+their own [discussion group](http://groups.google.com/group/googlemock). You are
+definitely encouraged to contribute to the discussion and you can also help us
+to keep the effectiveness of the group high by following and promoting the
+guidelines listed here.
+
+### Please Be Friendly
+
+Showing courtesy and respect to others is a vital part of the Google culture,
+and we strongly encourage everyone participating in Google Test development to
+join us in accepting nothing less. Of course, being courteous is not the same as
+failing to constructively disagree with each other, but it does mean that we
+should be respectful of each other when enumerating the 42 technical reasons
+that a particular proposal may not be the best choice. There's never a reason to
+be antagonistic or dismissive toward anyone who is sincerely trying to
contribute to a discussion.
-Sure, C++ testing is serious business and all that, but it's also
-a lot of fun. Let's keep it that way. Let's strive to be one of the
-friendliest communities in all of open source.
+Sure, C++ testing is serious business and all that, but it's also a lot of fun.
+Let's keep it that way. Let's strive to be one of the friendliest communities in
+all of open source.
-As always, discuss Google Test in the official GoogleTest discussion group.
-You don't have to actually submit code in order to sign up. Your participation
+As always, discuss Google Test in the official GoogleTest discussion group. You
+don't have to actually submit code in order to sign up. Your participation
itself is a valuable contribution.
## Style
-To keep the source consistent, readable, diffable and easy to merge,
-we use a fairly rigid coding style, as defined by the [google-styleguide](https://github.com/google/styleguide) project. All patches will be expected
-to conform to the style outlined [here](https://google.github.io/styleguide/cppguide.html).
-Use [.clang-format](https://github.com/google/googletest/blob/master/.clang-format) to check your formatting
+To keep the source consistent, readable, diffable and easy to merge, we use a
+fairly rigid coding style, as defined by the
+[google-styleguide](https://github.com/google/styleguide) project. All patches
+will be expected to conform to the style outlined
+[here](https://google.github.io/styleguide/cppguide.html). Use
+[.clang-format](https://github.com/google/googletest/blob/master/.clang-format)
+to check your formatting
-## Requirements for Contributors ###
+## Requirements for Contributors
-If you plan to contribute a patch, you need to build Google Test,
-Google Mock, and their own tests from a git checkout, which has
-further requirements:
+If you plan to contribute a patch, you need to build Google Test, Google Mock,
+and their own tests from a git checkout, which has further requirements:
- * [Python](https://www.python.org/) v2.3 or newer (for running some of
- the tests and re-generating certain source files from templates)
- * [CMake](https://cmake.org/) v2.6.4 or newer
- * [GNU Build System](https://en.wikipedia.org/wiki/GNU_Build_System)
- including automake (>= 1.9), autoconf (>= 2.59), and
- libtool / libtoolize.
+* [Python](https://www.python.org/) v2.3 or newer (for running some of the
+ tests and re-generating certain source files from templates)
+* [CMake](https://cmake.org/) v2.6.4 or newer
+* [GNU Build System](https://en.wikipedia.org/wiki/GNU_Build_System) including
+ automake (>= 1.9), autoconf (>= 2.59), and libtool / libtoolize.
-## Developing Google Test ##
+## Developing Google Test
This section discusses how to make your own changes to Google Test.
-### Testing Google Test Itself ###
+### Testing Google Test Itself
To make sure your changes work as intended and don't break existing
-functionality, you'll want to compile and run Google Test's own tests.
-For that you can use CMake:
+functionality, you'll want to compile and run Google Test's own tests. For that
+you can use CMake:
mkdir mybuild
cd mybuild
cmake -Dgtest_build_tests=ON ${GTEST_DIR}
-Make sure you have Python installed, as some of Google Test's tests
-are written in Python. If the cmake command complains about not being
-able to find Python (`Could NOT find PythonInterp (missing:
-PYTHON_EXECUTABLE)`), try telling it explicitly where your Python
-executable can be found:
+Make sure you have Python installed, as some of Google Test's tests are written
+in Python. If the cmake command complains about not being able to find Python
+(`Could NOT find PythonInterp (missing: PYTHON_EXECUTABLE)`), try telling it
+explicitly where your Python executable can be found:
cmake -DPYTHON_EXECUTABLE=path/to/python -Dgtest_build_tests=ON ${GTEST_DIR}
-Next, you can build Google Test and all of its own tests. On \*nix,
-this is usually done by 'make'. To run the tests, do
+Next, you can build Google Test and all of its own tests. On \*nix, this is
+usually done by 'make'. To run the tests, do
make test
All tests should pass.
-### Regenerating Source Files ##
+### Regenerating Source Files
-Some of Google Test's source files are generated from templates (not
-in the C++ sense) using a script.
-For example, the
-file include/gtest/internal/gtest-type-util.h.pump is used to generate
+Some of Google Test's source files are generated from templates (not in the C++
+sense) using a script. For example, the file
+include/gtest/internal/gtest-type-util.h.pump is used to generate
gtest-type-util.h in the same directory.
-You don't need to worry about regenerating the source files
-unless you need to modify them. You would then modify the
-corresponding `.pump` files and run the '[pump.py](googletest/scripts/pump.py)'
-generator script. See the [Pump Manual](googletest/docs/PumpManual.md).
+You don't need to worry about regenerating the source files unless you need to
+modify them. You would then modify the corresponding `.pump` files and run the
+'[pump.py](googletest/scripts/pump.py)' generator script. See the
+[Pump Manual](googletest/docs/PumpManual.md).
-## Developing Google Mock ###
+## Developing Google Mock
This section discusses how to make your own changes to Google Mock.
-#### Testing Google Mock Itself ####
+#### Testing Google Mock Itself
To make sure your changes work as intended and don't break existing
-functionality, you'll want to compile and run Google Test's own tests.
-For that you'll need Autotools. First, make sure you have followed
-the instructions above to configure Google Mock.
-Then, create a build output directory and enter it. Next,
+functionality, you'll want to compile and run Google Test's own tests. For that
+you'll need Autotools. First, make sure you have followed the instructions above
+to configure Google Mock. Then, create a build output directory and enter it.
+Next,
${GMOCK_DIR}/configure # try --help for more info
-Once you have successfully configured Google Mock, the build steps are
-standard for GNU-style OSS packages.
+Once you have successfully configured Google Mock, the build steps are standard
+for GNU-style OSS packages.
make # Standard makefile following GNU conventions
make check # Builds and runs all tests - all should pass.
Note that when building your project against Google Mock, you are building
-against Google Test as well. There is no need to configure Google Test
+against Google Test as well. There is no need to configure Google Test
separately.
diff --git a/README.md b/README.md
index 3cd83968..5b417fa8 100644
--- a/README.md
+++ b/README.md
@@ -5,11 +5,6 @@
[![Build Status](https://api.travis-ci.org/google/googletest.svg?branch=master)](https://travis-ci.org/google/googletest)
[![Build status](https://ci.appveyor.com/api/projects/status/4o38plt0xbo1ubc8/branch/master?svg=true)](https://ci.appveyor.com/project/GoogleTestAppVeyor/googletest/branch/master)
-### Summer Vacation
-
-June 26, 2019 - July 20 2019 due to summer vacations there will be much reduced
-activity on Pull Requests and issues from the maintainers.
-
### Future Plans
#### 1.8.x Release:
diff --git a/googlemock/CMakeLists.txt b/googlemock/CMakeLists.txt
index c204f271..f75ec45d 100644
--- a/googlemock/CMakeLists.txt
+++ b/googlemock/CMakeLists.txt
@@ -142,7 +142,7 @@ if (gmock_build_tests)
"$project_bin = \"${CMAKE_BINARY_DIR}/bin/$<CONFIG>\"
$env:Path = \"$project_bin;$env:Path\"
& $args")
- elseif (MINGW)
+ elseif (MINGW OR CYGWIN)
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/RunTest.ps1"
CONTENT
"$project_bin = (cygpath --windows ${CMAKE_BINARY_DIR}/bin)
@@ -162,7 +162,7 @@ $env:Path = \"$project_bin;$env:Path\"
cxx_test(gmock-generated-matchers_test gmock_main)
cxx_test(gmock-internal-utils_test gmock_main)
cxx_test(gmock-matchers_test gmock_main)
- if (MINGW)
+ if (MINGW OR CYGWIN)
target_compile_options(gmock-matchers_test PRIVATE "-Wa,-mbig-obj")
endif()
cxx_test(gmock-more-actions_test gmock_main)
diff --git a/googlemock/docs/cheat_sheet.md b/googlemock/docs/cheat_sheet.md
index ea46a68c..6441a7a8 100644
--- a/googlemock/docs/cheat_sheet.md
+++ b/googlemock/docs/cheat_sheet.md
@@ -1,6 +1,8 @@
## gMock Cheat Sheet
-<!-- GOOGLETEST_CM0018 DO NOT DELETE -->
+<!-- GOOGLETEST_CM0019 DO NOT DELETE -->
+
+<!-- GOOGLETEST_CM0033 DO NOT DELETE -->
### Defining a Mock Class
@@ -215,7 +217,7 @@ and the default action will be taken each time.
### Matchers {#MatcherList}
-<!-- GOOGLETEST_CM0019 DO NOT DELETE -->
+<!-- GOOGLETEST_CM0020 DO NOT DELETE -->
A **matcher** matches a *single* argument. You can use it inside `ON_CALL()` or
`EXPECT_CALL()`, or use it to validate a value directly:
@@ -232,7 +234,7 @@ A **matcher** matches a *single* argument. You can use it inside `ON_CALL()` or
Built-in matchers (where `argument` is the function argument) are divided into
several categories:
-## Wildcard
+#### Wildcard
Matcher | Description
:-------------------------- | :-----------------------------------------------
@@ -340,67 +342,99 @@ or simply `expected_container` to match a container exactly. If you want to
write the elements in-line, match them more flexibly, or get more informative
messages, you can use:
-| Matcher | Description |
-| :----------------------------------- | :----------------------------------- |
-| `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. :
-| `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. 0 :
-: : to 10 arguments are allowed. :
-| `ElementsAreArray({ e0, e1, ..., en | The same as `ElementsAre()` except |
-: })`, `ElementsAreArray(array)`, or : that the expected element :
-: `ElementsAreArray(array, count)` : values/matchers come from an :
-: : initializer list, STL-style :
-: : container, or C-style array. :
-| `IsEmpty()` | `argument` is an empty container |
-: : (`container.empty()`). :
-| `Pointwise(m, container)` | `argument` contains the same number |
-: : of elements as in `container`, and :
-: : for all i, (the i-th element in :
-: : `argument`, the i-th element in :
-: : `container`) match `m`, which is a :
-: : matcher on 2-tuples. E.g. :
-: : `Pointwise(Le(), upper_bounds)` :
-: : verifies that each element in :
-: : `argument` doesn't exceed the :
-: : corresponding element in :
-: : `upper_bounds`. See more detail :
-: : below. :
-| `SizeIs(m)` | `argument` is a container whose size |
-: : matches `m`. E.g. `SizeIs(2)` or :
-: : `SizeIs(Lt(2))`. :
-| `UnorderedElementsAre(e0, e1, ..., | `argument` has `n + 1` elements, and |
-: en)` : under some permutation each element :
-: : matches an `ei` (for a different :
-: : `i`), which can be a value or a :
-: : matcher. 0 to 10 arguments are :
-: : allowed. :
-| `UnorderedElementsAreArray({ e0, e1, | The same as `UnorderedElementsAre()` |
-: ..., en })`, : except that the expected element :
-: `UnorderedElementsAreArray(array)`, : values/matchers come from an :
-: or `UnorderedElementsAreArray(array, : initializer list, STL-style :
-: count)` : container, or C-style array. :
-| `WhenSorted(m)` | When `argument` is sorted using the |
-: : `<` operator, it matches container :
-: : matcher `m`. E.g. :
-: : `WhenSorted(ElementsAre(1, 2, 3))` :
-: : verifies that `argument` contains :
-: : elements `1`, `2`, and `3`, ignoring :
-: : order. :
-| `WhenSortedBy(comparator, m)` | The same as `WhenSorted(m)`, except |
-: : that the given comparator instead of :
-: : `<` is used to sort `argument`. E.g. :
-: : `WhenSortedBy(std\:\:greater<int>(), :
-: : ElementsAre(3, 2, 1))`. :
+| Matcher | Description |
+| :---------------------------------------- | :------------------------------- |
+| `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. :
+| `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})`, | The same as `ElementsAre()` |
+: `ElementsAreArray(a_container)`, : except that the expected element :
+: `ElementsAreArray(begin, end)`, : values/matchers come from an :
+: `ElementsAreArray(array)`, or : initializer list, STL-style :
+: `ElementsAreArray(array, count)` : container, iterator range, or :
+: : C-style array. :
+| `IsEmpty()` | `argument` is an empty container |
+: : (`container.empty()`). :
+| `IsFalse()` | `argument` evaluates to `false` |
+: : in a Boolean context. :
+| `IsSubsetOf({e0, e1, ..., en})`, | `argument` matches |
+: `IsSubsetOf(a_container)`, : `UnorderedElementsAre(x0, x1, :
+: `IsSubsetOf(begin, end)`, : ..., xk)` for some subset `{x0, :
+: `IsSubsetOf(array)`, or : x1, ..., xk}` of the expected :
+: `IsSubsetOf(array, count)` : matchers. :
+| `IsSupersetOf({e0, e1, ..., en})`, | Some subset of `argument` |
+: `IsSupersetOf(a_container)`, : matches :
+: `IsSupersetOf(begin, end)`, : `UnorderedElementsAre(`expected :
+: `IsSupersetOf(array)`, or : matchers`)`. :
+: `IsSupersetOf(array, count)` : :
+| `IsTrue()` | `argument` evaluates to `true` |
+: : in a Boolean context. :
+| `Pointwise(m, container)`, `Pointwise(m, | `argument` contains the same |
+: {e0, e1, ..., en})` : number of elements as in :
+: : `container`, and for all i, (the :
+: : i-th element in `argument`, the :
+: : i-th element in `container`) :
+: : match `m`, which is a matcher on :
+: : 2-tuples. E.g. `Pointwise(Le(), :
+: : upper_bounds)` verifies that :
+: : each element in `argument` :
+: : doesn't exceed the corresponding :
+: : element in `upper_bounds`. See :
+: : more detail below. :
+| `SizeIs(m)` | `argument` is a container whose |
+: : size matches `m`. E.g. :
+: : `SizeIs(2)` or `SizeIs(Lt(2))`. :
+| `UnorderedElementsAre(e0, e1, ..., en)` | `argument` has `n + 1` elements, |
+: : and under *some* permutation of :
+: : the elements, each element :
+: : matches an `ei` (for a different :
+: : `i`), which can be a value or a :
+: : matcher. :
+| `UnorderedElementsAreArray({e0, e1, ..., | The same as |
+: en})`, : `UnorderedElementsAre()` except :
+: `UnorderedElementsAreArray(a_container)`, : that the expected element :
+: `UnorderedElementsAreArray(begin, end)`, : values/matchers come from an :
+: `UnorderedElementsAreArray(array)`, or : initializer list, STL-style :
+: `UnorderedElementsAreArray(array, count)` : container, iterator range, or :
+: : C-style array. :
+| `UnorderedPointwise(m, container)`, | Like `Pointwise(m, container)`, |
+: `UnorderedPointwise(m, {e0, e1, ..., : but ignores the order of :
+: en})` : elements. :
+| `WhenSorted(m)` | When `argument` is sorted using |
+: : the `<` operator, it matches :
+: : container matcher `m`. E.g. :
+: : `WhenSorted(ElementsAre(1, 2, :
+: : 3))` verifies that `argument` :
+: : contains elements 1, 2, and 3, :
+: : ignoring order. :
+| `WhenSortedBy(comparator, m)` | The same as `WhenSorted(m)`, |
+: : except that the given comparator :
+: : instead of `<` is used to sort :
+: : `argument`. E.g. :
+: : `WhenSortedBy(std\:\:greater(), :
+: : ElementsAre(3, 2, 1))`. :
**Notes:**
@@ -463,6 +497,10 @@ messages, you can use:
| `WhenDynamicCastTo<T>(m)` | when `argument` is passed through |
: : `dynamic_cast<T>()`, it matches matcher `m`. :
+<!-- GOOGLETEST_CM0026 DO NOT DELETE -->
+
+<!-- GOOGLETEST_CM0027 DO NOT DELETE -->
+
#### Multi-argument Matchers {#MultiArgMatchers}
Technically, all matchers match a *single* value. A "multi-argument" matcher is
@@ -493,13 +531,25 @@ reorder them) to participate in the matching:
You can make a matcher from one or more other matchers:
-| Matcher | Description |
-| :----------------------- | :---------------------------------------------- |
-| `AllOf(m1, m2, ..., mn)` | `argument` matches all of the matchers `m1` to |
-: : `mn`. :
-| `AnyOf(m1, m2, ..., mn)` | `argument` matches at least one of the matchers |
-: : `m1` to `mn`. :
-| `Not(m)` | `argument` doesn't match matcher `m`. |
+| Matcher | Description |
+| :------------------------------- | :-------------------------------------- |
+| `AllOf(m1, m2, ..., mn)` | `argument` matches all of the matchers |
+: : `m1` to `mn`. :
+| `AllOfArray({m0, m1, ..., mn})`, | The same as `AllOf()` except that the |
+: `AllOfArray(a_container)`, : matchers come from an initializer list, :
+: `AllOfArray(begin, end)`, : STL-style container, iterator range, or :
+: `AllOfArray(array)`, or : C-style array. :
+: `AllOfArray(array, count)` : :
+| `AnyOf(m1, m2, ..., mn)` | `argument` matches at least one of the |
+: : matchers `m1` to `mn`. :
+| `AnyOfArray({m0, m1, ..., mn})`, | The same as `AnyOf()` except that the |
+: `AnyOfArray(a_container)`, : matchers come from an initializer list, :
+: `AnyOfArray(begin, end)`, : STL-style container, iterator range, or :
+: `AnyOfArray(array)`, or : C-style array. :
+: `AnyOfArray(array, count)` : :
+| `Not(m)` | `argument` doesn't match matcher `m`. |
+
+<!-- GOOGLETEST_CM0028 DO NOT DELETE -->
#### Adapters for Matchers
@@ -518,7 +568,7 @@ You can make a matcher from one or more other matchers:
`AddressSatisfies(callback)` and `Truly(callback)` take ownership of `callback`,
which must be a permanent callback.
-#### Matchers as Predicates {#MatchersAsPredicatesCheat}
+#### Using Matchers as Predicates {#MatchersAsPredicatesCheat}
| Matcher | Description |
| :---------------------------- | :------------------------------------------ |
@@ -555,20 +605,13 @@ which must be a permanent callback.
1. You can use `PrintToString(x)` to convert a value `x` of any type to a
string.
-## Matchers as Test Assertions
-
-Matcher | Description
-:--------------------------- | :----------
-`ASSERT_THAT(expression, m)` | Generates a [fatal failure](../../googletest/docs/primer.md#assertions) if the value of `expression` doesn't match matcher `m`.
-`EXPECT_THAT(expression, m)` | Generates a non-fatal failure if the value of `expression` doesn't match matcher `m`.
-
### Actions {#ActionList}
**Actions** specify what a mock function should do when invoked.
#### Returning a Value
-| Matcher | Description |
+| | |
| :-------------------------- | :-------------------------------------------- |
| `Return()` | Return from a `void` mock function. |
| `Return(value)` | Return `value`. If the type of `value` is |
@@ -587,7 +630,7 @@ Matcher | Description
#### Side Effects
-| Matcher | Description |
+| | |
| :--------------------------------- | :-------------------------------------- |
| `Assign(&variable, value)` | Assign `value` to variable. |
| `DeleteArg<N>()` | Delete the `N`-th (0-based) argument, |
@@ -620,8 +663,11 @@ Matcher | Description
In the following, by "callable" we mean a free function, `std::function`,
functor, lambda, or `google3`-style permanent callback.
-| Matcher | Description |
+| | |
| :---------------------------------- | :------------------------------------- |
+| `f` | Invoke f with the arguments passed to |
+: : the mock function, where f is a :
+: : callable (except of google3 callback). :
| `Invoke(f)` | Invoke `f` with the arguments passed |
: : to the mock function, where `f` can be :
: : a global/static function or a functor. :
@@ -676,7 +722,7 @@ InvokeArgument<2>(5, string("Hi"), ByRef(foo))
calls the mock function's #2 argument, passing to it `5` and `string("Hi")` by
value, and `foo` by reference.
-## Default Action
+#### Default Action
| Matcher | Description |
| :------------ | :----------------------------------------------------- |
@@ -686,9 +732,11 @@ value, and `foo` by reference.
**Note:** due to technical reasons, `DoDefault()` cannot be used inside a
composite action - trying to do so will result in a run-time error.
-## Composite Actions
+<!-- GOOGLETEST_CM0032 DO NOT DELETE -->
-| Matcher | Description |
+#### Composite Actions
+
+| | |
| :----------------------------- | :------------------------------------------ |
| `DoAll(a1, a2, ..., an)` | Do all actions `a1` to `an` and return the |
: : result of `an` in each invocation. The :
@@ -702,9 +750,22 @@ composite action - trying to do so will result in a run-time error.
: : it. :
| `WithoutArgs(a)` | Perform action `a` without any arguments. |
-## Defining Actions
-
-| Matcher | Description |
+#### Defining Actions
+
+<table border="1" cellspacing="0" cellpadding="1">
+ <tr>
+ <td>`struct SumAction {` <br>
+ &emsp;`template <typename T>` <br>
+ &emsp;`T operator()(T x, Ty) { return x + y; }` <br>
+ `};`
+ </td>
+ <td> Defines a generic functor that can be used as an action summing its
+ arguments. </td> </tr>
+ <tr>
+ </tr>
+</table>
+
+| | |
| :--------------------------------- | :-------------------------------------- |
| `ACTION(Sum) { return arg0 + arg1; | Defines an action `Sum()` to return the |
: }` : sum of the mock function's argument #0 :
@@ -723,7 +784,7 @@ The `ACTION*` macros cannot be used inside a function or class.
These are used in `Times()` to specify how many times a mock function will be
called:
-| Matcher | Description |
+| | |
| :---------------- | :----------------------------------------------------- |
| `AnyNumber()` | The function can be called any number of times. |
| `AtLeast(n)` | The call is expected at least `n` times. |
diff --git a/googlemock/docs/cook_book.md b/googlemock/docs/cook_book.md
index 7116fd4c..17c26459 100644
--- a/googlemock/docs/cook_book.md
+++ b/googlemock/docs/cook_book.md
@@ -1,6 +1,6 @@
-## Googletest Mocking (gMock) Cookbook
+## gMock Cookbook
-<!-- GOOGLETEST_CM0011 DO NOT DELETE -->
+<!-- GOOGLETEST_CM0012 DO NOT DELETE -->
You can find recipes for using gMock here. If you haven't yet, please read
[this](for_dummies.md) first to make sure you understand the basics.
@@ -154,7 +154,7 @@ class MockStack : public StackInterface<Elem> {
#### Mocking Non-virtual Methods {#MockingNonVirtualMethods}
gMock can mock non-virtual functions to be used in Hi-perf dependency
-injection.<!-- GOOGLETEST_CM0016 DO NOT DELETE -->.
+injection.<!-- GOOGLETEST_CM0017 DO NOT DELETE -->.
In this case, instead of sharing a common base class with the real class, your
mock class will be *unrelated* to the real class, but contain methods with the
@@ -824,6 +824,7 @@ A frequently used matcher is `_`, which matches anything:
```cpp
EXPECT_CALL(foo, DoThat(_, NotNull()));
```
+<!-- GOOGLETEST_CM0022 DO NOT DELETE -->
#### Combining Matchers {#CombiningMatchers}
@@ -1138,6 +1139,8 @@ Note that the predicate function / functor doesn't have to return `bool`. It
works as long as the return value can be used as the condition in in statement
`if (condition) ...`.
+<!-- GOOGLETEST_CM0023 DO NOT DELETE -->
+
#### Matching Arguments that Are Not Copyable
When you do an `EXPECT_CALL(mock_obj, Foo(bar))`, gMock saves away a copy of
@@ -1455,7 +1458,7 @@ mock object and gMock.
#### Knowing When to Expect {#UseOnCall}
-<!-- GOOGLETEST_CM0017 DO NOT DELETE -->
+<!-- GOOGLETEST_CM0018 DO NOT DELETE -->
**`ON_CALL`** is likely the *single most under-utilized construct* in gMock.
@@ -2147,7 +2150,11 @@ own precedence order distinct from the `ON_CALL` precedence order.
#### Using Functions/Methods/Functors/Lambdas as Actions {#FunctionsAsActions}
If the built-in actions don't suit you, you can use an existing callable
-(function, `std::function`, method, functor, lambda as an action. ```cpp
+(function, `std::function`, method, functor, lambda as an action.
+
+<!-- GOOGLETEST_CM0024 DO NOT DELETE -->
+
+```cpp
using ::testing::_; using ::testing::Invoke;
class MockFoo : public Foo {
@@ -3239,6 +3246,8 @@ If you are interested in the mock call trace but not the stack traces, you can
combine `--gmock_verbose=info` with `--gtest_stack_trace_depth=0` on the test
command line.
+<!-- GOOGLETEST_CM0025 DO NOT DELETE -->
+
#### Running Tests in Emacs
If you build and run your tests in Emacs using the `M-x google-compile` command
@@ -4175,3 +4184,61 @@ prints the raw bytes in the value and hopes that you the user can figure it out.
[googletest's advanced guide](../../googletest/docs/advanced.md#teaching-googletest-how-to-print-your-values)
explains how to extend the printer to do a better job at printing your
particular type than to dump the bytes.
+
+### Useful Mocks Created Using gMock
+
+<!--#include file="includes/g3_testing_LOGs.md"-->
+<!--#include file="includes/g3_mock_callbacks.md"-->
+
+#### Mock std::function {#MockFunction}
+
+`std::function` is a general function type introduced in C++11. It is a
+preferred way of passing callbacks to new interfaces. Functions are copiable,
+and are not usually passed around by pointer, which makes them tricky to mock.
+But fear not - `MockFunction` can help you with that.
+
+`MockFunction<R(T1, ..., Tn)>` has a mock method `Call()` with the signature:
+
+```cpp
+ R Call(T1, ..., Tn);
+```
+
+It also has a `AsStdFunction()` method, which creates a `std::function` proxy
+forwarding to Call:
+
+```cpp
+ std::function<R(T1, ..., Tn)> AsStdFunction();
+```
+
+To use `MockFunction`, first create `MockFunction` object and set up
+expectations on its `Call` method. Then pass proxy obtained from
+`AsStdFunction()` to the code you are testing. For example:
+
+```cpp
+TEST(FooTest, RunsCallbackWithBarArgument) {
+ // 1. Create a mock object.
+ MockFunction<int(string)> mock_function;
+
+ // 2. Set expectations on Call() method.
+ EXPECT_CALL(mock_function, Call("bar")).WillOnce(Return(1));
+
+ // 3. Exercise code that uses std::function.
+ Foo(mock_function.AsStdFunction());
+ // Foo's signature can be either of:
+ // void Foo(const std::function<int(string)>& fun);
+ // void Foo(std::function<int(string)> fun);
+
+ // 4. All expectations will be verified when mock_function
+ // goes out of scope and is destroyed.
+}
+```
+
+Remember that function objects created with `AsStdFunction()` are just
+forwarders. If you create multiple of them, they will share the same set of
+expectations.
+
+Although `std::function` supports unlimited number of arguments, `MockFunction`
+implementation is limited to ten. If you ever hit that limit... well, your
+callback has bigger problems than being mockable. :-)
+
+<!-- GOOGLETEST_CM0034 DO NOT DELETE -->
diff --git a/googlemock/docs/for_dummies.md b/googlemock/docs/for_dummies.md
index b75c9a09..5551cd8b 100644
--- a/googlemock/docs/for_dummies.md
+++ b/googlemock/docs/for_dummies.md
@@ -1,6 +1,6 @@
-## Googletest Mocking (gMock) for Dummies {#GMockForDummies}
+## gMock for Dummies {#GMockForDummies}
-<!-- GOOGLETEST_CM0012 DO NOT DELETE -->
+<!-- GOOGLETEST_CM0013 DO NOT DELETE -->
### What Is gMock?
@@ -206,6 +206,8 @@ choosing the adaptor interface can make your code easier to write and more
readable (a net win in the long run), as you can choose `FooAdaptor` to fit your
specific domain much better than `Foo` does.
+<!-- GOOGLETEST_CM0029 DO NOT DELETE -->
+
### Using Mocks in Tests
Once you have a mock class, using it is easy. The typical work flow is:
@@ -499,7 +501,7 @@ always return 100 as `n++` is only evaluated once. Similarly, `Return(new Foo)`
will create a new `Foo` object when the `EXPECT_CALL()` is executed, and will
return the same pointer every time. If you want the side effect to happen every
time, you need to define a custom action, which we'll teach in the
-[cook book](http://<!-- GOOGLETEST_CM0011 DO NOT DELETE -->).
+[cook book](http://<!-- GOOGLETEST_CM0012 DO NOT DELETE -->).
Time for another quiz! What do you think the following means?
@@ -593,8 +595,8 @@ In this example, we test that `Foo()` calls the three expected functions in the
order as written. If a call is made out-of-order, it will be an error.
(What if you care about the relative order of some of the calls, but not all of
-them? Can you specify an arbitrary partial order? The answer is ... yes! If you
-are impatient, the details can be found [here](#PartialOrder).)
+them? Can you specify an arbitrary partial order? The answer is ... yes! The
+details can be found [here](cook_book.md#OrderedCalls).)
#### All Expectations Are Sticky (Unless Said Otherwise) {#StickyExpectations}
diff --git a/googlemock/docs/gmock_faq.md b/googlemock/docs/gmock_faq.md
index 27f0eb06..8bc45b18 100644
--- a/googlemock/docs/gmock_faq.md
+++ b/googlemock/docs/gmock_faq.md
@@ -1,6 +1,6 @@
## Legacy gMock FAQ {#GMockFaq}
-<!-- GOOGLETEST_CM0020 DO NOT DELETE -->
+<!-- GOOGLETEST_CM0021 DO NOT DELETE -->
### When I call a method on my mock object, the method for the real object is invoked instead. What's the problem?
@@ -81,6 +81,8 @@ void Bar(int* p); // Neither p nor *p is const.
void Bar(const int* p); // p is not const, but *p is.
```
+<<!-- GOOGLETEST_CM0030 DO NOT DELETE -->
+
### I can't figure out why gMock thinks my expectations are not satisfied. What should I do?
You might want to run your test with `--gmock_verbose=info`. This flag lets
@@ -124,6 +126,8 @@ using ::testing::_;
.Times(0);
```
+<!-- GOOGLETEST_CM0031 DO NOT DELETE -->
+
### I have a failed test where gMock tells me TWICE that a particular expectation is not satisfied. Isn't this redundant?
When gMock detects a failure, it prints relevant information (the mock function
diff --git a/googlemock/include/gmock/gmock-function-mocker.h b/googlemock/include/gmock/gmock-function-mocker.h
index 84a608e1..cc1535c8 100644
--- a/googlemock/include/gmock/gmock-function-mocker.h
+++ b/googlemock/include/gmock/gmock-function-mocker.h
@@ -1,3 +1,38 @@
+// Copyright 2007, 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.
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file implements MOCK_METHOD.
+
+// GOOGLETEST_CM0002 DO NOT DELETE
+
#ifndef THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
#define THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
diff --git a/googletest/CMakeLists.txt b/googletest/CMakeLists.txt
index 52a615d5..db292946 100644
--- a/googletest/CMakeLists.txt
+++ b/googletest/CMakeLists.txt
@@ -188,7 +188,7 @@ if (gtest_build_tests)
"$project_bin = \"${CMAKE_BINARY_DIR}/bin/$<CONFIG>\"
$env:Path = \"$project_bin;$env:Path\"
& $args")
- elseif (MINGW)
+ elseif (MINGW OR CYGWIN)
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/RunTest.ps1"
CONTENT
"$project_bin = (cygpath --windows ${CMAKE_BINARY_DIR}/bin)
diff --git a/googletest/README.md b/googletest/README.md
index 6992f3ca..766ddc1e 100644
--- a/googletest/README.md
+++ b/googletest/README.md
@@ -174,9 +174,9 @@ We list the most frequently used macros below. For a complete list, see file
### Multi-threaded Tests
Google Test is thread-safe where the pthread library is available. After
-`#include "gtest/gtest.h"`, you can check the `GTEST_IS_THREADSAFE` macro to see
-whether this is the case (yes if the macro is `#defined` to 1, no if it's
-undefined.).
+`#include "gtest/gtest.h"`, you can check the
+`GTEST_IS_THREADSAFE` macro to see whether this is the case (yes if the macro is
+`#defined` to 1, no if it's undefined.).
If Google Test doesn't correctly detect whether pthread is available in your
environment, you can force it with
diff --git a/googletest/docs/advanced.md b/googletest/docs/advanced.md
index 25697701..edf3c08b 100644
--- a/googletest/docs/advanced.md
+++ b/googletest/docs/advanced.md
@@ -1,6 +1,6 @@
# Advanced googletest Topics
-<!-- GOOGLETEST_CM0015 DO NOT DELETE -->
+<!-- GOOGLETEST_CM0016 DO NOT DELETE -->
## Introduction
@@ -385,7 +385,7 @@ using ::testing::StartsWith;
```
Read this
-[recipe](https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md#using-matchers-in-googletest-assertions)
+[recipe](../../googlemock/docs/cook_book.md#using-matchers-in-googletest-assertions)
in the gMock Cookbook for more details.
gMock has a rich set of matchers. You can do many things googletest cannot do
diff --git a/googletest/docs/faq.md b/googletest/docs/faq.md
index 05baf236..0e9cfeeb 100644
--- a/googletest/docs/faq.md
+++ b/googletest/docs/faq.md
@@ -1,6 +1,6 @@
# Googletest FAQ
-<!-- GOOGLETEST_CM0013 DO NOT DELETE -->
+<!-- GOOGLETEST_CM0014 DO NOT DELETE -->
## Why should test suite names and test names not contain underscore?
@@ -332,7 +332,7 @@ You may still want to use `SetUp()/TearDown()` in the following cases:
* In the body of a constructor (or destructor), it's not possible to use the
`ASSERT_xx` macros. Therefore, if the set-up operation could cause a fatal
test failure that should prevent the test from running, it's necessary to
- use `abort` <!-- GOOGLETEST_CM0014 DO NOT DELETE --> and abort the whole test executable,
+ use `abort` <!-- GOOGLETEST_CM0015 DO NOT DELETE --> and abort the whole test executable,
or to use `SetUp()` instead of a constructor.
* If the tear-down operation could throw an exception, you must use
`TearDown()` as opposed to the destructor, as throwing in a destructor leads
diff --git a/googletest/docs/pkgconfig.md b/googletest/docs/pkgconfig.md
index 5ad1f011..b7758738 100644
--- a/googletest/docs/pkgconfig.md
+++ b/googletest/docs/pkgconfig.md
@@ -1,25 +1,24 @@
-## Using GoogleTest from various build systems ##
+## Using GoogleTest from various build systems
GoogleTest comes with pkg-config files that can be used to determine all
necessary flags for compiling and linking to GoogleTest (and GoogleMock).
Pkg-config is a standardised plain-text format containing
- * the includedir (-I) path
- * necessary macro (-D) definitions
- * further required flags (-pthread)
- * the library (-L) path
- * the library (-l) to link to
+* the includedir (-I) path
+* necessary macro (-D) definitions
+* further required flags (-pthread)
+* the library (-L) path
+* the library (-l) to link to
-All current build systems support pkg-config in one way or another. For
-all examples here we assume you want to compile the sample
+All current build systems support pkg-config in one way or another. For all
+examples here we assume you want to compile the sample
`samples/sample3_unittest.cc`.
-
-### CMake ###
+### CMake
Using `pkg-config` in CMake is fairly easy:
-``` cmake
+```cmake
cmake_minimum_required(VERSION 3.0)
cmake_policy(SET CMP0048 NEW)
@@ -43,11 +42,10 @@ that all libraries have been compiled with threading enabled. In addition,
GoogleTest might also require `-pthread` in the compiling step, and as such
splitting the pkg-config `Cflags` variable into include dirs and macros for
`target_compile_definitions()` might still miss this). The same recommendation
-goes for using `_LDFLAGS` over the more commonplace `_LIBRARIES`, which
-happens to discard `-L` flags and `-pthread`.
-
+goes for using `_LDFLAGS` over the more commonplace `_LIBRARIES`, which happens
+to discard `-L` flags and `-pthread`.
-### Autotools ###
+### Autotools
Finding GoogleTest in Autoconf and using it from Automake is also fairly easy:
@@ -77,8 +75,7 @@ testapp_CXXFLAGS = $(GTEST_CFLAGS)
testapp_LDADD = $(GTEST_LIBS)
```
-
-### Meson ###
+### Meson
Meson natively uses pkgconfig to query dependencies:
@@ -96,13 +93,12 @@ testapp = executable(
test('first_and_only_test', testapp)
```
+### Plain Makefiles
-### Plain Makefiles ###
+Since `pkg-config` is a small Unix command-line utility, it can be used in
+handwritten `Makefile`s too:
-Since `pkg-config` is a small Unix command-line utility, it can be used
-in handwritten `Makefile`s too:
-
-``` Makefile
+```Makefile
GTEST_CFLAGS = `pkg-config --cflags gtest_main`
GTEST_LIBS = `pkg-config --libs gtest_main`
@@ -120,12 +116,11 @@ testapp.o: samples/sample3_unittest.cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $< -c -o $@ $(GTEST_CFLAGS)
```
-
-### Help! pkg-config can't find GoogleTest! ###
+### Help! pkg-config can't find GoogleTest!
Let's say you have a `CMakeLists.txt` along the lines of the one in this
-tutorial and you try to run `cmake`. It is very possible that you get a
-failure along the lines of:
+tutorial and you try to run `cmake`. It is very possible that you get a failure
+along the lines of:
```
-- Checking for one of the modules 'gtest_main'
@@ -135,9 +130,9 @@ CMake Error at /usr/share/cmake/Modules/FindPkgConfig.cmake:640 (message):
These failures are common if you installed GoogleTest yourself and have not
sourced it from a distro or other package manager. If so, you need to tell
-pkg-config where it can find the `.pc` files containing the information.
-Say you installed GoogleTest to `/usr/local`, then it might be that the
-`.pc` files are installed under `/usr/local/lib64/pkgconfig`. If you set
+pkg-config where it can find the `.pc` files containing the information. Say you
+installed GoogleTest to `/usr/local`, then it might be that the `.pc` files are
+installed under `/usr/local/lib64/pkgconfig`. If you set
```
export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig
diff --git a/googletest/docs/primer.md b/googletest/docs/primer.md
index ba17ce85..6bd6e9bf 100644
--- a/googletest/docs/primer.md
+++ b/googletest/docs/primer.md
@@ -164,7 +164,7 @@ you'll get a compiler error. We used to require the arguments to support the
`<<` is supported, it will be called to print the arguments when the assertion
fails; otherwise googletest will attempt to print them in the best way it can.
For more details and how to customize the printing of the arguments, see
-[documentation](https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md#teaching-gmock-how-to-print-your-values)
+[documentation](../../googlemock/docs/cook_book.md#teaching-gmock-how-to-print-your-values)
These assertions can work with a user-defined type, but only if you define the
corresponding comparison operator (e.g. `==`, `<`, etc). Since this is
@@ -193,7 +193,7 @@ objects, you should use `ASSERT_EQ`.
When doing pointer comparisons use `*_EQ(ptr, nullptr)` and `*_NE(ptr, nullptr)`
instead of `*_EQ(ptr, NULL)` and `*_NE(ptr, NULL)`. This is because `nullptr` is
-typed while `NULL` is not. See [FAQ](faq.md)for more details.
+typed while `NULL` is not. See [FAQ](faq.md) for more details.
If you're working with floating point numbers, you may want to use the floating
point variations of some of these macros in order to avoid problems caused by
@@ -456,7 +456,7 @@ When invoked, the `RUN_ALL_TESTS()` macro:
* Deletes the fixture.
-* Restores the state of all all googletest flags
+* Restores the state of all googletest flags
* Repeats the above steps for the next test, until all tests have run.
diff --git a/googletest/docs/pump_manual.md b/googletest/docs/pump_manual.md
index 3ec428e3..10b3c5ff 100644
--- a/googletest/docs/pump_manual.md
+++ b/googletest/docs/pump_manual.md
@@ -1,52 +1,51 @@
-
-
<b>P</b>ump is <b>U</b>seful for <b>M</b>eta <b>P</b>rogramming.
-# The Problem #
+# The Problem
-Template and macro libraries often need to define many classes,
-functions, or macros that vary only (or almost only) in the number of
-arguments they take. It's a lot of repetitive, mechanical, and
-error-prone work.
+Template and macro libraries often need to define many classes, functions, or
+macros that vary only (or almost only) in the number of arguments they take.
+It's a lot of repetitive, mechanical, and error-prone work.
-Variadic templates and variadic macros can alleviate the problem.
-However, while both are being considered by the C++ committee, neither
-is in the standard yet or widely supported by compilers. Thus they
-are often not a good choice, especially when your code needs to be
-portable. And their capabilities are still limited.
+Variadic templates and variadic macros can alleviate the problem. However, while
+both are being considered by the C++ committee, neither is in the standard yet
+or widely supported by compilers. Thus they are often not a good choice,
+especially when your code needs to be portable. And their capabilities are still
+limited.
-As a result, authors of such libraries often have to write scripts to
-generate their implementation. However, our experience is that it's
-tedious to write such scripts, which tend to reflect the structure of
-the generated code poorly and are often hard to read and edit. For
-example, a small change needed in the generated code may require some
-non-intuitive, non-trivial changes in the script. This is especially
-painful when experimenting with the code.
+As a result, authors of such libraries often have to write scripts to generate
+their implementation. However, our experience is that it's tedious to write such
+scripts, which tend to reflect the structure of the generated code poorly and
+are often hard to read and edit. For example, a small change needed in the
+generated code may require some non-intuitive, non-trivial changes in the
+script. This is especially painful when experimenting with the code.
-# Our Solution #
+# Our Solution
Pump (for Pump is Useful for Meta Programming, Pretty Useful for Meta
-Programming, or Practical Utility for Meta Programming, whichever you
-prefer) is a simple meta-programming tool for C++. The idea is that a
-programmer writes a `foo.pump` file which contains C++ code plus meta
-code that manipulates the C++ code. The meta code can handle
-iterations over a range, nested iterations, local meta variable
-definitions, simple arithmetic, and conditional expressions. You can
-view it as a small Domain-Specific Language. The meta language is
-designed to be non-intrusive (s.t. it won't confuse Emacs' C++ mode,
-for example) and concise, making Pump code intuitive and easy to
-maintain.
-
-## Highlights ##
-
- * The implementation is in a single Python script and thus ultra portable: no build or installation is needed and it works cross platforms.
- * Pump tries to be smart with respect to [Google's style guide](https://github.com/google/styleguide): it breaks long lines (easy to have when they are generated) at acceptable places to fit within 80 columns and indent the continuation lines correctly.
- * The format is human-readable and more concise than XML.
- * The format works relatively well with Emacs' C++ mode.
-
-## Examples ##
-
-The following Pump code (where meta keywords start with `$`, `[[` and `]]` are meta brackets, and `$$` starts a meta comment that ends with the line):
+Programming, or Practical Utility for Meta Programming, whichever you prefer) is
+a simple meta-programming tool for C++. The idea is that a programmer writes a
+`foo.pump` file which contains C++ code plus meta code that manipulates the C++
+code. The meta code can handle iterations over a range, nested iterations, local
+meta variable definitions, simple arithmetic, and conditional expressions. You
+can view it as a small Domain-Specific Language. The meta language is designed
+to be non-intrusive (s.t. it won't confuse Emacs' C++ mode, for example) and
+concise, making Pump code intuitive and easy to maintain.
+
+## Highlights
+
+* The implementation is in a single Python script and thus ultra portable: no
+ build or installation is needed and it works cross platforms.
+* Pump tries to be smart with respect to
+ [Google's style guide](https://github.com/google/styleguide): it breaks long
+ lines (easy to have when they are generated) at acceptable places to fit
+ within 80 columns and indent the continuation lines correctly.
+* The format is human-readable and more concise than XML.
+* The format works relatively well with Emacs' C++ mode.
+
+## Examples
+
+The following Pump code (where meta keywords start with `$`, `[[` and `]]` are
+meta brackets, and `$$` starts a meta comment that ends with the line):
```
$var n = 3 $$ Defines a meta variable n.
@@ -71,7 +70,7 @@ $if i == 0 [[
will be translated by the Pump compiler to:
-``` cpp
+```cpp
// Foo0 does blah for 0-ary predicates.
template <size_t N>
class Foo0 {
@@ -105,9 +104,10 @@ Func($for i + [[a$i]]);
$$ The text between i and [[ is the separator between iterations.
```
-will generate one of the following lines (without the comments), depending on the value of `n`:
+will generate one of the following lines (without the comments), depending on
+the value of `n`:
-``` cpp
+```cpp
Func(); // If n is 0.
Func(a1); // If n is 1.
Func(a1 + a2); // If n is 2.
@@ -115,32 +115,38 @@ Func(a1 + a2 + a3); // If n is 3.
// And so on...
```
-## Constructs ##
+## Constructs
We support the following meta programming constructs:
-| `$var id = exp` | Defines a named constant value. `$id` is valid util the end of the current meta lexical block. |
-|:----------------|:-----------------------------------------------------------------------------------------------|
-| `$range id exp..exp` | Sets the range of an iteration variable, which can be reused in multiple loops later. |
-| `$for id sep [[ code ]]` | Iteration. The range of `id` must have been defined earlier. `$id` is valid in `code`. |
-| `$($)` | Generates a single `$` character. |
-| `$id` | Value of the named constant or iteration variable. |
-| `$(exp)` | Value of the expression. |
-| `$if exp [[ code ]] else_branch` | Conditional. |
-| `[[ code ]]` | Meta lexical block. |
-| `cpp_code` | Raw C++ code. |
-| `$$ comment` | Meta comment. |
-
-**Note:** To give the user some freedom in formatting the Pump source
-code, Pump ignores a new-line character if it's right after `$for foo`
-or next to `[[` or `]]`. Without this rule you'll often be forced to write
-very long lines to get the desired output. Therefore sometimes you may
-need to insert an extra new-line in such places for a new-line to show
-up in your output.
-
-## Grammar ##
-
-``` ebnf
+| `$var id = exp` | Defines a named constant value. `$id` is |
+: : valid util the end of the current meta :
+: : lexical block. :
+| :------------------------------- | :--------------------------------------- |
+| `$range id exp..exp` | Sets the range of an iteration variable, |
+: : which can be reused in multiple loops :
+: : later. :
+| `$for id sep [[ code ]]` | Iteration. The range of `id` must have |
+: : been defined earlier. `$id` is valid in :
+: : `code`. :
+| `$($)` | Generates a single `$` character. |
+| `$id` | Value of the named constant or iteration |
+: : variable. :
+| `$(exp)` | Value of the expression. |
+| `$if exp [[ code ]] else_branch` | Conditional. |
+| `[[ code ]]` | Meta lexical block. |
+| `cpp_code` | Raw C++ code. |
+| `$$ comment` | Meta comment. |
+
+**Note:** To give the user some freedom in formatting the Pump source code, Pump
+ignores a new-line character if it's right after `$for foo` or next to `[[` or
+`]]`. Without this rule you'll often be forced to write very long lines to get
+the desired output. Therefore sometimes you may need to insert an extra new-line
+in such places for a new-line to show up in your output.
+
+## Grammar
+
+```ebnf
code ::= atomic_code*
atomic_code ::= $var id = exp
| $var id = [[ code ]]
@@ -159,19 +165,26 @@ else_branch ::= $else [[ code ]]
exp ::= simple_expression_in_Python_syntax
```
-## Code ##
+## Code
-You can find the source code of Pump in [scripts/pump.py](../scripts/pump.py). It is still
-very unpolished and lacks automated tests, although it has been
-successfully used many times. If you find a chance to use it in your
-project, please let us know what you think! We also welcome help on
-improving Pump.
+You can find the source code of Pump in [scripts/pump.py](../scripts/pump.py).
+It is still very unpolished and lacks automated tests, although it has been
+successfully used many times. If you find a chance to use it in your project,
+please let us know what you think! We also welcome help on improving Pump.
-## Real Examples ##
+## Real Examples
-You can find real-world applications of Pump in [Google Test](https://github.com/google/googletest/tree/master/googletest) and [Google Mock](https://github.com/google/googletest/tree/master/googlemock). The source file `foo.h.pump` generates `foo.h`.
+You can find real-world applications of Pump in
+[Google Test](https://github.com/google/googletest/tree/master/googletest) and
+[Google Mock](https://github.com/google/googletest/tree/master/googlemock). The
+source file `foo.h.pump` generates `foo.h`.
-## Tips ##
+## Tips
- * If a meta variable is followed by a letter or digit, you can separate them using `[[]]`, which inserts an empty string. For example `Foo$j[[]]Helper` generate `Foo1Helper` when `j` is 1.
- * To avoid extra-long Pump source lines, you can break a line anywhere you want by inserting `[[]]` followed by a new line. Since any new-line character next to `[[` or `]]` is ignored, the generated code won't contain this new line.
+* If a meta variable is followed by a letter or digit, you can separate them
+ using `[[]]`, which inserts an empty string. For example `Foo$j[[]]Helper`
+ generate `Foo1Helper` when `j` is 1.
+* To avoid extra-long Pump source lines, you can break a line anywhere you
+ want by inserting `[[]]` followed by a new line. Since any new-line
+ character next to `[[` or `]]` is ignored, the generated code won't contain
+ this new line.
diff --git a/googletest/include/gtest/gtest.h b/googletest/include/gtest/gtest.h
index 0cb5a2e7..ff77075d 100644
--- a/googletest/include/gtest/gtest.h
+++ b/googletest/include/gtest/gtest.h
@@ -588,6 +588,10 @@ class GTEST_API_ TestResult {
// Returns the elapsed time, in milliseconds.
TimeInMillis elapsed_time() const { return elapsed_time_; }
+ // Gets the time of the test case start, in ms from the start of the
+ // UNIX epoch.
+ TimeInMillis start_timestamp() const { return start_timestamp_; }
+
// Returns the i-th test part result among all the results. i can range from 0
// to total_part_count() - 1. If i is not in that range, aborts the program.
const TestPartResult& GetTestPartResult(int i) const;
@@ -618,6 +622,9 @@ class GTEST_API_ TestResult {
return test_properties_;
}
+ // Sets the start time.
+ void set_start_timestamp(TimeInMillis start) { start_timestamp_ = start; }
+
// Sets the elapsed time.
void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; }
@@ -661,6 +668,8 @@ class GTEST_API_ TestResult {
std::vector<TestProperty> test_properties_;
// Running count of death tests.
int death_test_count_;
+ // The start time, in milliseconds since UNIX Epoch.
+ TimeInMillis start_timestamp_;
// The elapsed time, in milliseconds.
TimeInMillis elapsed_time_;
@@ -881,6 +890,10 @@ class GTEST_API_ TestSuite {
// Returns the elapsed time, in milliseconds.
TimeInMillis elapsed_time() const { return elapsed_time_; }
+ // Gets the time of the test suite start, in ms from the start of the
+ // UNIX epoch.
+ TimeInMillis start_timestamp() const { return start_timestamp_; }
+
// Returns the i-th test among all the tests. i can range from 0 to
// total_test_count() - 1. If i is not in that range, returns NULL.
const TestInfo* GetTestInfo(int i) const;
@@ -999,6 +1012,8 @@ class GTEST_API_ TestSuite {
internal::TearDownTestSuiteFunc tear_down_tc_;
// True iff any test in this test suite should run.
bool should_run_;
+ // The start time, in milliseconds since UNIX Epoch.
+ TimeInMillis start_timestamp_;
// Elapsed time, in milliseconds.
TimeInMillis elapsed_time_;
// Holds test properties recorded during execution of SetUpTestSuite and
diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc
index 0da3cc20..d6b56304 100644
--- a/googletest/src/gtest.cc
+++ b/googletest/src/gtest.cc
@@ -2032,9 +2032,7 @@ std::string AppendUserMessage(const std::string& gtest_msg,
// Creates an empty TestResult.
TestResult::TestResult()
- : death_test_count_(0),
- elapsed_time_(0) {
-}
+ : death_test_count_(0), start_timestamp_(0), elapsed_time_(0) {}
// D'tor.
TestResult::~TestResult() {
@@ -2103,13 +2101,7 @@ static const char* const kReservedTestSuitesAttributes[] = {
// The list of reserved attributes used in the <testsuite> element of XML
// output.
static const char* const kReservedTestSuiteAttributes[] = {
- "disabled",
- "errors",
- "failures",
- "name",
- "tests",
- "time"
-};
+ "disabled", "errors", "failures", "name", "tests", "time", "timestamp"};
// The list of reserved attributes used in the <testcase> element of XML output.
static const char* const kReservedTestCaseAttributes[] = {
@@ -2117,10 +2109,10 @@ static const char* const kReservedTestCaseAttributes[] = {
"value_param", "file", "line"};
// Use a slightly different set for allowed output to ensure existing tests can
-// still RecordProperty("result")
+// still RecordProperty("result") or "RecordProperty(timestamp")
static const char* const kReservedOutputTestCaseAttributes[] = {
- "classname", "name", "status", "time", "type_param",
- "value_param", "file", "line", "result"};
+ "classname", "name", "status", "time", "type_param",
+ "value_param", "file", "line", "result", "timestamp"};
template <int kSize>
std::vector<std::string> ArrayAsVector(const char* const (&array)[kSize]) {
@@ -2705,6 +2697,7 @@ void TestInfo::Run() {
test, &Test::DeleteSelf_, "the test fixture's destructor");
}
+ result_.set_start_timestamp(start);
result_.set_elapsed_time(internal::GetTimeInMillis() - start);
// Notifies the unit test event listener that a test has just finished.
@@ -2774,6 +2767,7 @@ TestSuite::TestSuite(const char* a_name, const char* a_type_param,
set_up_tc_(set_up_tc),
tear_down_tc_(tear_down_tc),
should_run_(false),
+ start_timestamp_(0),
elapsed_time_(0) {}
// Destructor of TestSuite.
@@ -2823,11 +2817,11 @@ void TestSuite::Run() {
internal::HandleExceptionsInMethodIfSupported(
this, &TestSuite::RunSetUpTestSuite, "SetUpTestSuite()");
- const internal::TimeInMillis start = internal::GetTimeInMillis();
+ start_timestamp_ = internal::GetTimeInMillis();
for (int i = 0; i < total_test_count(); i++) {
GetMutableTestInfo(i)->Run();
}
- elapsed_time_ = internal::GetTimeInMillis() - start;
+ elapsed_time_ = internal::GetTimeInMillis() - start_timestamp_;
impl->os_stack_trace_getter()->UponLeavingGTest();
internal::HandleExceptionsInMethodIfSupported(
@@ -3788,6 +3782,9 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
: "suppressed");
OutputXmlAttribute(stream, kTestsuite, "time",
FormatTimeInMillisAsSeconds(result.elapsed_time()));
+ OutputXmlAttribute(
+ stream, kTestsuite, "timestamp",
+ FormatEpochTimeInMillisAsIso8601(result.start_timestamp()));
OutputXmlAttribute(stream, kTestsuite, "classname", test_suite_name);
int failures = 0;
@@ -3838,6 +3835,9 @@ void XmlUnitTestResultPrinter::PrintXmlTestSuite(std::ostream* stream,
OutputXmlAttribute(stream, kTestsuite, "errors", "0");
OutputXmlAttribute(stream, kTestsuite, "time",
FormatTimeInMillisAsSeconds(test_suite.elapsed_time()));
+ OutputXmlAttribute(
+ stream, kTestsuite, "timestamp",
+ FormatEpochTimeInMillisAsIso8601(test_suite.start_timestamp()));
*stream << TestPropertiesAsXmlAttributes(test_suite.ad_hoc_test_result());
}
*stream << ">\n";
@@ -3864,11 +3864,11 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream,
stream, kTestsuites, "disabled",
StreamableToString(unit_test.reportable_disabled_test_count()));
OutputXmlAttribute(stream, kTestsuites, "errors", "0");
+ OutputXmlAttribute(stream, kTestsuites, "time",
+ FormatTimeInMillisAsSeconds(unit_test.elapsed_time()));
OutputXmlAttribute(
stream, kTestsuites, "timestamp",
FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp()));
- OutputXmlAttribute(stream, kTestsuites, "time",
- FormatTimeInMillisAsSeconds(unit_test.elapsed_time()));
if (GTEST_FLAG(shuffle)) {
OutputXmlAttribute(stream, kTestsuites, "random_seed",
@@ -4156,6 +4156,9 @@ void JsonUnitTestResultPrinter::OutputJsonTestInfo(::std::ostream* stream,
? (result.Skipped() ? "SKIPPED" : "COMPLETED")
: "SUPPRESSED",
kIndent);
+ OutputJsonKey(stream, kTestsuite, "timestamp",
+ FormatEpochTimeInMillisAsRFC3339(result.start_timestamp()),
+ kIndent);
OutputJsonKey(stream, kTestsuite, "time",
FormatTimeInMillisAsDuration(result.elapsed_time()), kIndent);
OutputJsonKey(stream, kTestsuite, "classname", test_suite_name, kIndent,
@@ -4202,6 +4205,10 @@ void JsonUnitTestResultPrinter::PrintJsonTestSuite(
OutputJsonKey(stream, kTestsuite, "disabled",
test_suite.reportable_disabled_test_count(), kIndent);
OutputJsonKey(stream, kTestsuite, "errors", 0, kIndent);
+ OutputJsonKey(
+ stream, kTestsuite, "timestamp",
+ FormatEpochTimeInMillisAsRFC3339(test_suite.start_timestamp()),
+ kIndent);
OutputJsonKey(stream, kTestsuite, "time",
FormatTimeInMillisAsDuration(test_suite.elapsed_time()),
kIndent, false);
diff --git a/googletest/test/googletest-json-outfiles-test.py b/googletest/test/googletest-json-outfiles-test.py
index b81a03d2..8ef47b8f 100644
--- a/googletest/test/googletest-json-outfiles-test.py
+++ b/googletest/test/googletest-json-outfiles-test.py
@@ -67,11 +67,14 @@ EXPECTED_1 = {
0,
u'time':
u'*',
+ u'timestamp':
+ u'*',
u'testsuite': [{
u'name': u'TestSomeProperties',
u'status': u'RUN',
u'result': u'COMPLETED',
u'time': u'*',
+ u'timestamp': u'*',
u'classname': u'PropertyOne',
u'SetUpProp': u'1',
u'TestSomeProperty': u'1',
@@ -108,10 +111,13 @@ EXPECTED_2 = {
0,
u'time':
u'*',
+ u'timestamp':
+ u'*',
u'testsuite': [{
u'name': u'TestSomeProperties',
u'status': u'RUN',
u'result': u'COMPLETED',
+ u'timestamp': u'*',
u'time': u'*',
u'classname': u'PropertyTwo',
u'SetUpProp': u'2',
diff --git a/googletest/test/googletest-json-output-unittest.py b/googletest/test/googletest-json-output-unittest.py
index 64d7534b..15861f75 100644
--- a/googletest/test/googletest-json-output-unittest.py
+++ b/googletest/test/googletest-json-output-unittest.py
@@ -73,457 +73,474 @@ EXPECTED_NON_EMPTY = {
u'42',
u'name':
u'AllTests',
- u'testsuites': [
- {
+ u'testsuites': [{
+ u'name':
+ u'SuccessfulTest',
+ u'tests':
+ 1,
+ u'failures':
+ 0,
+ u'disabled':
+ 0,
+ u'errors':
+ 0,
+ u'time':
+ u'*',
+ u'timestamp':
+ u'*',
+ u'testsuite': [{
+ u'name': u'Succeeds',
+ u'status': u'RUN',
+ u'result': u'COMPLETED',
+ u'time': u'*',
+ u'timestamp': u'*',
+ u'classname': u'SuccessfulTest'
+ }]
+ }, {
+ u'name':
+ u'FailedTest',
+ u'tests':
+ 1,
+ u'failures':
+ 1,
+ u'disabled':
+ 0,
+ u'errors':
+ 0,
+ u'time':
+ u'*',
+ u'timestamp':
+ u'*',
+ u'testsuite': [{
u'name':
- u'SuccessfulTest',
- u'tests':
- 1,
- u'failures':
- 0,
- u'disabled':
- 0,
- u'errors':
- 0,
+ u'Fails',
+ u'status':
+ u'RUN',
+ u'result':
+ u'COMPLETED',
u'time':
u'*',
- u'testsuite': [{
- u'name': u'Succeeds',
- u'status': u'RUN',
- u'result': u'COMPLETED',
- u'time': u'*',
- u'classname': u'SuccessfulTest'
- }]
- },
- {
- u'name':
- u'FailedTest',
- u'tests':
- 1,
- u'failures':
- 1,
- u'disabled':
- 0,
- u'errors':
- 0,
- u'time':
+ u'timestamp':
u'*',
- u'testsuite': [{
- u'name':
- u'Fails',
- u'status':
- u'RUN',
- u'result':
- u'COMPLETED',
- u'time':
- u'*',
- u'classname':
- u'FailedTest',
- u'failures': [{
- u'failure': u'gtest_xml_output_unittest_.cc:*\n'
- u'Expected equality of these values:\n'
- u' 1\n 2' + STACK_TRACE_TEMPLATE,
- u'type': u''
- }]
+ u'classname':
+ u'FailedTest',
+ u'failures': [{
+ u'failure': u'gtest_xml_output_unittest_.cc:*\n'
+ u'Expected equality of these values:\n'
+ u' 1\n 2' + STACK_TRACE_TEMPLATE,
+ u'type': u''
}]
- },
- {
+ }]
+ }, {
+ u'name':
+ u'DisabledTest',
+ u'tests':
+ 1,
+ u'failures':
+ 0,
+ u'disabled':
+ 1,
+ u'errors':
+ 0,
+ u'time':
+ u'*',
+ u'timestamp':
+ u'*',
+ u'testsuite': [{
+ u'name': u'DISABLED_test_not_run',
+ u'status': u'NOTRUN',
+ u'result': u'SUPPRESSED',
+ u'time': u'*',
+ u'timestamp': u'*',
+ u'classname': u'DisabledTest'
+ }]
+ }, {
+ u'name':
+ u'SkippedTest',
+ u'tests':
+ 1,
+ u'failures':
+ 0,
+ u'disabled':
+ 0,
+ u'errors':
+ 0,
+ u'time':
+ u'*',
+ u'timestamp':
+ u'*',
+ u'testsuite': [{
+ u'name': u'Skipped',
+ u'status': u'RUN',
+ u'result': u'SKIPPED',
+ u'time': u'*',
+ u'timestamp': u'*',
+ u'classname': u'SkippedTest'
+ }]
+ }, {
+ u'name':
+ u'MixedResultTest',
+ u'tests':
+ 3,
+ u'failures':
+ 1,
+ u'disabled':
+ 1,
+ u'errors':
+ 0,
+ u'time':
+ u'*',
+ u'timestamp':
+ u'*',
+ u'testsuite': [{
+ u'name': u'Succeeds',
+ u'status': u'RUN',
+ u'result': u'COMPLETED',
+ u'time': u'*',
+ u'timestamp': u'*',
+ u'classname': u'MixedResultTest'
+ }, {
u'name':
- u'DisabledTest',
- u'tests':
- 1,
- u'failures':
- 0,
- u'disabled':
- 1,
- u'errors':
- 0,
+ u'Fails',
+ u'status':
+ u'RUN',
+ u'result':
+ u'COMPLETED',
u'time':
u'*',
- u'testsuite': [{
- u'name': u'DISABLED_test_not_run',
- u'status': u'NOTRUN',
- u'result': u'SUPPRESSED',
- u'time': u'*',
- u'classname': u'DisabledTest'
- }]
- },
- {
- u'name':
- u'SkippedTest',
- u'tests':
- 1,
- u'failures':
- 0,
- u'disabled':
- 0,
- u'errors':
- 0,
- u'time':
+ u'timestamp':
u'*',
- u'testsuite': [{
- u'name': u'Skipped',
- u'status': u'RUN',
- u'result': u'SKIPPED',
- u'time': u'*',
- u'classname': u'SkippedTest'
- }]
- },
- {
- u'name':
+ u'classname':
u'MixedResultTest',
- u'tests':
- 3,
- u'failures':
- 1,
- u'disabled':
- 1,
- u'errors':
- 0,
- u'time':
- u'*',
- u'testsuite': [
- {
- u'name': u'Succeeds',
- u'status': u'RUN',
- u'result': u'COMPLETED',
- u'time': u'*',
- u'classname': u'MixedResultTest'
- },
- {
- u'name':
- u'Fails',
- u'status':
- u'RUN',
- u'result':
- u'COMPLETED',
- u'time':
- u'*',
- u'classname':
- u'MixedResultTest',
- u'failures':
- [{
- u'failure': u'gtest_xml_output_unittest_.cc:*\n'
- u'Expected equality of these values:\n'
- u' 1\n 2' + STACK_TRACE_TEMPLATE,
- u'type': u''
- },
- {
- u'failure': u'gtest_xml_output_unittest_.cc:*\n'
- u'Expected equality of these values:\n'
- u' 2\n 3' + STACK_TRACE_TEMPLATE,
- u'type': u''
- }]
- },
- {
- u'name': u'DISABLED_test',
- u'status': u'NOTRUN',
- u'result': u'SUPPRESSED',
- u'time': u'*',
- u'classname': u'MixedResultTest'
- }
- ]
- },
- {
- u'name':
- u'XmlQuotingTest',
- u'tests':
- 1,
- u'failures':
- 1,
- u'disabled':
- 0,
- u'errors':
- 0,
- u'time':
- u'*',
- u'testsuite': [{
- u'name':
- u'OutputsCData',
- u'status':
- u'RUN',
- u'result':
- u'COMPLETED',
- u'time':
- u'*',
- u'classname':
- u'XmlQuotingTest',
- u'failures': [{
- u'failure': u'gtest_xml_output_unittest_.cc:*\n'
- u'Failed\nXML output: <?xml encoding="utf-8">'
- u'<top><![CDATA[cdata text]]></top>' +
- STACK_TRACE_TEMPLATE,
- u'type': u''
- }]
- }]
- },
- {
- u'name':
- u'InvalidCharactersTest',
- u'tests':
- 1,
- u'failures':
- 1,
- u'disabled':
- 0,
- u'errors':
- 0,
- u'time':
- u'*',
- u'testsuite': [{
- u'name':
- u'InvalidCharactersInMessage',
- u'status':
- u'RUN',
- u'result':
- u'COMPLETED',
- u'time':
- u'*',
- u'classname':
- u'InvalidCharactersTest',
- u'failures': [{
- u'failure': u'gtest_xml_output_unittest_.cc:*\n'
- u'Failed\nInvalid characters in brackets'
- u' [\x01\x02]' + STACK_TRACE_TEMPLATE,
- u'type': u''
- }]
+ u'failures': [{
+ u'failure': u'gtest_xml_output_unittest_.cc:*\n'
+ u'Expected equality of these values:\n'
+ u' 1\n 2' + STACK_TRACE_TEMPLATE,
+ u'type': u''
+ }, {
+ u'failure': u'gtest_xml_output_unittest_.cc:*\n'
+ u'Expected equality of these values:\n'
+ u' 2\n 3' + STACK_TRACE_TEMPLATE,
+ u'type': u''
}]
- },
- {
- u'name':
- u'PropertyRecordingTest',
- u'tests':
- 4,
- u'failures':
- 0,
- u'disabled':
- 0,
- u'errors':
- 0,
- u'time':
- u'*',
- u'SetUpTestSuite':
- u'yes',
- u'TearDownTestSuite':
- u'aye',
- u'testsuite': [{
- u'name': u'OneProperty',
- u'status': u'RUN',
- u'result': u'COMPLETED',
- u'time': u'*',
- u'classname': u'PropertyRecordingTest',
- u'key_1': u'1'
- },
- {
- u'name': u'IntValuedProperty',
- u'status': u'RUN',
- u'result': u'COMPLETED',
- u'time': u'*',
- u'classname': u'PropertyRecordingTest',
- u'key_int': u'1'
- },
- {
- u'name': u'ThreeProperties',
- u'status': u'RUN',
- u'result': u'COMPLETED',
- u'time': u'*',
- u'classname': u'PropertyRecordingTest',
- u'key_1': u'1',
- u'key_2': u'2',
- u'key_3': u'3'
- },
- {
- u'name': u'TwoValuesForOneKeyUsesLastValue',
- u'status': u'RUN',
- u'result': u'COMPLETED',
- u'time': u'*',
- u'classname': u'PropertyRecordingTest',
- u'key_1': u'2'
- }]
- },
- {
- u'name':
- u'NoFixtureTest',
- u'tests':
- 3,
- u'failures':
- 0,
- u'disabled':
- 0,
- u'errors':
- 0,
- u'time':
- u'*',
- u'testsuite': [
- {
- u'name': u'RecordProperty',
- u'status': u'RUN',
- u'result': u'COMPLETED',
- u'time': u'*',
- u'classname': u'NoFixtureTest',
- u'key': u'1'
- },
- {
- u'name': u'ExternalUtilityThatCallsRecordIntValuedProperty',
- u'status': u'RUN',
- u'result': u'COMPLETED',
- u'time': u'*',
- u'classname': u'NoFixtureTest',
- u'key_for_utility_int': u'1'
- },
- {
- u'name':
- u'ExternalUtilityThatCallsRecordStringValuedProperty',
- u'status':
- u'RUN',
- u'result':
- u'COMPLETED',
- u'time':
- u'*',
- u'classname':
- u'NoFixtureTest',
- u'key_for_utility_string':
- u'1'
- }
- ]
- },
- {
+ }, {
+ u'name': u'DISABLED_test',
+ u'status': u'NOTRUN',
+ u'result': u'SUPPRESSED',
+ u'time': u'*',
+ u'timestamp': u'*',
+ u'classname': u'MixedResultTest'
+ }]
+ }, {
+ u'name':
+ u'XmlQuotingTest',
+ u'tests':
+ 1,
+ u'failures':
+ 1,
+ u'disabled':
+ 0,
+ u'errors':
+ 0,
+ u'time':
+ u'*',
+ u'timestamp':
+ u'*',
+ u'testsuite': [{
u'name':
- u'TypedTest/0',
- u'tests':
- 1,
- u'failures':
- 0,
- u'disabled':
- 0,
- u'errors':
- 0,
+ u'OutputsCData',
+ u'status':
+ u'RUN',
+ u'result':
+ u'COMPLETED',
u'time':
u'*',
- u'testsuite': [{
- u'name': u'HasTypeParamAttribute',
- u'type_param': u'int',
- u'status': u'RUN',
- u'result': u'COMPLETED',
- u'time': u'*',
- u'classname': u'TypedTest/0'
- }]
- },
- {
- u'name':
- u'TypedTest/1',
- u'tests':
- 1,
- u'failures':
- 0,
- u'disabled':
- 0,
- u'errors':
- 0,
- u'time':
+ u'timestamp':
u'*',
- u'testsuite': [{
- u'name': u'HasTypeParamAttribute',
- u'type_param': u'long',
- u'status': u'RUN',
- u'result': u'COMPLETED',
- u'time': u'*',
- u'classname': u'TypedTest/1'
+ u'classname':
+ u'XmlQuotingTest',
+ u'failures': [{
+ u'failure': u'gtest_xml_output_unittest_.cc:*\n'
+ u'Failed\nXML output: <?xml encoding="utf-8">'
+ u'<top><![CDATA[cdata text]]></top>' +
+ STACK_TRACE_TEMPLATE,
+ u'type': u''
}]
- },
- {
+ }]
+ }, {
+ u'name':
+ u'InvalidCharactersTest',
+ u'tests':
+ 1,
+ u'failures':
+ 1,
+ u'disabled':
+ 0,
+ u'errors':
+ 0,
+ u'time':
+ u'*',
+ u'timestamp':
+ u'*',
+ u'testsuite': [{
u'name':
- u'Single/TypeParameterizedTestSuite/0',
- u'tests':
- 1,
- u'failures':
- 0,
- u'disabled':
- 0,
- u'errors':
- 0,
+ u'InvalidCharactersInMessage',
+ u'status':
+ u'RUN',
+ u'result':
+ u'COMPLETED',
u'time':
u'*',
- u'testsuite': [{
- u'name': u'HasTypeParamAttribute',
- u'type_param': u'int',
- u'status': u'RUN',
- u'result': u'COMPLETED',
- u'time': u'*',
- u'classname': u'Single/TypeParameterizedTestSuite/0'
- }]
- },
- {
- u'name':
- u'Single/TypeParameterizedTestSuite/1',
- u'tests':
- 1,
- u'failures':
- 0,
- u'disabled':
- 0,
- u'errors':
- 0,
- u'time':
+ u'timestamp':
u'*',
- u'testsuite': [{
- u'name': u'HasTypeParamAttribute',
- u'type_param': u'long',
- u'status': u'RUN',
- u'result': u'COMPLETED',
- u'time': u'*',
- u'classname': u'Single/TypeParameterizedTestSuite/1'
+ u'classname':
+ u'InvalidCharactersTest',
+ u'failures': [{
+ u'failure': u'gtest_xml_output_unittest_.cc:*\n'
+ u'Failed\nInvalid characters in brackets'
+ u' [\x01\x02]' + STACK_TRACE_TEMPLATE,
+ u'type': u''
}]
- },
- {
- u'name':
- u'Single/ValueParamTest',
- u'tests':
- 4,
- u'failures':
- 0,
- u'disabled':
- 0,
- u'errors':
- 0,
- u'time':
- u'*',
- u'testsuite': [
- {
- u'name': u'HasValueParamAttribute/0',
- u'value_param': u'33',
- u'status': u'RUN',
- u'result': u'COMPLETED',
- u'time': u'*',
- u'classname': u'Single/ValueParamTest'
- },
- {
- u'name': u'HasValueParamAttribute/1',
- u'value_param': u'42',
- u'status': u'RUN',
- u'result': u'COMPLETED',
- u'time': u'*',
- u'classname': u'Single/ValueParamTest'
- },
- {
- u'name': u'AnotherTestThatHasValueParamAttribute/0',
- u'value_param': u'33',
- u'status': u'RUN',
- u'result': u'COMPLETED',
- u'time': u'*',
- u'classname': u'Single/ValueParamTest'
- },
- {
- u'name': u'AnotherTestThatHasValueParamAttribute/1',
- u'value_param': u'42',
- u'status': u'RUN',
- u'result': u'COMPLETED',
- u'time': u'*',
- u'classname': u'Single/ValueParamTest'
- }
- ]
- }
- ]
+ }]
+ }, {
+ u'name':
+ u'PropertyRecordingTest',
+ u'tests':
+ 4,
+ u'failures':
+ 0,
+ u'disabled':
+ 0,
+ u'errors':
+ 0,
+ u'time':
+ u'*',
+ u'timestamp':
+ u'*',
+ u'SetUpTestSuite':
+ u'yes',
+ u'TearDownTestSuite':
+ u'aye',
+ u'testsuite': [{
+ u'name': u'OneProperty',
+ u'status': u'RUN',
+ u'result': u'COMPLETED',
+ u'time': u'*',
+ u'timestamp': u'*',
+ u'classname': u'PropertyRecordingTest',
+ u'key_1': u'1'
+ }, {
+ u'name': u'IntValuedProperty',
+ u'status': u'RUN',
+ u'result': u'COMPLETED',
+ u'time': u'*',
+ u'timestamp': u'*',
+ u'classname': u'PropertyRecordingTest',
+ u'key_int': u'1'
+ }, {
+ u'name': u'ThreeProperties',
+ u'status': u'RUN',
+ u'result': u'COMPLETED',
+ u'time': u'*',
+ u'timestamp': u'*',
+ u'classname': u'PropertyRecordingTest',
+ u'key_1': u'1',
+ u'key_2': u'2',
+ u'key_3': u'3'
+ }, {
+ u'name': u'TwoValuesForOneKeyUsesLastValue',
+ u'status': u'RUN',
+ u'result': u'COMPLETED',
+ u'time': u'*',
+ u'timestamp': u'*',
+ u'classname': u'PropertyRecordingTest',
+ u'key_1': u'2'
+ }]
+ }, {
+ u'name':
+ u'NoFixtureTest',
+ u'tests':
+ 3,
+ u'failures':
+ 0,
+ u'disabled':
+ 0,
+ u'errors':
+ 0,
+ u'time':
+ u'*',
+ u'timestamp':
+ u'*',
+ u'testsuite': [{
+ u'name': u'RecordProperty',
+ u'status': u'RUN',
+ u'result': u'COMPLETED',
+ u'time': u'*',
+ u'timestamp': u'*',
+ u'classname': u'NoFixtureTest',
+ u'key': u'1'
+ }, {
+ u'name': u'ExternalUtilityThatCallsRecordIntValuedProperty',
+ u'status': u'RUN',
+ u'result': u'COMPLETED',
+ u'time': u'*',
+ u'timestamp': u'*',
+ u'classname': u'NoFixtureTest',
+ u'key_for_utility_int': u'1'
+ }, {
+ u'name': u'ExternalUtilityThatCallsRecordStringValuedProperty',
+ u'status': u'RUN',
+ u'result': u'COMPLETED',
+ u'time': u'*',
+ u'timestamp': u'*',
+ u'classname': u'NoFixtureTest',
+ u'key_for_utility_string': u'1'
+ }]
+ }, {
+ u'name':
+ u'TypedTest/0',
+ u'tests':
+ 1,
+ u'failures':
+ 0,
+ u'disabled':
+ 0,
+ u'errors':
+ 0,
+ u'time':
+ u'*',
+ u'timestamp':
+ u'*',
+ u'testsuite': [{
+ u'name': u'HasTypeParamAttribute',
+ u'type_param': u'int',
+ u'status': u'RUN',
+ u'result': u'COMPLETED',
+ u'time': u'*',
+ u'timestamp': u'*',
+ u'classname': u'TypedTest/0'
+ }]
+ }, {
+ u'name':
+ u'TypedTest/1',
+ u'tests':
+ 1,
+ u'failures':
+ 0,
+ u'disabled':
+ 0,
+ u'errors':
+ 0,
+ u'time':
+ u'*',
+ u'timestamp':
+ u'*',
+ u'testsuite': [{
+ u'name': u'HasTypeParamAttribute',
+ u'type_param': u'long',
+ u'status': u'RUN',
+ u'result': u'COMPLETED',
+ u'time': u'*',
+ u'timestamp': u'*',
+ u'classname': u'TypedTest/1'
+ }]
+ }, {
+ u'name':
+ u'Single/TypeParameterizedTestSuite/0',
+ u'tests':
+ 1,
+ u'failures':
+ 0,
+ u'disabled':
+ 0,
+ u'errors':
+ 0,
+ u'time':
+ u'*',
+ u'timestamp':
+ u'*',
+ u'testsuite': [{
+ u'name': u'HasTypeParamAttribute',
+ u'type_param': u'int',
+ u'status': u'RUN',
+ u'result': u'COMPLETED',
+ u'time': u'*',
+ u'timestamp': u'*',
+ u'classname': u'Single/TypeParameterizedTestSuite/0'
+ }]
+ }, {
+ u'name':
+ u'Single/TypeParameterizedTestSuite/1',
+ u'tests':
+ 1,
+ u'failures':
+ 0,
+ u'disabled':
+ 0,
+ u'errors':
+ 0,
+ u'time':
+ u'*',
+ u'timestamp':
+ u'*',
+ u'testsuite': [{
+ u'name': u'HasTypeParamAttribute',
+ u'type_param': u'long',
+ u'status': u'RUN',
+ u'result': u'COMPLETED',
+ u'time': u'*',
+ u'timestamp': u'*',
+ u'classname': u'Single/TypeParameterizedTestSuite/1'
+ }]
+ }, {
+ u'name':
+ u'Single/ValueParamTest',
+ u'tests':
+ 4,
+ u'failures':
+ 0,
+ u'disabled':
+ 0,
+ u'errors':
+ 0,
+ u'time':
+ u'*',
+ u'timestamp':
+ u'*',
+ u'testsuite': [{
+ u'name': u'HasValueParamAttribute/0',
+ u'value_param': u'33',
+ u'status': u'RUN',
+ u'result': u'COMPLETED',
+ u'time': u'*',
+ u'timestamp': u'*',
+ u'classname': u'Single/ValueParamTest'
+ }, {
+ u'name': u'HasValueParamAttribute/1',
+ u'value_param': u'42',
+ u'status': u'RUN',
+ u'result': u'COMPLETED',
+ u'time': u'*',
+ u'timestamp': u'*',
+ u'classname': u'Single/ValueParamTest'
+ }, {
+ u'name': u'AnotherTestThatHasValueParamAttribute/0',
+ u'value_param': u'33',
+ u'status': u'RUN',
+ u'result': u'COMPLETED',
+ u'time': u'*',
+ u'timestamp': u'*',
+ u'classname': u'Single/ValueParamTest'
+ }, {
+ u'name': u'AnotherTestThatHasValueParamAttribute/1',
+ u'value_param': u'42',
+ u'status': u'RUN',
+ u'result': u'COMPLETED',
+ u'time': u'*',
+ u'timestamp': u'*',
+ u'classname': u'Single/ValueParamTest'
+ }]
+ }]
}
EXPECTED_FILTERED = {
@@ -556,11 +573,14 @@ EXPECTED_FILTERED = {
0,
u'time':
u'*',
+ u'timestamp':
+ u'*',
u'testsuite': [{
u'name': u'Succeeds',
u'status': u'RUN',
u'result': u'COMPLETED',
u'time': u'*',
+ u'timestamp': u'*',
u'classname': u'SuccessfulTest',
}]
}],
diff --git a/googletest/test/gtest_xml_outfiles_test.py b/googletest/test/gtest_xml_outfiles_test.py
index eaca1a74..e093f6f0 100755
--- a/googletest/test/gtest_xml_outfiles_test.py
+++ b/googletest/test/gtest_xml_outfiles_test.py
@@ -42,8 +42,8 @@ GTEST_OUTPUT_2_TEST = "gtest_xml_outfile2_test_"
EXPECTED_XML_1 = """<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*" name="AllTests">
- <testsuite name="PropertyOne" tests="1" failures="0" disabled="0" errors="0" time="*">
- <testcase name="TestSomeProperties" status="run" result="completed" time="*" classname="PropertyOne">
+ <testsuite name="PropertyOne" tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*">
+ <testcase name="TestSomeProperties" status="run" result="completed" time="*" timestamp="*" classname="PropertyOne">
<properties>
<property name="SetUpProp" value="1"/>
<property name="TestSomeProperty" value="1"/>
@@ -56,8 +56,8 @@ EXPECTED_XML_1 = """<?xml version="1.0" encoding="UTF-8"?>
EXPECTED_XML_2 = """<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*" name="AllTests">
- <testsuite name="PropertyTwo" tests="1" failures="0" disabled="0" errors="0" time="*">
- <testcase name="TestSomeProperties" status="run" result="completed" time="*" classname="PropertyTwo">
+ <testsuite name="PropertyTwo" tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*">
+ <testcase name="TestSomeProperties" status="run" result="completed" time="*" timestamp="*" classname="PropertyTwo">
<properties>
<property name="SetUpProp" value="2"/>
<property name="TestSomeProperty" value="2"/>
diff --git a/googletest/test/gtest_xml_output_unittest.py b/googletest/test/gtest_xml_output_unittest.py
index 745a1346..63b1af0b 100755
--- a/googletest/test/gtest_xml_output_unittest.py
+++ b/googletest/test/gtest_xml_output_unittest.py
@@ -66,20 +66,20 @@ else:
EXPECTED_NON_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="24" failures="4" disabled="2" errors="0" time="*" timestamp="*" name="AllTests" ad_hoc_property="42">
- <testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" errors="0" time="*">
- <testcase name="Succeeds" status="run" result="completed" time="*" classname="SuccessfulTest"/>
+ <testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*">
+ <testcase name="Succeeds" status="run" result="completed" time="*" timestamp="*" classname="SuccessfulTest"/>
</testsuite>
- <testsuite name="FailedTest" tests="1" failures="1" disabled="0" errors="0" time="*">
- <testcase name="Fails" status="run" result="completed" time="*" classname="FailedTest">
+ <testsuite name="FailedTest" tests="1" failures="1" disabled="0" errors="0" time="*" timestamp="*">
+ <testcase name="Fails" status="run" result="completed" time="*" timestamp="*" classname="FailedTest">
<failure message="gtest_xml_output_unittest_.cc:*&#x0A;Expected equality of these values:&#x0A; 1&#x0A; 2" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
Expected equality of these values:
1
2%(stack)s]]></failure>
</testcase>
</testsuite>
- <testsuite name="MixedResultTest" tests="3" failures="1" disabled="1" errors="0" time="*">
- <testcase name="Succeeds" status="run" result="completed" time="*" classname="MixedResultTest"/>
- <testcase name="Fails" status="run" result="completed" time="*" classname="MixedResultTest">
+ <testsuite name="MixedResultTest" tests="3" failures="1" disabled="1" errors="0" time="*" timestamp="*">
+ <testcase name="Succeeds" status="run" result="completed" time="*" timestamp="*" classname="MixedResultTest"/>
+ <testcase name="Fails" status="run" result="completed" time="*" timestamp="*" classname="MixedResultTest">
<failure message="gtest_xml_output_unittest_.cc:*&#x0A;Expected equality of these values:&#x0A; 1&#x0A; 2" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
Expected equality of these values:
1
@@ -89,86 +89,86 @@ Expected equality of these values:
2
3%(stack)s]]></failure>
</testcase>
- <testcase name="DISABLED_test" status="notrun" result="suppressed" time="*" classname="MixedResultTest"/>
+ <testcase name="DISABLED_test" status="notrun" result="suppressed" time="*" timestamp="*" classname="MixedResultTest"/>
</testsuite>
- <testsuite name="XmlQuotingTest" tests="1" failures="1" disabled="0" errors="0" time="*">
- <testcase name="OutputsCData" status="run" result="completed" time="*" classname="XmlQuotingTest">
+ <testsuite name="XmlQuotingTest" tests="1" failures="1" disabled="0" errors="0" time="*" timestamp="*">
+ <testcase name="OutputsCData" status="run" result="completed" time="*" timestamp="*" classname="XmlQuotingTest">
<failure message="gtest_xml_output_unittest_.cc:*&#x0A;Failed&#x0A;XML output: &lt;?xml encoding=&quot;utf-8&quot;&gt;&lt;top&gt;&lt;![CDATA[cdata text]]&gt;&lt;/top&gt;" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
Failed
XML output: <?xml encoding="utf-8"><top><![CDATA[cdata text]]>]]&gt;<![CDATA[</top>%(stack)s]]></failure>
</testcase>
</testsuite>
- <testsuite name="InvalidCharactersTest" tests="1" failures="1" disabled="0" errors="0" time="*">
- <testcase name="InvalidCharactersInMessage" status="run" result="completed" time="*" classname="InvalidCharactersTest">
+ <testsuite name="InvalidCharactersTest" tests="1" failures="1" disabled="0" errors="0" time="*" timestamp="*">
+ <testcase name="InvalidCharactersInMessage" status="run" result="completed" time="*" timestamp="*" classname="InvalidCharactersTest">
<failure message="gtest_xml_output_unittest_.cc:*&#x0A;Failed&#x0A;Invalid characters in brackets []" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
Failed
Invalid characters in brackets []%(stack)s]]></failure>
</testcase>
</testsuite>
- <testsuite name="DisabledTest" tests="1" failures="0" disabled="1" errors="0" time="*">
- <testcase name="DISABLED_test_not_run" status="notrun" result="suppressed" time="*" classname="DisabledTest"/>
+ <testsuite name="DisabledTest" tests="1" failures="0" disabled="1" errors="0" time="*" timestamp="*">
+ <testcase name="DISABLED_test_not_run" status="notrun" result="suppressed" time="*" timestamp="*" classname="DisabledTest"/>
</testsuite>
- <testsuite name="SkippedTest" tests="1" failures="0" disabled="0" errors="0" time="*">
- <testcase name="Skipped" status="run" result="skipped" time="*" classname="SkippedTest"/>
+ <testsuite name="SkippedTest" tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*">
+ <testcase name="Skipped" status="run" result="skipped" time="*" timestamp="*" classname="SkippedTest"/>
</testsuite>
- <testsuite name="PropertyRecordingTest" tests="4" failures="0" disabled="0" errors="0" time="*" SetUpTestSuite="yes" TearDownTestSuite="aye">
- <testcase name="OneProperty" status="run" result="completed" time="*" classname="PropertyRecordingTest">
+ <testsuite name="PropertyRecordingTest" tests="4" failures="0" disabled="0" errors="0" time="*" timestamp="*" SetUpTestSuite="yes" TearDownTestSuite="aye">
+ <testcase name="OneProperty" status="run" result="completed" time="*" timestamp="*" classname="PropertyRecordingTest">
<properties>
<property name="key_1" value="1"/>
</properties>
</testcase>
- <testcase name="IntValuedProperty" status="run" result="completed" time="*" classname="PropertyRecordingTest">
+ <testcase name="IntValuedProperty" status="run" result="completed" time="*" timestamp="*" classname="PropertyRecordingTest">
<properties>
<property name="key_int" value="1"/>
</properties>
</testcase>
- <testcase name="ThreeProperties" status="run" result="completed" time="*" classname="PropertyRecordingTest">
+ <testcase name="ThreeProperties" status="run" result="completed" time="*" timestamp="*" classname="PropertyRecordingTest">
<properties>
<property name="key_1" value="1"/>
<property name="key_2" value="2"/>
<property name="key_3" value="3"/>
</properties>
</testcase>
- <testcase name="TwoValuesForOneKeyUsesLastValue" status="run" result="completed" time="*" classname="PropertyRecordingTest">
+ <testcase name="TwoValuesForOneKeyUsesLastValue" status="run" result="completed" time="*" timestamp="*" classname="PropertyRecordingTest">
<properties>
<property name="key_1" value="2"/>
</properties>
</testcase>
</testsuite>
- <testsuite name="NoFixtureTest" tests="3" failures="0" disabled="0" errors="0" time="*">
- <testcase name="RecordProperty" status="run" result="completed" time="*" classname="NoFixtureTest">
+ <testsuite name="NoFixtureTest" tests="3" failures="0" disabled="0" errors="0" time="*" timestamp="*">
+ <testcase name="RecordProperty" status="run" result="completed" time="*" timestamp="*" classname="NoFixtureTest">
<properties>
<property name="key" value="1"/>
</properties>
</testcase>
- <testcase name="ExternalUtilityThatCallsRecordIntValuedProperty" status="run" result="completed" time="*" classname="NoFixtureTest">
+ <testcase name="ExternalUtilityThatCallsRecordIntValuedProperty" status="run" result="completed" time="*" timestamp="*" classname="NoFixtureTest">
<properties>
<property name="key_for_utility_int" value="1"/>
</properties>
</testcase>
- <testcase name="ExternalUtilityThatCallsRecordStringValuedProperty" status="run" result="completed" time="*" classname="NoFixtureTest">
+ <testcase name="ExternalUtilityThatCallsRecordStringValuedProperty" status="run" result="completed" time="*" timestamp="*" classname="NoFixtureTest">
<properties>
<property name="key_for_utility_string" value="1"/>
</properties>
</testcase>
</testsuite>
- <testsuite name="Single/ValueParamTest" tests="4" failures="0" disabled="0" errors="0" time="*">
- <testcase name="HasValueParamAttribute/0" value_param="33" status="run" result="completed" time="*" classname="Single/ValueParamTest" />
- <testcase name="HasValueParamAttribute/1" value_param="42" status="run" result="completed" time="*" classname="Single/ValueParamTest" />
- <testcase name="AnotherTestThatHasValueParamAttribute/0" value_param="33" status="run" result="completed" time="*" classname="Single/ValueParamTest" />
- <testcase name="AnotherTestThatHasValueParamAttribute/1" value_param="42" status="run" result="completed" time="*" classname="Single/ValueParamTest" />
+ <testsuite name="Single/ValueParamTest" tests="4" failures="0" disabled="0" errors="0" time="*" timestamp="*">
+ <testcase name="HasValueParamAttribute/0" value_param="33" status="run" result="completed" time="*" timestamp="*" classname="Single/ValueParamTest" />
+ <testcase name="HasValueParamAttribute/1" value_param="42" status="run" result="completed" time="*" timestamp="*" classname="Single/ValueParamTest" />
+ <testcase name="AnotherTestThatHasValueParamAttribute/0" value_param="33" status="run" result="completed" time="*" timestamp="*" classname="Single/ValueParamTest" />
+ <testcase name="AnotherTestThatHasValueParamAttribute/1" value_param="42" status="run" result="completed" time="*" timestamp="*" classname="Single/ValueParamTest" />
</testsuite>
- <testsuite name="TypedTest/0" tests="1" failures="0" disabled="0" errors="0" time="*">
- <testcase name="HasTypeParamAttribute" type_param="*" status="run" result="completed" time="*" classname="TypedTest/0" />
+ <testsuite name="TypedTest/0" tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*">
+ <testcase name="HasTypeParamAttribute" type_param="*" status="run" result="completed" time="*" timestamp="*" classname="TypedTest/0" />
</testsuite>
- <testsuite name="TypedTest/1" tests="1" failures="0" disabled="0" errors="0" time="*">
- <testcase name="HasTypeParamAttribute" type_param="*" status="run" result="completed" time="*" classname="TypedTest/1" />
+ <testsuite name="TypedTest/1" tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*">
+ <testcase name="HasTypeParamAttribute" type_param="*" status="run" result="completed" time="*" timestamp="*" classname="TypedTest/1" />
</testsuite>
- <testsuite name="Single/TypeParameterizedTestSuite/0" tests="1" failures="0" disabled="0" errors="0" time="*">
- <testcase name="HasTypeParamAttribute" type_param="*" status="run" result="completed" time="*" classname="Single/TypeParameterizedTestSuite/0" />
+ <testsuite name="Single/TypeParameterizedTestSuite/0" tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*">
+ <testcase name="HasTypeParamAttribute" type_param="*" status="run" result="completed" time="*" timestamp="*" classname="Single/TypeParameterizedTestSuite/0" />
</testsuite>
- <testsuite name="Single/TypeParameterizedTestSuite/1" tests="1" failures="0" disabled="0" errors="0" time="*">
- <testcase name="HasTypeParamAttribute" type_param="*" status="run" result="completed" time="*" classname="Single/TypeParameterizedTestSuite/1" />
+ <testsuite name="Single/TypeParameterizedTestSuite/1" tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*">
+ <testcase name="HasTypeParamAttribute" type_param="*" status="run" result="completed" time="*" timestamp="*" classname="Single/TypeParameterizedTestSuite/1" />
</testsuite>
</testsuites>""" % {
'stack': STACK_TRACE_TEMPLATE
@@ -178,25 +178,25 @@ EXPECTED_FILTERED_TEST_XML = """<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="1" failures="0" disabled="0" errors="0" time="*"
timestamp="*" name="AllTests" ad_hoc_property="42">
<testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0"
- errors="0" time="*">
- <testcase name="Succeeds" status="run" result="completed" time="*" classname="SuccessfulTest"/>
+ errors="0" time="*" timestamp="*">
+ <testcase name="Succeeds" status="run" result="completed" time="*" timestamp="*" classname="SuccessfulTest"/>
</testsuite>
</testsuites>"""
EXPECTED_SHARDED_TEST_XML = """<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="3" failures="0" disabled="0" errors="0" time="*" timestamp="*" name="AllTests" ad_hoc_property="42">
- <testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" errors="0" time="*">
- <testcase name="Succeeds" status="run" result="completed" time="*" classname="SuccessfulTest"/>
+ <testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*">
+ <testcase name="Succeeds" status="run" result="completed" time="*" timestamp="*" classname="SuccessfulTest"/>
</testsuite>
- <testsuite name="PropertyRecordingTest" tests="1" failures="0" disabled="0" errors="0" time="*" SetUpTestSuite="yes" TearDownTestSuite="aye">
- <testcase name="TwoValuesForOneKeyUsesLastValue" status="run" result="completed" time="*" classname="PropertyRecordingTest">
+ <testsuite name="PropertyRecordingTest" tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*" SetUpTestSuite="yes" TearDownTestSuite="aye">
+ <testcase name="TwoValuesForOneKeyUsesLastValue" status="run" result="completed" time="*" timestamp="*" classname="PropertyRecordingTest">
<properties>
<property name="key_1" value="2"/>
</properties>
</testcase>
</testsuite>
- <testsuite name="Single/ValueParamTest" tests="1" failures="0" disabled="0" errors="0" time="*">
- <testcase name="AnotherTestThatHasValueParamAttribute/0" value_param="33" status="run" result="completed" time="*" classname="Single/ValueParamTest" />
+ <testsuite name="Single/ValueParamTest" tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*">
+ <testcase name="AnotherTestThatHasValueParamAttribute/0" value_param="33" status="run" result="completed" time="*" timestamp="*" classname="Single/ValueParamTest" />
</testsuite>
</testsuites>"""
diff --git a/googletest/test/gtest_xml_test_utils.py b/googletest/test/gtest_xml_test_utils.py
index afcf55e0..9914a49e 100755
--- a/googletest/test/gtest_xml_test_utils.py
+++ b/googletest/test/gtest_xml_test_utils.py
@@ -169,7 +169,7 @@ class GTestXMLTestCase(gtest_test_utils.TestCase):
* The stack traces are removed.
"""
- if element.tagName == 'testsuites':
+ if element.tagName in ('testsuites', 'testsuite', 'testcase'):
timestamp = element.getAttributeNode('timestamp')
timestamp.value = re.sub(r'^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d$',
'*', timestamp.value)