summaryrefslogtreecommitdiffstats
path: root/googletest
diff options
context:
space:
mode:
Diffstat (limited to 'googletest')
-rw-r--r--googletest/CMakeLists.txt4
-rw-r--r--googletest/cmake/internal_utils.cmake9
-rw-r--r--googletest/docs/AdvancedGuide.md242
-rw-r--r--googletest/docs/Documentation.md2
-rw-r--r--googletest/docs/FAQ.md2
-rw-r--r--googletest/docs/Primer.md2
-rw-r--r--googletest/include/gtest/gtest-printers.h101
-rw-r--r--googletest/include/gtest/gtest.h19
-rw-r--r--googletest/include/gtest/gtest_prod.h11
-rw-r--r--googletest/include/gtest/internal/gtest-death-test-internal.h20
-rw-r--r--googletest/include/gtest/internal/gtest-internal.h27
-rw-r--r--googletest/include/gtest/internal/gtest-port.h174
-rw-r--r--googletest/src/gtest-death-test.cc20
-rw-r--r--googletest/src/gtest-filepath.cc2
-rw-r--r--googletest/src/gtest-internal-inl.h8
-rw-r--r--googletest/src/gtest-port.cc42
-rw-r--r--googletest/src/gtest-printers.cc94
-rw-r--r--googletest/src/gtest-typed-test.cc1
-rw-r--r--googletest/src/gtest.cc550
-rw-r--r--googletest/test/BUILD.bazel17
-rw-r--r--googletest/test/gtest-death-test_test.cc6
-rw-r--r--googletest/test/gtest-param-test_test.cc63
-rw-r--r--googletest/test/gtest-printers_test.cc102
-rw-r--r--googletest/test/gtest_all_test.cc24
-rw-r--r--googletest/test/gtest_assert_by_exception_test.cc119
-rw-r--r--googletest/test/gtest_env_var_test_.cc1
-rw-r--r--googletest/test/gtest_json_outfiles_test.py162
-rw-r--r--googletest/test/gtest_json_output_unittest.py611
-rw-r--r--googletest/test/gtest_json_test_utils.py60
-rw-r--r--googletest/test/gtest_main_unittest.cc4
-rwxr-xr-xgoogletest/test/gtest_uninitialized_test.py1
-rw-r--r--googletest/test/gtest_uninitialized_test_.cc2
-rw-r--r--googletest/test/gtest_unittest.cc189
-rwxr-xr-xgoogletest/test/gtest_xml_outfiles_test.py16
-rwxr-xr-xgoogletest/test/gtest_xml_output_unittest.py50
-rwxr-xr-xgoogletest/test/gtest_xml_test_utils.py35
-rwxr-xr-xgoogletest/xcode/Scripts/versiongenerate.py2
37 files changed, 2432 insertions, 362 deletions
diff --git a/googletest/CMakeLists.txt b/googletest/CMakeLists.txt
index 77b55ca..b09c46e 100644
--- a/googletest/CMakeLists.txt
+++ b/googletest/CMakeLists.txt
@@ -27,8 +27,6 @@ option(
"Build gtest with internal symbols hidden in shared libraries."
OFF)
-set(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Generate debug library name with a postfix.")
-
# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build().
include(cmake/hermetic_build.cmake OPTIONAL)
@@ -306,7 +304,9 @@ if (gtest_build_tests)
cxx_executable(gtest_xml_outfile1_test_ test gtest_main)
cxx_executable(gtest_xml_outfile2_test_ test gtest_main)
py_test(gtest_xml_outfiles_test)
+ py_test(gtest_json_outfiles_test)
cxx_executable(gtest_xml_output_unittest_ test gtest)
py_test(gtest_xml_output_unittest)
+ py_test(gtest_json_output_unittest)
endif()
diff --git a/googletest/cmake/internal_utils.cmake b/googletest/cmake/internal_utils.cmake
index c54bc94..6448918 100644
--- a/googletest/cmake/internal_utils.cmake
+++ b/googletest/cmake/internal_utils.cmake
@@ -91,10 +91,13 @@ macro(config_compiler_and_linker)
set(cxx_base_flags "${cxx_base_flags} -D_UNICODE -DUNICODE -DWIN32 -D_WIN32")
set(cxx_base_flags "${cxx_base_flags} -DSTRICT -DWIN32_LEAN_AND_MEAN")
set(cxx_exception_flags "-EHsc -D_HAS_EXCEPTIONS=1")
- set(cxx_no_exception_flags "-D_HAS_EXCEPTIONS=0")
+ set(cxx_no_exception_flags "-EHs-c- -D_HAS_EXCEPTIONS=0")
set(cxx_no_rtti_flags "-GR-")
elseif (CMAKE_COMPILER_IS_GNUCXX)
set(cxx_base_flags "-Wall -Wshadow -Werror")
+ if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0)
+ set(cxx_base_flags "${cxx_base_flags} -Wno-error=dangling-else")
+ endif()
set(cxx_exception_flags "-fexceptions")
set(cxx_no_exception_flags "-fno-exceptions")
# Until version 4.3.2, GCC doesn't define a macro to indicate
@@ -155,6 +158,10 @@ function(cxx_library_with_type name type cxx_flags)
set_target_properties(${name}
PROPERTIES
COMPILE_FLAGS "${cxx_flags}")
+ # Generate debug library name with a postfix.
+ set_target_properties(${name}
+ PROPERTIES
+ DEBUG_POSTFIX "d")
if (BUILD_SHARED_LIBS OR type STREQUAL "SHARED")
set_target_properties(${name}
PROPERTIES
diff --git a/googletest/docs/AdvancedGuide.md b/googletest/docs/AdvancedGuide.md
index ccb087c..c1a1a4a 100644
--- a/googletest/docs/AdvancedGuide.md
+++ b/googletest/docs/AdvancedGuide.md
@@ -872,13 +872,33 @@ TEST(FooTest, Bar) {
}
```
-Since we don't use exceptions, it is technically impossible to
-implement the intended behavior here. To alleviate this, Google Test
-provides two solutions. You could use either the
-`(ASSERT|EXPECT)_NO_FATAL_FAILURE` assertions or the
-`HasFatalFailure()` function. They are described in the following two
+To alleviate this, gUnit provides three different solutions. You could use
+either exceptions, the `(ASSERT|EXPECT)_NO_FATAL_FAILURE` assertions or the
+`HasFatalFailure()` function. They are described in the following two
subsections.
+#### Asserting on Subroutines with an exception
+
+The following code can turn ASSERT-failure into an exception:
+
+```c++
+class ThrowListener : public testing::EmptyTestEventListener {
+ void OnTestPartResult(const testing::TestPartResult& result) override {
+ if (result.type() == testing::TestPartResult::kFatalFailure) {
+ throw testing::AssertionException(result);
+ }
+ }
+};
+int main(int argc, char** argv) {
+ ...
+ testing::UnitTest::GetInstance()->listeners().Append(new ThrowListener);
+ return RUN_ALL_TESTS();
+}
+```
+
+This listener should be added after other listeners if you have any, otherwise
+they won't see failed `OnTestPartResult`.
+
### Asserting on Subroutines ###
As shown above, if your test calls a subroutine that has an `ASSERT_*`
@@ -1951,6 +1971,17 @@ variable to `0` has the same effect.
_Availability:_ Linux, Windows, Mac. (In Google Test 1.3.0 and lower,
the default behavior is that the elapsed time is **not** printed.)
+**Availability**: Linux, Windows, Mac.
+
+#### Suppressing UTF-8 Text Output
+
+In case of assertion failures, gUnit prints expected and actual values of type
+`string` both as hex-encoded strings as well as in readable UTF-8 text if they
+contain valid non-ASCII UTF-8 characters. If you want to suppress the UTF-8 text
+because, for example, you don't have an UTF-8 compatible output medium, run the
+test program with `--gunit_print_utf8=0` or set the `GUNIT_PRINT_UTF8`
+environment variable to `0`.
+
### Generating an XML Report ###
Google Test can emit a detailed XML report to a file in addition to its normal
@@ -2029,6 +2060,207 @@ Things to note:
_Availability:_ Linux, Windows, Mac.
+#### Generating an JSON Report {#JsonReport}
+
+gUnit can also emit a JSON report as an alternative format to XML. To generate
+the JSON report, set the `GUNIT_OUTPUT` environment variable or the
+`--gunit_output` flag to the string `"json:path_to_output_file"`, which will
+create the file at the given location. You can also just use the string
+`"json"`, in which case the output can be found in the `test_detail.json` file
+in the current directory.
+
+The report format conforms to the following JSON Schema:
+
+```json
+{
+ "$schema": "http://json-schema.org/schema#",
+ "type": "object",
+ "definitions": {
+ "TestCase": {
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "tests": { "type": "integer" },
+ "failures": { "type": "integer" },
+ "disabled": { "type": "integer" },
+ "time": { "type": "string" },
+ "testsuite": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/TestInfo"
+ }
+ }
+ }
+ },
+ "TestInfo": {
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "status": {
+ "type": "string",
+ "enum": ["RUN", "NOTRUN"]
+ },
+ "time": { "type": "string" },
+ "classname": { "type": "string" },
+ "failures": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/Failure"
+ }
+ }
+ }
+ },
+ "Failure": {
+ "type": "object",
+ "properties": {
+ "failures": { "type": "string" },
+ "type": { "type": "string" }
+ }
+ }
+ },
+ "properties": {
+ "tests": { "type": "integer" },
+ "failures": { "type": "integer" },
+ "disabled": { "type": "integer" },
+ "errors": { "type": "integer" },
+ "timestamp": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "time": { "type": "string" },
+ "name": { "type": "string" },
+ "testsuites": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/TestCase"
+ }
+ }
+ }
+}
+```
+
+The report uses the format that conforms to the following Proto3 using the
+[JSON encoding](https://developers.google.com/protocol-buffers/docs/proto3#json):
+
+```proto
+syntax = "proto3";
+
+package googletest;
+
+import "google/protobuf/timestamp.proto";
+import "google/protobuf/duration.proto";
+
+message UnitTest {
+ int32 tests = 1;
+ int32 failures = 2;
+ int32 disabled = 3;
+ int32 errors = 4;
+ google.protobuf.Timestamp timestamp = 5;
+ google.protobuf.Duration time = 6;
+ string name = 7;
+ repeated TestCase testsuites = 8;
+}
+
+message TestCase {
+ string name = 1;
+ int32 tests = 2;
+ int32 failures = 3;
+ int32 disabled = 4;
+ int32 errors = 5;
+ google.protobuf.Duration time = 6;
+ repeated TestInfo testsuite = 7;
+}
+
+message TestInfo {
+ string name = 1;
+ enum Status {
+ RUN = 0;
+ NOTRUN = 1;
+ }
+ Status status = 2;
+ google.protobuf.Duration time = 3;
+ string classname = 4;
+ message Failure {
+ string failures = 1;
+ string type = 2;
+ }
+ repeated Failure failures = 5;
+}
+```
+
+For instance, the following program
+
+```c++
+TEST(MathTest, Addition) { ... }
+TEST(MathTest, Subtraction) { ... }
+TEST(LogicTest, NonContradiction) { ... }
+```
+
+could generate this report:
+
+```json
+{
+ "tests": 3,
+ "failures": 1,
+ "errors": 0,
+ "time": "0.035s",
+ "timestamp": "2011-10-31T18:52:42Z"
+ "name": "AllTests",
+ "testsuites": [
+ {
+ "name": "MathTest",
+ "tests": 2,
+ "failures": 1,
+ "errors": 0,
+ "time": "0.015s",
+ "testsuite": [
+ {
+ "name": "Addition",
+ "status": "RUN",
+ "time": "0.007s",
+ "classname": "",
+ "failures": [
+ {
+ "message": "Value of: add(1, 1)\x0A Actual: 3\x0AExpected: 2",
+ "type": ""
+ },
+ {
+ "message": "Value of: add(1, -1)\x0A Actual: 1\x0AExpected: 0",
+ "type": ""
+ }
+ ]
+ },
+ {
+ "name": "Subtraction",
+ "status": "RUN",
+ "time": "0.005s",
+ "classname": ""
+ }
+ ]
+ }
+ {
+ "name": "LogicTest",
+ "tests": 1,
+ "failures": 0,
+ "errors": 0,
+ "time": "0.005s",
+ "testsuite": [
+ {
+ "name": "NonContradiction",
+ "status": "RUN",
+ "time": "0.005s",
+ "classname": ""
+ }
+ ]
+ }
+ ]
+}
+```
+
+IMPORTANT: The exact format of the JSON document is subject to change.
+
+**Availability**: Linux, Windows, Mac.
+
## Controlling How Failures Are Reported ##
### Turning Assertion Failures into Break-Points ###
diff --git a/googletest/docs/Documentation.md b/googletest/docs/Documentation.md
index 3784c8f..20f2503 100644
--- a/googletest/docs/Documentation.md
+++ b/googletest/docs/Documentation.md
@@ -12,5 +12,5 @@ the respective git branch/tag).**
To contribute code to Google Test, read:
- * [CONTRIBUTING](../CONTRIBUTING.md) -- read this _before_ writing your first patch.
+ * [CONTRIBUTING](../../CONTRIBUTING.md) -- read this _before_ writing your first patch.
* [PumpManual](PumpManual.md) -- how we generate some of Google Test's source files.
diff --git a/googletest/docs/FAQ.md b/googletest/docs/FAQ.md
index 1a216a1..bd9526d 100644
--- a/googletest/docs/FAQ.md
+++ b/googletest/docs/FAQ.md
@@ -460,7 +460,7 @@ following benefits:
You may still want to use `SetUp()/TearDown()` in the following rare cases:
* If the tear-down operation could throw an exception, you must use `TearDown()` as opposed to the destructor, as throwing in a destructor leads to undefined behavior and usually will kill your program right away. Note that many standard libraries (like STL) may throw when exceptions are enabled in the compiler. Therefore you should prefer `TearDown()` if you want to write portable tests that work with or without exceptions.
* The assertion macros throw an exception when flag `--gtest_throw_on_failure` is specified. Therefore, you shouldn't use Google Test assertions in a destructor if you plan to run your tests with this flag.
- * In a constructor or destructor, you cannot make a virtual function call on this object. (You can call a method declared as virtual, but it will be statically bound.) Therefore, if you need to call a method that will be overriden in a derived class, you have to use `SetUp()/TearDown()`.
+ * In a constructor or destructor, you cannot make a virtual function call on this object. (You can call a method declared as virtual, but it will be statically bound.) Therefore, if you need to call a method that will be overridden in a derived class, you have to use `SetUp()/TearDown()`.
## The compiler complains "no matching function to call" when I use ASSERT\_PREDn. How do I fix it? ##
diff --git a/googletest/docs/Primer.md b/googletest/docs/Primer.md
index 384d4d6..5e8ee0c 100644
--- a/googletest/docs/Primer.md
+++ b/googletest/docs/Primer.md
@@ -239,7 +239,7 @@ To create a test:
1. The test's result is determined by the assertions; if any assertion in the test fails (either fatally or non-fatally), or if the test crashes, the entire test fails. Otherwise, it succeeds.
```
-TEST(test_case_name, test_name) {
+TEST(testCaseName, testName) {
... test body ...
}
```
diff --git a/googletest/include/gtest/gtest-printers.h b/googletest/include/gtest/gtest-printers.h
index 38c63d2..2c83c3f 100644
--- a/googletest/include/gtest/gtest-printers.h
+++ b/googletest/include/gtest/gtest-printers.h
@@ -46,6 +46,10 @@
// 2. operator<<(ostream&, const T&) defined in either foo or the
// global namespace.
//
+// However if T is an STL-style container then it is printed element-wise
+// unless foo::PrintTo(const T&, ostream*) is defined. Note that
+// operator<<() is ignored for container types.
+//
// If none of the above is defined, it will print the debug string of
// the value if it is a protocol buffer, or print the raw bytes in the
// value otherwise.
@@ -107,6 +111,11 @@
# include <tuple>
#endif
+#if GTEST_HAS_ABSL
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#endif // GTEST_HAS_ABSL
+
namespace testing {
// Definitions in the 'internal' and 'internal2' name spaces are
@@ -125,7 +134,11 @@ enum TypeKind {
kProtobuf, // a protobuf type
kConvertibleToInteger, // a type implicitly convertible to BiggestInt
// (e.g. a named or unnamed enum type)
- kOtherType // anything else
+#if GTEST_HAS_ABSL
+ kConvertibleToStringView, // a type implicitly convertible to
+ // absl::string_view
+#endif
+ kOtherType // anything else
};
// TypeWithoutFormatter<T, kTypeKind>::PrintValue(value, os) is called
@@ -138,7 +151,7 @@ class TypeWithoutFormatter {
// This default version is called when kTypeKind is kOtherType.
static void PrintValue(const T& value, ::std::ostream* os) {
PrintBytesInObjectTo(static_cast<const unsigned char*>(
- reinterpret_cast<const void *>(&value)),
+ reinterpret_cast<const void*>(&value)),
sizeof(value), os);
}
};
@@ -176,6 +189,19 @@ class TypeWithoutFormatter<T, kConvertibleToInteger> {
}
};
+#if GTEST_HAS_ABSL
+template <typename T>
+class TypeWithoutFormatter<T, kConvertibleToStringView> {
+ public:
+ // Since T has neither operator<< nor PrintTo() but can be implicitly
+ // converted to absl::string_view, we print it as a absl::string_view.
+ //
+ // Note: the implementation is further below, as it depends on
+ // internal::PrintTo symbol which is defined later in the file.
+ static void PrintValue(const T& value, ::std::ostream* os);
+};
+#endif
+
// Prints the given value to the given ostream. If the value is a
// protocol message, its debug string is printed; if it's an enum or
// of a type implicitly convertible to BiggestInt, it's printed as an
@@ -203,10 +229,19 @@ class TypeWithoutFormatter<T, kConvertibleToInteger> {
template <typename Char, typename CharTraits, typename T>
::std::basic_ostream<Char, CharTraits>& operator<<(
::std::basic_ostream<Char, CharTraits>& os, const T& x) {
- TypeWithoutFormatter<T,
- (internal::IsAProtocolMessage<T>::value ? kProtobuf :
- internal::ImplicitlyConvertible<const T&, internal::BiggestInt>::value ?
- kConvertibleToInteger : kOtherType)>::PrintValue(x, &os);
+ TypeWithoutFormatter<T, (internal::IsAProtocolMessage<T>::value
+ ? kProtobuf
+ : internal::ImplicitlyConvertible<
+ const T&, internal::BiggestInt>::value
+ ? kConvertibleToInteger
+ :
+#if GTEST_HAS_ABSL
+ internal::ImplicitlyConvertible<
+ const T&, absl::string_view>::value
+ ? kConvertibleToStringView
+ :
+#endif
+ kOtherType)>::PrintValue(x, &os);
return os;
}
@@ -427,7 +462,8 @@ void DefaultPrintTo(WrapPrinterType<kPrintFunctionPointer> /* dummy */,
*os << "NULL";
} else {
// T is a function type, so '*os << p' doesn't do what we want
- // (it just prints p as bool). Cast p to const void* to print it.
+ // (it just prints p as bool). We want to print p as a const
+ // void*.
*os << reinterpret_cast<const void*>(p);
}
}
@@ -456,17 +492,15 @@ void PrintTo(const T& value, ::std::ostream* os) {
// DefaultPrintTo() is overloaded. The type of its first argument
// determines which version will be picked.
//
- // Note that we check for recursive and other container types here, prior
- // to we check for protocol message types in our operator<<. The rationale is:
+ // Note that we check for container types here, prior to we check
+ // for protocol message types in our operator<<. The rationale is:
//
// For protocol messages, we want to give people a chance to
// override Google Mock's format by defining a PrintTo() or
// operator<<. For STL containers, other formats can be
// incompatible with Google Mock's format for the container
// elements; therefore we check for container types here to ensure
- // that our format is used. To prevent an infinite runtime recursion
- // during the output of recursive container types, we check first for
- // those.
+ // that our format is used.
//
// Note that MSVC and clang-cl do allow an implicit conversion from
// pointer-to-function to pointer-to-object, but clang-cl warns on it.
@@ -484,8 +518,8 @@ void PrintTo(const T& value, ::std::ostream* os) {
#else
: !internal::ImplicitlyConvertible<T, const void*>::value
#endif
- ? kPrintFunctionPointer
- : kPrintPointer>(),
+ ? kPrintFunctionPointer
+ : kPrintPointer>(),
value, os);
}
@@ -593,6 +627,13 @@ inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
}
#endif // GTEST_HAS_STD_WSTRING
+#if GTEST_HAS_ABSL
+// Overload for absl::string_view.
+inline void PrintTo(absl::string_view sp, ::std::ostream* os) {
+ PrintTo(::std::string(sp), os);
+}
+#endif // GTEST_HAS_ABSL
+
#if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
// Helper function for printing a tuple. T must be instantiated with
// a tuple type.
@@ -722,6 +763,26 @@ class UniversalPrinter {
GTEST_DISABLE_MSC_WARNINGS_POP_()
};
+#if GTEST_HAS_ABSL
+
+// Printer for absl::optional
+
+template <typename T>
+class UniversalPrinter<::absl::optional<T>> {
+ public:
+ static void Print(const ::absl::optional<T>& value, ::std::ostream* os) {
+ *os << '(';
+ if (!value) {
+ *os << "nullopt";
+ } else {
+ UniversalPrint(*value, os);
+ }
+ *os << ')';
+ }
+};
+
+#endif // GTEST_HAS_ABSL
+
// UniversalPrintArray(begin, len, os) prints an array of 'len'
// elements, starting at address 'begin'.
template <typename T>
@@ -868,7 +929,7 @@ void UniversalPrint(const T& value, ::std::ostream* os) {
UniversalPrinter<T1>::Print(value, os);
}
-typedef ::std::vector<string> Strings;
+typedef ::std::vector< ::std::string> Strings;
// TuplePolicy<TupleT> must provide:
// - tuple_size
@@ -988,6 +1049,16 @@ Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
} // namespace internal
+#if GTEST_HAS_ABSL
+namespace internal2 {
+template <typename T>
+void TypeWithoutFormatter<T, kConvertibleToStringView>::PrintValue(
+ const T& value, ::std::ostream* os) {
+ internal::PrintTo(absl::string_view(value), os);
+}
+} // namespace internal2
+#endif
+
template <typename T>
::std::string PrintToString(const T& value) {
::std::stringstream ss;
diff --git a/googletest/include/gtest/gtest.h b/googletest/include/gtest/gtest.h
index 93b755f..26e787d 100644
--- a/googletest/include/gtest/gtest.h
+++ b/googletest/include/gtest/gtest.h
@@ -115,6 +115,9 @@ GTEST_DECLARE_string_(output);
// test.
GTEST_DECLARE_bool_(print_time);
+// This flags control whether Google Test prints UTF8 characters as text.
+GTEST_DECLARE_bool_(print_utf8);
+
// This flag specifies the random number seed.
GTEST_DECLARE_int32_(random_seed);
@@ -135,7 +138,7 @@ GTEST_DECLARE_int32_(stack_trace_depth);
// When this flag is specified, a failed assertion will throw an
// exception if exceptions are enabled, or exit the program with a
-// non-zero code otherwise.
+// non-zero code otherwise. For use with an external test framework.
GTEST_DECLARE_bool_(throw_on_failure);
// When this flag is set with a "host:port" string, on supported
@@ -1001,6 +1004,18 @@ class Environment {
virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; }
};
+#if GTEST_HAS_EXCEPTIONS
+
+// Exception which can be thrown from TestEventListener::OnTestPartResult.
+class GTEST_API_ AssertionException
+ : public internal::GoogleTestFailureException {
+ public:
+ explicit AssertionException(const TestPartResult& result)
+ : GoogleTestFailureException(result) {}
+};
+
+#endif // GTEST_HAS_EXCEPTIONS
+
// The interface for tracing execution of tests. The methods are organized in
// the order the corresponding events are fired.
class TestEventListener {
@@ -1029,6 +1044,8 @@ class TestEventListener {
virtual void OnTestStart(const TestInfo& test_info) = 0;
// Fired after a failed assertion or a SUCCEED() invocation.
+ // If you want to throw an exception from this function to skip to the next
+ // TEST, it must be AssertionException defined above, or inherited from it.
virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0;
// Fired after the test ends.
diff --git a/googletest/include/gtest/gtest_prod.h b/googletest/include/gtest/gtest_prod.h
index da80ddc..d9ea685 100644
--- a/googletest/include/gtest/gtest_prod.h
+++ b/googletest/include/gtest/gtest_prod.h
@@ -40,17 +40,20 @@
//
// class MyClass {
// private:
-// void MyMethod();
-// FRIEND_TEST(MyClassTest, MyMethod);
+// void PrivateMethod();
+// FRIEND_TEST(MyClassTest, PrivateMethodWorks);
// };
//
// class MyClassTest : public testing::Test {
// // ...
// };
//
-// TEST_F(MyClassTest, MyMethod) {
-// // Can call MyClass::MyMethod() here.
+// TEST_F(MyClassTest, PrivateMethodWorks) {
+// // Can call MyClass::PrivateMethod() here.
// }
+//
+// Note: The test class must be in the same namespace as the class being tested.
+// For example, putting MyClassTest in an anonymous namespace will not work.
#define FRIEND_TEST(test_case_name, test_name)\
friend class test_case_name##_##test_name##_Test
diff --git a/googletest/include/gtest/internal/gtest-death-test-internal.h b/googletest/include/gtest/internal/gtest-death-test-internal.h
index a9e6610..88e7799 100644
--- a/googletest/include/gtest/internal/gtest-death-test-internal.h
+++ b/googletest/include/gtest/internal/gtest-death-test-internal.h
@@ -217,14 +217,18 @@ GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
// can be streamed.
// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in
-// NDEBUG mode. In this case we need the statements to be executed, the regex is
-// ignored, and the macro must accept a streamed message even though the message
-// is never printed.
-# define GTEST_EXECUTE_STATEMENT_(statement, regex) \
- GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
- if (::testing::internal::AlwaysTrue()) { \
- GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
- } else \
+// NDEBUG mode. In this case we need the statements to be executed and the macro
+// must accept a streamed message even though the message is never printed.
+// The regex object is not evaluated, but it is used to prevent "unused"
+// warnings and to avoid an expression that doesn't compile in debug mode.
+#define GTEST_EXECUTE_STATEMENT_(statement, regex) \
+ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+ if (::testing::internal::AlwaysTrue()) { \
+ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+ } else if (!::testing::internal::AlwaysTrue()) { \
+ const ::testing::internal::RE& gtest_regex = (regex); \
+ static_cast<void>(gtest_regex); \
+ } else \
::testing::Message()
// A class representing the parsed contents of the
diff --git a/googletest/include/gtest/internal/gtest-internal.h b/googletest/include/gtest/internal/gtest-internal.h
index 8d6a461..e87f85e 100644
--- a/googletest/include/gtest/internal/gtest-internal.h
+++ b/googletest/include/gtest/internal/gtest-internal.h
@@ -806,31 +806,6 @@ struct RemoveConst<T[N]> {
#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \
GTEST_REMOVE_CONST_(GTEST_REMOVE_REFERENCE_(T))
-// Adds reference to a type if it is not a reference type,
-// otherwise leaves it unchanged. This is the same as
-// tr1::add_reference, which is not widely available yet.
-template <typename T>
-struct AddReference { typedef T& type; }; // NOLINT
-template <typename T>
-struct AddReference<T&> { typedef T& type; }; // NOLINT
-
-// A handy wrapper around AddReference that works when the argument T
-// depends on template parameters.
-#define GTEST_ADD_REFERENCE_(T) \
- typename ::testing::internal::AddReference<T>::type
-
-// Adds a reference to const on top of T as necessary. For example,
-// it transforms
-//
-// char ==> const char&
-// const char ==> const char&
-// char& ==> const char&
-// const char& ==> const char&
-//
-// The argument T must depend on some template parameters.
-#define GTEST_REFERENCE_TO_CONST_(T) \
- GTEST_ADD_REFERENCE_(const GTEST_REMOVE_REFERENCE_(T))
-
// ImplicitlyConvertible<From, To>::value is a compile-time bool
// constant that's true iff type From can be implicitly converted to
// type To.
@@ -1078,7 +1053,7 @@ class NativeArray {
private:
enum {
kCheckTypeIsNotConstOrAReference = StaticAssertTypeEqHelper<
- Element, GTEST_REMOVE_REFERENCE_AND_CONST_(Element)>::value,
+ Element, GTEST_REMOVE_REFERENCE_AND_CONST_(Element)>::value
};
// Initializes this object with a copy of the input.
diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h
index 01ad5da..7a10d90 100644
--- a/googletest/include/gtest/internal/gtest-port.h
+++ b/googletest/include/gtest/internal/gtest-port.h
@@ -73,11 +73,9 @@
// GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions
// are enabled.
// GTEST_HAS_GLOBAL_STRING - Define it to 1/0 to indicate that ::string
-// is/isn't available (some systems define
-// ::string, which is different to std::string).
-// GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string
-// is/isn't available (some systems define
-// ::wstring, which is different to std::wstring).
+// is/isn't available
+// GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::wstring
+// is/isn't available
// GTEST_HAS_POSIX_RE - Define it to 1/0 to indicate that POSIX regular
// expressions are/aren't available.
// GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that <pthread.h>
@@ -109,6 +107,12 @@
// GTEST_CREATE_SHARED_LIBRARY
// - Define to 1 when compiling Google Test itself
// as a shared library.
+// GTEST_DEFAULT_DEATH_TEST_STYLE
+// - The default value of --gtest_death_test_style.
+// The legacy default has been "fast" in the open
+// source version since 2008. The recommended value
+// is "threadsafe", and can be set in
+// custom/gtest-port.h.
// Platform-indicating macros
// --------------------------
@@ -178,7 +182,7 @@
// GTEST_HAS_POSIX_RE (see above) which users can
// define themselves.
// GTEST_USES_SIMPLE_RE - our own simple regex is used;
-// the above two are mutually exclusive.
+// the above RE\b(s) are mutually exclusive.
// GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ().
// Misc public macros
@@ -207,6 +211,7 @@
//
// C++11 feature wrappers:
//
+// testing::internal::forward - portability wrapper for std::forward.
// testing::internal::move - portability wrapper for std::move.
//
// Synchronization:
@@ -272,10 +277,12 @@
# include <TargetConditionals.h>
#endif
+// Brings in the definition of HAS_GLOBAL_STRING. This must be done
+// BEFORE we test HAS_GLOBAL_STRING.
+#include <string> // NOLINT
#include <algorithm> // NOLINT
#include <iostream> // NOLINT
#include <sstream> // NOLINT
-#include <string> // NOLINT
#include <utility>
#include <vector> // NOLINT
@@ -464,8 +471,11 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#ifndef GTEST_HAS_EXCEPTIONS
// The user didn't tell us whether exceptions are enabled, so we need
// to figure it out.
-# if defined(_MSC_VER) || defined(__BORLANDC__)
-// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS
+# if defined(_MSC_VER) && defined(_CPPUNWIND)
+// MSVC defines _CPPUNWIND to 1 iff exceptions are enabled.
+# define GTEST_HAS_EXCEPTIONS 1
+# elif defined(__BORLANDC__)
+// C++Builder's implementation of the STL uses the _HAS_EXCEPTIONS
// macro to enable exceptions, so we'll do the same.
// Assumes that exceptions are enabled by default.
# ifndef _HAS_EXCEPTIONS
@@ -509,7 +519,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
# define GTEST_HAS_STD_STRING 1
#elif !GTEST_HAS_STD_STRING
// The user told us that ::std::string isn't available.
-# error "Google Test cannot be used where ::std::string isn't available."
+# error "::std::string isn't available."
#endif // !defined(GTEST_HAS_STD_STRING)
#ifndef GTEST_HAS_GLOBAL_STRING
@@ -611,8 +621,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
//
// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0
// to your compiler flags.
-#define GTEST_HAS_PTHREAD \
- (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX || GTEST_OS_QNX || \
+#define GTEST_HAS_PTHREAD \
+ (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX || GTEST_OS_QNX || \
GTEST_OS_FREEBSD || GTEST_OS_NACL || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA)
#endif // GTEST_HAS_PTHREAD
@@ -806,9 +816,9 @@ using ::std::tuple_size;
// Google Test does not support death tests for VC 7.1 and earlier as
// abort() in a VC 7.1 application compiled as GUI in debug config
// pops up a dialog window that cannot be suppressed programmatically.
-#if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \
- (GTEST_OS_MAC && !GTEST_OS_IOS) || \
- (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \
+#if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \
+ (GTEST_OS_MAC && !GTEST_OS_IOS) || \
+ (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \
GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX || \
GTEST_OS_OPENBSD || GTEST_OS_QNX || GTEST_OS_FREEBSD || GTEST_OS_NETBSD)
# define GTEST_HAS_DEATH_TEST 1
@@ -824,9 +834,10 @@ using ::std::tuple_size;
# define GTEST_HAS_TYPED_TEST_P 1
#endif
-// Determines whether to support Combine().
-// The implementation doesn't work on Sun Studio since it doesn't
-// understand templated conversion operators.
+// Determines whether to support Combine(). This only makes sense when
+// value-parameterized tests are enabled. The implementation doesn't
+// work on Sun Studio since it doesn't understand templated conversion
+// operators.
#if (GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_) && !defined(__SUNPRO_CC)
# define GTEST_HAS_COMBINE 1
#endif
@@ -878,6 +889,12 @@ using ::std::tuple_size;
# define GTEST_ATTRIBUTE_UNUSED_
#endif
+#if GTEST_LANG_CXX11
+# define GTEST_CXX11_EQUALS_DELETE_ = delete
+#else // GTEST_LANG_CXX11
+# define GTEST_CXX11_EQUALS_DELETE_
+#endif // GTEST_LANG_CXX11
+
// Use this annotation before a function that takes a printf format string.
#if (defined(__GNUC__) || defined(__clang__)) && !defined(COMPILER_ICC)
# if defined(__MINGW_PRINTF_FORMAT)
@@ -895,15 +912,16 @@ using ::std::tuple_size;
# define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check)
#endif
+
// A macro to disallow operator=
// This should be used in the private: declarations for a class.
-#define GTEST_DISALLOW_ASSIGN_(type)\
- void operator=(type const &)
+#define GTEST_DISALLOW_ASSIGN_(type) \
+ void operator=(type const &) GTEST_CXX11_EQUALS_DELETE_
// A macro to disallow copy constructor and operator=
// This should be used in the private: declarations for a class.
-#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\
- type(type const &);\
+#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type) \
+ type(type const &) GTEST_CXX11_EQUALS_DELETE_; \
GTEST_DISALLOW_ASSIGN_(type)
// Tell the compiler to warn about unused return values for functions declared
@@ -972,6 +990,10 @@ using ::std::tuple_size;
# define GTEST_API_
#endif // GTEST_API_
+#ifndef GTEST_DEFAULT_DEATH_TEST_STYLE
+# define GTEST_DEFAULT_DEATH_TEST_STYLE "fast"
+#endif // GTEST_DEFAULT_DEATH_TEST_STYLE
+
#ifdef __GNUC__
// Ask the compiler to never inline a given function.
# define GTEST_NO_INLINE_ __attribute__((noinline))
@@ -980,10 +1002,12 @@ using ::std::tuple_size;
#endif
// _LIBCPP_VERSION is defined by the libc++ library from the LLVM project.
-#if defined(__GLIBCXX__) || (defined(_LIBCPP_VERSION) && !defined(_MSC_VER))
-# define GTEST_HAS_CXXABI_H_ 1
-#else
-# define GTEST_HAS_CXXABI_H_ 0
+#if !defined(GTEST_HAS_CXXABI_H_)
+# if defined(__GLIBCXX__) || (defined(_LIBCPP_VERSION) && !defined(_MSC_VER))
+# define GTEST_HAS_CXXABI_H_ 1
+# else
+# define GTEST_HAS_CXXABI_H_ 0
+# endif
#endif
// A function level attribute to disable checking for use of uninitialized
@@ -1126,6 +1150,16 @@ struct StaticAssertTypeEqHelper<T, T> {
enum { value = true };
};
+// Same as std::is_same<>.
+template <typename T, typename U>
+struct IsSame {
+ enum { value = false };
+};
+template <typename T>
+struct IsSame<T, T> {
+ enum { value = true };
+};
+
// Evaluates to the number of elements in 'array'.
#define GTEST_ARRAY_SIZE_(array) (sizeof(array) / sizeof(array[0]))
@@ -1189,6 +1223,10 @@ class scoped_ptr {
// Defines RE.
+#if GTEST_USES_PCRE
+using ::RE;
+#elif GTEST_USES_POSIX_RE || GTEST_USES_SIMPLE_RE
+
// A simple C++ wrapper for <regex.h>. It uses the POSIX Extended
// Regular Expression syntax.
class GTEST_API_ RE {
@@ -1200,11 +1238,11 @@ class GTEST_API_ RE {
// Constructs an RE from a string.
RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT
-#if GTEST_HAS_GLOBAL_STRING
+# if GTEST_HAS_GLOBAL_STRING
RE(const ::string& regex) { Init(regex.c_str()); } // NOLINT
-#endif // GTEST_HAS_GLOBAL_STRING
+# endif // GTEST_HAS_GLOBAL_STRING
RE(const char* regex) { Init(regex); } // NOLINT
~RE();
@@ -1226,7 +1264,7 @@ class GTEST_API_ RE {
return PartialMatch(str.c_str(), re);
}
-#if GTEST_HAS_GLOBAL_STRING
+# if GTEST_HAS_GLOBAL_STRING
static bool FullMatch(const ::string& str, const RE& re) {
return FullMatch(str.c_str(), re);
@@ -1235,7 +1273,7 @@ class GTEST_API_ RE {
return PartialMatch(str.c_str(), re);
}
-#endif // GTEST_HAS_GLOBAL_STRING
+# endif // GTEST_HAS_GLOBAL_STRING
static bool FullMatch(const char* str, const RE& re);
static bool PartialMatch(const char* str, const RE& re);
@@ -1249,20 +1287,22 @@ class GTEST_API_ RE {
const char* pattern_;
bool is_valid_;
-#if GTEST_USES_POSIX_RE
+# if GTEST_USES_POSIX_RE
regex_t full_regex_; // For FullMatch().
regex_t partial_regex_; // For PartialMatch().
-#else // GTEST_USES_SIMPLE_RE
+# else // GTEST_USES_SIMPLE_RE
const char* full_pattern_; // For FullMatch();
-#endif
+# endif
GTEST_DISALLOW_ASSIGN_(RE);
};
+#endif // GTEST_USES_PCRE
+
// Formats a source file path and a line number as they would appear
// in an error message from the compiler used to compile this code.
GTEST_API_ ::std::string FormatFileLocation(const char* file, int line);
@@ -1348,13 +1388,57 @@ inline void FlushInfoLog() { fflush(NULL); }
GTEST_LOG_(FATAL) << #posix_call << "failed with error " \
<< gtest_error
+// Adds reference to a type if it is not a reference type,
+// otherwise leaves it unchanged. This is the same as
+// tr1::add_reference, which is not widely available yet.
+template <typename T>
+struct AddReference { typedef T& type; }; // NOLINT
+template <typename T>
+struct AddReference<T&> { typedef T& type; }; // NOLINT
+
+// A handy wrapper around AddReference that works when the argument T
+// depends on template parameters.
+#define GTEST_ADD_REFERENCE_(T) \
+ typename ::testing::internal::AddReference<T>::type
+
+// Transforms "T" into "const T&" according to standard reference collapsing
+// rules (this is only needed as a backport for C++98 compilers that do not
+// support reference collapsing). Specifically, it transforms:
+//
+// char ==> const char&
+// const char ==> const char&
+// char& ==> char&
+// const char& ==> const char&
+//
+// Note that the non-const reference will not have "const" added. This is
+// standard, and necessary so that "T" can always bind to "const T&".
+template <typename T>
+struct ConstRef { typedef const T& type; };
+template <typename T>
+struct ConstRef<T&> { typedef T& type; };
+
+// The argument T must depend on some template parameters.
+#define GTEST_REFERENCE_TO_CONST_(T) \
+ typename ::testing::internal::ConstRef<T>::type
+
#if GTEST_HAS_STD_MOVE_
+using std::forward;
using std::move;
+
+template <typename T>
+struct RvalueRef {
+ typedef T&& type;
+};
#else // GTEST_HAS_STD_MOVE_
template <typename T>
const T& move(const T& t) {
return t;
}
+
+template <typename T>
+struct RvalueRef {
+ typedef const T& type;
+};
#endif // GTEST_HAS_STD_MOVE_
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
@@ -1455,7 +1539,6 @@ GTEST_API_ void CaptureStderr();
GTEST_API_ std::string GetCapturedStderr();
#endif // GTEST_HAS_STREAM_REDIRECTION
-
// Returns the size (in bytes) of a file.
GTEST_API_ size_t GetFileSize(FILE* file);
@@ -1463,14 +1546,18 @@ GTEST_API_ size_t GetFileSize(FILE* file);
GTEST_API_ std::string ReadEntireFile(FILE* file);
// All command line arguments.
-GTEST_API_ const ::std::vector<testing::internal::string>& GetArgvs();
+GTEST_API_ std::vector<std::string> GetArgvs();
#if GTEST_HAS_DEATH_TEST
-const ::std::vector<testing::internal::string>& GetInjectableArgvs();
-void SetInjectableArgvs(const ::std::vector<testing::internal::string>*
- new_argvs);
-
+std::vector<std::string> GetInjectableArgvs();
+// Deprecated: pass the args vector by value instead.
+void SetInjectableArgvs(const std::vector<std::string>* new_argvs);
+void SetInjectableArgvs(const std::vector<std::string>& new_argvs);
+#if GTEST_HAS_GLOBAL_STRING
+void SetInjectableArgvs(const std::vector< ::string>& new_argvs);
+#endif // GTEST_HAS_GLOBAL_STRING
+void ClearInjectableArgvs();
#endif // GTEST_HAS_DEATH_TEST
@@ -2557,15 +2644,15 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds.
# define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name)
# define GTEST_DECLARE_int32_(name) \
GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name)
-#define GTEST_DECLARE_string_(name) \
+# define GTEST_DECLARE_string_(name) \
GTEST_API_ extern ::std::string GTEST_FLAG(name)
// Macros for defining flags.
-#define GTEST_DEFINE_bool_(name, default_val, doc) \
+# define GTEST_DEFINE_bool_(name, default_val, doc) \
GTEST_API_ bool GTEST_FLAG(name) = (default_val)
-#define GTEST_DEFINE_int32_(name, default_val, doc) \
+# define GTEST_DEFINE_int32_(name, default_val, doc) \
GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val)
-#define GTEST_DEFINE_string_(name, default_val, doc) \
+# define GTEST_DEFINE_string_(name, default_val, doc) \
GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val)
#endif // !defined(GTEST_DECLARE_bool_)
@@ -2591,7 +2678,6 @@ GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val);
std::string StringFromGTestEnv(const char* flag, const char* default_val);
} // namespace internal
-
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
diff --git a/googletest/src/gtest-death-test.cc b/googletest/src/gtest-death-test.cc
index 2bbb1bc..9ecab8f 100644
--- a/googletest/src/gtest-death-test.cc
+++ b/googletest/src/gtest-death-test.cc
@@ -73,7 +73,11 @@ namespace testing {
// Constants.
// The default death test style.
-static const char kDefaultDeathTestStyle[] = "fast";
+//
+// This is defined in internal/gtest-port.h as "fast", but can be overridden by
+// a definition in internal/custom/gtest-port.h. The recommended value, which is
+// used internally at Google, is "threadsafe".
+static const char kDefaultDeathTestStyle[] = GTEST_DEFAULT_DEATH_TEST_STYLE;
GTEST_DEFINE_string_(
death_test_style,
@@ -555,7 +559,13 @@ bool DeathTestImpl::Passed(bool status_ok) {
break;
case DIED:
if (status_ok) {
+# if GTEST_USES_PCRE
+ // PCRE regexes support embedded NULs.
+ // GTEST_USES_PCRE is defined only in google3 mode
+ const bool matched = RE::PartialMatch(error_message, *regex());
+# else
const bool matched = RE::PartialMatch(error_message.c_str(), *regex());
+# endif // GTEST_USES_PCRE
if (matched) {
success = true;
} else {
@@ -1219,11 +1229,11 @@ bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex,
// signals the event, and returns a file descriptor wrapped around the pipe
// handle. This function is called in the child process only.
static int GetStatusFileDescriptor(unsigned int parent_process_id,
- size_t write_handle_as_size_t,
- size_t event_handle_as_size_t) {
+ size_t write_handle_as_size_t,
+ size_t event_handle_as_size_t) {
AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE,
- FALSE, // Non-inheritable.
- parent_process_id));
+ FALSE, // Non-inheritable.
+ parent_process_id));
if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) {
DeathTestAbort("Unable to open parent process " +
StreamableToString(parent_process_id));
diff --git a/googletest/src/gtest-filepath.cc b/googletest/src/gtest-filepath.cc
index a1fc0e3..6b76ea0 100644
--- a/googletest/src/gtest-filepath.cc
+++ b/googletest/src/gtest-filepath.cc
@@ -128,7 +128,7 @@ FilePath FilePath::RemoveExtension(const char* extension) const {
return *this;
}
-// Returns a pointer to the last occurence of a valid path separator in
+// Returns a pointer to the last occurrence of a valid path separator in
// the FilePath. On Windows, for example, both '/' and '\' are valid path
// separators. Returns NULL if no path separator was found.
const char* FilePath::FindLastPathSeparator() const {
diff --git a/googletest/src/gtest-internal-inl.h b/googletest/src/gtest-internal-inl.h
index 5ec0af9..e77c8b6 100644
--- a/googletest/src/gtest-internal-inl.h
+++ b/googletest/src/gtest-internal-inl.h
@@ -59,7 +59,7 @@
# include <windows.h> // NOLINT
#endif // GTEST_OS_WINDOWS
-#include "gtest/gtest.h" // NOLINT
+#include "gtest/gtest.h"
#include "gtest/gtest-spi.h"
namespace testing {
@@ -86,6 +86,7 @@ const char kFilterFlag[] = "filter";
const char kListTestsFlag[] = "list_tests";
const char kOutputFlag[] = "output";
const char kPrintTimeFlag[] = "print_time";
+const char kPrintUTF8Flag[] = "print_utf8";
const char kRandomSeedFlag[] = "random_seed";
const char kRepeatFlag[] = "repeat";
const char kShuffleFlag[] = "shuffle";
@@ -166,6 +167,7 @@ class GTestFlagSaver {
list_tests_ = GTEST_FLAG(list_tests);
output_ = GTEST_FLAG(output);
print_time_ = GTEST_FLAG(print_time);
+ print_utf8_ = GTEST_FLAG(print_utf8);
random_seed_ = GTEST_FLAG(random_seed);
repeat_ = GTEST_FLAG(repeat);
shuffle_ = GTEST_FLAG(shuffle);
@@ -187,6 +189,7 @@ class GTestFlagSaver {
GTEST_FLAG(list_tests) = list_tests_;
GTEST_FLAG(output) = output_;
GTEST_FLAG(print_time) = print_time_;
+ GTEST_FLAG(print_utf8) = print_utf8_;
GTEST_FLAG(random_seed) = random_seed_;
GTEST_FLAG(repeat) = repeat_;
GTEST_FLAG(shuffle) = shuffle_;
@@ -208,6 +211,7 @@ class GTestFlagSaver {
bool list_tests_;
std::string output_;
bool print_time_;
+ bool print_utf8_;
internal::Int32 random_seed_;
internal::Int32 repeat_;
bool shuffle_;
@@ -1020,7 +1024,7 @@ class TestResultAccessor {
#if GTEST_CAN_STREAM_RESULTS_
// Streams test results to the given port on the given host machine.
-class GTEST_API_ StreamingListener : public EmptyTestEventListener {
+class StreamingListener : public EmptyTestEventListener {
public:
// Abstract base class for writing strings to a socket.
class AbstractSocketWriter {
diff --git a/googletest/src/gtest-port.cc b/googletest/src/gtest-port.cc
index 01711fd..99791f9 100644
--- a/googletest/src/gtest-port.cc
+++ b/googletest/src/gtest-port.cc
@@ -915,6 +915,7 @@ GTestLog::~GTestLog() {
posix::Abort();
}
}
+
// Disable Microsoft deprecation warnings for POSIX functions called from
// this class (creat, dup, dup2, and close)
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996)
@@ -1007,8 +1008,7 @@ static CapturedStream* g_captured_stderr = NULL;
static CapturedStream* g_captured_stdout = NULL;
// Starts capturing an output stream (stdout/stderr).
-static void CaptureStream(int fd,
- const char* stream_name,
+static void CaptureStream(int fd, const char* stream_name,
CapturedStream** stream) {
if (*stream != NULL) {
GTEST_LOG_(FATAL) << "Only one " << stream_name
@@ -1049,6 +1049,10 @@ std::string GetCapturedStderr() {
#endif // GTEST_HAS_STREAM_REDIRECTION
+
+
+
+
size_t GetFileSize(FILE* file) {
fseek(file, 0, SEEK_END);
return static_cast<size_t>(ftell(file));
@@ -1077,22 +1081,36 @@ std::string ReadEntireFile(FILE* file) {
}
#if GTEST_HAS_DEATH_TEST
+static const std::vector<std::string>* g_injected_test_argvs = NULL; // Owned.
-static const ::std::vector<testing::internal::string>* g_injected_test_argvs =
- NULL; // Owned.
-
-void SetInjectableArgvs(const ::std::vector<testing::internal::string>* argvs) {
- if (g_injected_test_argvs != argvs)
- delete g_injected_test_argvs;
- g_injected_test_argvs = argvs;
-}
-
-const ::std::vector<testing::internal::string>& GetInjectableArgvs() {
+std::vector<std::string> GetInjectableArgvs() {
if (g_injected_test_argvs != NULL) {
return *g_injected_test_argvs;
}
return GetArgvs();
}
+
+void SetInjectableArgvs(const std::vector<std::string>* new_argvs) {
+ if (g_injected_test_argvs != new_argvs) delete g_injected_test_argvs;
+ g_injected_test_argvs = new_argvs;
+}
+
+void SetInjectableArgvs(const std::vector<std::string>& new_argvs) {
+ SetInjectableArgvs(
+ new std::vector<std::string>(new_argvs.begin(), new_argvs.end()));
+}
+
+#if GTEST_HAS_GLOBAL_STRING
+void SetInjectableArgvs(const std::vector< ::string>& new_argvs) {
+ SetInjectableArgvs(
+ new std::vector<std::string>(new_argvs.begin(), new_argvs.end()));
+}
+#endif // GTEST_HAS_GLOBAL_STRING
+
+void ClearInjectableArgvs() {
+ delete g_injected_test_argvs;
+ g_injected_test_argvs = NULL;
+}
#endif // GTEST_HAS_DEATH_TEST
#if GTEST_OS_WINDOWS_MOBILE
diff --git a/googletest/src/gtest-printers.cc b/googletest/src/gtest-printers.cc
index dd67f64..d55a5e9 100644
--- a/googletest/src/gtest-printers.cc
+++ b/googletest/src/gtest-printers.cc
@@ -43,12 +43,13 @@
// defines Foo.
#include "gtest/gtest-printers.h"
-#include <ctype.h>
#include <stdio.h>
+#include <cctype>
#include <cwchar>
#include <ostream> // NOLINT
#include <string>
#include "gtest/internal/gtest-port.h"
+#include "src/gtest-internal-inl.h"
namespace testing {
@@ -123,7 +124,7 @@ namespace internal {
// Depending on the value of a char (or wchar_t), we print it in one
// of three formats:
// - as is if it's a printable ASCII (e.g. 'a', '2', ' '),
-// - as a hexidecimal escape sequence (e.g. '\x7F'), or
+// - as a hexadecimal escape sequence (e.g. '\x7F'), or
// - as a special escape sequence (e.g. '\r', '\n').
enum CharFormat {
kAsIs,
@@ -230,7 +231,7 @@ void PrintCharAndCodeTo(Char c, ostream* os) {
return;
*os << " (" << static_cast<int>(c);
- // For more convenience, we print c's code again in hexidecimal,
+ // For more convenience, we print c's code again in hexadecimal,
// unless c was already printed in the form '\x##' or the code is in
// [1, 9].
if (format == kHexEscape || (1 <= c && c <= 9)) {
@@ -262,11 +263,12 @@ template <typename CharType>
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
-static void PrintCharsAsStringTo(
+static CharFormat PrintCharsAsStringTo(
const CharType* begin, size_t len, ostream* os) {
const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\"";
*os << kQuoteBegin;
bool is_previous_hex = false;
+ CharFormat print_format = kAsIs;
for (size_t index = 0; index < len; ++index) {
const CharType cur = begin[index];
if (is_previous_hex && IsXDigit(cur)) {
@@ -276,8 +278,13 @@ static void PrintCharsAsStringTo(
*os << "\" " << kQuoteBegin;
}
is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape;
+ // Remember if any characters required hex escaping.
+ if (is_previous_hex) {
+ print_format = kHexEscape;
+ }
}
*os << "\"";
+ return print_format;
}
// Prints a (const) char/wchar_t array of 'len' elements, starting at address
@@ -347,15 +354,90 @@ void PrintTo(const wchar_t* s, ostream* os) {
}
#endif // wchar_t is native
+namespace {
+
+bool ContainsUnprintableControlCodes(const char* str, size_t length) {
+ const unsigned char *s = reinterpret_cast<const unsigned char *>(str);
+
+ for (size_t i = 0; i < length; i++) {
+ unsigned char ch = *s++;
+ if (std::iscntrl(ch)) {
+ switch (ch) {
+ case '\t':
+ case '\n':
+ case '\r':
+ break;
+ default:
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool IsUTF8TrailByte(unsigned char t) { return 0x80 <= t && t<= 0xbf; }
+
+bool IsValidUTF8(const char* str, size_t length) {
+ const unsigned char *s = reinterpret_cast<const unsigned char *>(str);
+
+ for (size_t i = 0; i < length;) {
+ unsigned char lead = s[i++];
+
+ if (lead <= 0x7f) {
+ continue; // single-byte character (ASCII) 0..7F
+ }
+ if (lead < 0xc2) {
+ return false; // trail byte or non-shortest form
+ } else if (lead <= 0xdf && (i + 1) <= length && IsUTF8TrailByte(s[i])) {
+ ++i; // 2-byte character
+ } else if (0xe0 <= lead && lead <= 0xef && (i + 2) <= length &&
+ IsUTF8TrailByte(s[i]) &&
+ IsUTF8TrailByte(s[i + 1]) &&
+ // check for non-shortest form and surrogate
+ (lead != 0xe0 || s[i] >= 0xa0) &&
+ (lead != 0xed || s[i] < 0xa0)) {
+ i += 2; // 3-byte character
+ } else if (0xf0 <= lead && lead <= 0xf4 && (i + 3) <= length &&
+ IsUTF8TrailByte(s[i]) &&
+ IsUTF8TrailByte(s[i + 1]) &&
+ IsUTF8TrailByte(s[i + 2]) &&
+ // check for non-shortest form
+ (lead != 0xf0 || s[i] >= 0x90) &&
+ (lead != 0xf4 || s[i] < 0x90)) {
+ i += 3; // 4-byte character
+ } else {
+ return false;
+ }
+ }
+ return true;
+}
+
+void ConditionalPrintAsText(const char* str, size_t length, ostream* os) {
+ if (!ContainsUnprintableControlCodes(str, length) &&
+ IsValidUTF8(str, length)) {
+ *os << "\n As Text: \"" << str << "\"";
+ }
+}
+
+} // anonymous namespace
+
// Prints a ::string object.
#if GTEST_HAS_GLOBAL_STRING
void PrintStringTo(const ::string& s, ostream* os) {
- PrintCharsAsStringTo(s.data(), s.size(), os);
+ if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) {
+ if (GTEST_FLAG(print_utf8)) {
+ ConditionalPrintAsText(s.data(), s.size(), os);
+ }
+ }
}
#endif // GTEST_HAS_GLOBAL_STRING
void PrintStringTo(const ::std::string& s, ostream* os) {
- PrintCharsAsStringTo(s.data(), s.size(), os);
+ if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) {
+ if (GTEST_FLAG(print_utf8)) {
+ ConditionalPrintAsText(s.data(), s.size(), os);
+ }
+ }
}
// Prints a ::wstring object.
diff --git a/googletest/src/gtest-typed-test.cc b/googletest/src/gtest-typed-test.cc
index df1eef4..b358243 100644
--- a/googletest/src/gtest-typed-test.cc
+++ b/googletest/src/gtest-typed-test.cc
@@ -30,6 +30,7 @@
// Author: wan@google.com (Zhanyong Wan)
#include "gtest/gtest-typed-test.h"
+
#include "gtest/gtest.h"
namespace testing {
diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc
index 3435f9c..74df549 100644
--- a/googletest/src/gtest.cc
+++ b/googletest/src/gtest.cc
@@ -160,8 +160,10 @@ static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*";
// A test filter that matches everything.
static const char kUniversalFilter[] = "*";
-// The default output file for XML output.
-static const char kDefaultOutputFile[] = "test_detail.xml";
+// The default output format.
+static const char kDefaultOutputFormat[] = "xml";
+// The default output file.
+static const char kDefaultOutputFile[] = "test_detail";
// The environment variable name for the test shard index.
static const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
@@ -231,9 +233,9 @@ GTEST_DEFINE_bool_(list_tests, false,
GTEST_DEFINE_string_(
output,
internal::StringFromGTestEnv("output", ""),
- "A format (currently must be \"xml\"), optionally followed "
- "by a colon and an output file name or directory. A directory "
- "is indicated by a trailing pathname separator. "
+ "A format (defaults to \"xml\" but can be specified to be \"json\"), "
+ "optionally followed by a colon and an output file name or directory. "
+ "A directory is indicated by a trailing pathname separator. "
"Examples: \"xml:filename.xml\", \"xml::directoryname/\". "
"If a directory is specified, output files will be created "
"within that directory, with file-names based on the test "
@@ -246,6 +248,12 @@ GTEST_DEFINE_bool_(
"True iff " GTEST_NAME_
" should display elapsed time in text output.");
+GTEST_DEFINE_bool_(
+ print_utf8,
+ internal::BoolFromGTestEnv("print_utf8", true),
+ "True iff " GTEST_NAME_
+ " prints UTF8 characters as text.");
+
GTEST_DEFINE_int32_(
random_seed,
internal::Int32FromGTestEnv("random_seed", 0),
@@ -287,7 +295,7 @@ GTEST_DEFINE_bool_(
internal::BoolFromGTestEnv("throw_on_failure", false),
"When this flag is specified, a failed assertion will throw an exception "
"if exceptions are enabled or exit the program with a non-zero code "
- "otherwise.");
+ "otherwise. For use with an external test framework.");
#if GTEST_USE_OWN_FLAGFILE_FLAG_
GTEST_DEFINE_string_(
@@ -378,12 +386,15 @@ void AssertHelper::operator=(const Message& message) const {
GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex);
// A copy of all command line arguments. Set by InitGoogleTest().
-::std::vector<testing::internal::string> g_argvs;
+::std::vector<std::string> g_argvs;
-const ::std::vector<testing::internal::string>& GetArgvs() {
+::std::vector<std::string> GetArgvs() {
#if defined(GTEST_CUSTOM_GET_ARGVS_)
- return GTEST_CUSTOM_GET_ARGVS_();
-#else // defined(GTEST_CUSTOM_GET_ARGVS_)
+ // GTEST_CUSTOM_GET_ARGVS_() may return a container of std::string or
+ // ::string. This code converts it to the appropriate type.
+ const auto& custom = GTEST_CUSTOM_GET_ARGVS_();
+ return ::std::vector<std::string>(custom.begin(), custom.end());
+#else // defined(GTEST_CUSTOM_GET_ARGVS_)
return g_argvs;
#endif // defined(GTEST_CUSTOM_GET_ARGVS_)
}
@@ -422,12 +433,17 @@ std::string UnitTestOptions::GetAbsolutePathToOutputFile() {
if (gtest_output_flag == NULL)
return "";
+ std::string format = GetOutputFormat();
+ if (format.empty())
+ format = std::string(kDefaultOutputFormat);
+
const char* const colon = strchr(gtest_output_flag, ':');
if (colon == NULL)
- return internal::FilePath::ConcatPaths(
+ return internal::FilePath::MakeFileName(
internal::FilePath(
UnitTest::GetInstance()->original_working_dir()),
- internal::FilePath(kDefaultOutputFile)).string();
+ internal::FilePath(kDefaultOutputFile), 0,
+ format.c_str()).string();
internal::FilePath output_name(colon + 1);
if (!output_name.IsAbsolutePath())
@@ -1712,7 +1728,7 @@ AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT
// Utility functions for encoding Unicode text (wide strings) in
// UTF-8.
-// A Unicode code-point can have upto 21 bits, and is encoded in UTF-8
+// A Unicode code-point can have up to 21 bits, and is encoded in UTF-8
// like this:
//
// Code-point length Encoding
@@ -2429,6 +2445,8 @@ Result HandleExceptionsInMethodIfSupported(
#if GTEST_HAS_EXCEPTIONS
try {
return HandleSehExceptionsInMethodIfSupported(object, method, location);
+ } catch (const AssertionException&) { // NOLINT
+ // This failure was reported already.
} catch (const internal::GoogleTestFailureException&) { // NOLINT
// This exception type can only be thrown by a failed Google
// Test assertion with the intention of letting another testing
@@ -2563,12 +2581,10 @@ void ReportInvalidTestCaseType(const char* test_case_name,
<< "probably rename one of the classes to put the tests into different\n"
<< "test cases.";
- GTEST_LOG_(ERROR)
- << FormatFileLocation(code_location.file.c_str(),
- code_location.line)
- << " " << errors.GetString();
+ GTEST_LOG_(ERROR) << FormatFileLocation(code_location.file.c_str(),
+ code_location.line)
+ << " " << errors.GetString();
}
-
} // namespace internal
namespace {
@@ -2890,7 +2906,7 @@ static int GetBitOffset(WORD color_mask) {
if (color_mask == 0) return 0;
int bitOffset = 0;
- while((color_mask & 1) == 0) {
+ while ((color_mask & 1) == 0) {
color_mask >>= 1;
++bitOffset;
}
@@ -2899,16 +2915,20 @@ static int GetBitOffset(WORD color_mask) {
static WORD GetNewColor(GTestColor color, WORD old_color_attrs) {
// Let's reuse the BG
- static const WORD background_mask = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY;
- static const WORD foreground_mask = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY;
+ static const WORD background_mask = BACKGROUND_BLUE | BACKGROUND_GREEN |
+ BACKGROUND_RED | BACKGROUND_INTENSITY;
+ static const WORD foreground_mask = FOREGROUND_BLUE | FOREGROUND_GREEN |
+ FOREGROUND_RED | FOREGROUND_INTENSITY;
const WORD existing_bg = old_color_attrs & background_mask;
- WORD new_color = GetColorAttribute(color) | existing_bg | FOREGROUND_INTENSITY;
+ WORD new_color =
+ GetColorAttribute(color) | existing_bg | FOREGROUND_INTENSITY;
static const int bg_bitOffset = GetBitOffset(background_mask);
static const int fg_bitOffset = GetBitOffset(foreground_mask);
- if (((new_color & background_mask) >> bg_bitOffset) == ((new_color & foreground_mask) >> fg_bitOffset)) {
- new_color ^= FOREGROUND_INTENSITY; //invert intensity
+ if (((new_color & background_mask) >> bg_bitOffset) ==
+ ((new_color & foreground_mask) >> fg_bitOffset)) {
+ new_color ^= FOREGROUND_INTENSITY; // invert intensity
}
return new_color;
}
@@ -2969,7 +2989,6 @@ bool ShouldUseColor(bool stdout_is_tty) {
// cannot simply emit special characters and have the terminal change colors.
// This routine must actually emit the characters rather than return a string
// that would be colored when printed, as can be done on Linux.
-GTEST_ATTRIBUTE_PRINTF_(2, 3)
static void ColoredPrintf(GTestColor color, const char* fmt, ...) {
va_list args;
va_start(args, fmt);
@@ -3019,7 +3038,7 @@ static void ColoredPrintf(GTestColor color, const char* fmt, ...) {
va_end(args);
}
-// Text printed in Google Test's text output and --gunit_list_tests
+// Text printed in Google Test's text output and --gtest_list_tests
// output to label the type parameter and value parameter for a test.
static const char kTypeParamLabel[] = "TypeParam";
static const char kValueParamLabel[] = "GetParam()";
@@ -3098,7 +3117,6 @@ void PrettyUnitTestResultPrinter::OnTestIterationStart(
"Note: Randomizing tests' orders with a seed of %d .\n",
unit_test.random_seed());
}
-
ColoredPrintf(COLOR_GREEN, "[==========] ");
printf("Running %s from %s.\n",
FormatTestCount(unit_test.test_to_run_count()).c_str(),
@@ -3430,6 +3448,11 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener {
// to delimit this attribute from prior attributes.
static std::string TestPropertiesAsXmlAttributes(const TestResult& result);
+ // Streams an XML representation of the test properties of a TestResult
+ // object.
+ static void OutputXmlTestProperties(std::ostream* stream,
+ const TestResult& result);
+
// The output file.
const std::string output_file_;
@@ -3465,8 +3488,8 @@ void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
// 3. To interpret the meaning of errno in a thread-safe way,
// we need the strerror_r() function, which is not available on
// Windows.
- GTEST_LOG_(FATAL) << "Unable to open file \""
- << output_file_ << "\"";
+
+ GTEST_LOG_(FATAL) << "Unable to open file \"" << output_file_ << "\"";
}
std::stringstream stream;
PrintXmlUnitTest(&stream, unit_test);
@@ -3641,6 +3664,10 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
const TestResult& result = *test_info.result();
const std::string kTestcase = "testcase";
+ if (test_info.is_in_another_shard()) {
+ return;
+ }
+
*stream << " <testcase";
OutputXmlAttribute(stream, kTestcase, "name", test_info.name());
@@ -3657,7 +3684,6 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
OutputXmlAttribute(stream, kTestcase, "time",
FormatTimeInMillisAsSeconds(result.elapsed_time()));
OutputXmlAttribute(stream, kTestcase, "classname", test_case_name);
- *stream << TestPropertiesAsXmlAttributes(result);
int failures = 0;
for (int i = 0; i < result.total_part_count(); ++i) {
@@ -3679,10 +3705,15 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
}
}
- if (failures == 0)
+ if (failures == 0 && result.test_property_count() == 0) {
*stream << " />\n";
- else
+ } else {
+ if (failures == 0) {
+ *stream << ">\n";
+ }
+ OutputXmlTestProperties(stream, result);
*stream << " </testcase>\n";
+ }
}
// Prints an XML representation of a TestCase object
@@ -3737,7 +3768,6 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream,
OutputXmlAttribute(stream, kTestsuites, "random_seed",
StreamableToString(unit_test.random_seed()));
}
-
*stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result());
OutputXmlAttribute(stream, kTestsuites, "name", "AllTests");
@@ -3763,8 +3793,374 @@ std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(
return attributes.GetString();
}
+void XmlUnitTestResultPrinter::OutputXmlTestProperties(
+ std::ostream* stream, const TestResult& result) {
+ const std::string kProperties = "properties";
+ const std::string kProperty = "property";
+
+ if (result.test_property_count() <= 0) {
+ return;
+ }
+
+ *stream << "<" << kProperties << ">\n";
+ for (int i = 0; i < result.test_property_count(); ++i) {
+ const TestProperty& property = result.GetTestProperty(i);
+ *stream << "<" << kProperty;
+ *stream << " name=\"" << EscapeXmlAttribute(property.key()) << "\"";
+ *stream << " value=\"" << EscapeXmlAttribute(property.value()) << "\"";
+ *stream << "/>\n";
+ }
+ *stream << "</" << kProperties << ">\n";
+}
+
// End XmlUnitTestResultPrinter
+
+// This class generates an JSON output file.
+class JsonUnitTestResultPrinter : public EmptyTestEventListener {
+ public:
+ explicit JsonUnitTestResultPrinter(const char* output_file);
+
+ virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
+
+ private:
+ // Returns an JSON-escaped copy of the input string str.
+ static std::string EscapeJson(const std::string& str);
+
+ //// Verifies that the given attribute belongs to the given element and
+ //// streams the attribute as JSON.
+ static void OutputJsonKey(std::ostream* stream,
+ const std::string& element_name,
+ const std::string& name,
+ const std::string& value,
+ const std::string& indent,
+ bool comma = true);
+ static void OutputJsonKey(std::ostream* stream,
+ const std::string& element_name,
+ const std::string& name,
+ int value,
+ const std::string& indent,
+ bool comma = true);
+
+ // Streams a JSON representation of a TestInfo object.
+ static void OutputJsonTestInfo(::std::ostream* stream,
+ const char* test_case_name,
+ const TestInfo& test_info);
+
+ // Prints a JSON representation of a TestCase object
+ static void PrintJsonTestCase(::std::ostream* stream,
+ const TestCase& test_case);
+
+ // Prints a JSON summary of unit_test to output stream out.
+ static void PrintJsonUnitTest(::std::ostream* stream,
+ const UnitTest& unit_test);
+
+ // Produces a string representing the test properties in a result as
+ // a JSON dictionary.
+ static std::string TestPropertiesAsJson(const TestResult& result,
+ const std::string& indent);
+
+ // The output file.
+ const std::string output_file_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(JsonUnitTestResultPrinter);
+};
+
+// Creates a new JsonUnitTestResultPrinter.
+JsonUnitTestResultPrinter::JsonUnitTestResultPrinter(const char* output_file)
+ : output_file_(output_file) {
+ if (output_file_.empty()) {
+ GTEST_LOG_(FATAL) << "JSON output file may not be null";
+ }
+}
+
+void JsonUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
+ int /*iteration*/) {
+ FILE* jsonout = NULL;
+ FilePath output_file(output_file_);
+ FilePath output_dir(output_file.RemoveFileName());
+
+ if (output_dir.CreateDirectoriesRecursively()) {
+ jsonout = posix::FOpen(output_file_.c_str(), "w");
+ }
+ if (jsonout == NULL) {
+ // TODO(phosek): report the reason of the failure.
+ //
+ // We don't do it for now as:
+ //
+ // 1. There is no urgent need for it.
+ // 2. It's a bit involved to make the errno variable thread-safe on
+ // all three operating systems (Linux, Windows, and Mac OS).
+ // 3. To interpret the meaning of errno in a thread-safe way,
+ // we need the strerror_r() function, which is not available on
+ // Windows.
+ GTEST_LOG_(FATAL) << "Unable to open file \""
+ << output_file_ << "\"";
+ }
+ std::stringstream stream;
+ PrintJsonUnitTest(&stream, unit_test);
+ fprintf(jsonout, "%s", StringStreamToString(&stream).c_str());
+ fclose(jsonout);
+}
+
+// Returns an JSON-escaped copy of the input string str.
+std::string JsonUnitTestResultPrinter::EscapeJson(const std::string& str) {
+ Message m;
+
+ for (size_t i = 0; i < str.size(); ++i) {
+ const char ch = str[i];
+ switch (ch) {
+ case '\\':
+ case '"':
+ case '/':
+ m << '\\' << ch;
+ break;
+ case '\b':
+ m << "\\b";
+ break;
+ case '\t':
+ m << "\\t";
+ break;
+ case '\n':
+ m << "\\n";
+ break;
+ case '\f':
+ m << "\\f";
+ break;
+ case '\r':
+ m << "\\r";
+ break;
+ default:
+ if (ch < ' ') {
+ m << "\\u00" << String::FormatByte(static_cast<unsigned char>(ch));
+ } else {
+ m << ch;
+ }
+ break;
+ }
+ }
+
+ return m.GetString();
+}
+
+// The following routines generate an JSON representation of a UnitTest
+// object.
+
+// Formats the given time in milliseconds as seconds.
+static std::string FormatTimeInMillisAsDuration(TimeInMillis ms) {
+ ::std::stringstream ss;
+ ss << (static_cast<double>(ms) * 1e-3) << "s";
+ return ss.str();
+}
+
+// Converts the given epoch time in milliseconds to a date string in the
+// RFC3339 format, without the timezone information.
+static std::string FormatEpochTimeInMillisAsRFC3339(TimeInMillis ms) {
+ struct tm time_struct;
+ if (!PortableLocaltime(static_cast<time_t>(ms / 1000), &time_struct))
+ return "";
+ // YYYY-MM-DDThh:mm:ss
+ return StreamableToString(time_struct.tm_year + 1900) + "-" +
+ String::FormatIntWidth2(time_struct.tm_mon + 1) + "-" +
+ String::FormatIntWidth2(time_struct.tm_mday) + "T" +
+ String::FormatIntWidth2(time_struct.tm_hour) + ":" +
+ String::FormatIntWidth2(time_struct.tm_min) + ":" +
+ String::FormatIntWidth2(time_struct.tm_sec) + "Z";
+}
+
+static inline std::string Indent(int width) {
+ return std::string(width, ' ');
+}
+
+void JsonUnitTestResultPrinter::OutputJsonKey(
+ std::ostream* stream,
+ const std::string& element_name,
+ const std::string& name,
+ const std::string& value,
+ const std::string& indent,
+ bool comma) {
+ const std::vector<std::string>& allowed_names =
+ GetReservedAttributesForElement(element_name);
+
+ GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) !=
+ allowed_names.end())
+ << "Key \"" << name << "\" is not allowed for value \"" << element_name
+ << "\".";
+
+ *stream << indent << "\"" << name << "\": \"" << EscapeJson(value) << "\"";
+ if (comma)
+ *stream << ",\n";
+}
+
+void JsonUnitTestResultPrinter::OutputJsonKey(
+ std::ostream* stream,
+ const std::string& element_name,
+ const std::string& name,
+ int value,
+ const std::string& indent,
+ bool comma) {
+ const std::vector<std::string>& allowed_names =
+ GetReservedAttributesForElement(element_name);
+
+ GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) !=
+ allowed_names.end())
+ << "Key \"" << name << "\" is not allowed for value \"" << element_name
+ << "\".";
+
+ *stream << indent << "\"" << name << "\": " << StreamableToString(value);
+ if (comma)
+ *stream << ",\n";
+}
+
+// Prints a JSON representation of a TestInfo object.
+void JsonUnitTestResultPrinter::OutputJsonTestInfo(::std::ostream* stream,
+ const char* test_case_name,
+ const TestInfo& test_info) {
+ const TestResult& result = *test_info.result();
+ const std::string kTestcase = "testcase";
+ const std::string kIndent = Indent(10);
+
+ *stream << Indent(8) << "{\n";
+ OutputJsonKey(stream, kTestcase, "name", test_info.name(), kIndent);
+
+ if (test_info.value_param() != NULL) {
+ OutputJsonKey(stream, kTestcase, "value_param",
+ test_info.value_param(), kIndent);
+ }
+ if (test_info.type_param() != NULL) {
+ OutputJsonKey(stream, kTestcase, "type_param", test_info.type_param(),
+ kIndent);
+ }
+
+ OutputJsonKey(stream, kTestcase, "status",
+ test_info.should_run() ? "RUN" : "NOTRUN", kIndent);
+ OutputJsonKey(stream, kTestcase, "time",
+ FormatTimeInMillisAsDuration(result.elapsed_time()), kIndent);
+ OutputJsonKey(stream, kTestcase, "classname", test_case_name, kIndent, false);
+ *stream << TestPropertiesAsJson(result, kIndent);
+
+ int failures = 0;
+ for (int i = 0; i < result.total_part_count(); ++i) {
+ const TestPartResult& part = result.GetTestPartResult(i);
+ if (part.failed()) {
+ *stream << ",\n";
+ if (++failures == 1) {
+ *stream << kIndent << "\"" << "failures" << "\": [\n";
+ }
+ const std::string location =
+ internal::FormatCompilerIndependentFileLocation(part.file_name(),
+ part.line_number());
+ const std::string message = EscapeJson(location + "\n" + part.message());
+ *stream << kIndent << " {\n"
+ << kIndent << " \"failure\": \"" << message << "\",\n"
+ << kIndent << " \"type\": \"\"\n"
+ << kIndent << " }";
+ }
+ }
+
+ if (failures > 0)
+ *stream << "\n" << kIndent << "]";
+ *stream << "\n" << Indent(8) << "}";
+}
+
+// Prints an JSON representation of a TestCase object
+void JsonUnitTestResultPrinter::PrintJsonTestCase(std::ostream* stream,
+ const TestCase& test_case) {
+ const std::string kTestsuite = "testsuite";
+ const std::string kIndent = Indent(6);
+
+ *stream << Indent(4) << "{\n";
+ OutputJsonKey(stream, kTestsuite, "name", test_case.name(), kIndent);
+ OutputJsonKey(stream, kTestsuite, "tests", test_case.reportable_test_count(),
+ kIndent);
+ OutputJsonKey(stream, kTestsuite, "failures", test_case.failed_test_count(),
+ kIndent);
+ OutputJsonKey(stream, kTestsuite, "disabled",
+ test_case.reportable_disabled_test_count(), kIndent);
+ OutputJsonKey(stream, kTestsuite, "errors", 0, kIndent);
+ OutputJsonKey(stream, kTestsuite, "time",
+ FormatTimeInMillisAsDuration(test_case.elapsed_time()), kIndent,
+ false);
+ *stream << TestPropertiesAsJson(test_case.ad_hoc_test_result(), kIndent)
+ << ",\n";
+
+ *stream << kIndent << "\"" << kTestsuite << "\": [\n";
+
+ bool comma = false;
+ for (int i = 0; i < test_case.total_test_count(); ++i) {
+ if (test_case.GetTestInfo(i)->is_reportable()) {
+ if (comma) {
+ *stream << ",\n";
+ } else {
+ comma = true;
+ }
+ OutputJsonTestInfo(stream, test_case.name(), *test_case.GetTestInfo(i));
+ }
+ }
+ *stream << "\n" << kIndent << "]\n" << Indent(4) << "}";
+}
+
+// Prints a JSON summary of unit_test to output stream out.
+void JsonUnitTestResultPrinter::PrintJsonUnitTest(std::ostream* stream,
+ const UnitTest& unit_test) {
+ const std::string kTestsuites = "testsuites";
+ const std::string kIndent = Indent(2);
+ *stream << "{\n";
+
+ OutputJsonKey(stream, kTestsuites, "tests", unit_test.reportable_test_count(),
+ kIndent);
+ OutputJsonKey(stream, kTestsuites, "failures", unit_test.failed_test_count(),
+ kIndent);
+ OutputJsonKey(stream, kTestsuites, "disabled",
+ unit_test.reportable_disabled_test_count(), kIndent);
+ OutputJsonKey(stream, kTestsuites, "errors", 0, kIndent);
+ if (GTEST_FLAG(shuffle)) {
+ OutputJsonKey(stream, kTestsuites, "random_seed", unit_test.random_seed(),
+ kIndent);
+ }
+ OutputJsonKey(stream, kTestsuites, "timestamp",
+ FormatEpochTimeInMillisAsRFC3339(unit_test.start_timestamp()),
+ kIndent);
+ OutputJsonKey(stream, kTestsuites, "time",
+ FormatTimeInMillisAsDuration(unit_test.elapsed_time()), kIndent,
+ false);
+
+ *stream << TestPropertiesAsJson(unit_test.ad_hoc_test_result(), kIndent)
+ << ",\n";
+
+ OutputJsonKey(stream, kTestsuites, "name", "AllTests", kIndent);
+ *stream << kIndent << "\"" << kTestsuites << "\": [\n";
+
+ bool comma = false;
+ for (int i = 0; i < unit_test.total_test_case_count(); ++i) {
+ if (unit_test.GetTestCase(i)->reportable_test_count() > 0) {
+ if (comma) {
+ *stream << ",\n";
+ } else {
+ comma = true;
+ }
+ PrintJsonTestCase(stream, *unit_test.GetTestCase(i));
+ }
+ }
+
+ *stream << "\n" << kIndent << "]\n" << "}\n";
+}
+
+// Produces a string representing the test properties in a result as
+// a JSON dictionary.
+std::string JsonUnitTestResultPrinter::TestPropertiesAsJson(
+ const TestResult& result, const std::string& indent) {
+ Message attributes;
+ for (int i = 0; i < result.test_property_count(); ++i) {
+ const TestProperty& property = result.GetTestProperty(i);
+ attributes << ",\n" << indent << "\"" << property.key() << "\": "
+ << "\"" << EscapeJson(property.value()) << "\"";
+ }
+ return attributes.GetString();
+}
+
+// End JsonUnitTestResultPrinter
+
#if GTEST_CAN_STREAM_RESULTS_
// Checks if str contains '=', '&', '%' or '\n' characters. If yes,
@@ -3852,9 +4248,10 @@ void OsStackTraceGetter::UponLeavingGTest() {}
class ScopedPrematureExitFile {
public:
explicit ScopedPrematureExitFile(const char* premature_exit_filepath)
- : premature_exit_filepath_(premature_exit_filepath) {
+ : premature_exit_filepath_(premature_exit_filepath ?
+ premature_exit_filepath : "") {
// If a path to the premature-exit file is specified...
- if (premature_exit_filepath != NULL && *premature_exit_filepath != '\0') {
+ if (!premature_exit_filepath_.empty()) {
// create the file with a single "0" character in it. I/O
// errors are ignored as there's nothing better we can do and we
// don't want to fail the test because of this.
@@ -3865,13 +4262,18 @@ class ScopedPrematureExitFile {
}
~ScopedPrematureExitFile() {
- if (premature_exit_filepath_ != NULL && *premature_exit_filepath_ != '\0') {
- remove(premature_exit_filepath_);
+ if (!premature_exit_filepath_.empty()) {
+ int retval = remove(premature_exit_filepath_.c_str());
+ if (retval) {
+ GTEST_LOG_(ERROR) << "Failed to remove premature exit filepath \""
+ << premature_exit_filepath_ << "\" with error "
+ << retval;
+ }
}
}
private:
- const char* const premature_exit_filepath_;
+ const std::string premature_exit_filepath_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedPrematureExitFile);
};
@@ -4391,10 +4793,12 @@ void UnitTestImpl::ConfigureXmlOutput() {
if (output_format == "xml") {
listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter(
UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
+ } else if (output_format == "json") {
+ listeners()->SetDefaultXmlGenerator(new JsonUnitTestResultPrinter(
+ UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
} else if (output_format != "") {
GTEST_LOG_(WARNING) << "WARNING: unrecognized output format \""
- << output_format
- << "\" ignored.";
+ << output_format << "\" ignored.";
}
}
@@ -4409,8 +4813,7 @@ void UnitTestImpl::ConfigureStreamingOutput() {
listeners()->Append(new StreamingListener(target.substr(0, pos),
target.substr(pos+1)));
} else {
- GTEST_LOG_(WARNING) << "unrecognized streaming target \""
- << target
+ GTEST_LOG_(WARNING) << "unrecognized streaming target \"" << target
<< "\" ignored.";
}
}
@@ -4538,13 +4941,8 @@ static void TearDownEnvironment(Environment* env) { env->TearDown(); }
// All other functions called from RunAllTests() may safely assume that
// parameterized tests are ready to be counted and run.
bool UnitTestImpl::RunAllTests() {
- // Makes sure InitGoogleTest() was called.
- if (!GTestIsInitialized()) {
- GTEST_LOG_(ERROR) <<
- "\nThis test program did NOT call ::testing::InitGoogleTest "
- "before calling RUN_ALL_TESTS(). Please fix it.";
- return false;
- }
+ // True iff Google Test is initialized before RUN_ALL_TESTS() is called.
+ const bool gtest_is_initialized_before_run_all_tests = GTestIsInitialized();
// Do not run any test if the --help flag was specified.
if (g_help_flag)
@@ -4672,6 +5070,20 @@ bool UnitTestImpl::RunAllTests() {
repeater->OnTestProgramEnd(*parent_);
+ if (!gtest_is_initialized_before_run_all_tests) {
+ ColoredPrintf(
+ COLOR_RED,
+ "\nIMPORTANT NOTICE - DO NOT IGNORE:\n"
+ "This test program did NOT call " GTEST_INIT_GOOGLE_TEST_NAME_
+ "() before calling RUN_ALL_TESTS(). This is INVALID. Soon " GTEST_NAME_
+ " will start to enforce the valid usage. "
+ "Please fix it ASAP, or IT WILL START TO FAIL.\n"); // NOLINT
+#if GTEST_FOR_GOOGLE_
+ ColoredPrintf(COLOR_RED,
+ "For more details, see http://wiki/Main/ValidGUnitMain.\n");
+#endif // GTEST_FOR_GOOGLE_
+ }
+
return !failed;
}
@@ -4718,7 +5130,7 @@ bool ShouldShard(const char* total_shards_env,
<< "Invalid environment variables: you have "
<< kTestShardIndex << " = " << shard_index
<< ", but have left " << kTestTotalShards << " unset.\n";
- ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str());
+ ColoredPrintf(COLOR_RED, msg.GetString().c_str());
fflush(stdout);
exit(EXIT_FAILURE);
} else if (total_shards != -1 && shard_index == -1) {
@@ -4726,7 +5138,7 @@ bool ShouldShard(const char* total_shards_env,
<< "Invalid environment variables: you have "
<< kTestTotalShards << " = " << total_shards
<< ", but have left " << kTestShardIndex << " unset.\n";
- ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str());
+ ColoredPrintf(COLOR_RED, msg.GetString().c_str());
fflush(stdout);
exit(EXIT_FAILURE);
} else if (shard_index < 0 || shard_index >= total_shards) {
@@ -4735,7 +5147,7 @@ bool ShouldShard(const char* total_shards_env,
<< kTestShardIndex << " < " << kTestTotalShards
<< ", but you have " << kTestShardIndex << "=" << shard_index
<< ", " << kTestTotalShards << "=" << total_shards << ".\n";
- ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str());
+ ColoredPrintf(COLOR_RED, msg.GetString().c_str());
fflush(stdout);
exit(EXIT_FAILURE);
}
@@ -5002,8 +5414,7 @@ bool SkipPrefix(const char* prefix, const char** pstr) {
// part can be omitted.
//
// Returns the value of the flag, or NULL if the parsing failed.
-static const char* ParseFlagValue(const char* str,
- const char* flag,
+static const char* ParseFlagValue(const char* str, const char* flag,
bool def_optional) {
// str and flag must not be NULL.
if (str == NULL || flag == NULL) return NULL;
@@ -5074,9 +5485,8 @@ bool ParseInt32Flag(const char* str, const char* flag, Int32* value) {
//
// On success, stores the value of the flag in *value, and returns
// true. On failure, returns false without changing *value.
-static bool ParseStringFlag(const char* str,
- const char* flag,
- std::string* value) {
+template <typename String>
+static bool ParseStringFlag(const char* str, const char* flag, String* value) {
// Gets the value of the flag as a string.
const char* const value_str = ParseFlagValue(str, flag, false);
@@ -5176,26 +5586,27 @@ static const char kColorEncodedHelpMessage[] =
"Test Output:\n"
" @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n"
" Enable/disable colored output. The default is @Gauto@D.\n"
-" @G--" GTEST_FLAG_PREFIX_ "print_time=0@D\n"
+" -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n"
" Don't print the elapsed time of each test.\n"
-" @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G"
+" @G--" GTEST_FLAG_PREFIX_ "output=@Y(@Gjson@Y|@Gxml@Y)[@G:@YDIRECTORY_PATH@G"
GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n"
-" Generate an XML report in the given directory or with the given file\n"
-" name. @YFILE_PATH@D defaults to @Gtest_detail.xml@D.\n"
-#if GTEST_CAN_STREAM_RESULTS_
+" Generate a JSON or XML report in the given directory or with the given\n"
+" file name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n"
+# if GTEST_CAN_STREAM_RESULTS_
" @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n"
" Stream test results to the given server.\n"
-#endif // GTEST_CAN_STREAM_RESULTS_
+# endif // GTEST_CAN_STREAM_RESULTS_
"\n"
"Assertion Behavior:\n"
-#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
+# if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
" @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n"
" Set the default death test style.\n"
-#endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
+# endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
" @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n"
" Turn assertion failures into debugger break-points.\n"
" @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n"
-" Turn assertion failures into C++ exceptions.\n"
+" Turn assertion failures into C++ exceptions for use by an external\n"
+" test framework.\n"
" @G--" GTEST_FLAG_PREFIX_ "catch_exceptions=0@D\n"
" Do not report exceptions as test failures. Instead, allow them\n"
" to crash the program or throw a pop-up (on Windows).\n"
@@ -5230,6 +5641,7 @@ static bool ParseGoogleTestFlag(const char* const arg) {
ParseBoolFlag(arg, kListTestsFlag, &GTEST_FLAG(list_tests)) ||
ParseStringFlag(arg, kOutputFlag, &GTEST_FLAG(output)) ||
ParseBoolFlag(arg, kPrintTimeFlag, &GTEST_FLAG(print_time)) ||
+ ParseBoolFlag(arg, kPrintUTF8Flag, &GTEST_FLAG(print_utf8)) ||
ParseInt32Flag(arg, kRandomSeedFlag, &GTEST_FLAG(random_seed)) ||
ParseInt32Flag(arg, kRepeatFlag, &GTEST_FLAG(repeat)) ||
ParseBoolFlag(arg, kShuffleFlag, &GTEST_FLAG(shuffle)) ||
@@ -5245,8 +5657,7 @@ static bool ParseGoogleTestFlag(const char* const arg) {
static void LoadFlagsFromFile(const std::string& path) {
FILE* flagfile = posix::FOpen(path.c_str(), "r");
if (!flagfile) {
- GTEST_LOG_(FATAL) << "Unable to open file \""
- << GTEST_FLAG(flagfile)
+ GTEST_LOG_(FATAL) << "Unable to open file \"" << GTEST_FLAG(flagfile)
<< "\"";
}
std::string contents(ReadEntireFile(flagfile));
@@ -5377,8 +5788,9 @@ void InitGoogleTest(int* argc, wchar_t** argv) {
std::string TempDir() {
#if defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_)
- return GTEST_CUSTOM_TEMPDIR_FUNCTION_();
+ return GTEST_CUSTOM_TEMPDIR_FUNCTION_();
#endif
+
#if GTEST_OS_WINDOWS_MOBILE
return "\\temp\\";
#elif GTEST_OS_WINDOWS
diff --git a/googletest/test/BUILD.bazel b/googletest/test/BUILD.bazel
index 3c700b1..6ea18ec 100644
--- a/googletest/test/BUILD.bazel
+++ b/googletest/test/BUILD.bazel
@@ -119,6 +119,16 @@ cc_test(
"//:gtest",
],
)
+
+cc_test(
+ name = "gtest_unittest",
+ size = "small",
+ srcs = ["gtest_unittest.cc"],
+ args = ["--heap_check=strict"],
+ shard_count = 2,
+ deps = ["//:gtest_main"],
+)
+
# Py tests
py_library(
@@ -219,6 +229,13 @@ py_test(
deps = [":gtest_test_utils"],
)
+cc_test(
+ name = "gtest_assert_by_exception_test",
+ size = "small",
+ srcs = ["gtest_assert_by_exception_test.cc"],
+ deps = ["//:gtest"],
+)
+
cc_binary(
name = "gtest_throw_on_failure_test_",
testonly = 1,
diff --git a/googletest/test/gtest-death-test_test.cc b/googletest/test/gtest-death-test_test.cc
index b7846b2..21573c7 100644
--- a/googletest/test/gtest-death-test_test.cc
+++ b/googletest/test/gtest-death-test_test.cc
@@ -617,7 +617,11 @@ TEST_F(TestForDeathTest, ReturnIsFailure) {
TEST_F(TestForDeathTest, TestExpectDebugDeath) {
int sideeffect = 0;
- EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), "death.*DieInDebugElse12")
+ // Put the regex in a local variable to make sure we don't get an "unused"
+ // warning in opt mode.
+ const char* regex = "death.*DieInDebugElse12";
+
+ EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), regex)
<< "Must accept a streamed message";
# ifdef NDEBUG
diff --git a/googletest/test/gtest-param-test_test.cc b/googletest/test/gtest-param-test_test.cc
index 16d1e6e..adc4d1b 100644
--- a/googletest/test/gtest-param-test_test.cc
+++ b/googletest/test/gtest-param-test_test.cc
@@ -41,8 +41,8 @@
# include <sstream>
# include <string>
# include <vector>
-# include "src/gtest-internal-inl.h" // for UnitTestOptions
+# include "src/gtest-internal-inl.h" // for UnitTestOptions
# include "test/gtest-param-test_test.h"
using ::std::vector;
@@ -536,6 +536,51 @@ TEST(CombineTest, CombineWithMaxNumberOfParameters) {
VerifyGenerator(gen, expected_values);
}
+#if GTEST_LANG_CXX11
+
+class NonDefaultConstructAssignString {
+ public:
+ NonDefaultConstructAssignString(const std::string& s) : str_(s) {}
+
+ const std::string& str() const { return str_; }
+
+ private:
+ std::string str_;
+
+ // Not default constructible
+ NonDefaultConstructAssignString();
+ // Not assignable
+ void operator=(const NonDefaultConstructAssignString&);
+};
+
+TEST(CombineTest, NonDefaultConstructAssign) {
+ const ParamGenerator<tuple<int, NonDefaultConstructAssignString> > gen =
+ Combine(Values(0, 1), Values(NonDefaultConstructAssignString("A"),
+ NonDefaultConstructAssignString("B")));
+
+ ParamGenerator<tuple<int, NonDefaultConstructAssignString> >::iterator it =
+ gen.begin();
+
+ EXPECT_EQ(0, std::get<0>(*it));
+ EXPECT_EQ("A", std::get<1>(*it).str());
+ ++it;
+
+ EXPECT_EQ(0, std::get<0>(*it));
+ EXPECT_EQ("B", std::get<1>(*it).str());
+ ++it;
+
+ EXPECT_EQ(1, std::get<0>(*it));
+ EXPECT_EQ("A", std::get<1>(*it).str());
+ ++it;
+
+ EXPECT_EQ(1, std::get<0>(*it));
+ EXPECT_EQ("B", std::get<1>(*it).str());
+ ++it;
+
+ EXPECT_TRUE(it == gen.end());
+}
+
+#endif // GTEST_LANG_CXX11
# endif // GTEST_HAS_COMBINE
// Tests that an generator produces correct sequence after being
@@ -839,8 +884,8 @@ class CustomFunctorNamingTest : public TestWithParam<std::string> {};
TEST_P(CustomFunctorNamingTest, CustomTestNames) {}
struct CustomParamNameFunctor {
- std::string operator()(const ::testing::TestParamInfo<std::string>& info) {
- return info.param;
+ std::string operator()(const ::testing::TestParamInfo<std::string>& inf) {
+ return inf.param;
}
};
@@ -857,8 +902,8 @@ INSTANTIATE_TEST_CASE_P(AllAllowedCharacters,
CustomParamNameFunctor());
inline std::string CustomParamNameFunction(
- const ::testing::TestParamInfo<std::string>& info) {
- return info.param;
+ const ::testing::TestParamInfo<std::string>& inf) {
+ return inf.param;
}
class CustomFunctionNamingTest : public TestWithParam<std::string> {};
@@ -876,11 +921,10 @@ INSTANTIATE_TEST_CASE_P(CustomParamNameFunction,
class CustomLambdaNamingTest : public TestWithParam<std::string> {};
TEST_P(CustomLambdaNamingTest, CustomTestNames) {}
-INSTANTIATE_TEST_CASE_P(CustomParamNameLambda,
- CustomLambdaNamingTest,
+INSTANTIATE_TEST_CASE_P(CustomParamNameLambda, CustomLambdaNamingTest,
Values(std::string("LambdaName")),
- [](const ::testing::TestParamInfo<std::string>& tpinfo) {
- return tpinfo.param;
+ [](const ::testing::TestParamInfo<std::string>& inf) {
+ return inf.param;
});
#endif // GTEST_LANG_CXX11
@@ -1047,6 +1091,7 @@ TEST_F(ParameterizedDeathTest, GetParamDiesFromTestF) {
INSTANTIATE_TEST_CASE_P(RangeZeroToFive, ParameterizedDerivedTest, Range(0, 5));
+
int main(int argc, char **argv) {
// Used in TestGenerationTest test case.
AddGlobalTestEnvironment(TestGenerationTest::Environment::Instance());
diff --git a/googletest/test/gtest-printers_test.cc b/googletest/test/gtest-printers_test.cc
index aff97a2..cd7c5d3 100644
--- a/googletest/test/gtest-printers_test.cc
+++ b/googletest/test/gtest-printers_test.cc
@@ -239,7 +239,7 @@ using ::testing::internal::UniversalTersePrint;
#if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
using ::testing::internal::UniversalTersePrintTupleFieldsToStrings;
#endif
-using ::testing::internal::string;
+
// The hash_* classes are not part of the C++ standard. STLport
// defines them in namespace std. MSVC defines them in ::stdext. GCC
@@ -837,22 +837,22 @@ TEST(PrintTypeWithGenericStreamingTest, TypeImplicitlyConvertible) {
EXPECT_EQ("AllowsGenericStreamingAndImplicitConversionTemplate", Print(a));
}
-#if GTEST_HAS_STRING_PIECE_
+#if GTEST_HAS_ABSL
-// Tests printing StringPiece.
+// Tests printing ::absl::string_view.
-TEST(PrintStringPieceTest, SimpleStringPiece) {
- const StringPiece sp = "Hello";
+TEST(PrintStringViewTest, SimpleStringView) {
+ const ::absl::string_view sp = "Hello";
EXPECT_EQ("\"Hello\"", Print(sp));
}
-TEST(PrintStringPieceTest, UnprintableCharacters) {
+TEST(PrintStringViewTest, UnprintableCharacters) {
const char str[] = "NUL (\0) and \r\t";
- const StringPiece sp(str, sizeof(str) - 1);
+ const ::absl::string_view sp(str, sizeof(str) - 1);
EXPECT_EQ("\"NUL (\\0) and \\r\\t\"", Print(sp));
}
-#endif // GTEST_HAS_STRING_PIECE_
+#endif // GTEST_HAS_ABSL
// Tests printing STL containers.
@@ -1327,7 +1327,7 @@ TEST(FormatForComparisonFailureMessageTest, FormatsNonCharArrayAsPointer) {
}
// Tests formatting a char pointer when it's compared with another pointer.
-// In this case we want to print it as a raw pointer, as the comparision is by
+// In this case we want to print it as a raw pointer, as the comparison is by
// pointer.
// char pointer vs pointer
@@ -1552,6 +1552,78 @@ TEST(PrintToStringTest, WorksForCharArrayWithEmbeddedNul) {
EXPECT_PRINT_TO_STRING_(mutable_str_with_nul, "\"hello\\0 world\"");
}
+ TEST(PrintToStringTest, ContainsNonLatin) {
+ // Sanity test with valid UTF-8. Prints both in hex and as text.
+ std::string non_ascii_str = ::std::string("오전 4:30");
+ EXPECT_PRINT_TO_STRING_(non_ascii_str,
+ "\"\\xEC\\x98\\xA4\\xEC\\xA0\\x84 4:30\"\n"
+ " As Text: \"오전 4:30\"");
+ non_ascii_str = ::std::string("From ä — ẑ");
+ EXPECT_PRINT_TO_STRING_(non_ascii_str,
+ "\"From \\xC3\\xA4 \\xE2\\x80\\x94 \\xE1\\xBA\\x91\""
+ "\n As Text: \"From ä — ẑ\"");
+}
+
+TEST(IsValidUTF8Test, IllFormedUTF8) {
+ // The following test strings are ill-formed UTF-8 and are printed
+ // as hex only (or ASCII, in case of ASCII bytes) because IsValidUTF8() is
+ // expected to fail, thus output does not contain "As Text:".
+
+ static const char *const kTestdata[][2] = {
+ // 2-byte lead byte followed by a single-byte character.
+ {"\xC3\x74", "\"\\xC3t\""},
+ // Valid 2-byte character followed by an orphan trail byte.
+ {"\xC3\x84\xA4", "\"\\xC3\\x84\\xA4\""},
+ // Lead byte without trail byte.
+ {"abc\xC3", "\"abc\\xC3\""},
+ // 3-byte lead byte, single-byte character, orphan trail byte.
+ {"x\xE2\x70\x94", "\"x\\xE2p\\x94\""},
+ // Truncated 3-byte character.
+ {"\xE2\x80", "\"\\xE2\\x80\""},
+ // Truncated 3-byte character followed by valid 2-byte char.
+ {"\xE2\x80\xC3\x84", "\"\\xE2\\x80\\xC3\\x84\""},
+ // Truncated 3-byte character followed by a single-byte character.
+ {"\xE2\x80\x7A", "\"\\xE2\\x80z\""},
+ // 3-byte lead byte followed by valid 3-byte character.
+ {"\xE2\xE2\x80\x94", "\"\\xE2\\xE2\\x80\\x94\""},
+ // 4-byte lead byte followed by valid 3-byte character.
+ {"\xF0\xE2\x80\x94", "\"\\xF0\\xE2\\x80\\x94\""},
+ // Truncated 4-byte character.
+ {"\xF0\xE2\x80", "\"\\xF0\\xE2\\x80\""},
+ // Invalid UTF-8 byte sequences embedded in other chars.
+ {"abc\xE2\x80\x94\xC3\x74xyc", "\"abc\\xE2\\x80\\x94\\xC3txyc\""},
+ {"abc\xC3\x84\xE2\x80\xC3\x84xyz",
+ "\"abc\\xC3\\x84\\xE2\\x80\\xC3\\x84xyz\""},
+ // Non-shortest UTF-8 byte sequences are also ill-formed.
+ // The classics: xC0, xC1 lead byte.
+ {"\xC0\x80", "\"\\xC0\\x80\""},
+ {"\xC1\x81", "\"\\xC1\\x81\""},
+ // Non-shortest sequences.
+ {"\xE0\x80\x80", "\"\\xE0\\x80\\x80\""},
+ {"\xf0\x80\x80\x80", "\"\\xF0\\x80\\x80\\x80\""},
+ // Last valid code point before surrogate range, should be printed as text,
+ // too.
+ {"\xED\x9F\xBF", "\"\\xED\\x9F\\xBF\"\n As Text: \"퟿\""},
+ // Start of surrogate lead. Surrogates are not printed as text.
+ {"\xED\xA0\x80", "\"\\xED\\xA0\\x80\""},
+ // Last non-private surrogate lead.
+ {"\xED\xAD\xBF", "\"\\xED\\xAD\\xBF\""},
+ // First private-use surrogate lead.
+ {"\xED\xAE\x80", "\"\\xED\\xAE\\x80\""},
+ // Last private-use surrogate lead.
+ {"\xED\xAF\xBF", "\"\\xED\\xAF\\xBF\""},
+ // Mid-point of surrogate trail.
+ {"\xED\xB3\xBF", "\"\\xED\\xB3\\xBF\""},
+ // First valid code point after surrogate range, should be printed as text,
+ // too.
+ {"\xEE\x80\x80", "\"\\xEE\\x80\\x80\"\n As Text: \"\""}
+ };
+
+ for (int i = 0; i < int(sizeof(kTestdata)/sizeof(kTestdata[0])); ++i) {
+ EXPECT_PRINT_TO_STRING_(kTestdata[i][0], kTestdata[i][1]);
+ }
+}
+
#undef EXPECT_PRINT_TO_STRING_
TEST(UniversalTersePrintTest, WorksForNonReference) {
@@ -1693,5 +1765,17 @@ TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTersely) {
#endif // GTEST_HAS_STD_TUPLE_
+#if GTEST_HAS_ABSL
+
+TEST(PrintOptionalTest, Basic) {
+ absl::optional<int> value;
+ EXPECT_EQ("(nullopt)", PrintToString(value));
+ value = {7};
+ EXPECT_EQ("(7)", PrintToString(value));
+ EXPECT_EQ("(1.1)", PrintToString(absl::optional<double>{1.1}));
+ EXPECT_EQ("(\"A\")", PrintToString(absl::optional<std::string>{"A"}));
+}
+#endif // GTEST_HAS_ABSL
+
} // namespace gtest_printers_test
} // namespace testing
diff --git a/googletest/test/gtest_all_test.cc b/googletest/test/gtest_all_test.cc
index 955aa62..e16ef53 100644
--- a/googletest/test/gtest_all_test.cc
+++ b/googletest/test/gtest_all_test.cc
@@ -33,15 +33,15 @@
//
// Sometimes it's desirable to build most of Google Test's own tests
// by compiling a single file. This file serves this purpose.
-#include "test/gtest-filepath_test.cc"
-#include "test/gtest-linked_ptr_test.cc"
-#include "test/gtest-message_test.cc"
-#include "test/gtest-options_test.cc"
-#include "test/gtest-port_test.cc"
-#include "test/gtest_pred_impl_unittest.cc"
-#include "test/gtest_prod_test.cc"
-#include "test/gtest-test-part_test.cc"
-#include "test/gtest-typed-test_test.cc"
-#include "test/gtest-typed-test2_test.cc"
-#include "test/gtest_unittest.cc"
-#include "test/production.cc"
+#include "gtest-filepath_test.cc"
+#include "gtest-linked_ptr_test.cc"
+#include "gtest-message_test.cc"
+#include "gtest-options_test.cc"
+#include "gtest-port_test.cc"
+#include "gtest_pred_impl_unittest.cc"
+#include "gtest_prod_test.cc"
+#include "gtest-test-part_test.cc"
+#include "gtest-typed-test_test.cc"
+#include "gtest-typed-test2_test.cc"
+#include "gtest_unittest.cc"
+#include "production.cc"
diff --git a/googletest/test/gtest_assert_by_exception_test.cc b/googletest/test/gtest_assert_by_exception_test.cc
new file mode 100644
index 0000000..2f0e34a
--- /dev/null
+++ b/googletest/test/gtest_assert_by_exception_test.cc
@@ -0,0 +1,119 @@
+// Copyright 2009, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Tests Google Test's assert-by-exception mode with exceptions enabled.
+
+#include "gtest/gtest.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdexcept>
+
+class ThrowListener : public testing::EmptyTestEventListener {
+ void OnTestPartResult(const testing::TestPartResult& result) override {
+ if (result.type() == testing::TestPartResult::kFatalFailure) {
+ throw testing::AssertionException(result);
+ }
+ }
+};
+
+// Prints the given failure message and exits the program with
+// non-zero. We use this instead of a Google Test assertion to
+// indicate a failure, as the latter is been tested and cannot be
+// relied on.
+void Fail(const char* msg) {
+ printf("FAILURE: %s\n", msg);
+ fflush(stdout);
+ exit(1);
+}
+
+static void AssertFalse() {
+ ASSERT_EQ(2, 3) << "Expected failure";
+}
+
+// Tests that an assertion failure throws a subclass of
+// std::runtime_error.
+TEST(Test, Test) {
+ // A successful assertion shouldn't throw.
+ try {
+ EXPECT_EQ(3, 3);
+ } catch(...) {
+ Fail("A successful assertion wrongfully threw.");
+ }
+
+ // A successful assertion shouldn't throw.
+ try {
+ EXPECT_EQ(3, 4);
+ } catch(...) {
+ Fail("A failed non-fatal assertion wrongfully threw.");
+ }
+
+ // A failed assertion should throw.
+ try {
+ AssertFalse();
+ } catch(const testing::AssertionException& e) {
+ if (strstr(e.what(), "Expected failure") != NULL)
+ throw;
+
+ printf("%s",
+ "A failed assertion did throw an exception of the right type, "
+ "but the message is incorrect. Instead of containing \"Expected "
+ "failure\", it is:\n");
+ Fail(e.what());
+ } catch(...) {
+ Fail("A failed assertion threw the wrong type of exception.");
+ }
+ Fail("A failed assertion should've thrown but didn't.");
+}
+
+int kTestForContinuingTest = 0;
+
+TEST(Test, Test2) {
+ // FIXME(sokolov): how to force Test2 to be after Test?
+ kTestForContinuingTest = 1;
+}
+
+int main(int argc, char** argv) {
+ testing::InitGoogleTest(&argc, argv);
+ testing::UnitTest::GetInstance()->listeners().Append(new ThrowListener);
+
+ int result = RUN_ALL_TESTS();
+ if (result == 0) {
+ printf("RUN_ALL_TESTS returned %d\n", result);
+ Fail("Expected failure instead.");
+ }
+
+ if (kTestForContinuingTest == 0) {
+ Fail("Should have continued with other tests, but did not.");
+ }
+ return 0;
+}
diff --git a/googletest/test/gtest_env_var_test_.cc b/googletest/test/gtest_env_var_test_.cc
index ed62372..9b668dc 100644
--- a/googletest/test/gtest_env_var_test_.cc
+++ b/googletest/test/gtest_env_var_test_.cc
@@ -35,6 +35,7 @@
#include "gtest/gtest.h"
#include <iostream>
+
#include "src/gtest-internal-inl.h"
using ::std::cout;
diff --git a/googletest/test/gtest_json_outfiles_test.py b/googletest/test/gtest_json_outfiles_test.py
new file mode 100644
index 0000000..46010d8
--- /dev/null
+++ b/googletest/test/gtest_json_outfiles_test.py
@@ -0,0 +1,162 @@
+#!/usr/bin/env python
+# Copyright 2018, 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.
+
+"""Unit test for the gtest_json_output module."""
+
+import json
+import os
+import gtest_json_test_utils
+import gtest_test_utils
+
+GTEST_OUTPUT_SUBDIR = 'json_outfiles'
+GTEST_OUTPUT_1_TEST = 'gtest_xml_outfile1_test_'
+GTEST_OUTPUT_2_TEST = 'gtest_xml_outfile2_test_'
+
+EXPECTED_1 = {
+ u'tests': 1,
+ u'failures': 0,
+ u'disabled': 0,
+ u'errors': 0,
+ u'time': u'*',
+ u'timestamp': u'*',
+ u'name': u'AllTests',
+ u'testsuites': [{
+ u'name': u'PropertyOne',
+ u'tests': 1,
+ u'failures': 0,
+ u'disabled': 0,
+ u'errors': 0,
+ u'time': u'*',
+ u'testsuite': [{
+ u'name': u'TestSomeProperties',
+ u'status': u'RUN',
+ u'time': u'*',
+ u'classname': u'PropertyOne',
+ u'SetUpProp': u'1',
+ u'TestSomeProperty': u'1',
+ u'TearDownProp': u'1',
+ }],
+ }],
+}
+
+EXPECTED_2 = {
+ u'tests': 1,
+ u'failures': 0,
+ u'disabled': 0,
+ u'errors': 0,
+ u'time': u'*',
+ u'timestamp': u'*',
+ u'name': u'AllTests',
+ u'testsuites': [{
+ u'name': u'PropertyTwo',
+ u'tests': 1,
+ u'failures': 0,
+ u'disabled': 0,
+ u'errors': 0,
+ u'time': u'*',
+ u'testsuite': [{
+ u'name': u'TestSomeProperties',
+ u'status': u'RUN',
+ u'time': u'*',
+ u'classname': u'PropertyTwo',
+ u'SetUpProp': u'2',
+ u'TestSomeProperty': u'2',
+ u'TearDownProp': u'2',
+ }],
+ }],
+}
+
+
+class GTestJsonOutFilesTest(gtest_test_utils.TestCase):
+ """Unit test for Google Test's JSON output functionality."""
+
+ def setUp(self):
+ # We want the trailing '/' that the last "" provides in os.path.join, for
+ # telling Google Test to create an output directory instead of a single file
+ # for xml output.
+ self.output_dir_ = os.path.join(gtest_test_utils.GetTempDir(),
+ GTEST_OUTPUT_SUBDIR, '')
+ self.DeleteFilesAndDir()
+
+ def tearDown(self):
+ self.DeleteFilesAndDir()
+
+ def DeleteFilesAndDir(self):
+ try:
+ os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_1_TEST + '.json'))
+ except os.error:
+ pass
+ try:
+ os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_2_TEST + '.json'))
+ except os.error:
+ pass
+ try:
+ os.rmdir(self.output_dir_)
+ except os.error:
+ pass
+
+ def testOutfile1(self):
+ self._TestOutFile(GTEST_OUTPUT_1_TEST, EXPECTED_1)
+
+ def testOutfile2(self):
+ self._TestOutFile(GTEST_OUTPUT_2_TEST, EXPECTED_2)
+
+ def _TestOutFile(self, test_name, expected):
+ gtest_prog_path = gtest_test_utils.GetTestExecutablePath(test_name)
+ command = [gtest_prog_path, '--gtest_output=json:%s' % self.output_dir_]
+ p = gtest_test_utils.Subprocess(command,
+ working_dir=gtest_test_utils.GetTempDir())
+ self.assert_(p.exited)
+ self.assertEquals(0, p.exit_code)
+
+ # TODO(wan@google.com): libtool causes the built test binary to be
+ # named lt-gtest_xml_outfiles_test_ instead of
+ # gtest_xml_outfiles_test_. To account for this possibility, we
+ # allow both names in the following code. We should remove this
+ # hack when Chandler Carruth's libtool replacement tool is ready.
+ output_file_name1 = test_name + '.json'
+ output_file1 = os.path.join(self.output_dir_, output_file_name1)
+ output_file_name2 = 'lt-' + output_file_name1
+ output_file2 = os.path.join(self.output_dir_, output_file_name2)
+ self.assert_(os.path.isfile(output_file1) or os.path.isfile(output_file2),
+ output_file1)
+
+ if os.path.isfile(output_file1):
+ with open(output_file1) as f:
+ actual = json.load(f)
+ else:
+ with open(output_file2) as f:
+ actual = json.load(f)
+ self.assertEqual(expected, gtest_json_test_utils.normalize(actual))
+
+
+if __name__ == '__main__':
+ os.environ['GTEST_STACK_TRACE_DEPTH'] = '0'
+ gtest_test_utils.Main()
diff --git a/googletest/test/gtest_json_output_unittest.py b/googletest/test/gtest_json_output_unittest.py
new file mode 100644
index 0000000..12047c4
--- /dev/null
+++ b/googletest/test/gtest_json_output_unittest.py
@@ -0,0 +1,611 @@
+#!/usr/bin/env python
+# Copyright 2018, 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.
+
+"""Unit test for the gtest_json_output module."""
+
+import datetime
+import errno
+import json
+import os
+import re
+import sys
+
+import gtest_json_test_utils
+import gtest_test_utils
+
+GTEST_FILTER_FLAG = '--gtest_filter'
+GTEST_LIST_TESTS_FLAG = '--gtest_list_tests'
+GTEST_OUTPUT_FLAG = '--gtest_output'
+GTEST_DEFAULT_OUTPUT_FILE = 'test_detail.json'
+GTEST_PROGRAM_NAME = 'gtest_xml_output_unittest_'
+
+SUPPORTS_STACK_TRACES = False
+
+if SUPPORTS_STACK_TRACES:
+ STACK_TRACE_TEMPLATE = '\nStack trace:\n*'
+else:
+ STACK_TRACE_TEMPLATE = ''
+
+EXPECTED_NON_EMPTY = {
+ u'tests': 23,
+ u'failures': 4,
+ u'disabled': 2,
+ u'errors': 0,
+ u'timestamp': u'*',
+ u'time': u'*',
+ u'ad_hoc_property': u'42',
+ u'name': u'AllTests',
+ u'testsuites': [
+ {
+ u'name': u'SuccessfulTest',
+ u'tests': 1,
+ u'failures': 0,
+ u'disabled': 0,
+ u'errors': 0,
+ u'time': u'*',
+ u'testsuite': [
+ {
+ u'name': u'Succeeds',
+ u'status': u'RUN',
+ 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'*',
+ u'testsuite': [
+ {
+ u'name': u'Fails',
+ u'status': u'RUN',
+ 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'name': u'DisabledTest',
+ u'tests': 1,
+ u'failures': 0,
+ u'disabled': 1,
+ u'errors': 0,
+ u'time': u'*',
+ u'testsuite': [
+ {
+ u'name': u'DISABLED_test_not_run',
+ u'status': u'NOTRUN',
+ u'time': u'*',
+ u'classname': u'DisabledTest'
+ }
+ ]
+ },
+ {
+ u'name': 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'time': u'*',
+ u'classname': u'MixedResultTest'
+ },
+ {
+ u'name': u'Fails',
+ u'status': u'RUN',
+ 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'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'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'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'name': u'PropertyRecordingTest',
+ u'tests': 4,
+ u'failures': 0,
+ u'disabled': 0,
+ u'errors': 0,
+ u'time': u'*',
+ u'SetUpTestCase': u'yes',
+ u'TearDownTestCase': u'aye',
+ u'testsuite': [
+ {
+ u'name': u'OneProperty',
+ u'status': u'RUN',
+ u'time': u'*',
+ u'classname': u'PropertyRecordingTest',
+ u'key_1': u'1'
+ },
+ {
+ u'name': u'IntValuedProperty',
+ u'status': u'RUN',
+ u'time': u'*',
+ u'classname': u'PropertyRecordingTest',
+ u'key_int': u'1'
+ },
+ {
+ u'name': u'ThreeProperties',
+ u'status': u'RUN',
+ 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'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'time': u'*',
+ u'classname': u'NoFixtureTest',
+ u'key': u'1'
+ },
+ {
+ u'name': u'ExternalUtilityThatCallsRecordIntValuedProperty',
+ u'status': u'RUN',
+ u'time': u'*',
+ u'classname': u'NoFixtureTest',
+ u'key_for_utility_int': u'1'
+ },
+ {
+ u'name':
+ u'ExternalUtilityThatCallsRecordStringValuedProperty',
+ u'status': u'RUN',
+ u'time': 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'testsuite': [
+ {
+ u'name': u'HasTypeParamAttribute',
+ u'type_param': u'int',
+ u'status': u'RUN',
+ 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'*',
+ u'testsuite': [
+ {
+ u'name': u'HasTypeParamAttribute',
+ u'type_param': u'long',
+ u'status': u'RUN',
+ u'time': u'*',
+ u'classname': u'TypedTest/1'
+ }
+ ]
+ },
+ {
+ u'name': u'Single/TypeParameterizedTestCase/0',
+ u'tests': 1,
+ u'failures': 0,
+ u'disabled': 0,
+ u'errors': 0,
+ u'time': u'*',
+ u'testsuite': [
+ {
+ u'name': u'HasTypeParamAttribute',
+ u'type_param': u'int',
+ u'status': u'RUN',
+ u'time': u'*',
+ u'classname': u'Single/TypeParameterizedTestCase/0'
+ }
+ ]
+ },
+ {
+ u'name': u'Single/TypeParameterizedTestCase/1',
+ u'tests': 1,
+ u'failures': 0,
+ u'disabled': 0,
+ u'errors': 0,
+ u'time': u'*',
+ u'testsuite': [
+ {
+ u'name': u'HasTypeParamAttribute',
+ u'type_param': u'long',
+ u'status': u'RUN',
+ u'time': u'*',
+ u'classname': u'Single/TypeParameterizedTestCase/1'
+ }
+ ]
+ },
+ {
+ 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'time': u'*',
+ u'classname': u'Single/ValueParamTest'
+ },
+ {
+ u'name': u'HasValueParamAttribute/1',
+ u'value_param': u'42',
+ u'status': u'RUN',
+ u'time': u'*',
+ u'classname': u'Single/ValueParamTest'
+ },
+ {
+ u'name': u'AnotherTestThatHasValueParamAttribute/0',
+ u'value_param': u'33',
+ u'status': u'RUN',
+ u'time': u'*',
+ u'classname': u'Single/ValueParamTest'
+ },
+ {
+ u'name': u'AnotherTestThatHasValueParamAttribute/1',
+ u'value_param': u'42',
+ u'status': u'RUN',
+ u'time': u'*',
+ u'classname': u'Single/ValueParamTest'
+ }
+ ]
+ }
+ ]
+}
+
+EXPECTED_FILTERED = {
+ u'tests': 1,
+ u'failures': 0,
+ u'disabled': 0,
+ u'errors': 0,
+ u'time': u'*',
+ u'timestamp': u'*',
+ u'name': u'AllTests',
+ u'ad_hoc_property': u'42',
+ u'testsuites': [{
+ u'name': u'SuccessfulTest',
+ u'tests': 1,
+ u'failures': 0,
+ u'disabled': 0,
+ u'errors': 0,
+ u'time': u'*',
+ u'testsuite': [{
+ u'name': u'Succeeds',
+ u'status': u'RUN',
+ u'time': u'*',
+ u'classname': u'SuccessfulTest',
+ }]
+ }],
+}
+
+EXPECTED_EMPTY = {
+ u'tests': 0,
+ u'failures': 0,
+ u'disabled': 0,
+ u'errors': 0,
+ u'time': u'*',
+ u'timestamp': u'*',
+ u'name': u'AllTests',
+ u'testsuites': [],
+}
+
+GTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME)
+
+SUPPORTS_TYPED_TESTS = 'TypedTest' in gtest_test_utils.Subprocess(
+ [GTEST_PROGRAM_PATH, GTEST_LIST_TESTS_FLAG], capture_stderr=False).output
+
+
+class GTestJsonOutputUnitTest(gtest_test_utils.TestCase):
+ """Unit test for Google Test's JSON output functionality.
+ """
+
+ # This test currently breaks on platforms that do not support typed and
+ # type-parameterized tests, so we don't run it under them.
+ if SUPPORTS_TYPED_TESTS:
+
+ def testNonEmptyJsonOutput(self):
+ """Verifies JSON output for a Google Test binary with non-empty output.
+
+ Runs a test program that generates a non-empty JSON output, and
+ tests that the JSON output is expected.
+ """
+ self._TestJsonOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY, 1)
+
+ def testEmptyJsonOutput(self):
+ """Verifies JSON output for a Google Test binary without actual tests.
+
+ Runs a test program that generates an empty JSON output, and
+ tests that the JSON output is expected.
+ """
+
+ self._TestJsonOutput('gtest_no_test_unittest', EXPECTED_EMPTY, 0)
+
+ def testTimestampValue(self):
+ """Checks whether the timestamp attribute in the JSON output is valid.
+
+ Runs a test program that generates an empty JSON output, and checks if
+ the timestamp attribute in the testsuites tag is valid.
+ """
+ actual = self._GetJsonOutput('gtest_no_test_unittest', [], 0)
+ date_time_str = actual['timestamp']
+ # datetime.strptime() is only available in Python 2.5+ so we have to
+ # parse the expected datetime manually.
+ match = re.match(r'(\d+)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)', date_time_str)
+ self.assertTrue(
+ re.match,
+ 'JSON datettime string %s has incorrect format' % date_time_str)
+ date_time_from_json = datetime.datetime(
+ year=int(match.group(1)), month=int(match.group(2)),
+ day=int(match.group(3)), hour=int(match.group(4)),
+ minute=int(match.group(5)), second=int(match.group(6)))
+
+ time_delta = abs(datetime.datetime.now() - date_time_from_json)
+ # timestamp value should be near the current local time
+ self.assertTrue(time_delta < datetime.timedelta(seconds=600),
+ 'time_delta is %s' % time_delta)
+
+ def testDefaultOutputFile(self):
+ """Verifies the default output file name.
+
+ Confirms that Google Test produces an JSON output file with the expected
+ default name if no name is explicitly specified.
+ """
+ output_file = os.path.join(gtest_test_utils.GetTempDir(),
+ GTEST_DEFAULT_OUTPUT_FILE)
+ gtest_prog_path = gtest_test_utils.GetTestExecutablePath(
+ 'gtest_no_test_unittest')
+ try:
+ os.remove(output_file)
+ except OSError:
+ e = sys.exc_info()[1]
+ if e.errno != errno.ENOENT:
+ raise
+
+ p = gtest_test_utils.Subprocess(
+ [gtest_prog_path, '%s=json' % GTEST_OUTPUT_FLAG],
+ working_dir=gtest_test_utils.GetTempDir())
+ self.assert_(p.exited)
+ self.assertEquals(0, p.exit_code)
+ self.assert_(os.path.isfile(output_file))
+
+ def testSuppressedJsonOutput(self):
+ """Verifies that no JSON output is generated.
+
+ Tests that no JSON file is generated if the default JSON listener is
+ shut down before RUN_ALL_TESTS is invoked.
+ """
+
+ json_path = os.path.join(gtest_test_utils.GetTempDir(),
+ GTEST_PROGRAM_NAME + 'out.json')
+ if os.path.isfile(json_path):
+ os.remove(json_path)
+
+ command = [GTEST_PROGRAM_PATH,
+ '%s=json:%s' % (GTEST_OUTPUT_FLAG, json_path),
+ '--shut_down_xml']
+ p = gtest_test_utils.Subprocess(command)
+ if p.terminated_by_signal:
+ # p.signal is available only if p.terminated_by_signal is True.
+ self.assertFalse(
+ p.terminated_by_signal,
+ '%s was killed by signal %d' % (GTEST_PROGRAM_NAME, p.signal))
+ else:
+ self.assert_(p.exited)
+ self.assertEquals(1, p.exit_code,
+ "'%s' exited with code %s, which doesn't match "
+ 'the expected exit code %s.'
+ % (command, p.exit_code, 1))
+
+ self.assert_(not os.path.isfile(json_path))
+
+ def testFilteredTestJsonOutput(self):
+ """Verifies JSON output when a filter is applied.
+
+ Runs a test program that executes only some tests and verifies that
+ non-selected tests do not show up in the JSON output.
+ """
+
+ self._TestJsonOutput(GTEST_PROGRAM_NAME, EXPECTED_FILTERED, 0,
+ extra_args=['%s=SuccessfulTest.*' % GTEST_FILTER_FLAG])
+
+ def _GetJsonOutput(self, gtest_prog_name, extra_args, expected_exit_code):
+ """Returns the JSON output generated by running the program gtest_prog_name.
+
+ Furthermore, the program's exit code must be expected_exit_code.
+
+ Args:
+ gtest_prog_name: Google Test binary name.
+ extra_args: extra arguments to binary invocation.
+ expected_exit_code: program's exit code.
+ """
+ json_path = os.path.join(gtest_test_utils.GetTempDir(),
+ gtest_prog_name + 'out.json')
+ gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name)
+
+ command = (
+ [gtest_prog_path, '%s=json:%s' % (GTEST_OUTPUT_FLAG, json_path)] +
+ extra_args
+ )
+ p = gtest_test_utils.Subprocess(command)
+ if p.terminated_by_signal:
+ self.assert_(False,
+ '%s was killed by signal %d' % (gtest_prog_name, p.signal))
+ else:
+ self.assert_(p.exited)
+ self.assertEquals(expected_exit_code, p.exit_code,
+ "'%s' exited with code %s, which doesn't match "
+ 'the expected exit code %s.'
+ % (command, p.exit_code, expected_exit_code))
+ with open(json_path) as f:
+ actual = json.load(f)
+ return actual
+
+ def _TestJsonOutput(self, gtest_prog_name, expected,
+ expected_exit_code, extra_args=None):
+ """Checks the JSON output generated by the Google Test binary.
+
+ Asserts that the JSON document generated by running the program
+ gtest_prog_name matches expected_json, a string containing another
+ JSON document. Furthermore, the program's exit code must be
+ expected_exit_code.
+
+ Args:
+ gtest_prog_name: Google Test binary name.
+ expected: expected output.
+ expected_exit_code: program's exit code.
+ extra_args: extra arguments to binary invocation.
+ """
+
+ actual = self._GetJsonOutput(gtest_prog_name, extra_args or [],
+ expected_exit_code)
+ self.assertEqual(expected, gtest_json_test_utils.normalize(actual))
+
+
+if __name__ == '__main__':
+ os.environ['GTEST_STACK_TRACE_DEPTH'] = '1'
+ gtest_test_utils.Main()
diff --git a/googletest/test/gtest_json_test_utils.py b/googletest/test/gtest_json_test_utils.py
new file mode 100644
index 0000000..62bbfc2
--- /dev/null
+++ b/googletest/test/gtest_json_test_utils.py
@@ -0,0 +1,60 @@
+# Copyright 2018, 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.
+
+"""Unit test utilities for gtest_json_output."""
+
+import re
+
+
+def normalize(obj):
+ """Normalize output object.
+
+ Args:
+ obj: Google Test's JSON output object to normalize.
+
+ Returns:
+ Normalized output without any references to transient information that may
+ change from run to run.
+ """
+ def _normalize(key, value):
+ if key == 'time':
+ return re.sub(r'^\d+(\.\d+)?s$', '*', value)
+ elif key == 'timestamp':
+ return re.sub(r'^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\dZ$', '*', value)
+ elif key == 'failure':
+ value = re.sub(r'^.*[/\\](.*:)\d+\n', '\\1*\n', value)
+ return re.sub(r'Stack trace:\n(.|\n)*', 'Stack trace:\n*', value)
+ else:
+ return normalize(value)
+ if isinstance(obj, dict):
+ return {k: _normalize(k, v) for k, v in obj.items()}
+ if isinstance(obj, list):
+ return [normalize(x) for x in obj]
+ else:
+ return obj
diff --git a/googletest/test/gtest_main_unittest.cc b/googletest/test/gtest_main_unittest.cc
index ecd9bb8..c979fce 100644
--- a/googletest/test/gtest_main_unittest.cc
+++ b/googletest/test/gtest_main_unittest.cc
@@ -41,5 +41,5 @@ TEST(GTestMainTest, ShouldSucceed) {
} // namespace
-// We are using the main() function defined in src/gtest_main.cc, so
-// we don't define it here.
+// We are using the main() function defined in gtest_main.cc, so we
+// don't define it here.
diff --git a/googletest/test/gtest_uninitialized_test.py b/googletest/test/gtest_uninitialized_test.py
index 574db77..ae91f2a 100755
--- a/googletest/test/gtest_uninitialized_test.py
+++ b/googletest/test/gtest_uninitialized_test.py
@@ -33,7 +33,6 @@
__author__ = 'wan@google.com (Zhanyong Wan)'
-import os
import gtest_test_utils
COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_uninitialized_test_')
diff --git a/googletest/test/gtest_uninitialized_test_.cc b/googletest/test/gtest_uninitialized_test_.cc
index 502b0ad..2ba0e8b 100644
--- a/googletest/test/gtest_uninitialized_test_.cc
+++ b/googletest/test/gtest_uninitialized_test_.cc
@@ -34,7 +34,7 @@
TEST(DummyTest, Dummy) {
// This test doesn't verify anything. We just need it to create a
// realistic stage for testing the behavior of Google Test when
- // RUN_ALL_TESTS() is called without
+ // RUN_ALL_TESTS() is called without
// testing::InitGoogleTest() being called first.
}
diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc
index a45927d..11af9c9 100644
--- a/googletest/test/gtest_unittest.cc
+++ b/googletest/test/gtest_unittest.cc
@@ -538,7 +538,7 @@ TEST(CodePointToUtf8Test, CanEncode8To11Bits) {
// 101 0111 0110 => 110-10101 10-110110
// Some compilers (e.g., GCC on MinGW) cannot handle non-ASCII codepoints
- // in wide strings and wide chars. In order to accomodate them, we have to
+ // in wide strings and wide chars. In order to accommodate them, we have to
// introduce such character constants as integers.
EXPECT_EQ("\xD5\xB6",
CodePointToUtf8(static_cast<wchar_t>(0x576)));
@@ -1779,7 +1779,7 @@ TEST(Int32FromEnvOrDieDeathTest, AbortsOnFailure) {
}
// Tests that Int32FromEnvOrDie() aborts with an error message
-// if the variable cannot be represnted by an Int32.
+// if the variable cannot be represented by an Int32.
TEST(Int32FromEnvOrDieDeathTest, AbortsOnInt32Overflow) {
SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "1234567891234567891234");
EXPECT_DEATH_IF_SUPPORTED(
@@ -2088,7 +2088,7 @@ class UnitTestRecordPropertyTestEnvironment : public Environment {
};
// This will test property recording outside of any test or test case.
-Environment* record_property_env GTEST_ATTRIBUTE_UNUSED_ =
+static Environment* record_property_env =
AddGlobalTestEnvironment(new UnitTestRecordPropertyTestEnvironment);
// This group of tests is for predicate assertions (ASSERT_PRED*, etc)
@@ -2421,9 +2421,8 @@ TEST(StringAssertionTest, ASSERT_STREQ) {
const char p2[] = "good";
ASSERT_STREQ(p1, p2);
- EXPECT_FATAL_FAILURE(
- ASSERT_STREQ("bad", "good"),
- "Expected equality of these values:\n \"bad\"\n \"good\"");
+ EXPECT_FATAL_FAILURE(ASSERT_STREQ("bad", "good"),
+ " \"bad\"\n \"good\"");
}
// Tests ASSERT_STREQ with NULL arguments.
@@ -3361,7 +3360,7 @@ class NoFatalFailureTest : public Test {
void DoAssertNoFatalFailureOnFails() {
ASSERT_NO_FATAL_FAILURE(Fails());
- ADD_FAILURE() << "shold not reach here.";
+ ADD_FAILURE() << "should not reach here.";
}
void DoExpectNoFatalFailureOnFails() {
@@ -3658,7 +3657,7 @@ TEST(AssertionTest, AssertFalseWithAssertionResult) {
}
#ifdef __BORLANDC__
-// Restores warnings after previous "#pragma option push" supressed them
+// Restores warnings after previous "#pragma option push" suppressed them
# pragma option pop
#endif
@@ -3813,7 +3812,7 @@ void TestEq1(int x) {
// Tests calling a test subroutine that's not part of a fixture.
TEST(AssertionTest, NonFixtureSubroutine) {
EXPECT_FATAL_FAILURE(TestEq1(2),
- "Which is: 2");
+ " x\n Which is: 2");
}
// An uncopyable class.
@@ -3952,13 +3951,13 @@ TEST(AssertionTest, AnonymousEnum) {
// ICE's in C++Builder.
EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseB),
- "kCaseB");
+ " kCaseB\n Which is: ");
EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC),
- "Which is: 42");
+ "\n Which is: 42");
# endif
EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC),
- "Which is: -1");
+ "\n Which is: -1");
}
#endif // !GTEST_OS_MAC && !defined(__SUNPRO_CC)
@@ -4384,7 +4383,7 @@ TEST(ExpectTest, ExpectFalseWithAssertionResult) {
}
#ifdef __BORLANDC__
-// Restores warnings after previous "#pragma option push" supressed them
+// Restores warnings after previous "#pragma option push" suppressed them
# pragma option pop
#endif
@@ -4426,7 +4425,7 @@ TEST(ExpectTest, EXPECT_EQ_NULL) {
// A failure.
int n = 0;
EXPECT_NONFATAL_FAILURE(EXPECT_EQ(NULL, &n),
- "&n\n");
+ " &n\n Which is:");
}
#endif // GTEST_CAN_COMPARE_NULL
@@ -4442,7 +4441,7 @@ TEST(ExpectTest, EXPECT_EQ_0) {
// A failure.
EXPECT_NONFATAL_FAILURE(EXPECT_EQ(0, 5.6),
- "Expected equality of these values:\n 0\n 5.6");
+ " 0\n 5.6");
}
// Tests EXPECT_NE.
@@ -4542,7 +4541,7 @@ TEST(ExpectTest, EXPECT_ANY_THROW) {
TEST(ExpectTest, ExpectPrecedence) {
EXPECT_EQ(1 < 2, true);
EXPECT_NONFATAL_FAILURE(EXPECT_EQ(true, true && false),
- "true && false");
+ " true && false\n Which is: false");
}
@@ -4689,14 +4688,14 @@ TEST(EqAssertionTest, Bool) {
EXPECT_FATAL_FAILURE({
bool false_value = false;
ASSERT_EQ(false_value, true);
- }, "Which is: false");
+ }, " false_value\n Which is: false\n true");
}
// Tests using int values in {EXPECT|ASSERT}_EQ.
TEST(EqAssertionTest, Int) {
ASSERT_EQ(32, 32);
EXPECT_NONFATAL_FAILURE(EXPECT_EQ(32, 33),
- "33");
+ " 32\n 33");
}
// Tests using time_t values in {EXPECT|ASSERT}_EQ.
@@ -4713,9 +4712,9 @@ TEST(EqAssertionTest, Char) {
ASSERT_EQ('z', 'z');
const char ch = 'b';
EXPECT_NONFATAL_FAILURE(EXPECT_EQ('\0', ch),
- "ch");
+ " ch\n Which is: 'b'");
EXPECT_NONFATAL_FAILURE(EXPECT_EQ('a', ch),
- "ch");
+ " ch\n Which is: 'b'");
}
// Tests using wchar_t values in {EXPECT|ASSERT}_EQ.
@@ -4735,7 +4734,7 @@ TEST(EqAssertionTest, WideChar) {
"wchar");
wchar = 0x8119;
EXPECT_FATAL_FAILURE(ASSERT_EQ(static_cast<wchar_t>(0x8120), wchar),
- "wchar");
+ " wchar\n Which is: L'");
}
// Tests using ::std::string values in {EXPECT|ASSERT}_EQ.
@@ -4764,8 +4763,7 @@ TEST(EqAssertionTest, StdString) {
static ::std::string str3(str1);
str3.at(2) = '\0';
EXPECT_FATAL_FAILURE(ASSERT_EQ(str1, str3),
- " str3\n"
- " Which is: \"A \\0 in the middle\"");
+ " str3\n Which is: \"A \\0 in the middle\"");
}
#if GTEST_HAS_STD_WSTRING
@@ -4885,9 +4883,9 @@ TEST(EqAssertionTest, CharPointer) {
ASSERT_EQ(p1, p1);
EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p0, p2),
- "p2");
+ " p2\n Which is:");
EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, p2),
- "p2");
+ " p2\n Which is:");
EXPECT_FATAL_FAILURE(ASSERT_EQ(reinterpret_cast<char*>(0x1234),
reinterpret_cast<char*>(0xABC0)),
"ABC0");
@@ -4907,9 +4905,9 @@ TEST(EqAssertionTest, WideCharPointer) {
EXPECT_EQ(p0, p0);
EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p0, p2),
- "p2");
+ " p2\n Which is:");
EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, p2),
- "p2");
+ " p2\n Which is:");
void* pv3 = (void*)0x1234; // NOLINT
void* pv4 = (void*)0xABC0; // NOLINT
const wchar_t* p3 = reinterpret_cast<const wchar_t*>(pv3);
@@ -5454,7 +5452,8 @@ TEST_F(SetUpTestCaseTest, Test2) {
EXPECT_STREQ("123", shared_resource_);
}
-// The InitGoogleTestTest test case tests testing::InitGoogleTest().
+
+// The ParseFlagsTest test case tests ParseGoogleTestFlagsOnly.
// The Flags struct stores a copy of all Google Test flags.
struct Flags {
@@ -5540,8 +5539,8 @@ struct Flags {
return flags;
}
- // Creates a Flags struct where the gtest_random_seed flag has
- // the given value.
+ // Creates a Flags struct where the gtest_random_seed flag has the given
+ // value.
static Flags RandomSeed(Int32 random_seed) {
Flags flags;
flags.random_seed = random_seed;
@@ -5556,8 +5555,8 @@ struct Flags {
return flags;
}
- // Creates a Flags struct where the gtest_shuffle flag has
- // the given value.
+ // Creates a Flags struct where the gtest_shuffle flag has the given
+ // value.
static Flags Shuffle(bool shuffle) {
Flags flags;
flags.shuffle = shuffle;
@@ -5605,8 +5604,8 @@ struct Flags {
bool throw_on_failure;
};
-// Fixture for testing InitGoogleTest().
-class InitGoogleTestTest : public Test {
+// Fixture for testing ParseGoogleTestFlagsOnly().
+class ParseFlagsTest : public Test {
protected:
// Clears the flags before each test.
virtual void SetUp() {
@@ -5667,16 +5666,16 @@ class InitGoogleTestTest : public Test {
const bool saved_help_flag = ::testing::internal::g_help_flag;
::testing::internal::g_help_flag = false;
-#if GTEST_HAS_STREAM_REDIRECTION
+# if GTEST_HAS_STREAM_REDIRECTION
CaptureStdout();
-#endif
+# endif
// Parses the command line.
internal::ParseGoogleTestFlagsOnly(&argc1, const_cast<CharType**>(argv1));
-#if GTEST_HAS_STREAM_REDIRECTION
+# if GTEST_HAS_STREAM_REDIRECTION
const std::string captured_stdout = GetCapturedStdout();
-#endif
+# endif
// Verifies the flag values.
CheckFlags(expected);
@@ -5689,7 +5688,7 @@ class InitGoogleTestTest : public Test {
// help message for the flags it recognizes.
EXPECT_EQ(should_print_help, ::testing::internal::g_help_flag);
-#if GTEST_HAS_STREAM_REDIRECTION
+# if GTEST_HAS_STREAM_REDIRECTION
const char* const expected_help_fragment =
"This program contains tests written using";
if (should_print_help) {
@@ -5698,7 +5697,7 @@ class InitGoogleTestTest : public Test {
EXPECT_PRED_FORMAT2(IsNotSubstring,
expected_help_fragment, captured_stdout);
}
-#endif // GTEST_HAS_STREAM_REDIRECTION
+# endif // GTEST_HAS_STREAM_REDIRECTION
::testing::internal::g_help_flag = saved_help_flag;
}
@@ -5706,14 +5705,14 @@ class InitGoogleTestTest : public Test {
// This macro wraps TestParsingFlags s.t. the user doesn't need
// to specify the array sizes.
-#define GTEST_TEST_PARSING_FLAGS_(argv1, argv2, expected, should_print_help) \
+# define GTEST_TEST_PARSING_FLAGS_(argv1, argv2, expected, should_print_help) \
TestParsingFlags(sizeof(argv1)/sizeof(*argv1) - 1, argv1, \
sizeof(argv2)/sizeof(*argv2) - 1, argv2, \
expected, should_print_help)
};
// Tests parsing an empty command line.
-TEST_F(InitGoogleTestTest, Empty) {
+TEST_F(ParseFlagsTest, Empty) {
const char* argv[] = {
NULL
};
@@ -5726,7 +5725,7 @@ TEST_F(InitGoogleTestTest, Empty) {
}
// Tests parsing a command line that has no flag.
-TEST_F(InitGoogleTestTest, NoFlag) {
+TEST_F(ParseFlagsTest, NoFlag) {
const char* argv[] = {
"foo.exe",
NULL
@@ -5741,7 +5740,7 @@ TEST_F(InitGoogleTestTest, NoFlag) {
}
// Tests parsing a bad --gtest_filter flag.
-TEST_F(InitGoogleTestTest, FilterBad) {
+TEST_F(ParseFlagsTest, FilterBad) {
const char* argv[] = {
"foo.exe",
"--gtest_filter",
@@ -5758,7 +5757,7 @@ TEST_F(InitGoogleTestTest, FilterBad) {
}
// Tests parsing an empty --gtest_filter flag.
-TEST_F(InitGoogleTestTest, FilterEmpty) {
+TEST_F(ParseFlagsTest, FilterEmpty) {
const char* argv[] = {
"foo.exe",
"--gtest_filter=",
@@ -5774,7 +5773,7 @@ TEST_F(InitGoogleTestTest, FilterEmpty) {
}
// Tests parsing a non-empty --gtest_filter flag.
-TEST_F(InitGoogleTestTest, FilterNonEmpty) {
+TEST_F(ParseFlagsTest, FilterNonEmpty) {
const char* argv[] = {
"foo.exe",
"--gtest_filter=abc",
@@ -5790,7 +5789,7 @@ TEST_F(InitGoogleTestTest, FilterNonEmpty) {
}
// Tests parsing --gtest_break_on_failure.
-TEST_F(InitGoogleTestTest, BreakOnFailureWithoutValue) {
+TEST_F(ParseFlagsTest, BreakOnFailureWithoutValue) {
const char* argv[] = {
"foo.exe",
"--gtest_break_on_failure",
@@ -5806,7 +5805,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureWithoutValue) {
}
// Tests parsing --gtest_break_on_failure=0.
-TEST_F(InitGoogleTestTest, BreakOnFailureFalse_0) {
+TEST_F(ParseFlagsTest, BreakOnFailureFalse_0) {
const char* argv[] = {
"foo.exe",
"--gtest_break_on_failure=0",
@@ -5822,7 +5821,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureFalse_0) {
}
// Tests parsing --gtest_break_on_failure=f.
-TEST_F(InitGoogleTestTest, BreakOnFailureFalse_f) {
+TEST_F(ParseFlagsTest, BreakOnFailureFalse_f) {
const char* argv[] = {
"foo.exe",
"--gtest_break_on_failure=f",
@@ -5838,7 +5837,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureFalse_f) {
}
// Tests parsing --gtest_break_on_failure=F.
-TEST_F(InitGoogleTestTest, BreakOnFailureFalse_F) {
+TEST_F(ParseFlagsTest, BreakOnFailureFalse_F) {
const char* argv[] = {
"foo.exe",
"--gtest_break_on_failure=F",
@@ -5855,7 +5854,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureFalse_F) {
// Tests parsing a --gtest_break_on_failure flag that has a "true"
// definition.
-TEST_F(InitGoogleTestTest, BreakOnFailureTrue) {
+TEST_F(ParseFlagsTest, BreakOnFailureTrue) {
const char* argv[] = {
"foo.exe",
"--gtest_break_on_failure=1",
@@ -5871,7 +5870,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureTrue) {
}
// Tests parsing --gtest_catch_exceptions.
-TEST_F(InitGoogleTestTest, CatchExceptions) {
+TEST_F(ParseFlagsTest, CatchExceptions) {
const char* argv[] = {
"foo.exe",
"--gtest_catch_exceptions",
@@ -5887,7 +5886,7 @@ TEST_F(InitGoogleTestTest, CatchExceptions) {
}
// Tests parsing --gtest_death_test_use_fork.
-TEST_F(InitGoogleTestTest, DeathTestUseFork) {
+TEST_F(ParseFlagsTest, DeathTestUseFork) {
const char* argv[] = {
"foo.exe",
"--gtest_death_test_use_fork",
@@ -5904,7 +5903,7 @@ TEST_F(InitGoogleTestTest, DeathTestUseFork) {
// Tests having the same flag twice with different values. The
// expected behavior is that the one coming last takes precedence.
-TEST_F(InitGoogleTestTest, DuplicatedFlags) {
+TEST_F(ParseFlagsTest, DuplicatedFlags) {
const char* argv[] = {
"foo.exe",
"--gtest_filter=a",
@@ -5921,7 +5920,7 @@ TEST_F(InitGoogleTestTest, DuplicatedFlags) {
}
// Tests having an unrecognized flag on the command line.
-TEST_F(InitGoogleTestTest, UnrecognizedFlag) {
+TEST_F(ParseFlagsTest, UnrecognizedFlag) {
const char* argv[] = {
"foo.exe",
"--gtest_break_on_failure",
@@ -5943,7 +5942,7 @@ TEST_F(InitGoogleTestTest, UnrecognizedFlag) {
}
// Tests having a --gtest_list_tests flag
-TEST_F(InitGoogleTestTest, ListTestsFlag) {
+TEST_F(ParseFlagsTest, ListTestsFlag) {
const char* argv[] = {
"foo.exe",
"--gtest_list_tests",
@@ -5959,7 +5958,7 @@ TEST_F(InitGoogleTestTest, ListTestsFlag) {
}
// Tests having a --gtest_list_tests flag with a "true" value
-TEST_F(InitGoogleTestTest, ListTestsTrue) {
+TEST_F(ParseFlagsTest, ListTestsTrue) {
const char* argv[] = {
"foo.exe",
"--gtest_list_tests=1",
@@ -5975,7 +5974,7 @@ TEST_F(InitGoogleTestTest, ListTestsTrue) {
}
// Tests having a --gtest_list_tests flag with a "false" value
-TEST_F(InitGoogleTestTest, ListTestsFalse) {
+TEST_F(ParseFlagsTest, ListTestsFalse) {
const char* argv[] = {
"foo.exe",
"--gtest_list_tests=0",
@@ -5991,7 +5990,7 @@ TEST_F(InitGoogleTestTest, ListTestsFalse) {
}
// Tests parsing --gtest_list_tests=f.
-TEST_F(InitGoogleTestTest, ListTestsFalse_f) {
+TEST_F(ParseFlagsTest, ListTestsFalse_f) {
const char* argv[] = {
"foo.exe",
"--gtest_list_tests=f",
@@ -6007,7 +6006,7 @@ TEST_F(InitGoogleTestTest, ListTestsFalse_f) {
}
// Tests parsing --gtest_list_tests=F.
-TEST_F(InitGoogleTestTest, ListTestsFalse_F) {
+TEST_F(ParseFlagsTest, ListTestsFalse_F) {
const char* argv[] = {
"foo.exe",
"--gtest_list_tests=F",
@@ -6023,7 +6022,7 @@ TEST_F(InitGoogleTestTest, ListTestsFalse_F) {
}
// Tests parsing --gtest_output (invalid).
-TEST_F(InitGoogleTestTest, OutputEmpty) {
+TEST_F(ParseFlagsTest, OutputEmpty) {
const char* argv[] = {
"foo.exe",
"--gtest_output",
@@ -6040,7 +6039,7 @@ TEST_F(InitGoogleTestTest, OutputEmpty) {
}
// Tests parsing --gtest_output=xml
-TEST_F(InitGoogleTestTest, OutputXml) {
+TEST_F(ParseFlagsTest, OutputXml) {
const char* argv[] = {
"foo.exe",
"--gtest_output=xml",
@@ -6056,7 +6055,7 @@ TEST_F(InitGoogleTestTest, OutputXml) {
}
// Tests parsing --gtest_output=xml:file
-TEST_F(InitGoogleTestTest, OutputXmlFile) {
+TEST_F(ParseFlagsTest, OutputXmlFile) {
const char* argv[] = {
"foo.exe",
"--gtest_output=xml:file",
@@ -6072,7 +6071,7 @@ TEST_F(InitGoogleTestTest, OutputXmlFile) {
}
// Tests parsing --gtest_output=xml:directory/path/
-TEST_F(InitGoogleTestTest, OutputXmlDirectory) {
+TEST_F(ParseFlagsTest, OutputXmlDirectory) {
const char* argv[] = {
"foo.exe",
"--gtest_output=xml:directory/path/",
@@ -6089,7 +6088,7 @@ TEST_F(InitGoogleTestTest, OutputXmlDirectory) {
}
// Tests having a --gtest_print_time flag
-TEST_F(InitGoogleTestTest, PrintTimeFlag) {
+TEST_F(ParseFlagsTest, PrintTimeFlag) {
const char* argv[] = {
"foo.exe",
"--gtest_print_time",
@@ -6105,7 +6104,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFlag) {
}
// Tests having a --gtest_print_time flag with a "true" value
-TEST_F(InitGoogleTestTest, PrintTimeTrue) {
+TEST_F(ParseFlagsTest, PrintTimeTrue) {
const char* argv[] = {
"foo.exe",
"--gtest_print_time=1",
@@ -6121,7 +6120,7 @@ TEST_F(InitGoogleTestTest, PrintTimeTrue) {
}
// Tests having a --gtest_print_time flag with a "false" value
-TEST_F(InitGoogleTestTest, PrintTimeFalse) {
+TEST_F(ParseFlagsTest, PrintTimeFalse) {
const char* argv[] = {
"foo.exe",
"--gtest_print_time=0",
@@ -6137,7 +6136,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFalse) {
}
// Tests parsing --gtest_print_time=f.
-TEST_F(InitGoogleTestTest, PrintTimeFalse_f) {
+TEST_F(ParseFlagsTest, PrintTimeFalse_f) {
const char* argv[] = {
"foo.exe",
"--gtest_print_time=f",
@@ -6153,7 +6152,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFalse_f) {
}
// Tests parsing --gtest_print_time=F.
-TEST_F(InitGoogleTestTest, PrintTimeFalse_F) {
+TEST_F(ParseFlagsTest, PrintTimeFalse_F) {
const char* argv[] = {
"foo.exe",
"--gtest_print_time=F",
@@ -6169,7 +6168,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFalse_F) {
}
// Tests parsing --gtest_random_seed=number
-TEST_F(InitGoogleTestTest, RandomSeed) {
+TEST_F(ParseFlagsTest, RandomSeed) {
const char* argv[] = {
"foo.exe",
"--gtest_random_seed=1000",
@@ -6185,7 +6184,7 @@ TEST_F(InitGoogleTestTest, RandomSeed) {
}
// Tests parsing --gtest_repeat=number
-TEST_F(InitGoogleTestTest, Repeat) {
+TEST_F(ParseFlagsTest, Repeat) {
const char* argv[] = {
"foo.exe",
"--gtest_repeat=1000",
@@ -6201,7 +6200,7 @@ TEST_F(InitGoogleTestTest, Repeat) {
}
// Tests having a --gtest_also_run_disabled_tests flag
-TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFlag) {
+TEST_F(ParseFlagsTest, AlsoRunDisabledTestsFlag) {
const char* argv[] = {
"foo.exe",
"--gtest_also_run_disabled_tests",
@@ -6218,7 +6217,7 @@ TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFlag) {
}
// Tests having a --gtest_also_run_disabled_tests flag with a "true" value
-TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsTrue) {
+TEST_F(ParseFlagsTest, AlsoRunDisabledTestsTrue) {
const char* argv[] = {
"foo.exe",
"--gtest_also_run_disabled_tests=1",
@@ -6235,7 +6234,7 @@ TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsTrue) {
}
// Tests having a --gtest_also_run_disabled_tests flag with a "false" value
-TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFalse) {
+TEST_F(ParseFlagsTest, AlsoRunDisabledTestsFalse) {
const char* argv[] = {
"foo.exe",
"--gtest_also_run_disabled_tests=0",
@@ -6252,7 +6251,7 @@ TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFalse) {
}
// Tests parsing --gtest_shuffle.
-TEST_F(InitGoogleTestTest, ShuffleWithoutValue) {
+TEST_F(ParseFlagsTest, ShuffleWithoutValue) {
const char* argv[] = {
"foo.exe",
"--gtest_shuffle",
@@ -6268,7 +6267,7 @@ TEST_F(InitGoogleTestTest, ShuffleWithoutValue) {
}
// Tests parsing --gtest_shuffle=0.
-TEST_F(InitGoogleTestTest, ShuffleFalse_0) {
+TEST_F(ParseFlagsTest, ShuffleFalse_0) {
const char* argv[] = {
"foo.exe",
"--gtest_shuffle=0",
@@ -6283,9 +6282,8 @@ TEST_F(InitGoogleTestTest, ShuffleFalse_0) {
GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(false), false);
}
-// Tests parsing a --gtest_shuffle flag that has a "true"
-// definition.
-TEST_F(InitGoogleTestTest, ShuffleTrue) {
+// Tests parsing a --gtest_shuffle flag that has a "true" definition.
+TEST_F(ParseFlagsTest, ShuffleTrue) {
const char* argv[] = {
"foo.exe",
"--gtest_shuffle=1",
@@ -6301,7 +6299,7 @@ TEST_F(InitGoogleTestTest, ShuffleTrue) {
}
// Tests parsing --gtest_stack_trace_depth=number.
-TEST_F(InitGoogleTestTest, StackTraceDepth) {
+TEST_F(ParseFlagsTest, StackTraceDepth) {
const char* argv[] = {
"foo.exe",
"--gtest_stack_trace_depth=5",
@@ -6316,7 +6314,7 @@ TEST_F(InitGoogleTestTest, StackTraceDepth) {
GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::StackTraceDepth(5), false);
}
-TEST_F(InitGoogleTestTest, StreamResultTo) {
+TEST_F(ParseFlagsTest, StreamResultTo) {
const char* argv[] = {
"foo.exe",
"--gtest_stream_result_to=localhost:1234",
@@ -6333,7 +6331,7 @@ TEST_F(InitGoogleTestTest, StreamResultTo) {
}
// Tests parsing --gtest_throw_on_failure.
-TEST_F(InitGoogleTestTest, ThrowOnFailureWithoutValue) {
+TEST_F(ParseFlagsTest, ThrowOnFailureWithoutValue) {
const char* argv[] = {
"foo.exe",
"--gtest_throw_on_failure",
@@ -6349,7 +6347,7 @@ TEST_F(InitGoogleTestTest, ThrowOnFailureWithoutValue) {
}
// Tests parsing --gtest_throw_on_failure=0.
-TEST_F(InitGoogleTestTest, ThrowOnFailureFalse_0) {
+TEST_F(ParseFlagsTest, ThrowOnFailureFalse_0) {
const char* argv[] = {
"foo.exe",
"--gtest_throw_on_failure=0",
@@ -6366,7 +6364,7 @@ TEST_F(InitGoogleTestTest, ThrowOnFailureFalse_0) {
// Tests parsing a --gtest_throw_on_failure flag that has a "true"
// definition.
-TEST_F(InitGoogleTestTest, ThrowOnFailureTrue) {
+TEST_F(ParseFlagsTest, ThrowOnFailureTrue) {
const char* argv[] = {
"foo.exe",
"--gtest_throw_on_failure=1",
@@ -6381,9 +6379,9 @@ TEST_F(InitGoogleTestTest, ThrowOnFailureTrue) {
GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true), false);
}
-#if GTEST_OS_WINDOWS
+# if GTEST_OS_WINDOWS
// Tests parsing wide strings.
-TEST_F(InitGoogleTestTest, WideStrings) {
+TEST_F(ParseFlagsTest, WideStrings) {
const wchar_t* argv[] = {
L"foo.exe",
L"--gtest_filter=Foo*",
@@ -6409,10 +6407,10 @@ TEST_F(InitGoogleTestTest, WideStrings) {
# endif // GTEST_OS_WINDOWS
#if GTEST_USE_OWN_FLAGFILE_FLAG_
-class FlagfileTest : public InitGoogleTestTest {
+class FlagfileTest : public ParseFlagsTest {
public:
virtual void SetUp() {
- InitGoogleTestTest::SetUp();
+ ParseFlagsTest::SetUp();
testdata_path_.Set(internal::FilePath(
testing::TempDir() + internal::GetCurrentExecutableName().string() +
@@ -6423,7 +6421,7 @@ class FlagfileTest : public InitGoogleTestTest {
virtual void TearDown() {
testing::internal::posix::RmDir(testdata_path_.c_str());
- InitGoogleTestTest::TearDown();
+ ParseFlagsTest::TearDown();
}
internal::FilePath CreateFlagfile(const char* contents) {
@@ -6562,6 +6560,7 @@ TEST_F(CurrentTestInfoTest, WorksForSecondTestInATestCase) {
} // namespace testing
+
// These two lines test that we can define tests in a namespace that
// has the name "testing" and is nested in another namespace.
namespace my_namespace {
@@ -6642,7 +6641,7 @@ TEST(StreamingAssertionsTest, Truth2) {
}
#ifdef __BORLANDC__
-// Restores warnings after previous "#pragma option push" supressed them
+// Restores warnings after previous "#pragma option push" suppressed them
# pragma option pop
#endif
@@ -6892,14 +6891,6 @@ TEST(StaticAssertTypeEqTest, CompilesForEqualTypes) {
StaticAssertTypeEq<int*, IntAlias*>();
}
-TEST(GetCurrentOsStackTraceExceptTopTest, ReturnsTheStackTrace) {
- testing::UnitTest* const unit_test = testing::UnitTest::GetInstance();
-
- // We don't have a stack walker in Google Test yet.
- EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 0).c_str());
- EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 1).c_str());
-}
-
TEST(HasNonfatalFailureTest, ReturnsFalseWhenThereIsNoFailure) {
EXPECT_FALSE(HasNonfatalFailure());
}
@@ -7659,7 +7650,7 @@ TEST(NativeArrayTest, MethodsWork) {
EXPECT_EQ(0, *it);
++it;
EXPECT_EQ(1, *it);
- ++it;
+ it++;
EXPECT_EQ(2, *it);
++it;
EXPECT_EQ(na.end(), it);
diff --git a/googletest/test/gtest_xml_outfiles_test.py b/googletest/test/gtest_xml_outfiles_test.py
index 24c6ee6..c7d3413 100755
--- a/googletest/test/gtest_xml_outfiles_test.py
+++ b/googletest/test/gtest_xml_outfiles_test.py
@@ -43,7 +43,13 @@ 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" time="*" classname="PropertyOne" SetUpProp="1" TestSomeProperty="1" TearDownProp="1" />
+ <testcase name="TestSomeProperties" status="run" time="*" classname="PropertyOne">
+ <properties>
+ <property name="SetUpProp" value="1"/>
+ <property name="TestSomeProperty" value="1"/>
+ <property name="TearDownProp" value="1"/>
+ </properties>
+ </testcase>
</testsuite>
</testsuites>
"""
@@ -51,7 +57,13 @@ 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" time="*" classname="PropertyTwo" SetUpProp="2" TestSomeProperty="2" TearDownProp="2" />
+ <testcase name="TestSomeProperties" status="run" time="*" classname="PropertyTwo">
+ <properties>
+ <property name="SetUpProp" value="2"/>
+ <property name="TestSomeProperty" value="2"/>
+ <property name="TearDownProp" value="2"/>
+ </properties>
+ </testcase>
</testsuite>
</testsuites>
"""
diff --git a/googletest/test/gtest_xml_output_unittest.py b/googletest/test/gtest_xml_output_unittest.py
index 325ca13..6ffb6e3 100755
--- a/googletest/test/gtest_xml_output_unittest.py
+++ b/googletest/test/gtest_xml_output_unittest.py
@@ -104,15 +104,45 @@ Invalid characters in brackets []%(stack)s]]></failure>
<testcase name="DISABLED_test_not_run" status="notrun" time="*" classname="DisabledTest"/>
</testsuite>
<testsuite name="PropertyRecordingTest" tests="4" failures="0" disabled="0" errors="0" time="*" SetUpTestCase="yes" TearDownTestCase="aye">
- <testcase name="OneProperty" status="run" time="*" classname="PropertyRecordingTest" key_1="1"/>
- <testcase name="IntValuedProperty" status="run" time="*" classname="PropertyRecordingTest" key_int="1"/>
- <testcase name="ThreeProperties" status="run" time="*" classname="PropertyRecordingTest" key_1="1" key_2="2" key_3="3"/>
- <testcase name="TwoValuesForOneKeyUsesLastValue" status="run" time="*" classname="PropertyRecordingTest" key_1="2"/>
+ <testcase name="OneProperty" status="run" time="*" classname="PropertyRecordingTest">
+ <properties>
+ <property name="key_1" value="1"/>
+ </properties>
+ </testcase>
+ <testcase name="IntValuedProperty" status="run" time="*" classname="PropertyRecordingTest">
+ <properties>
+ <property name="key_int" value="1"/>
+ </properties>
+ </testcase>
+ <testcase name="ThreeProperties" status="run" time="*" 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" time="*" 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" time="*" classname="NoFixtureTest" key="1"/>
- <testcase name="ExternalUtilityThatCallsRecordIntValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_int="1"/>
- <testcase name="ExternalUtilityThatCallsRecordStringValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_string="1"/>
+ <testcase name="RecordProperty" status="run" time="*" classname="NoFixtureTest">
+ <properties>
+ <property name="key" value="1"/>
+ </properties>
+ </testcase>
+ <testcase name="ExternalUtilityThatCallsRecordIntValuedProperty" status="run" time="*" classname="NoFixtureTest">
+ <properties>
+ <property name="key_for_utility_int" value="1"/>
+ </properties>
+ </testcase>
+ <testcase name="ExternalUtilityThatCallsRecordStringValuedProperty" status="run" time="*" 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" time="*" classname="Single/ValueParamTest" />
@@ -149,7 +179,11 @@ EXPECTED_SHARDED_TEST_XML = """<?xml version="1.0" encoding="UTF-8"?>
<testcase name="Succeeds" status="run" time="*" classname="SuccessfulTest"/>
</testsuite>
<testsuite name="NoFixtureTest" tests="1" failures="0" disabled="0" errors="0" time="*">
- <testcase name="RecordProperty" status="run" time="*" classname="NoFixtureTest" key="1"/>
+ <testcase name="RecordProperty" status="run" time="*" classname="NoFixtureTest">
+ <properties>
+ <property name="key" value="1"/>
+ </properties>
+ </testcase>
</testsuite>
<testsuite name="Single/ValueParamTest" tests="1" failures="0" disabled="0" errors="0" time="*">
<testcase name="AnotherTestThatHasValueParamAttribute/1" value_param="42" status="run" time="*" classname="Single/ValueParamTest" />
diff --git a/googletest/test/gtest_xml_test_utils.py b/googletest/test/gtest_xml_test_utils.py
index d303425..1e03585 100755
--- a/googletest/test/gtest_xml_test_utils.py
+++ b/googletest/test/gtest_xml_test_utils.py
@@ -101,19 +101,22 @@ class GTestXMLTestCase(gtest_test_utils.TestCase):
self.AssertEquivalentNodes(child, actual_children[child_id])
identifying_attribute = {
- 'testsuites': 'name',
- 'testsuite': 'name',
- 'testcase': 'name',
- 'failure': 'message',
- }
+ 'testsuites': 'name',
+ 'testsuite': 'name',
+ 'testcase': 'name',
+ 'failure': 'message',
+ 'property': 'name',
+ }
def _GetChildren(self, element):
"""
Fetches all of the child nodes of element, a DOM Element object.
Returns them as the values of a dictionary keyed by the IDs of the
- children. For <testsuites>, <testsuite> and <testcase> elements, the ID
- is the value of their "name" attribute; for <failure> elements, it is
- the value of the "message" attribute; CDATA sections and non-whitespace
+ children. For <testsuites>, <testsuite>, <testcase>, and <property>
+ elements, the ID is the value of their "name" attribute; for <failure>
+ elements, it is the value of the "message" attribute; for <properties>
+ elements, it is the value of their parent's "name" attribute plus the
+ literal string "properties"; CDATA sections and non-whitespace
text nodes are concatenated into a single CDATA section with ID
"detail". An exception is raised if any element other than the above
four is encountered, if two child elements with the same identifying
@@ -123,11 +126,17 @@ class GTestXMLTestCase(gtest_test_utils.TestCase):
children = {}
for child in element.childNodes:
if child.nodeType == Node.ELEMENT_NODE:
- self.assert_(child.tagName in self.identifying_attribute,
- 'Encountered unknown element <%s>' % child.tagName)
- childID = child.getAttribute(self.identifying_attribute[child.tagName])
- self.assert_(childID not in children)
- children[childID] = child
+ if child.tagName == 'properties':
+ self.assert_(child.parentNode is not None,
+ 'Encountered <properties> element without a parent')
+ child_id = child.parentNode.getAttribute('name') + '-properties'
+ else:
+ self.assert_(child.tagName in self.identifying_attribute,
+ 'Encountered unknown element <%s>' % child.tagName)
+ child_id = child.getAttribute(
+ self.identifying_attribute[child.tagName])
+ self.assert_(child_id not in children)
+ children[child_id] = child
elif child.nodeType in [Node.TEXT_NODE, Node.CDATA_SECTION_NODE]:
if 'detail' not in children:
if (child.nodeType == Node.CDATA_SECTION_NODE or
diff --git a/googletest/xcode/Scripts/versiongenerate.py b/googletest/xcode/Scripts/versiongenerate.py
index 16791d2..bdd7541 100755
--- a/googletest/xcode/Scripts/versiongenerate.py
+++ b/googletest/xcode/Scripts/versiongenerate.py
@@ -29,7 +29,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""A script to prepare version informtion for use the gtest Info.plist file.
+"""A script to prepare version information for use the gtest Info.plist file.
This script extracts the version information from the configure.ac file and
uses it to generate a header file containing the same information. The