build: update gtest to v1.17.0

ignore character-conversion warning in gtest code

Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
This commit is contained in:
Mateusz Jablonski
2025-11-20 15:11:54 +00:00
committed by Compute-Runtime-Automation
parent ad767725c5
commit ebb4f48083
26 changed files with 1075 additions and 666 deletions

View File

@@ -1,2 +1,2 @@
git_url: https://github.com/google/googletest
git_revision: v1.14.0
git_revision: v1.17.0

View File

@@ -130,6 +130,13 @@ namespace testing {
// Expected: Foo() is even
// Actual: it's 5
//
// Returned AssertionResult objects may not be ignored.
// Note: Disabled for SWIG as it doesn't parse attributes correctly.
#if !defined(SWIG)
class [[nodiscard]] AssertionResult;
#endif // !SWIG
class GTEST_API_ AssertionResult {
public:
// Copy constructor.

View File

@@ -293,8 +293,8 @@ class GTEST_API_ KilledBySignal {
// statement is compiled but not executed, to ensure that
// EXPECT_DEATH_IF_SUPPORTED compiles with a certain
// parameter if and only if EXPECT_DEATH compiles with it.
// regex - A regex that a macro such as EXPECT_DEATH would use to test
// the output of statement. This parameter has to be
// regex_or_matcher - A regex that a macro such as EXPECT_DEATH would use
// to test the output of statement. This parameter has to be
// compiled but not evaluated by this macro, to ensure that
// this macro only accepts expressions that a macro such as
// EXPECT_DEATH would accept.
@@ -311,13 +311,13 @@ class GTEST_API_ KilledBySignal {
// statement unconditionally returns or throws. The Message constructor at
// the end allows the syntax of streaming additional messages into the
// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
#define GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, terminator) \
#define GTEST_UNSUPPORTED_DEATH_TEST(statement, regex_or_matcher, terminator) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
GTEST_LOG_(WARNING) << "Death tests are not supported on this platform.\n" \
<< "Statement '" #statement "' cannot be verified."; \
} else if (::testing::internal::AlwaysFalse()) { \
::testing::internal::RE::PartialMatch(".*", (regex)); \
::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
terminator; \
} else \

View File

@@ -67,10 +67,10 @@ namespace testing {
// To implement a matcher Foo for type T, define:
// 1. a class FooMatcherMatcher that implements the matcher interface:
// using is_gtest_matcher = void;
// bool MatchAndExplain(const T&, std::ostream*);
// bool MatchAndExplain(const T&, std::ostream*) const;
// (MatchResultListener* can also be used instead of std::ostream*)
// void DescribeTo(std::ostream*);
// void DescribeNegationTo(std::ostream*);
// void DescribeTo(std::ostream*) const;
// void DescribeNegationTo(std::ostream*) const;
//
// 2. a factory function that creates a Matcher<T> object from a
// FooMatcherMatcher.

View File

@@ -59,7 +59,7 @@
#ifdef GTEST_HAS_ABSL
#include <type_traits>
#include "absl/strings/internal/has_absl_stringify.h"
#include "absl/strings/has_absl_stringify.h"
#include "absl/strings/str_cat.h"
#endif // GTEST_HAS_ABSL
@@ -121,14 +121,14 @@ class GTEST_API_ Message {
// Streams a non-pointer value to this object. If building a version of
// GoogleTest with ABSL, this overload is only enabled if the value does not
// have an AbslStringify definition.
template <typename T
template <
typename T
#ifdef GTEST_HAS_ABSL
,
typename std::enable_if<
!absl::strings_internal::HasAbslStringify<T>::value, // NOLINT
int>::type = 0
,
typename std::enable_if<!absl::HasAbslStringify<T>::value, // NOLINT
int>::type = 0
#endif // GTEST_HAS_ABSL
>
>
inline Message& operator<<(const T& val) {
// Some libraries overload << for STL containers. These
// overloads are defined in the global namespace instead of ::std.
@@ -153,9 +153,8 @@ class GTEST_API_ Message {
// Streams a non-pointer value with an AbslStringify definition to this
// object.
template <typename T,
typename std::enable_if<
absl::strings_internal::HasAbslStringify<T>::value, // NOLINT
int>::type = 0>
typename std::enable_if<absl::HasAbslStringify<T>::value, // NOLINT
int>::type = 0>
inline Message& operator<<(const T& val) {
// ::operator<< is needed here for a similar reason as with the non-Abseil
// version above

View File

@@ -174,11 +174,12 @@ TEST_P(DerivedTest, DoesBlah) {
#endif // 0
#include <functional>
#include <iterator>
#include <utility>
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-param-util.h"
#include "gtest/internal/gtest-param-util.h" // IWYU pragma: export
#include "gtest/internal/gtest-port.h"
namespace testing {
@@ -413,7 +414,8 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
// Synopsis:
// ConvertGenerator<T>(gen)
// - returns a generator producing the same elements as generated by gen, but
// each element is static_cast to type T before being returned
// each T-typed element is static_cast to a type deduced from the interface
// that accepts this generator, and then returned
//
// It is useful when using the Combine() function to get the generated
// parameters in a custom type instead of std::tuple
@@ -441,10 +443,65 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
// Combine(Values("cat", "dog"),
// Values(BLACK, WHITE))));
//
template <typename T>
internal::ParamConverterGenerator<T> ConvertGenerator(
internal::ParamGenerator<T> gen) {
return internal::ParamConverterGenerator<T>(gen);
template <typename RequestedT>
internal::ParamConverterGenerator<RequestedT> ConvertGenerator(
internal::ParamGenerator<RequestedT> gen) {
return internal::ParamConverterGenerator<RequestedT>(std::move(gen));
}
// As above, but takes a callable as a second argument. The callable converts
// the generated parameter to the test fixture's parameter type. This allows you
// to use a parameter type that does not have a converting constructor from the
// generated type.
//
// Example:
//
// This will instantiate tests in test suite AnimalTest each one with
// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
// tuple("dog", BLACK), and tuple("dog", WHITE):
//
// enum Color { BLACK, GRAY, WHITE };
// struct ParamType {
// std::string animal;
// Color color;
// };
// class AnimalTest
// : public testing::TestWithParam<ParamType> {...};
//
// TEST_P(AnimalTest, AnimalLooksNice) {...}
//
// INSTANTIATE_TEST_SUITE_P(
// AnimalVariations, AnimalTest,
// ConvertGenerator(Combine(Values("cat", "dog"), Values(BLACK, WHITE)),
// [](std::tuple<std::string, Color> t) {
// return ParamType{.animal = std::get<0>(t),
// .color = std::get<1>(t)};
// }));
//
template <typename T, int&... ExplicitArgumentBarrier, typename Gen,
typename Func,
typename StdFunction = decltype(std::function(std::declval<Func>()))>
internal::ParamConverterGenerator<T, StdFunction> ConvertGenerator(Gen&& gen,
Func&& f) {
return internal::ParamConverterGenerator<T, StdFunction>(
std::forward<Gen>(gen), std::forward<Func>(f));
}
// As above, but infers the T from the supplied std::function instead of
// having the caller specify it.
template <int&... ExplicitArgumentBarrier, typename Gen, typename Func,
typename StdFunction = decltype(std::function(std::declval<Func>()))>
auto ConvertGenerator(Gen&& gen, Func&& f) {
constexpr bool is_single_arg_std_function =
internal::IsSingleArgStdFunction<StdFunction>::value;
if constexpr (is_single_arg_std_function) {
return ConvertGenerator<
typename internal::FuncSingleParamType<StdFunction>::type>(
std::forward<Gen>(gen), std::forward<Func>(f));
} else {
static_assert(is_single_arg_std_function,
"The call signature must contain a single argument.");
}
}
#define TEST_P(test_suite_name, test_name) \
@@ -469,7 +526,7 @@ internal::ParamConverterGenerator<T> ConvertGenerator(
::testing::internal::CodeLocation(__FILE__, __LINE__)); \
return 0; \
} \
static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \
[[maybe_unused]] static int gtest_registering_dummy_; \
}; \
int GTEST_TEST_CLASS_NAME_(test_suite_name, \
test_name)::gtest_registering_dummy_ = \
@@ -493,39 +550,38 @@ internal::ParamConverterGenerator<T> ConvertGenerator(
#define GTEST_GET_FIRST_(first, ...) first
#define GTEST_GET_SECOND_(first, second, ...) second
#define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...) \
static ::testing::internal::ParamGenerator<test_suite_name::ParamType> \
gtest_##prefix##test_suite_name##_EvalGenerator_() { \
return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_)); \
} \
static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \
const ::testing::TestParamInfo<test_suite_name::ParamType>& info) { \
if (::testing::internal::AlwaysFalse()) { \
::testing::internal::TestNotEmpty(GTEST_EXPAND_(GTEST_GET_SECOND_( \
__VA_ARGS__, \
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
DUMMY_PARAM_))); \
auto t = std::make_tuple(__VA_ARGS__); \
static_assert(std::tuple_size<decltype(t)>::value <= 2, \
"Too Many Args!"); \
} \
return ((GTEST_EXPAND_(GTEST_GET_SECOND_( \
__VA_ARGS__, \
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
DUMMY_PARAM_))))(info); \
} \
static int gtest_##prefix##test_suite_name##_dummy_ \
GTEST_ATTRIBUTE_UNUSED_ = \
::testing::UnitTest::GetInstance() \
->parameterized_test_registry() \
.GetTestSuitePatternHolder<test_suite_name>( \
GTEST_STRINGIFY_(test_suite_name), \
::testing::internal::CodeLocation(__FILE__, __LINE__)) \
->AddTestSuiteInstantiation( \
GTEST_STRINGIFY_(prefix), \
&gtest_##prefix##test_suite_name##_EvalGenerator_, \
&gtest_##prefix##test_suite_name##_EvalGenerateName_, \
__FILE__, __LINE__)
#define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...) \
static ::testing::internal::ParamGenerator<test_suite_name::ParamType> \
gtest_##prefix##test_suite_name##_EvalGenerator_() { \
return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_)); \
} \
static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \
const ::testing::TestParamInfo<test_suite_name::ParamType>& info) { \
if (::testing::internal::AlwaysFalse()) { \
::testing::internal::TestNotEmpty(GTEST_EXPAND_(GTEST_GET_SECOND_( \
__VA_ARGS__, \
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
DUMMY_PARAM_))); \
auto t = std::make_tuple(__VA_ARGS__); \
static_assert(std::tuple_size<decltype(t)>::value <= 2, \
"Too Many Args!"); \
} \
return ((GTEST_EXPAND_(GTEST_GET_SECOND_( \
__VA_ARGS__, \
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
DUMMY_PARAM_))))(info); \
} \
[[maybe_unused]] static int gtest_##prefix##test_suite_name##_dummy_ = \
::testing::UnitTest::GetInstance() \
->parameterized_test_registry() \
.GetTestSuitePatternHolder<test_suite_name>( \
GTEST_STRINGIFY_(test_suite_name), \
::testing::internal::CodeLocation(__FILE__, __LINE__)) \
->AddTestSuiteInstantiation( \
GTEST_STRINGIFY_(prefix), \
&gtest_##prefix##test_suite_name##_EvalGenerator_, \
&gtest_##prefix##test_suite_name##_EvalGenerateName_, __FILE__, \
__LINE__)
// Allow Marking a Parameterized test class as not needing to be instantiated.
#define GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(T) \

View File

@@ -116,12 +116,20 @@
#include <vector>
#ifdef GTEST_HAS_ABSL
#include "absl/strings/internal/has_absl_stringify.h"
#include "absl/strings/has_absl_stringify.h"
#include "absl/strings/str_cat.h"
#endif // GTEST_HAS_ABSL
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
#if GTEST_INTERNAL_HAS_STD_SPAN
#include <span> // NOLINT
#endif // GTEST_INTERNAL_HAS_STD_SPAN
#if GTEST_INTERNAL_HAS_COMPARE_LIB
#include <compare> // NOLINT
#endif // GTEST_INTERNAL_HAS_COMPARE_LIB
namespace testing {
// Definitions in the internal* namespaces are subject to change without notice.
@@ -131,13 +139,32 @@ namespace internal {
template <typename T>
void UniversalPrint(const T& value, ::std::ostream* os);
template <typename T>
struct IsStdSpan {
static constexpr bool value = false;
};
#if GTEST_INTERNAL_HAS_STD_SPAN
template <typename E>
struct IsStdSpan<std::span<E>> {
static constexpr bool value = true;
};
#endif // GTEST_INTERNAL_HAS_STD_SPAN
// Used to print an STL-style container when the user doesn't define
// a PrintTo() for it.
//
// NOTE: Since std::span does not have const_iterator until C++23, it would
// fail IsContainerTest before C++23. However, IsContainerTest only uses
// the presence of const_iterator to avoid treating iterators as containers
// because of iterator::iterator. Which means std::span satisfies the *intended*
// condition of IsContainerTest.
struct ContainerPrinter {
template <typename T,
typename = typename std::enable_if<
(sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
!IsRecursiveContainer<T>::value>::type>
((sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
!IsRecursiveContainer<T>::value) ||
IsStdSpan<T>::value>::type>
static void PrintValue(const T& container, std::ostream* os) {
const size_t kMaxCount = 32; // The maximum number of elements to print.
*os << '{';
@@ -218,8 +245,8 @@ struct StreamPrinter {
// ADL (possibly involving implicit conversions).
// (Use SFINAE via return type, because it seems GCC < 12 doesn't handle name
// lookup properly when we do it in the template parameter list.)
static auto PrintValue(const T& value, ::std::ostream* os)
-> decltype((void)(*os << value)) {
static auto PrintValue(const T& value,
::std::ostream* os) -> decltype((void)(*os << value)) {
// Call streaming operator found by ADL, possibly with implicit conversions
// of the arguments.
*os << value;
@@ -269,10 +296,9 @@ struct ConvertibleToStringViewPrinter {
#ifdef GTEST_HAS_ABSL
struct ConvertibleToAbslStringifyPrinter {
template <
typename T,
typename = typename std::enable_if<
absl::strings_internal::HasAbslStringify<T>::value>::type> // NOLINT
template <typename T,
typename = typename std::enable_if<
absl::HasAbslStringify<T>::value>::type> // NOLINT
static void PrintValue(const T& value, ::std::ostream* os) {
*os << absl::StrCat(value);
}
@@ -498,9 +524,16 @@ inline void PrintTo(char16_t c, ::std::ostream* os) {
PrintTo(ImplicitCast_<char32_t>(c), os);
}
#ifdef __cpp_lib_char8_t
#if defined(__clang__) && __clang_major__ >= 21
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wcharacter-conversion"
#endif
inline void PrintTo(char8_t c, ::std::ostream* os) {
PrintTo(ImplicitCast_<char32_t>(c), os);
}
#if defined(__clang__) && __clang_major__ >= 21
#pragma clang diagnostic pop
#endif
#endif
// gcc/clang __{u,}int128_t
@@ -530,49 +563,63 @@ int AppropriateResolution(FloatType val) {
int full = std::numeric_limits<FloatType>::max_digits10;
if (val < 0) val = -val;
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
if (val < 1000000) {
FloatType mulfor6 = 1e10;
if (val >= 100000.0) { // 100,000 to 999,999
// Without these static casts, the template instantiation for float would
// fail to compile when -Wdouble-promotion is enabled, as the arithmetic and
// comparison logic would promote floats to doubles.
if (val >= static_cast<FloatType>(100000.0)) { // 100,000 to 999,999
mulfor6 = 1.0;
} else if (val >= 10000.0) {
} else if (val >= static_cast<FloatType>(10000.0)) {
mulfor6 = 1e1;
} else if (val >= 1000.0) {
} else if (val >= static_cast<FloatType>(1000.0)) {
mulfor6 = 1e2;
} else if (val >= 100.0) {
} else if (val >= static_cast<FloatType>(100.0)) {
mulfor6 = 1e3;
} else if (val >= 10.0) {
} else if (val >= static_cast<FloatType>(10.0)) {
mulfor6 = 1e4;
} else if (val >= 1.0) {
} else if (val >= static_cast<FloatType>(1.0)) {
mulfor6 = 1e5;
} else if (val >= 0.1) {
} else if (val >= static_cast<FloatType>(0.1)) {
mulfor6 = 1e6;
} else if (val >= 0.01) {
} else if (val >= static_cast<FloatType>(0.01)) {
mulfor6 = 1e7;
} else if (val >= 0.001) {
} else if (val >= static_cast<FloatType>(0.001)) {
mulfor6 = 1e8;
} else if (val >= 0.0001) {
} else if (val >= static_cast<FloatType>(0.0001)) {
mulfor6 = 1e9;
}
if (static_cast<FloatType>(static_cast<int32_t>(val * mulfor6 + 0.5)) /
if (static_cast<FloatType>(static_cast<int32_t>(
val * mulfor6 + (static_cast<FloatType>(0.5)))) /
mulfor6 ==
val)
return 6;
} else if (val < 1e10) {
FloatType divfor6 = 1.0;
if (val >= 1e9) { // 1,000,000,000 to 9,999,999,999
} else if (val < static_cast<FloatType>(1e10)) {
FloatType divfor6 = static_cast<FloatType>(1.0);
if (val >= static_cast<FloatType>(1e9)) { // 1,000,000,000 to 9,999,999,999
divfor6 = 10000;
} else if (val >= 1e8) { // 100,000,000 to 999,999,999
} else if (val >=
static_cast<FloatType>(1e8)) { // 100,000,000 to 999,999,999
divfor6 = 1000;
} else if (val >= 1e7) { // 10,000,000 to 99,999,999
} else if (val >=
static_cast<FloatType>(1e7)) { // 10,000,000 to 99,999,999
divfor6 = 100;
} else if (val >= 1e6) { // 1,000,000 to 9,999,999
} else if (val >= static_cast<FloatType>(1e6)) { // 1,000,000 to 9,999,999
divfor6 = 10;
}
if (static_cast<FloatType>(static_cast<int32_t>(val / divfor6 + 0.5)) *
if (static_cast<FloatType>(static_cast<int32_t>(
val / divfor6 + (static_cast<FloatType>(0.5)))) *
divfor6 ==
val)
return 6;
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
return full;
}
@@ -746,6 +793,41 @@ void PrintTo(const std::shared_ptr<T>& ptr, std::ostream* os) {
(PrintSmartPointer<T>)(ptr, os, 0);
}
#if GTEST_INTERNAL_HAS_COMPARE_LIB
template <typename T>
void PrintOrderingHelper(T ordering, std::ostream* os) {
if (ordering == T::less) {
*os << "(less)";
} else if (ordering == T::greater) {
*os << "(greater)";
} else if (ordering == T::equivalent) {
*os << "(equivalent)";
} else {
*os << "(unknown ordering)";
}
}
inline void PrintTo(std::strong_ordering ordering, std::ostream* os) {
if (ordering == std::strong_ordering::equal) {
*os << "(equal)";
} else {
PrintOrderingHelper(ordering, os);
}
}
inline void PrintTo(std::partial_ordering ordering, std::ostream* os) {
if (ordering == std::partial_ordering::unordered) {
*os << "(unordered)";
} else {
PrintOrderingHelper(ordering, os);
}
}
inline void PrintTo(std::weak_ordering ordering, std::ostream* os) {
PrintOrderingHelper(ordering, os);
}
#endif
// Helper function for printing a tuple. T must be instantiated with
// a tuple type.
template <typename T>

View File

@@ -205,8 +205,8 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
typedef gtest_TypeParam_ TypeParam; \
void TestBody() override; \
}; \
static bool gtest_##CaseName##_##TestName##_registered_ \
GTEST_ATTRIBUTE_UNUSED_ = ::testing::internal::TypeParameterizedTest< \
[[maybe_unused]] static bool gtest_##CaseName##_##TestName##_registered_ = \
::testing::internal::TypeParameterizedTest< \
CaseName, \
::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_(CaseName, \
TestName)>, \
@@ -267,22 +267,22 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
TYPED_TEST_SUITE_P
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
#define TYPED_TEST_P(SuiteName, TestName) \
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
template <typename gtest_TypeParam_> \
class TestName : public SuiteName<gtest_TypeParam_> { \
private: \
typedef SuiteName<gtest_TypeParam_> TestFixture; \
typedef gtest_TypeParam_ TypeParam; \
void TestBody() override; \
}; \
static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \
__FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \
GTEST_STRINGIFY_(TestName)); \
} \
template <typename gtest_TypeParam_> \
void GTEST_SUITE_NAMESPACE_( \
#define TYPED_TEST_P(SuiteName, TestName) \
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
template <typename gtest_TypeParam_> \
class TestName : public SuiteName<gtest_TypeParam_> { \
private: \
typedef SuiteName<gtest_TypeParam_> TestFixture; \
typedef gtest_TypeParam_ TypeParam; \
void TestBody() override; \
}; \
[[maybe_unused]] static bool gtest_##TestName##_defined_ = \
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \
__FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \
GTEST_STRINGIFY_(TestName)); \
} \
template <typename gtest_TypeParam_> \
void GTEST_SUITE_NAMESPACE_( \
SuiteName)::TestName<gtest_TypeParam_>::TestBody()
// Note: this won't work correctly if the trailing arguments are macros.
@@ -290,8 +290,8 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
typedef ::testing::internal::Templates<__VA_ARGS__> gtest_AllTests_; \
} \
static const char* const GTEST_REGISTERED_TEST_NAMES_( \
SuiteName) GTEST_ATTRIBUTE_UNUSED_ = \
[[maybe_unused]] static const char* const GTEST_REGISTERED_TEST_NAMES_( \
SuiteName) = \
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \
GTEST_STRINGIFY_(SuiteName), __FILE__, __LINE__, #__VA_ARGS__)
@@ -306,7 +306,7 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \
static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \
"test-suit-prefix must not be empty"); \
static bool gtest_##Prefix##_##SuiteName GTEST_ATTRIBUTE_UNUSED_ = \
[[maybe_unused]] static bool gtest_##Prefix##_##SuiteName = \
::testing::internal::TypeParameterizedTestSuite< \
SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \
::testing::internal::GenerateTypeList<Types>::type>:: \

View File

@@ -51,7 +51,6 @@
#include <cstddef>
#include <cstdint>
#include <iomanip>
#include <limits>
#include <memory>
#include <ostream>
@@ -61,16 +60,16 @@
#include <type_traits>
#include <vector>
#include "gtest/gtest-assertion-result.h"
#include "gtest/gtest-death-test.h"
#include "gtest/gtest-matchers.h"
#include "gtest/gtest-message.h"
#include "gtest/gtest-param-test.h"
#include "gtest/gtest-printers.h"
#include "gtest/gtest-test-part.h"
#include "gtest/gtest-typed-test.h"
#include "gtest/gtest_pred_impl.h"
#include "gtest/gtest_prod.h"
#include "gtest/gtest-assertion-result.h" // IWYU pragma: export
#include "gtest/gtest-death-test.h" // IWYU pragma: export
#include "gtest/gtest-matchers.h" // IWYU pragma: export
#include "gtest/gtest-message.h" // IWYU pragma: export
#include "gtest/gtest-param-test.h" // IWYU pragma: export
#include "gtest/gtest-printers.h" // IWYU pragma: export
#include "gtest/gtest-test-part.h" // IWYU pragma: export
#include "gtest/gtest-typed-test.h" // IWYU pragma: export
#include "gtest/gtest_pred_impl.h" // IWYU pragma: export
#include "gtest/gtest_prod.h" // IWYU pragma: export
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-string.h"
@@ -608,7 +607,7 @@ class GTEST_API_ TestInfo {
friend class internal::UnitTestImpl;
friend class internal::StreamingListenerTest;
friend TestInfo* internal::MakeAndRegisterTestInfo(
const char* test_suite_name, const char* name, const char* type_param,
std::string test_suite_name, const char* name, const char* type_param,
const char* value_param, internal::CodeLocation code_location,
internal::TypeId fixture_class_id, internal::SetUpTestSuiteFunc set_up_tc,
internal::TearDownTestSuiteFunc tear_down_tc,
@@ -616,7 +615,7 @@ class GTEST_API_ TestInfo {
// Constructs a TestInfo object. The newly constructed instance assumes
// ownership of the factory object.
TestInfo(const std::string& test_suite_name, const std::string& name,
TestInfo(std::string test_suite_name, std::string name,
const char* a_type_param, // NULL if not a type-parameterized test
const char* a_value_param, // NULL if not a value-parameterized test
internal::CodeLocation a_code_location,
@@ -684,7 +683,7 @@ class GTEST_API_ TestSuite {
// this is not a type-parameterized test.
// set_up_tc: pointer to the function that sets up the test suite
// tear_down_tc: pointer to the function that tears down the test suite
TestSuite(const char* name, const char* a_type_param,
TestSuite(const std::string& name, const char* a_type_param,
internal::SetUpTestSuiteFunc set_up_tc,
internal::TearDownTestSuiteFunc tear_down_tc);
@@ -1124,7 +1123,7 @@ class GTEST_API_ UnitTest {
// This method can only be called from the main thread.
//
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
int Run() GTEST_MUST_USE_RESULT_;
[[nodiscard]] int Run();
// Returns the working directory when the first TEST() or TEST_F()
// was executed. The UnitTest object owns the string.
@@ -1263,6 +1262,20 @@ class GTEST_API_ UnitTest {
// total_test_suite_count() - 1. If i is not in that range, returns NULL.
TestSuite* GetMutableTestSuite(int i);
// Invokes OsStackTrackGetterInterface::UponLeavingGTest. UponLeavingGTest()
// should be called immediately before Google Test calls user code. It saves
// some information about the current stack that CurrentStackTrace() will use
// to find and hide Google Test stack frames.
void UponLeavingGTest();
// Sets the TestSuite object for the test that's currently running.
void set_current_test_suite(TestSuite* a_current_test_suite)
GTEST_LOCK_EXCLUDED_(mutex_);
// Sets the TestInfo object for the test that's currently running.
void set_current_test_info(TestInfo* a_current_test_info)
GTEST_LOCK_EXCLUDED_(mutex_);
// Accessors for the implementation object.
internal::UnitTestImpl* impl() { return impl_; }
const internal::UnitTestImpl* impl() const { return impl_; }
@@ -1271,6 +1284,8 @@ class GTEST_API_ UnitTest {
// members of UnitTest.
friend class ScopedTrace;
friend class Test;
friend class TestInfo;
friend class TestSuite;
friend class internal::AssertHelper;
friend class internal::StreamingListenerTest;
friend class internal::UnitTestRecordPropertyTestHelper;
@@ -1574,12 +1589,12 @@ AssertionResult CmpHelperFloatingPointEQ(const char* lhs_expression,
}
::std::stringstream lhs_ss;
lhs_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
<< lhs_value;
lhs_ss.precision(std::numeric_limits<RawType>::digits10 + 2);
lhs_ss << lhs_value;
::std::stringstream rhs_ss;
rhs_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
<< rhs_value;
rhs_ss.precision(std::numeric_limits<RawType>::digits10 + 2);
rhs_ss << rhs_value;
return EqFailure(lhs_expression, rhs_expression,
StringStreamToString(&lhs_ss), StringStreamToString(&rhs_ss),
@@ -1752,6 +1767,7 @@ class TestWithParam : public Test, public WithParamInterface<T> {};
// generic name and clashes with some other libraries.
#if !(defined(GTEST_DONT_DEFINE_FAIL) && GTEST_DONT_DEFINE_FAIL)
#define FAIL() GTEST_FAIL()
#define FAIL_AT(file, line) GTEST_FAIL_AT(file, line)
#endif
// Generates a success with a generic message.
@@ -2308,11 +2324,12 @@ TestInfo* RegisterTest(const char* test_suite_name, const char* test_name,
// tests are successful, or 1 otherwise.
//
// RUN_ALL_TESTS() should be invoked after the command line has been
// parsed by InitGoogleTest().
// parsed by InitGoogleTest(). RUN_ALL_TESTS will tear down and delete any
// installed environments and should only be called once per binary.
//
// This function was formerly a macro; thus, it is in the global
// namespace and has an all-caps name.
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_;
[[nodiscard]] int RUN_ALL_TESTS();
inline int RUN_ALL_TESTS() { return ::testing::UnitTest::GetInstance()->Run(); }

View File

@@ -46,17 +46,38 @@
#include "gtest/gtest-matchers.h"
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
GTEST_DECLARE_string_(internal_run_death_test);
namespace testing {
namespace internal {
// Names of the flags (needed for parsing Google Test flags).
const char kDeathTestStyleFlag[] = "death_test_style";
const char kDeathTestUseFork[] = "death_test_use_fork";
// Name of the flag (needed for parsing Google Test flag).
const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
// A string passed to EXPECT_DEATH (etc.) is caught by one of these overloads
// and interpreted as a regex (rather than an Eq matcher) for legacy
// compatibility.
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
::testing::internal::RE regex) {
return ContainsRegex(regex.pattern());
}
inline Matcher<const ::std::string&> MakeDeathTestMatcher(const char* regex) {
return ContainsRegex(regex);
}
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
const ::std::string& regex) {
return ContainsRegex(regex);
}
// If a Matcher<const ::std::string&> is passed to EXPECT_DEATH (etc.), it's
// used directly.
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
Matcher<const ::std::string&> matcher) {
return matcher;
}
#ifdef GTEST_HAS_DEATH_TEST
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
@@ -73,7 +94,7 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
//
// exit status: The integer exit information in the format specified
// by wait(2)
// exit code: The integer code passed to exit(3), _exit(2), or
// exit code: The integer code passed to exit(3), _Exit(2), or
// returned from main()
class GTEST_API_ DeathTest {
public:
@@ -170,28 +191,6 @@ class DefaultDeathTestFactory : public DeathTestFactory {
// by a signal, or exited normally with a nonzero exit code.
GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
// A string passed to EXPECT_DEATH (etc.) is caught by one of these overloads
// and interpreted as a regex (rather than an Eq matcher) for legacy
// compatibility.
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
::testing::internal::RE regex) {
return ContainsRegex(regex.pattern());
}
inline Matcher<const ::std::string&> MakeDeathTestMatcher(const char* regex) {
return ContainsRegex(regex);
}
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
const ::std::string& regex) {
return ContainsRegex(regex);
}
// If a Matcher<const ::std::string&> is passed to EXPECT_DEATH (etc.), it's
// used directly.
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
Matcher<const ::std::string&> matcher) {
return matcher;
}
// Traps C++ exceptions escaping statement and reports them as test
// failures. Note that trapping SEH exceptions is not implemented here.
#if GTEST_HAS_EXCEPTIONS

View File

@@ -43,6 +43,7 @@
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
#include <string>
#include <utility>
#include "gtest/internal/gtest-port.h"
#include "gtest/internal/gtest-string.h"
@@ -70,8 +71,9 @@ class GTEST_API_ FilePath {
public:
FilePath() : pathname_("") {}
FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) {}
FilePath(FilePath&& rhs) noexcept : pathname_(std::move(rhs.pathname_)) {}
explicit FilePath(const std::string& pathname) : pathname_(pathname) {
explicit FilePath(std::string pathname) : pathname_(std::move(pathname)) {
Normalize();
}
@@ -79,6 +81,10 @@ class GTEST_API_ FilePath {
Set(rhs);
return *this;
}
FilePath& operator=(FilePath&& rhs) noexcept {
pathname_ = std::move(rhs.pathname_);
return *this;
}
void Set(const FilePath& rhs) { pathname_ = rhs.pathname_; }

View File

@@ -58,7 +58,6 @@
#include <cstdint>
#include <functional>
#include <iomanip>
#include <limits>
#include <map>
#include <set>
@@ -79,7 +78,7 @@
//
// will result in the token foo__LINE__, instead of foo followed by
// the current line number. For more details, see
// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6
// https://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6
#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar)
#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo##bar
@@ -170,7 +169,7 @@ namespace edit_distance {
// All edits cost the same, with replace having lower priority than
// add/remove.
// Simple implementation of the Wagner-Fischer algorithm.
// See http://en.wikipedia.org/wiki/Wagner-Fischer_algorithm
// See https://en.wikipedia.org/wiki/Wagner-Fischer_algorithm
enum EditType { kMatch, kAdd, kRemove, kReplace };
GTEST_API_ std::vector<EditType> CalculateOptimalEdits(
const std::vector<size_t>& left, const std::vector<size_t>& right);
@@ -237,7 +236,7 @@ GTEST_API_ std::string GetBoolAssertionFailureMessage(
// For double, there are 11 exponent bits and 52 fraction bits.
//
// More details can be found at
// http://en.wikipedia.org/wiki/IEEE_floating-point_standard.
// https://en.wikipedia.org/wiki/IEEE_floating-point_standard.
//
// Template parameter:
//
@@ -282,7 +281,7 @@ class FloatingPoint {
// bits. Therefore, 4 should be enough for ordinary use.
//
// See the following article for more details on ULP:
// http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
// https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
static const uint32_t kMaxUlps = 4;
// Constructs a FloatingPoint from a raw floating-point number.
@@ -291,17 +290,17 @@ class FloatingPoint {
// around may change its bits, although the new value is guaranteed
// to be also a NAN. Therefore, don't expect this constructor to
// preserve the bits in x when x is a NAN.
explicit FloatingPoint(const RawType& x) { u_.value_ = x; }
explicit FloatingPoint(RawType x) { memcpy(&bits_, &x, sizeof(x)); }
// Static methods
// Reinterprets a bit pattern as a floating-point number.
//
// This function is needed to test the AlmostEquals() method.
static RawType ReinterpretBits(const Bits bits) {
FloatingPoint fp(0);
fp.u_.bits_ = bits;
return fp.u_.value_;
static RawType ReinterpretBits(Bits bits) {
RawType fp;
memcpy(&fp, &bits, sizeof(fp));
return fp;
}
// Returns the floating-point number that represent positive infinity.
@@ -310,16 +309,16 @@ class FloatingPoint {
// Non-static methods
// Returns the bits that represents this number.
const Bits& bits() const { return u_.bits_; }
const Bits& bits() const { return bits_; }
// Returns the exponent bits of this number.
Bits exponent_bits() const { return kExponentBitMask & u_.bits_; }
Bits exponent_bits() const { return kExponentBitMask & bits_; }
// Returns the fraction bits of this number.
Bits fraction_bits() const { return kFractionBitMask & u_.bits_; }
Bits fraction_bits() const { return kFractionBitMask & bits_; }
// Returns the sign bit of this number.
Bits sign_bit() const { return kSignBitMask & u_.bits_; }
Bits sign_bit() const { return kSignBitMask & bits_; }
// Returns true if and only if this is NAN (not a number).
bool is_nan() const {
@@ -333,23 +332,16 @@ class FloatingPoint {
//
// - returns false if either number is (or both are) NAN.
// - treats really large numbers as almost equal to infinity.
// - thinks +0.0 and -0.0 are 0 DLP's apart.
// - thinks +0.0 and -0.0 are 0 ULP's apart.
bool AlmostEquals(const FloatingPoint& rhs) const {
// The IEEE standard says that any comparison operation involving
// a NAN must return false.
if (is_nan() || rhs.is_nan()) return false;
return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) <=
kMaxUlps;
return DistanceBetweenSignAndMagnitudeNumbers(bits_, rhs.bits_) <= kMaxUlps;
}
private:
// The data type used to store the actual floating-point number.
union FloatingPointUnion {
RawType value_; // The raw floating-point number.
Bits bits_; // The bits that represent the number.
};
// Converts an integer from the sign-and-magnitude representation to
// the biased representation. More precisely, let N be 2 to the
// power of (kBitCount - 1), an integer x is represented by the
@@ -363,9 +355,9 @@ class FloatingPoint {
// N - 1 (the biggest number representable using
// sign-and-magnitude) is represented by 2N - 1.
//
// Read http://en.wikipedia.org/wiki/Signed_number_representations
// Read https://en.wikipedia.org/wiki/Signed_number_representations
// for more details on signed number representations.
static Bits SignAndMagnitudeToBiased(const Bits& sam) {
static Bits SignAndMagnitudeToBiased(Bits sam) {
if (kSignBitMask & sam) {
// sam represents a negative number.
return ~sam + 1;
@@ -377,14 +369,13 @@ class FloatingPoint {
// Given two numbers in the sign-and-magnitude representation,
// returns the distance between them as an unsigned number.
static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits& sam1,
const Bits& sam2) {
static Bits DistanceBetweenSignAndMagnitudeNumbers(Bits sam1, Bits sam2) {
const Bits biased1 = SignAndMagnitudeToBiased(sam1);
const Bits biased2 = SignAndMagnitudeToBiased(sam2);
return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
}
FloatingPointUnion u_;
Bits bits_; // The bits that represent the number.
};
// Typedefs the instances of the FloatingPoint template class that we
@@ -475,8 +466,8 @@ using SetUpTestSuiteFunc = void (*)();
using TearDownTestSuiteFunc = void (*)();
struct CodeLocation {
CodeLocation(const std::string& a_file, int a_line)
: file(a_file), line(a_line) {}
CodeLocation(std::string a_file, int a_line)
: file(std::move(a_file)), line(a_line) {}
std::string file;
int line;
@@ -556,7 +547,7 @@ struct SuiteApiResolver : T {
// type_param: the name of the test's type parameter, or NULL if
// this is not a typed or a type-parameterized test.
// value_param: text representation of the test's value parameter,
// or NULL if this is not a type-parameterized test.
// or NULL if this is not a value-parameterized test.
// code_location: code location where the test is defined
// fixture_class_id: ID of the test fixture class
// set_up_tc: pointer to the function that sets up the test suite
@@ -565,7 +556,7 @@ struct SuiteApiResolver : T {
// The newly created TestInfo instance will assume
// ownership of the factory object.
GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
const char* test_suite_name, const char* name, const char* type_param,
std::string test_suite_name, const char* name, const char* type_param,
const char* value_param, CodeLocation code_location,
TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc,
TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory);
@@ -596,8 +587,7 @@ class GTEST_API_ TypedTestSuitePState {
fflush(stderr);
posix::Abort();
}
registered_tests_.insert(
::std::make_pair(test_name, CodeLocation(file, line)));
registered_tests_.emplace(test_name, CodeLocation(file, line));
return true;
}
@@ -701,7 +691,7 @@ class TypeParameterizedTest {
// specified in INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, TestSuite,
// Types). Valid values for 'index' are [0, N - 1] where N is the
// length of Types.
static bool Register(const char* prefix, const CodeLocation& code_location,
static bool Register(const char* prefix, CodeLocation code_location,
const char* case_name, const char* test_names, int index,
const std::vector<std::string>& type_names =
GenerateNames<DefaultNameGenerator, Types>()) {
@@ -713,8 +703,7 @@ class TypeParameterizedTest {
// list.
MakeAndRegisterTestInfo(
(std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name +
"/" + type_names[static_cast<size_t>(index)])
.c_str(),
"/" + type_names[static_cast<size_t>(index)]),
StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(),
GetTypeName<Type>().c_str(),
nullptr, // No value parameter.
@@ -726,13 +715,9 @@ class TypeParameterizedTest {
new TestFactoryImpl<TestClass>);
// Next, recurses (at compile time) with the tail of the type list.
return TypeParameterizedTest<Fixture, TestSel,
typename Types::Tail>::Register(prefix,
code_location,
case_name,
test_names,
index + 1,
type_names);
return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail>::
Register(prefix, std::move(code_location), case_name, test_names,
index + 1, type_names);
}
};
@@ -740,7 +725,7 @@ class TypeParameterizedTest {
template <GTEST_TEMPLATE_ Fixture, class TestSel>
class TypeParameterizedTest<Fixture, TestSel, internal::None> {
public:
static bool Register(const char* /*prefix*/, const CodeLocation&,
static bool Register(const char* /*prefix*/, CodeLocation,
const char* /*case_name*/, const char* /*test_names*/,
int /*index*/,
const std::vector<std::string>& =
@@ -787,7 +772,8 @@ class TypeParameterizedTestSuite {
// Next, recurses (at compile time) with the tail of the test list.
return TypeParameterizedTestSuite<Fixture, typename Tests::Tail,
Types>::Register(prefix, code_location,
Types>::Register(prefix,
std::move(code_location),
state, case_name,
SkipComma(test_names),
type_names);
@@ -900,11 +886,6 @@ class HasDebugStringAndShortDebugString {
HasDebugStringType::value && HasShortDebugStringType::value;
};
#ifdef GTEST_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
template <typename T>
constexpr bool HasDebugStringAndShortDebugString<T>::value;
#endif
// When the compiler sees expression IsContainerTest<C>(0), if C is an
// STL-style container class, the first overload of IsContainerTest
// will be viable (since both C::iterator* and C::const_iterator* are
@@ -1143,40 +1124,6 @@ class NativeArray {
void (NativeArray::*clone_)(const Element*, size_t);
};
// Backport of std::index_sequence.
template <size_t... Is>
struct IndexSequence {
using type = IndexSequence;
};
// Double the IndexSequence, and one if plus_one is true.
template <bool plus_one, typename T, size_t sizeofT>
struct DoubleSequence;
template <size_t... I, size_t sizeofT>
struct DoubleSequence<true, IndexSequence<I...>, sizeofT> {
using type = IndexSequence<I..., (sizeofT + I)..., 2 * sizeofT>;
};
template <size_t... I, size_t sizeofT>
struct DoubleSequence<false, IndexSequence<I...>, sizeofT> {
using type = IndexSequence<I..., (sizeofT + I)...>;
};
// Backport of std::make_index_sequence.
// It uses O(ln(N)) instantiation depth.
template <size_t N>
struct MakeIndexSequenceImpl
: DoubleSequence<N % 2 == 1, typename MakeIndexSequenceImpl<N / 2>::type,
N / 2>::type {};
template <>
struct MakeIndexSequenceImpl<0> : IndexSequence<> {};
template <size_t N>
using MakeIndexSequence = typename MakeIndexSequenceImpl<N>::type;
template <typename... T>
using IndexSequenceFor = typename MakeIndexSequence<sizeof...(T)>::type;
template <size_t>
struct Ignore {
Ignore(...); // NOLINT
@@ -1185,7 +1132,7 @@ struct Ignore {
template <typename>
struct ElemFromListImpl;
template <size_t... I>
struct ElemFromListImpl<IndexSequence<I...>> {
struct ElemFromListImpl<std::index_sequence<I...>> {
// We make Ignore a template to solve a problem with MSVC.
// A non-template Ignore would work fine with `decltype(Ignore(I))...`, but
// MSVC doesn't understand how to deal with that pack expansion.
@@ -1196,9 +1143,8 @@ struct ElemFromListImpl<IndexSequence<I...>> {
template <size_t N, typename... T>
struct ElemFromList {
using type =
decltype(ElemFromListImpl<typename MakeIndexSequence<N>::type>::Apply(
static_cast<T (*)()>(nullptr)...));
using type = decltype(ElemFromListImpl<std::make_index_sequence<N>>::Apply(
static_cast<T (*)()>(nullptr)...));
};
struct FlatTupleConstructTag {};
@@ -1223,9 +1169,9 @@ template <typename Derived, typename Idx>
struct FlatTupleBase;
template <size_t... Idx, typename... T>
struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>>
struct FlatTupleBase<FlatTuple<T...>, std::index_sequence<Idx...>>
: FlatTupleElemBase<FlatTuple<T...>, Idx>... {
using Indices = IndexSequence<Idx...>;
using Indices = std::index_sequence<Idx...>;
FlatTupleBase() = default;
template <typename... Args>
explicit FlatTupleBase(FlatTupleConstructTag, Args&&... args)
@@ -1260,14 +1206,15 @@ struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>>
// implementations.
// FlatTuple and ElemFromList are not recursive and have a fixed depth
// regardless of T...
// MakeIndexSequence, on the other hand, it is recursive but with an
// std::make_index_sequence, on the other hand, it is recursive but with an
// instantiation depth of O(ln(N)).
template <typename... T>
class FlatTuple
: private FlatTupleBase<FlatTuple<T...>,
typename MakeIndexSequence<sizeof...(T)>::type> {
using Indices = typename FlatTupleBase<
FlatTuple<T...>, typename MakeIndexSequence<sizeof...(T)>::type>::Indices;
std::make_index_sequence<sizeof...(T)>> {
using Indices =
typename FlatTupleBase<FlatTuple<T...>,
std::make_index_sequence<sizeof...(T)>>::Indices;
public:
FlatTuple() = default;
@@ -1281,30 +1228,40 @@ class FlatTuple
// Utility functions to be called with static_assert to induce deprecation
// warnings.
GTEST_INTERNAL_DEPRECATED(
[[deprecated(
"INSTANTIATE_TEST_CASE_P is deprecated, please use "
"INSTANTIATE_TEST_SUITE_P")
constexpr bool InstantiateTestCase_P_IsDeprecated() { return true; }
"INSTANTIATE_TEST_SUITE_P")]]
constexpr bool InstantiateTestCase_P_IsDeprecated() {
return true;
}
GTEST_INTERNAL_DEPRECATED(
[[deprecated(
"TYPED_TEST_CASE_P is deprecated, please use "
"TYPED_TEST_SUITE_P")
constexpr bool TypedTestCase_P_IsDeprecated() { return true; }
"TYPED_TEST_SUITE_P")]]
constexpr bool TypedTestCase_P_IsDeprecated() {
return true;
}
GTEST_INTERNAL_DEPRECATED(
[[deprecated(
"TYPED_TEST_CASE is deprecated, please use "
"TYPED_TEST_SUITE")
constexpr bool TypedTestCaseIsDeprecated() { return true; }
"TYPED_TEST_SUITE")]]
constexpr bool TypedTestCaseIsDeprecated() {
return true;
}
GTEST_INTERNAL_DEPRECATED(
[[deprecated(
"REGISTER_TYPED_TEST_CASE_P is deprecated, please use "
"REGISTER_TYPED_TEST_SUITE_P")
constexpr bool RegisterTypedTestCase_P_IsDeprecated() { return true; }
"REGISTER_TYPED_TEST_SUITE_P")]]
constexpr bool RegisterTypedTestCase_P_IsDeprecated() {
return true;
}
GTEST_INTERNAL_DEPRECATED(
[[deprecated(
"INSTANTIATE_TYPED_TEST_CASE_P is deprecated, please use "
"INSTANTIATE_TYPED_TEST_SUITE_P")
constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; }
"INSTANTIATE_TYPED_TEST_SUITE_P")]]
constexpr bool InstantiateTypedTestCase_P_IsDeprecated() {
return true;
}
} // namespace internal
} // namespace testing
@@ -1541,7 +1498,7 @@ class NeverThrown {
\
private: \
void TestBody() override; \
static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_; \
[[maybe_unused]] static ::testing::TestInfo* const test_info_; \
}; \
\
::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \

View File

@@ -39,6 +39,7 @@
#include <ctype.h>
#include <cassert>
#include <functional>
#include <iterator>
#include <map>
#include <memory>
@@ -47,6 +48,7 @@
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>
@@ -85,7 +87,7 @@ namespace internal {
// TEST_P macro is used to define two tests with the same name
// but in different namespaces.
GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name,
CodeLocation code_location);
const CodeLocation& code_location);
template <typename>
class ParamGeneratorInterface;
@@ -379,9 +381,7 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
// integer test parameter index.
template <class ParamType>
std::string DefaultParamName(const TestParamInfo<ParamType>& info) {
Message name_stream;
name_stream << info.index;
return name_stream.GetString();
return std::to_string(info.index);
}
template <typename T = int>
@@ -513,9 +513,10 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
using ParamNameGeneratorFunc = std::string(const TestParamInfo<ParamType>&);
explicit ParameterizedTestSuiteInfo(const char* name,
explicit ParameterizedTestSuiteInfo(std::string name,
CodeLocation code_location)
: test_suite_name_(name), code_location_(code_location) {}
: test_suite_name_(std::move(name)),
code_location_(std::move(code_location)) {}
// Test suite base name for display purposes.
const std::string& GetTestSuiteName() const override {
@@ -529,20 +530,20 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
// prefix). test_base_name is the name of an individual test without
// parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
// test suite base name and DoBar is test base name.
void AddTestPattern(const char* test_suite_name, const char* test_base_name,
void AddTestPattern(const char*, const char* test_base_name,
TestMetaFactoryBase<ParamType>* meta_factory,
CodeLocation code_location) {
tests_.push_back(std::shared_ptr<TestInfo>(new TestInfo(
test_suite_name, test_base_name, meta_factory, code_location)));
tests_.emplace_back(
new TestInfo(test_base_name, meta_factory, std::move(code_location)));
}
// INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information
// about a generator.
int AddTestSuiteInstantiation(const std::string& instantiation_name,
int AddTestSuiteInstantiation(std::string instantiation_name,
GeneratorCreationFunc* func,
ParamNameGeneratorFunc* name_func,
const char* file, int line) {
instantiations_.push_back(
InstantiationInfo(instantiation_name, func, name_func, file, line));
instantiations_.emplace_back(std::move(instantiation_name), func, name_func,
file, line);
return 0; // Return value used only to run this method in namespace scope.
}
// UnitTest class invokes this method to register tests in this test suite
@@ -553,60 +554,61 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
void RegisterTests() override {
bool generated_instantiations = false;
for (typename TestInfoContainer::iterator test_it = tests_.begin();
test_it != tests_.end(); ++test_it) {
std::shared_ptr<TestInfo> test_info = *test_it;
for (typename InstantiationContainer::iterator gen_it =
instantiations_.begin();
gen_it != instantiations_.end(); ++gen_it) {
const std::string& instantiation_name = gen_it->name;
ParamGenerator<ParamType> generator((*gen_it->generator)());
ParamNameGeneratorFunc* name_func = gen_it->name_func;
const char* file = gen_it->file;
int line = gen_it->line;
std::string test_suite_name;
std::string test_name;
for (const std::shared_ptr<TestInfo>& test_info : tests_) {
for (const InstantiationInfo& instantiation : instantiations_) {
const std::string& instantiation_name = instantiation.name;
ParamGenerator<ParamType> generator((*instantiation.generator)());
ParamNameGeneratorFunc* name_func = instantiation.name_func;
const char* file = instantiation.file;
int line = instantiation.line;
std::string test_suite_name;
if (!instantiation_name.empty())
test_suite_name = instantiation_name + "/";
test_suite_name += test_info->test_suite_base_name;
else
test_suite_name.clear();
test_suite_name += test_suite_name_;
size_t i = 0;
std::set<std::string> test_param_names;
for (typename ParamGenerator<ParamType>::iterator param_it =
generator.begin();
param_it != generator.end(); ++param_it, ++i) {
for (const auto& param : generator) {
generated_instantiations = true;
Message test_name_stream;
test_name.clear();
std::string param_name =
name_func(TestParamInfo<ParamType>(*param_it, i));
name_func(TestParamInfo<ParamType>(param, i));
GTEST_CHECK_(IsValidParamName(param_name))
<< "Parameterized test name '" << param_name
<< "' is invalid, in " << file << " line " << line << std::endl;
<< "' is invalid (contains spaces, dashes, or any "
"non-alphanumeric characters other than underscores), in "
<< file << " line " << line << "" << std::endl;
GTEST_CHECK_(test_param_names.count(param_name) == 0)
<< "Duplicate parameterized test name '" << param_name << "', in "
<< file << " line " << line << std::endl;
test_param_names.insert(param_name);
if (!test_info->test_base_name.empty()) {
test_name_stream << test_info->test_base_name << "/";
test_name.append(test_info->test_base_name).append("/");
}
test_name_stream << param_name;
test_name += param_name;
test_param_names.insert(std::move(param_name));
MakeAndRegisterTestInfo(
test_suite_name.c_str(), test_name_stream.GetString().c_str(),
test_suite_name, test_name.c_str(),
nullptr, // No type parameter.
PrintToString(*param_it).c_str(), test_info->code_location,
PrintToString(param).c_str(), test_info->code_location,
GetTestSuiteTypeId(),
SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line),
SuiteApiResolver<TestSuite>::GetTearDownCaseOrSuite(file, line),
test_info->test_meta_factory->CreateTestFactory(*param_it));
} // for param_it
} // for gen_it
} // for test_it
test_info->test_meta_factory->CreateTestFactory(param));
++i;
} // for param
} // for instantiation
} // for test_info
if (!generated_instantiations) {
// There are no generaotrs, or they all generate nothing ...
@@ -619,15 +621,13 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
// LocalTestInfo structure keeps information about a single test registered
// with TEST_P macro.
struct TestInfo {
TestInfo(const char* a_test_suite_base_name, const char* a_test_base_name,
TestInfo(const char* a_test_base_name,
TestMetaFactoryBase<ParamType>* a_test_meta_factory,
CodeLocation a_code_location)
: test_suite_base_name(a_test_suite_base_name),
test_base_name(a_test_base_name),
: test_base_name(a_test_base_name),
test_meta_factory(a_test_meta_factory),
code_location(a_code_location) {}
code_location(std::move(a_code_location)) {}
const std::string test_suite_base_name;
const std::string test_base_name;
const std::unique_ptr<TestMetaFactoryBase<ParamType>> test_meta_factory;
const CodeLocation code_location;
@@ -637,11 +637,10 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
// <Instantiation name, Sequence generator creation function,
// Name generator function, Source file, Source line>
struct InstantiationInfo {
InstantiationInfo(const std::string& name_in,
GeneratorCreationFunc* generator_in,
InstantiationInfo(std::string name_in, GeneratorCreationFunc* generator_in,
ParamNameGeneratorFunc* name_func_in, const char* file_in,
int line_in)
: name(name_in),
: name(std::move(name_in)),
generator(generator_in),
name_func(name_func_in),
file(file_in),
@@ -702,29 +701,32 @@ class ParameterizedTestSuiteRegistry {
// tests and instantiations of a particular test suite.
template <class TestSuite>
ParameterizedTestSuiteInfo<TestSuite>* GetTestSuitePatternHolder(
const char* test_suite_name, CodeLocation code_location) {
std::string test_suite_name, CodeLocation code_location) {
ParameterizedTestSuiteInfo<TestSuite>* typed_test_info = nullptr;
for (auto& test_suite_info : test_suite_infos_) {
if (test_suite_info->GetTestSuiteName() == test_suite_name) {
if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {
// Complain about incorrect usage of Google Test facilities
// and terminate the program since we cannot guaranty correct
// test suite setup and tear-down in this case.
ReportInvalidTestSuiteType(test_suite_name, code_location);
posix::Abort();
} else {
// At this point we are sure that the object we found is of the same
// type we are looking for, so we downcast it to that type
// without further checks.
typed_test_info = CheckedDowncastToActualType<
ParameterizedTestSuiteInfo<TestSuite>>(test_suite_info);
}
break;
auto item_it = suite_name_to_info_index_.find(test_suite_name);
if (item_it != suite_name_to_info_index_.end()) {
auto* test_suite_info = test_suite_infos_[item_it->second];
if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {
// Complain about incorrect usage of Google Test facilities
// and terminate the program since we cannot guaranty correct
// test suite setup and tear-down in this case.
ReportInvalidTestSuiteType(test_suite_name.c_str(), code_location);
posix::Abort();
} else {
// At this point we are sure that the object we found is of the same
// type we are looking for, so we downcast it to that type
// without further checks.
typed_test_info =
CheckedDowncastToActualType<ParameterizedTestSuiteInfo<TestSuite>>(
test_suite_info);
}
}
if (typed_test_info == nullptr) {
typed_test_info = new ParameterizedTestSuiteInfo<TestSuite>(
test_suite_name, code_location);
test_suite_name, std::move(code_location));
suite_name_to_info_index_.emplace(std::move(test_suite_name),
test_suite_infos_.size());
test_suite_infos_.push_back(typed_test_info);
}
return typed_test_info;
@@ -738,8 +740,9 @@ class ParameterizedTestSuiteRegistry {
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
template <class TestCase>
ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
const char* test_case_name, CodeLocation code_location) {
return GetTestSuitePatternHolder<TestCase>(test_case_name, code_location);
std::string test_case_name, CodeLocation code_location) {
return GetTestSuitePatternHolder<TestCase>(std::move(test_case_name),
std::move(code_location));
}
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
@@ -748,6 +751,7 @@ class ParameterizedTestSuiteRegistry {
using TestSuiteInfoContainer = ::std::vector<ParameterizedTestSuiteInfoBase*>;
TestSuiteInfoContainer test_suite_infos_;
::std::unordered_map<std::string, size_t> suite_name_to_info_index_;
ParameterizedTestSuiteRegistry(const ParameterizedTestSuiteRegistry&) =
delete;
@@ -774,7 +778,7 @@ class TypeParameterizedTestSuiteRegistry {
private:
struct TypeParameterizedTestSuiteInfo {
explicit TypeParameterizedTestSuiteInfo(CodeLocation c)
: code_location(c), instantiated(false) {}
: code_location(std::move(c)), instantiated(false) {}
CodeLocation code_location;
bool instantiated;
@@ -803,12 +807,12 @@ class ValueArray {
template <typename T>
operator ParamGenerator<T>() const { // NOLINT
return ValuesIn(MakeVector<T>(MakeIndexSequence<sizeof...(Ts)>()));
return ValuesIn(MakeVector<T>(std::make_index_sequence<sizeof...(Ts)>()));
}
private:
template <typename T, size_t... I>
std::vector<T> MakeVector(IndexSequence<I...>) const {
std::vector<T> MakeVector(std::index_sequence<I...>) const {
return std::vector<T>{static_cast<T>(v_.template Get<I>())...};
}
@@ -838,7 +842,7 @@ class CartesianProductGenerator
template <class I>
class IteratorImpl;
template <size_t... I>
class IteratorImpl<IndexSequence<I...>>
class IteratorImpl<std::index_sequence<I...>>
: public ParamIteratorInterface<ParamType> {
public:
IteratorImpl(const ParamGeneratorInterface<ParamType>* base,
@@ -929,7 +933,7 @@ class CartesianProductGenerator
std::shared_ptr<ParamType> current_value_;
};
using Iterator = IteratorImpl<typename MakeIndexSequence<sizeof...(T)>::type>;
using Iterator = IteratorImpl<std::make_index_sequence<sizeof...(T)>>;
std::tuple<ParamGenerator<T>...> generators_;
};
@@ -948,11 +952,11 @@ class CartesianProductHolder {
std::tuple<Gen...> generators_;
};
template <typename From, typename To>
template <typename From, typename To, typename Func>
class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
public:
ParamGeneratorConverter(ParamGenerator<From> gen) // NOLINT
: generator_(std::move(gen)) {}
ParamGeneratorConverter(ParamGenerator<From> gen, Func converter) // NOLINT
: generator_(std::move(gen)), converter_(std::move(converter)) {}
ParamIteratorInterface<To>* Begin() const override {
return new Iterator(this, generator_.begin(), generator_.end());
@@ -961,13 +965,21 @@ class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
return new Iterator(this, generator_.end(), generator_.end());
}
// Returns the std::function wrapping the user-supplied converter callable. It
// is used by the iterator (see class Iterator below) to convert the object
// (of type FROM) returned by the ParamGenerator to an object of a type that
// can be static_cast to type TO.
const Func& TypeConverter() const { return converter_; }
private:
class Iterator : public ParamIteratorInterface<To> {
public:
Iterator(const ParamGeneratorInterface<To>* base, ParamIterator<From> it,
Iterator(const ParamGeneratorConverter* base, ParamIterator<From> it,
ParamIterator<From> end)
: base_(base), it_(it), end_(end) {
if (it_ != end_) value_ = std::make_shared<To>(static_cast<To>(*it_));
if (it_ != end_)
value_ =
std::make_shared<To>(static_cast<To>(base->TypeConverter()(*it_)));
}
~Iterator() override = default;
@@ -976,7 +988,9 @@ class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
}
void Advance() override {
++it_;
if (it_ != end_) value_ = std::make_shared<To>(static_cast<To>(*it_));
if (it_ != end_)
value_ =
std::make_shared<To>(static_cast<To>(base_->TypeConverter()(*it_)));
}
ParamIteratorInterface<To>* Clone() const override {
return new Iterator(*this);
@@ -996,30 +1010,54 @@ class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
private:
Iterator(const Iterator& other) = default;
const ParamGeneratorInterface<To>* const base_;
const ParamGeneratorConverter* const base_;
ParamIterator<From> it_;
ParamIterator<From> end_;
std::shared_ptr<To> value_;
}; // class ParamGeneratorConverter::Iterator
ParamGenerator<From> generator_;
Func converter_;
}; // class ParamGeneratorConverter
template <class Gen>
template <class GeneratedT,
typename StdFunction =
std::function<const GeneratedT&(const GeneratedT&)>>
class ParamConverterGenerator {
public:
ParamConverterGenerator(ParamGenerator<Gen> g) // NOLINT
: generator_(std::move(g)) {}
ParamConverterGenerator(ParamGenerator<GeneratedT> g) // NOLINT
: generator_(std::move(g)), converter_(Identity) {}
ParamConverterGenerator(ParamGenerator<GeneratedT> g, StdFunction converter)
: generator_(std::move(g)), converter_(std::move(converter)) {}
template <typename T>
operator ParamGenerator<T>() const { // NOLINT
return ParamGenerator<T>(new ParamGeneratorConverter<Gen, T>(generator_));
return ParamGenerator<T>(
new ParamGeneratorConverter<GeneratedT, T, StdFunction>(generator_,
converter_));
}
private:
ParamGenerator<Gen> generator_;
static const GeneratedT& Identity(const GeneratedT& v) { return v; }
ParamGenerator<GeneratedT> generator_;
StdFunction converter_;
};
// Template to determine the param type of a single-param std::function.
template <typename T>
struct FuncSingleParamType;
template <typename R, typename P>
struct FuncSingleParamType<std::function<R(P)>> {
using type = std::remove_cv_t<std::remove_reference_t<P>>;
};
template <typename T>
struct IsSingleArgStdFunction : public std::false_type {};
template <typename R, typename P>
struct IsSingleArgStdFunction<std::function<R(P)>> : public std::true_type {};
} // namespace internal
} // namespace testing

View File

@@ -56,6 +56,8 @@
#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE)
#define GTEST_OS_WINDOWS_PHONE 1
#define GTEST_OS_WINDOWS_TV_TITLE 1
#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_GAMES)
#define GTEST_OS_WINDOWS_GAMES 1
#else
// WINAPI_FAMILY defined but no known partition matched.
// Default to desktop.

View File

@@ -194,9 +194,6 @@
//
// Macros for basic C++ coding:
// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning.
// GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a
// variable don't have to be used.
// GTEST_MUST_USE_RESULT_ - declares that a function's result must be used.
// GTEST_INTENTIONAL_CONST_COND_PUSH_ - start code section where MSVC C4127 is
// suppressed (constant conditional).
// GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127
@@ -208,6 +205,8 @@
// or
// UniversalPrinter<absl::optional>
// specializations. Always defined to 0 or 1.
// GTEST_INTERNAL_HAS_STD_SPAN - for enabling UniversalPrinter<std::span>
// specializations. Always defined to 0 or 1
// GTEST_INTERNAL_HAS_STRING_VIEW - for enabling Matcher<std::string_view> or
// Matcher<absl::string_view>
// specializations. Always defined to 0 or 1.
@@ -260,11 +259,6 @@
// BoolFromGTestEnv() - parses a bool environment variable.
// Int32FromGTestEnv() - parses an int32_t environment variable.
// StringFromGTestEnv() - parses a string environment variable.
//
// Deprecation warnings:
// GTEST_INTERNAL_DEPRECATED(message) - attribute marking a function as
// deprecated; calling a marked function
// should generate a compiler warning
// The definition of GTEST_INTERNAL_CPLUSPLUS_LANG comes first because it can
// potentially be used as an #include guard.
@@ -275,8 +269,28 @@
#endif
#if !defined(GTEST_INTERNAL_CPLUSPLUS_LANG) || \
GTEST_INTERNAL_CPLUSPLUS_LANG < 201402L
#error C++ versions less than C++14 are not supported.
GTEST_INTERNAL_CPLUSPLUS_LANG < 201703L
#error C++ versions less than C++17 are not supported.
#endif
// MSVC >= 19.11 (VS 2017 Update 3) supports __has_include.
#ifdef __has_include
#define GTEST_INTERNAL_HAS_INCLUDE __has_include
#else
#define GTEST_INTERNAL_HAS_INCLUDE(...) 0
#endif
// Detect C++ feature test macros as gracefully as possible.
// MSVC >= 19.15, Clang >= 3.4.1, and GCC >= 4.1.2 support feature test macros.
//
// GCC15 warns that <ciso646> is deprecated in C++17 and suggests using
// <version> instead, even though <version> is not available in C++17 mode prior
// to GCC9.
#if GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L || \
GTEST_INTERNAL_HAS_INCLUDE(<version>)
#include <version> // C++20 or <version> support.
#else
#include <ciso646> // Pre-C++20
#endif
#include <ctype.h> // for isspace, etc
@@ -320,7 +334,8 @@
#define GTEST_HAS_NOTIFICATION_ 0
#endif
#ifdef GTEST_HAS_ABSL
#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
#define GTEST_INTERNAL_HAS_ABSL_FLAGS // Used only in this file.
#include "absl/flags/declare.h"
#include "absl/flags/flag.h"
#include "absl/flags/reflection.h"
@@ -590,7 +605,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
defined(GTEST_OS_NETBSD) || defined(GTEST_OS_FUCHSIA) || \
defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_GNU_KFREEBSD) || \
defined(GTEST_OS_OPENBSD) || defined(GTEST_OS_HAIKU) || \
defined(GTEST_OS_GNU_HURD))
defined(GTEST_OS_GNU_HURD) || defined(GTEST_OS_SOLARIS) || \
defined(GTEST_OS_AIX) || defined(GTEST_OS_ZOS))
#define GTEST_HAS_PTHREAD 1
#else
#define GTEST_HAS_PTHREAD 0
@@ -609,7 +625,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// Determines whether clone(2) is supported.
// Usually it will only be available on Linux, excluding
// Linux on the Itanium architecture.
// Also see http://linux.die.net/man/2/clone.
// Also see https://linux.die.net/man/2/clone.
#ifndef GTEST_HAS_CLONE
// The user didn't tell us, so we need to figure it out.
@@ -640,9 +656,9 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// platforms except known mobile / embedded ones. Also, if the port doesn't have
// a file system, stream redirection is not supported.
#if defined(GTEST_OS_WINDOWS_MOBILE) || defined(GTEST_OS_WINDOWS_PHONE) || \
defined(GTEST_OS_WINDOWS_RT) || defined(GTEST_OS_ESP8266) || \
defined(GTEST_OS_XTENSA) || defined(GTEST_OS_QURT) || \
!GTEST_HAS_FILE_SYSTEM
defined(GTEST_OS_WINDOWS_RT) || defined(GTEST_OS_WINDOWS_GAMES) || \
defined(GTEST_OS_ESP8266) || defined(GTEST_OS_XTENSA) || \
defined(GTEST_OS_QURT) || !GTEST_HAS_FILE_SYSTEM
#define GTEST_HAS_STREAM_REDIRECTION 0
#else
#define GTEST_HAS_STREAM_REDIRECTION 1
@@ -652,7 +668,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// Determines whether to support death tests.
// pops up a dialog window that cannot be suppressed programmatically.
#if (defined(GTEST_OS_LINUX) || defined(GTEST_OS_CYGWIN) || \
defined(GTEST_OS_SOLARIS) || \
defined(GTEST_OS_SOLARIS) || defined(GTEST_OS_ZOS) || \
(defined(GTEST_OS_MAC) && !defined(GTEST_OS_IOS)) || \
(defined(GTEST_OS_WINDOWS_DESKTOP) && _MSC_VER) || \
defined(GTEST_OS_WINDOWS_MINGW) || defined(GTEST_OS_AIX) || \
@@ -730,6 +746,20 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#define GTEST_HAVE_ATTRIBUTE_(x) 0
#endif
// GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE
//
// A function-like feature checking macro that accepts C++11 style attributes.
// It's a wrapper around `__has_cpp_attribute`, defined by ISO C++ SD-6
// (https://en.cppreference.com/w/cpp/experimental/feature_test). If we don't
// find `__has_cpp_attribute`, will evaluate to 0.
#if defined(__has_cpp_attribute)
// NOTE: requiring __cplusplus above should not be necessary, but
// works around https://bugs.llvm.org/show_bug.cgi?id=23435.
#define GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
#else
#define GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(x) 0
#endif
// GTEST_HAVE_FEATURE_
//
// A function-like feature checking macro that is a wrapper around
@@ -740,17 +770,6 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#define GTEST_HAVE_FEATURE_(x) 0
#endif
// Use this annotation after a variable or parameter declaration to tell the
// compiler the variable/parameter does not have to be used.
// Example:
//
// GTEST_ATTRIBUTE_UNUSED_ int foo = bar();
#if GTEST_HAVE_ATTRIBUTE_(unused)
#define GTEST_ATTRIBUTE_UNUSED_ __attribute__((unused))
#else
#define GTEST_ATTRIBUTE_UNUSED_
#endif
// Use this annotation before a function that takes a printf format string.
#if GTEST_HAVE_ATTRIBUTE_(format) && defined(__MINGW_PRINTF_FORMAT)
// MinGW has two different printf implementations. Ensure the format macro
@@ -765,17 +784,6 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check)
#endif
// Tell the compiler to warn about unused return values for functions declared
// with this macro. The macro should be used on function declarations
// following the argument list:
//
// Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_;
#if GTEST_HAVE_ATTRIBUTE_(warn_unused_result)
#define GTEST_MUST_USE_RESULT_ __attribute__((warn_unused_result))
#else
#define GTEST_MUST_USE_RESULT_
#endif
// MS C++ compiler emits warning when a conditional expression is compile time
// constant. In some contexts this warning is false positive and needs to be
// suppressed. Use the following two macros in such cases:
@@ -827,9 +835,9 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#ifndef GTEST_API_
#ifdef _MSC_VER
#if GTEST_LINKED_AS_SHARED_LIBRARY
#if defined(GTEST_LINKED_AS_SHARED_LIBRARY) && GTEST_LINKED_AS_SHARED_LIBRARY
#define GTEST_API_ __declspec(dllimport)
#elif GTEST_CREATE_SHARED_LIBRARY
#elif defined(GTEST_CREATE_SHARED_LIBRARY) && GTEST_CREATE_SHARED_LIBRARY
#define GTEST_API_ __declspec(dllexport)
#endif
#elif GTEST_HAVE_ATTRIBUTE_(visibility)
@@ -1987,7 +1995,9 @@ inline std::string StripTrailingSpaces(std::string str) {
namespace posix {
// File system porting.
#if GTEST_HAS_FILE_SYSTEM
// Note: Not every I/O-related function is related to file systems, so don't
// just disable all of them here. For example, fileno() and isatty(), etc. must
// always be available in order to detect if a pipe points to a terminal.
#ifdef GTEST_OS_WINDOWS
typedef struct _stat StatStruct;
@@ -1998,27 +2008,32 @@ inline int FileNo(FILE* file) { return reinterpret_cast<int>(_fileno(file)); }
// time and thus not defined there.
#else
inline int FileNo(FILE* file) { return _fileno(file); }
#if GTEST_HAS_FILE_SYSTEM
inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); }
inline int RmDir(const char* dir) { return _rmdir(dir); }
inline bool IsDir(const StatStruct& st) { return (_S_IFDIR & st.st_mode) != 0; }
#endif
#endif // GTEST_OS_WINDOWS_MOBILE
#elif defined(GTEST_OS_ESP8266)
typedef struct stat StatStruct;
inline int FileNo(FILE* file) { return fileno(file); }
#if GTEST_HAS_FILE_SYSTEM
inline int Stat(const char* path, StatStruct* buf) {
// stat function not implemented on ESP8266
return 0;
}
inline int RmDir(const char* dir) { return rmdir(dir); }
inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
#endif
#else
typedef struct stat StatStruct;
inline int FileNo(FILE* file) { return fileno(file); }
#if GTEST_HAS_FILE_SYSTEM
inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); }
#ifdef GTEST_OS_QURT
// QuRT doesn't support any directory functions, including rmdir
@@ -2027,9 +2042,9 @@ inline int RmDir(const char*) { return 0; }
inline int RmDir(const char* dir) { return rmdir(dir); }
#endif
inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
#endif
#endif // GTEST_OS_WINDOWS
#endif // GTEST_HAS_FILE_SYSTEM
// Other functions with a different name on Windows.
@@ -2082,8 +2097,9 @@ GTEST_DISABLE_MSC_DEPRECATED_PUSH_()
// defined there.
#if GTEST_HAS_FILE_SYSTEM
#if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_WINDOWS_PHONE) && \
!defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_ESP8266) && \
!defined(GTEST_OS_XTENSA) && !defined(GTEST_OS_QURT)
!defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_GAMES) && \
!defined(GTEST_OS_ESP8266) && !defined(GTEST_OS_XTENSA) && \
!defined(GTEST_OS_QURT)
inline int ChDir(const char* dir) { return chdir(dir); }
#endif
inline FILE* FOpen(const char* path, const char* mode) {
@@ -2227,7 +2243,7 @@ using TimeInMillis = int64_t; // Represents time in milliseconds.
#endif // !defined(GTEST_FLAG)
// Pick a command line flags implementation.
#ifdef GTEST_HAS_ABSL
#ifdef GTEST_INTERNAL_HAS_ABSL_FLAGS
// Macros for defining flags.
#define GTEST_DEFINE_bool_(name, default_val, doc) \
@@ -2252,7 +2268,8 @@ using TimeInMillis = int64_t; // Represents time in milliseconds.
(void)(::absl::SetFlag(&GTEST_FLAG(name), value))
#define GTEST_USE_OWN_FLAGFILE_FLAG_ 0
#else // GTEST_HAS_ABSL
#undef GTEST_INTERNAL_HAS_ABSL_FLAGS
#else // ndef GTEST_INTERNAL_HAS_ABSL_FLAGS
// Macros for defining flags.
#define GTEST_DEFINE_bool_(name, default_val, doc) \
@@ -2294,7 +2311,7 @@ using TimeInMillis = int64_t; // Represents time in milliseconds.
#define GTEST_FLAG_SET(name, value) (void)(::testing::GTEST_FLAG(name) = value)
#define GTEST_USE_OWN_FLAGFILE_FLAG_ 1
#endif // GTEST_HAS_ABSL
#endif // GTEST_INTERNAL_HAS_ABSL_FLAGS
// Thread annotations
#if !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_)
@@ -2318,26 +2335,6 @@ const char* StringFromGTestEnv(const char* flag, const char* default_val);
} // namespace internal
} // namespace testing
#if !defined(GTEST_INTERNAL_DEPRECATED)
// Internal Macro to mark an API deprecated, for googletest usage only
// Usage: class GTEST_INTERNAL_DEPRECATED(message) MyClass or
// GTEST_INTERNAL_DEPRECATED(message) <return_type> myFunction(); Every usage of
// a deprecated entity will trigger a warning when compiled with
// `-Wdeprecated-declarations` option (clang, gcc, any __GNUC__ compiler).
// For msvc /W3 option will need to be used
// Note that for 'other' compilers this macro evaluates to nothing to prevent
// compilations errors.
#if defined(_MSC_VER)
#define GTEST_INTERNAL_DEPRECATED(message) __declspec(deprecated(message))
#elif defined(__GNUC__)
#define GTEST_INTERNAL_DEPRECATED(message) __attribute__((deprecated(message)))
#else
#define GTEST_INTERNAL_DEPRECATED(message)
#endif
#endif // !defined(GTEST_INTERNAL_DEPRECATED)
#ifdef GTEST_HAS_ABSL
// Always use absl::any for UniversalPrinter<> specializations if googletest
// is built with absl support.
@@ -2349,9 +2346,9 @@ using Any = ::absl::any;
} // namespace internal
} // namespace testing
#else
#ifdef __has_include
#if __has_include(<any>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L && \
(!defined(_MSC_VER) || GTEST_HAS_RTTI)
#if defined(__cpp_lib_any) || (GTEST_INTERNAL_HAS_INCLUDE(<any>) && \
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L && \
(!defined(_MSC_VER) || GTEST_HAS_RTTI))
// Otherwise for C++17 and higher use std::any for UniversalPrinter<>
// specializations.
#define GTEST_INTERNAL_HAS_ANY 1
@@ -2363,8 +2360,7 @@ using Any = ::std::any;
} // namespace testing
// The case where absl is configured NOT to alias std::any is not
// supported.
#endif // __has_include(<any>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L
#endif // __has_include
#endif // __cpp_lib_any
#endif // GTEST_HAS_ABSL
#ifndef GTEST_INTERNAL_HAS_ANY
@@ -2384,8 +2380,8 @@ inline ::absl::nullopt_t Nullopt() { return ::absl::nullopt; }
} // namespace internal
} // namespace testing
#else
#ifdef __has_include
#if __has_include(<optional>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L
#if defined(__cpp_lib_optional) || (GTEST_INTERNAL_HAS_INCLUDE(<optional>) && \
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L)
// Otherwise for C++17 and higher use std::optional for UniversalPrinter<>
// specializations.
#define GTEST_INTERNAL_HAS_OPTIONAL 1
@@ -2399,14 +2395,22 @@ inline ::std::nullopt_t Nullopt() { return ::std::nullopt; }
} // namespace testing
// The case where absl is configured NOT to alias std::optional is not
// supported.
#endif // __has_include(<optional>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L
#endif // __has_include
#endif // __cpp_lib_optional
#endif // GTEST_HAS_ABSL
#ifndef GTEST_INTERNAL_HAS_OPTIONAL
#define GTEST_INTERNAL_HAS_OPTIONAL 0
#endif
#if defined(__cpp_lib_span) || (GTEST_INTERNAL_HAS_INCLUDE(<span>) && \
GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L)
#define GTEST_INTERNAL_HAS_STD_SPAN 1
#endif // __cpp_lib_span
#ifndef GTEST_INTERNAL_HAS_STD_SPAN
#define GTEST_INTERNAL_HAS_STD_SPAN 0
#endif
#ifdef GTEST_HAS_ABSL
// Always use absl::string_view for Matcher<> specializations if googletest
// is built with absl support.
@@ -2418,8 +2422,9 @@ using StringView = ::absl::string_view;
} // namespace internal
} // namespace testing
#else
#ifdef __has_include
#if __has_include(<string_view>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L
#if defined(__cpp_lib_string_view) || \
(GTEST_INTERNAL_HAS_INCLUDE(<string_view>) && \
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L)
// Otherwise for C++17 and higher use std::string_view for Matcher<>
// specializations.
#define GTEST_INTERNAL_HAS_STRING_VIEW 1
@@ -2431,9 +2436,7 @@ using StringView = ::std::string_view;
} // namespace testing
// The case where absl is configured NOT to alias std::string_view is not
// supported.
#endif // __has_include(<string_view>) && GTEST_INTERNAL_CPLUSPLUS_LANG >=
// 201703L
#endif // __has_include
#endif // __cpp_lib_string_view
#endif // GTEST_HAS_ABSL
#ifndef GTEST_INTERNAL_HAS_STRING_VIEW
@@ -2452,8 +2455,8 @@ using Variant = ::absl::variant<T...>;
} // namespace internal
} // namespace testing
#else
#ifdef __has_include
#if __has_include(<variant>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L
#if defined(__cpp_lib_variant) || (GTEST_INTERNAL_HAS_INCLUDE(<variant>) && \
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L)
// Otherwise for C++17 and higher use std::variant for UniversalPrinter<>
// specializations.
#define GTEST_INTERNAL_HAS_VARIANT 1
@@ -2465,17 +2468,19 @@ using Variant = ::std::variant<T...>;
} // namespace internal
} // namespace testing
// The case where absl is configured NOT to alias std::variant is not supported.
#endif // __has_include(<variant>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L
#endif // __has_include
#endif // __cpp_lib_variant
#endif // GTEST_HAS_ABSL
#ifndef GTEST_INTERNAL_HAS_VARIANT
#define GTEST_INTERNAL_HAS_VARIANT 0
#endif
#if defined(GTEST_INTERNAL_CPLUSPLUS_LANG) && \
GTEST_INTERNAL_CPLUSPLUS_LANG < 201703L
#define GTEST_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL 1
#if (defined(__cpp_lib_three_way_comparison) || \
(GTEST_INTERNAL_HAS_INCLUDE(<compare>) && \
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201907L))
#define GTEST_INTERNAL_HAS_COMPARE_LIB 1
#else
#define GTEST_INTERNAL_HAS_COMPARE_LIB 0
#endif
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_

View File

@@ -71,7 +71,7 @@ inline std::string CanonicalizeForStdLibVersioning(std::string s) {
// Strip redundant spaces in typename to match MSVC
// For example, std::pair<int, bool> -> std::pair<int,bool>
static const char to_search[] = ", ";
static const char replace_str[] = ",";
const char replace_char = ',';
size_t pos = 0;
while (true) {
// Get the next occurrence from the current position
@@ -80,8 +80,8 @@ inline std::string CanonicalizeForStdLibVersioning(std::string s) {
break;
}
// Replace this occurrence of substring
s.replace(pos, strlen(to_search), replace_str);
pos += strlen(replace_str);
s.replace(pos, strlen(to_search), 1, replace_char);
++pos;
}
return s;
}

View File

@@ -32,6 +32,8 @@
#include "gtest/gtest-death-test.h"
#include <stdlib.h>
#include <functional>
#include <memory>
#include <sstream>
@@ -115,7 +117,7 @@ GTEST_DEFINE_string_(
GTEST_DEFINE_bool_(
death_test_use_fork,
testing::internal::BoolFromGTestEnv("death_test_use_fork", false),
"Instructs to use fork()/_exit() instead of clone() in death tests. "
"Instructs to use fork()/_Exit() instead of clone() in death tests. "
"Ignored and always uses fork() on POSIX systems where clone() is not "
"implemented. Useful when running under valgrind or similar tools if "
"those do not support clone(). Valgrind 3.3.1 will just fail if "
@@ -299,7 +301,7 @@ enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW };
fputc(kDeathTestInternalError, parent);
fprintf(parent, "%s", message.c_str());
fflush(parent);
_exit(1);
_Exit(1);
} else {
fprintf(stderr, "%s", message.c_str());
fflush(stderr);
@@ -511,7 +513,7 @@ std::string DeathTestImpl::GetErrorLogs() { return GetCapturedStderr(); }
// Signals that the death test code which should have exited, didn't.
// Should be called only in a death test child process.
// Writes a status byte to the child's status file descriptor, then
// calls _exit(1).
// calls _Exit(1).
void DeathTestImpl::Abort(AbortReason reason) {
// The parent process considers the death test to be a failure if
// it finds any data in our pipe. So, here we write a single flag byte
@@ -523,13 +525,13 @@ void DeathTestImpl::Abort(AbortReason reason) {
GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1));
// We are leaking the descriptor here because on some platforms (i.e.,
// when built as Windows DLL), destructors of global objects will still
// run after calling _exit(). On such systems, write_fd_ will be
// run after calling _Exit(). On such systems, write_fd_ will be
// indirectly closed from the destructor of UnitTestImpl, causing double
// close if it is also closed here. On debug configurations, double close
// may assert. As there are no in-process buffers to flush here, we are
// relying on the OS to close the descriptor after the process terminates
// when the destructors are not run.
_exit(1); // Exits w/o any normal exit hooks (we were supposed to crash)
_Exit(1); // Exits w/o any normal exit hooks (we were supposed to crash)
}
// Returns an indented copy of stderr output for a death test.
@@ -628,13 +630,13 @@ bool DeathTestImpl::Passed(bool status_ok) {
#ifndef GTEST_OS_WINDOWS
// Note: The return value points into args, so the return value's lifetime is
// bound to that of args.
static std::unique_ptr<char*[]> CreateArgvFromArgs(
std::vector<std::string>& args) {
auto result = std::make_unique<char*[]>(args.size() + 1);
for (size_t i = 0; i < args.size(); ++i) {
result[i] = &args[i][0];
static std::vector<char*> CreateArgvFromArgs(std::vector<std::string>& args) {
std::vector<char*> result;
result.reserve(args.size() + 1);
for (auto& arg : args) {
result.push_back(&arg[0]);
}
result[args.size()] = nullptr; // extra null terminator
result.push_back(nullptr); // Extra null terminator.
return result;
}
#endif
@@ -783,7 +785,7 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
StreamableToString(static_cast<unsigned int>(::GetCurrentProcessId())) +
// size_t has the same width as pointers on both 32-bit and 64-bit
// Windows platforms.
// See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx.
// See https://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx.
"|" + StreamableToString(reinterpret_cast<size_t>(write_handle)) + "|" +
StreamableToString(reinterpret_cast<size_t>(event_handle_.Get()));
@@ -1034,8 +1036,8 @@ DeathTest::TestRole FuchsiaDeathTest::AssumeRole() {
// "Fuchsia Test Component" which contains a "Fuchsia Component Manifest")
// Launching processes is a privileged operation in Fuchsia, and the
// declaration indicates that the ability is required for the component.
std::unique_ptr<char*[]> argv = CreateArgvFromArgs(args);
status = fdio_spawn_etc(child_job, FDIO_SPAWN_CLONE_ALL, argv[0], argv.get(),
std::vector<char*> argv = CreateArgvFromArgs(args);
status = fdio_spawn_etc(child_job, FDIO_SPAWN_CLONE_ALL, argv[0], argv.data(),
nullptr, 2, spawn_actions,
child_process_.reset_and_get_address(), nullptr);
GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
@@ -1333,7 +1335,7 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
#endif // GTEST_HAS_CLONE
if (use_fork && (child_pid = fork()) == 0) {
_exit(ExecDeathTestChildMain(&args));
_Exit(ExecDeathTestChildMain(&args));
}
#endif // GTEST_OS_QNX
#ifdef GTEST_OS_LINUX
@@ -1386,8 +1388,8 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() {
// is necessary.
FlushInfoLog();
std::unique_ptr<char*[]> argv = CreateArgvFromArgs(args);
const pid_t child_pid = ExecDeathTestSpawnChild(argv.get(), pipe_fd[0]);
std::vector<char*> argv = CreateArgvFromArgs(args);
const pid_t child_pid = ExecDeathTestSpawnChild(argv.data(), pipe_fd[0]);
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
set_child_pid(child_pid);
set_read_fd(pipe_fd[0]);

View File

@@ -336,7 +336,7 @@ bool FilePath::CreateDirectoriesRecursively() const {
return false;
}
if (pathname_.length() == 0 || this->DirectoryExists()) {
if (pathname_.empty() || this->DirectoryExists()) {
return true;
}

View File

@@ -46,6 +46,7 @@
#include <memory>
#include <set>
#include <string>
#include <unordered_map>
#include <vector>
#include "gtest/internal/gtest-port.h"
@@ -312,7 +313,7 @@ void ShuffleRange(internal::Random* random, int begin, int end,
<< begin << ", " << size << "].";
// Fisher-Yates shuffle, from
// http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
// https://en.wikipedia.org/wiki/Fisher-Yates_shuffle
for (int range_width = end - begin; range_width >= 2; range_width--) {
const int last_in_range = begin + range_width - 1;
const int selected =
@@ -649,13 +650,15 @@ class GTEST_API_ UnitTestImpl {
// this is not a typed or a type-parameterized test.
// set_up_tc: pointer to the function that sets up the test suite
// tear_down_tc: pointer to the function that tears down the test suite
TestSuite* GetTestSuite(const char* test_suite_name, const char* type_param,
TestSuite* GetTestSuite(const std::string& test_suite_name,
const char* type_param,
internal::SetUpTestSuiteFunc set_up_tc,
internal::TearDownTestSuiteFunc tear_down_tc);
// Legacy API is deprecated but still available
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
TestCase* GetTestCase(const char* test_case_name, const char* type_param,
TestCase* GetTestCase(const std::string& test_case_name,
const char* type_param,
internal::SetUpTestSuiteFunc set_up_tc,
internal::TearDownTestSuiteFunc tear_down_tc) {
return GetTestSuite(test_case_name, type_param, set_up_tc, tear_down_tc);
@@ -681,13 +684,13 @@ class GTEST_API_ UnitTestImpl {
// AddTestInfo(), which is called to register a TEST or TEST_F
// before main() is reached.
if (original_working_dir_.IsEmpty()) {
original_working_dir_.Set(FilePath::GetCurrentDir());
original_working_dir_ = FilePath::GetCurrentDir();
GTEST_CHECK_(!original_working_dir_.IsEmpty())
<< "Failed to get the current working directory.";
}
#endif // GTEST_HAS_FILE_SYSTEM
GetTestSuite(test_info->test_suite_name(), test_info->type_param(),
GetTestSuite(test_info->test_suite_name_, test_info->type_param(),
set_up_tc, tear_down_tc)
->AddTestInfo(test_info);
}
@@ -709,18 +712,6 @@ class GTEST_API_ UnitTestImpl {
return type_parameterized_test_registry_;
}
// Sets the TestSuite object for the test that's currently running.
void set_current_test_suite(TestSuite* a_current_test_suite) {
current_test_suite_ = a_current_test_suite;
}
// Sets the TestInfo object for the test that's currently running. If
// current_test_info is NULL, the assertion results will be stored in
// ad_hoc_test_result_.
void set_current_test_info(TestInfo* a_current_test_info) {
current_test_info_ = a_current_test_info;
}
// Registers all parameterized tests defined using TEST_P and
// INSTANTIATE_TEST_SUITE_P, creating regular tests for each test/parameter
// combination. This method can be called more then once; it has guards
@@ -835,12 +826,34 @@ class GTEST_API_ UnitTestImpl {
bool catch_exceptions() const { return catch_exceptions_; }
private:
// Returns true if a warning should be issued if no tests match the test
// filter flag.
bool ShouldWarnIfNoTestsMatchFilter() const;
struct CompareTestSuitesByPointer {
bool operator()(const TestSuite* lhs, const TestSuite* rhs) const {
return lhs->name_ < rhs->name_;
}
};
friend class ::testing::UnitTest;
// Used by UnitTest::Run() to capture the state of
// GTEST_FLAG(catch_exceptions) at the moment it starts.
void set_catch_exceptions(bool value) { catch_exceptions_ = value; }
// Sets the TestSuite object for the test that's currently running.
void set_current_test_suite(TestSuite* a_current_test_suite) {
current_test_suite_ = a_current_test_suite;
}
// Sets the TestInfo object for the test that's currently running. If
// current_test_info is NULL, the assertion results will be stored in
// ad_hoc_test_result_.
void set_current_test_info(TestInfo* a_current_test_info) {
current_test_info_ = a_current_test_info;
}
// The UnitTest object that owns this implementation object.
UnitTest* const parent_;
@@ -873,6 +886,9 @@ class GTEST_API_ UnitTestImpl {
// elements in the vector.
std::vector<TestSuite*> test_suites_;
// The set of TestSuites by name.
std::unordered_map<std::string, TestSuite*> test_suites_by_name_;
// Provides a level of indirection for the test suite list to allow
// easy shuffling and restoring the test suite order. The i-th
// element of this vector is the index of the i-th test suite in the

View File

@@ -158,13 +158,13 @@ size_t GetThreadCount() {
// we cannot detect it.
size_t GetThreadCount() {
int mib[] = {
CTL_KERN,
KERN_PROC,
KERN_PROC_PID,
getpid(),
CTL_KERN,
KERN_PROC,
KERN_PROC_PID,
getpid(),
#ifdef GTEST_OS_NETBSD
sizeof(struct kinfo_proc),
1,
sizeof(struct kinfo_proc),
1,
#endif
};
u_int miblen = sizeof(mib) / sizeof(mib[0]);
@@ -587,9 +587,11 @@ class ThreadLocalRegistryImpl {
// thread's ID.
typedef std::map<DWORD, ThreadLocalValues> ThreadIdToThreadLocals;
// Holds the thread id and thread handle that we pass from
// StartWatcherThreadFor to WatcherThreadFunc.
typedef std::pair<DWORD, HANDLE> ThreadIdAndHandle;
struct WatcherThreadParams {
DWORD thread_id;
HANDLE handle;
Notification has_initialized;
};
static void StartWatcherThreadFor(DWORD thread_id) {
// The returned handle will be kept in thread_map and closed by
@@ -597,15 +599,20 @@ class ThreadLocalRegistryImpl {
HANDLE thread =
::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, FALSE, thread_id);
GTEST_CHECK_(thread != nullptr);
WatcherThreadParams* watcher_thread_params = new WatcherThreadParams;
watcher_thread_params->thread_id = thread_id;
watcher_thread_params->handle = thread;
// We need to pass a valid thread ID pointer into CreateThread for it
// to work correctly under Win98.
DWORD watcher_thread_id;
HANDLE watcher_thread = ::CreateThread(
nullptr, // Default security.
0, // Default stack size
&ThreadLocalRegistryImpl::WatcherThreadFunc,
reinterpret_cast<LPVOID>(new ThreadIdAndHandle(thread_id, thread)),
CREATE_SUSPENDED, &watcher_thread_id);
HANDLE watcher_thread =
::CreateThread(nullptr, // Default security.
0, // Default stack size
&ThreadLocalRegistryImpl::WatcherThreadFunc,
reinterpret_cast<LPVOID>(watcher_thread_params),
CREATE_SUSPENDED, &watcher_thread_id);
GTEST_CHECK_(watcher_thread != nullptr)
<< "CreateThread failed with error " << ::GetLastError() << ".";
// Give the watcher thread the same priority as ours to avoid being
@@ -614,17 +621,25 @@ class ThreadLocalRegistryImpl {
::GetThreadPriority(::GetCurrentThread()));
::ResumeThread(watcher_thread);
::CloseHandle(watcher_thread);
// Wait for the watcher thread to start to avoid race conditions.
// One specific race condition that can happen is that we have returned
// from main and have started to tear down, the newly spawned watcher
// thread may access already-freed variables, like global shared_ptrs.
watcher_thread_params->has_initialized.WaitForNotification();
}
// Monitors exit from a given thread and notifies those
// ThreadIdToThreadLocals about thread termination.
static DWORD WINAPI WatcherThreadFunc(LPVOID param) {
const ThreadIdAndHandle* tah =
reinterpret_cast<const ThreadIdAndHandle*>(param);
GTEST_CHECK_(::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0);
OnThreadExit(tah->first);
::CloseHandle(tah->second);
delete tah;
WatcherThreadParams* watcher_thread_params =
reinterpret_cast<WatcherThreadParams*>(param);
watcher_thread_params->has_initialized.Notify();
GTEST_CHECK_(::WaitForSingleObject(watcher_thread_params->handle,
INFINITE) == WAIT_OBJECT_0);
OnThreadExit(watcher_thread_params->thread_id);
::CloseHandle(watcher_thread_params->handle);
delete watcher_thread_params;
return 0;
}
@@ -697,13 +712,24 @@ bool RE::PartialMatch(const char* str, const RE& re) {
void RE::Init(const char* regex) {
pattern_ = regex;
// NetBSD (and Android, which takes its regex implemntation from NetBSD) does
// not include the GNU regex extensions (such as Perl style character classes
// like \w) in REG_EXTENDED. REG_EXTENDED is only specified to include the
// [[:alpha:]] style character classes. Enable REG_GNU wherever it is defined
// so users can use those extensions.
#if defined(REG_GNU)
constexpr int reg_flags = REG_EXTENDED | REG_GNU;
#else
constexpr int reg_flags = REG_EXTENDED;
#endif
// Reserves enough bytes to hold the regular expression used for a
// full match.
const size_t full_regex_len = strlen(regex) + 10;
char* const full_pattern = new char[full_regex_len];
snprintf(full_pattern, full_regex_len, "^(%s)$", regex);
is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0;
is_valid_ = regcomp(&full_regex_, full_pattern, reg_flags) == 0;
// We want to call regcomp(&partial_regex_, ...) even if the
// previous expression returns false. Otherwise partial_regex_ may
// not be properly initialized can may cause trouble when it's
@@ -714,7 +740,7 @@ void RE::Init(const char* regex) {
// regex. We change it to an equivalent form "()" to be safe.
if (is_valid_) {
const char* const partial_regex = (*regex == '\0') ? "()" : regex;
is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0;
is_valid_ = regcomp(&partial_regex_, partial_regex, reg_flags) == 0;
}
EXPECT_TRUE(is_valid_)
<< "Regular expression \"" << regex
@@ -1022,11 +1048,21 @@ GTestLog::~GTestLog() {
}
}
#if GTEST_HAS_STREAM_REDIRECTION
// Disable Microsoft deprecation warnings for POSIX functions called from
// this class (creat, dup, dup2, and close)
GTEST_DISABLE_MSC_DEPRECATED_PUSH_()
#if GTEST_HAS_STREAM_REDIRECTION
namespace {
#if defined(GTEST_OS_LINUX_ANDROID) || defined(GTEST_OS_IOS)
bool EndsWithPathSeparator(const std::string& path) {
return !path.empty() && path.back() == GTEST_PATH_SEP_[0];
}
#endif
} // namespace
// Object that captures an output stream (stdout/stderr).
class CapturedStream {
@@ -1064,7 +1100,13 @@ class CapturedStream {
// The location /data/local/tmp is directly accessible from native code.
// '/sdcard' and other variants cannot be relied on, as they are not
// guaranteed to be mounted, or may have a delay in mounting.
name_template = "/data/local/tmp/";
//
// However, prefer using the TMPDIR environment variable if set, as newer
// devices may have /data/local/tmp read-only.
name_template = TempDir();
if (!EndsWithPathSeparator(name_template))
name_template.push_back(GTEST_PATH_SEP_[0]);
#elif defined(GTEST_OS_IOS)
char user_temp_dir[PATH_MAX + 1];
@@ -1084,7 +1126,7 @@ class CapturedStream {
::confstr(_CS_DARWIN_USER_TEMP_DIR, user_temp_dir, sizeof(user_temp_dir));
name_template = user_temp_dir;
if (name_template.back() != GTEST_PATH_SEP_[0])
if (!EndsWithPathSeparator(name_template))
name_template.push_back(GTEST_PATH_SEP_[0]);
#else
name_template = "/tmp/";
@@ -1306,8 +1348,8 @@ bool ParseInt32(const Message& src_text, const char* str, int32_t* value) {
) {
Message msg;
msg << "WARNING: " << src_text
<< " is expected to be a 32-bit integer, but actually"
<< " has value " << str << ", which overflows.\n";
<< " is expected to be a 32-bit integer, but actually" << " has value "
<< str << ", which overflows.\n";
printf("%s", msg.GetString().c_str());
fflush(stdout);
return false;

View File

@@ -43,6 +43,7 @@
#include <algorithm>
#include <chrono> // NOLINT
#include <cmath>
#include <csignal> // NOLINT: raise(3) is used on some platforms
#include <cstdint>
#include <cstdlib>
#include <cstring>
@@ -161,6 +162,10 @@
#define GTEST_HAS_BUILTIN(x) 0
#endif // defined(__has_builtin)
#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
#define GTEST_HAS_ABSL_FLAGS
#endif
namespace testing {
using internal::CountIf;
@@ -187,12 +192,17 @@ static const char kDefaultOutputFormat[] = "xml";
// The default output file.
static const char kDefaultOutputFile[] = "test_detail";
// These environment variables are set by Bazel.
// https://bazel.build/reference/test-encyclopedia#initial-conditions
//
// The environment variable name for the test shard index.
static const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
// The environment variable name for the total number of test shards.
static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS";
// The environment variable name for the test shard status file.
static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE";
// The environment variable name for the test output warnings file.
static const char kTestWarningsOutputFile[] = "TEST_WARNINGS_OUTPUT_FILE";
namespace internal {
@@ -253,6 +263,12 @@ GTEST_DEFINE_bool_(
testing::GetDefaultFailFast()),
"True if and only if a test failure should stop further test execution.");
GTEST_DEFINE_bool_(
fail_if_no_test_linked,
testing::internal::BoolFromGTestEnv("fail_if_no_test_linked", false),
"True if and only if the test should fail if no test case (including "
"disabled test cases) is linked.");
GTEST_DEFINE_bool_(
also_run_disabled_tests,
testing::internal::BoolFromGTestEnv("also_run_disabled_tests", false),
@@ -374,7 +390,7 @@ GTEST_DEFINE_string_(
testing::internal::StringFromGTestEnv("stream_result_to", ""),
"This flag specifies the host name and the port number on which to stream "
"test results. Example: \"localhost:555\". The flag is effective only on "
"Linux.");
"Linux and macOS.");
GTEST_DEFINE_bool_(
throw_on_failure,
@@ -446,6 +462,19 @@ static bool ShouldRunTestSuite(const TestSuite* test_suite) {
return test_suite->should_run();
}
namespace {
// Returns true if test part results of type `type` should include a stack
// trace.
bool ShouldEmitStackTraceForResultType(TestPartResult::Type type) {
// Suppress emission of the stack trace for SUCCEED() since it likely never
// requires investigation, and GTEST_SKIP() since skipping is an intentional
// act by the developer rather than a failure requiring investigation.
return type != TestPartResult::kSuccess && type != TestPartResult::kSkip;
}
} // namespace
// AssertHelper constructor.
AssertHelper::AssertHelper(TestPartResult::Type type, const char* file,
int line, const char* message)
@@ -458,7 +487,9 @@ void AssertHelper::operator=(const Message& message) const {
UnitTest::GetInstance()->AddTestPartResult(
data_->type, data_->file, data_->line,
AppendUserMessage(data_->message, message),
UnitTest::GetInstance()->impl()->CurrentOsStackTraceExceptTop(1)
ShouldEmitStackTraceForResultType(data_->type)
? UnitTest::GetInstance()->impl()->CurrentOsStackTraceExceptTop(1)
: ""
// Skips the stack frame for this function itself.
); // NOLINT
}
@@ -516,7 +547,8 @@ void InsertSyntheticTestCase(const std::string& name, CodeLocation location,
if (ignored.find(name) != ignored.end()) return;
const char kMissingInstantiation[] = //
" is defined via TEST_P, but never instantiated. None of the test cases "
" is defined via TEST_P, but never instantiated. None of the test "
"cases "
"will run. Either no INSTANTIATE_TEST_SUITE_P is provided or the only "
"ones provided expand to nothing."
"\n\n"
@@ -557,7 +589,7 @@ void InsertSyntheticTestCase(const std::string& name, CodeLocation location,
void RegisterTypeParameterizedTestSuite(const char* test_suite_name,
CodeLocation code_location) {
GetUnitTestImpl()->type_parameterized_test_registry().RegisterTestSuite(
test_suite_name, code_location);
test_suite_name, std::move(code_location));
}
void RegisterTypeParameterizedTestSuiteInstantiation(const char* case_name) {
@@ -568,7 +600,7 @@ void RegisterTypeParameterizedTestSuiteInstantiation(const char* case_name) {
void TypeParameterizedTestSuiteRegistry::RegisterTestSuite(
const char* test_suite_name, CodeLocation code_location) {
suites_.emplace(std::string(test_suite_name),
TypeParameterizedTestSuiteInfo(code_location));
TypeParameterizedTestSuiteInfo(std::move(code_location)));
}
void TypeParameterizedTestSuiteRegistry::RegisterInstantiation(
@@ -595,10 +627,12 @@ void TypeParameterizedTestSuiteRegistry::CheckForInstantiations() {
"\n\n"
"Ideally, TYPED_TEST_P definitions should only ever be included as "
"part of binaries that intend to use them. (As opposed to, for "
"example, being placed in a library that may be linked in to get other "
"example, being placed in a library that may be linked in to get "
"other "
"utilities.)"
"\n\n"
"To suppress this error for this test suite, insert the following line "
"To suppress this error for this test suite, insert the following "
"line "
"(in a non-header) in the namespace it is defined in:"
"\n\n"
"GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(" +
@@ -638,11 +672,14 @@ static ::std::vector<std::string> g_argvs;
FilePath GetCurrentExecutableName() {
FilePath result;
auto args = GetArgvs();
if (!args.empty()) {
#if defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_OS2)
result.Set(FilePath(GetArgvs()[0]).RemoveExtension("exe"));
result.Set(FilePath(args[0]).RemoveExtension("exe"));
#else
result.Set(FilePath(GetArgvs()[0]));
result.Set(FilePath(args[0]));
#endif // GTEST_OS_WINDOWS
}
return result.RemoveDirectoryName();
}
@@ -778,7 +815,7 @@ class UnitTestFilter {
// Returns true if and only if name matches at least one of the patterns in
// the filter.
bool MatchesName(const std::string& name) const {
return exact_match_patterns_.count(name) > 0 ||
return exact_match_patterns_.find(name) != exact_match_patterns_.end() ||
std::any_of(glob_patterns_.begin(), glob_patterns_.end(),
[&name](const std::string& pattern) {
return PatternMatchesString(
@@ -879,7 +916,7 @@ int UnitTestOptions::GTestProcessSEH(DWORD seh_code, const char* location) {
// apparently).
//
// SEH exception code for C++ exceptions.
// (see http://support.microsoft.com/kb/185294 for more information).
// (see https://support.microsoft.com/kb/185294 for more information).
const DWORD kCxxExceptionCode = 0xe06d7363;
if (!GTEST_FLAG_GET(catch_exceptions) || seh_code == kCxxExceptionCode ||
@@ -1634,10 +1671,25 @@ std::string GetBoolAssertionFailureMessage(
return msg.GetString();
}
// Helper function for implementing ASSERT_NEAR.
// Helper function for implementing ASSERT_NEAR. Treats infinity as a specific
// value, such that comparing infinity to infinity is equal, the distance
// between -infinity and +infinity is infinity, and infinity <= infinity is
// true.
AssertionResult DoubleNearPredFormat(const char* expr1, const char* expr2,
const char* abs_error_expr, double val1,
double val2, double abs_error) {
// We want to return success when the two values are infinity and at least
// one of the following is true:
// * The values are the same-signed infinity.
// * The error limit itself is infinity.
// This is done here so that we don't end up with a NaN when calculating the
// difference in values.
if (std::isinf(val1) && std::isinf(val2) &&
(std::signbit(val1) == std::signbit(val2) ||
(abs_error > 0.0 && std::isinf(abs_error)))) {
return AssertionSuccess();
}
const double diff = fabs(val1 - val2);
if (diff <= abs_error) return AssertionSuccess();
@@ -2317,7 +2369,7 @@ static const char* const kReservedTestCaseAttributes[] = {
"type_param", "value_param", "file", "line"};
// Use a slightly different set for allowed output to ensure existing tests can
// still RecordProperty("result") or "RecordProperty(timestamp")
// still RecordProperty("result") or RecordProperty("timestamp")
static const char* const kReservedOutputTestCaseAttributes[] = {
"classname", "name", "status", "time", "type_param",
"value_param", "file", "line", "result", "timestamp"};
@@ -2717,18 +2769,16 @@ bool Test::IsSkipped() {
// Constructs a TestInfo object. It assumes ownership of the test factory
// object.
TestInfo::TestInfo(const std::string& a_test_suite_name,
const std::string& a_name, const char* a_type_param,
const char* a_value_param,
TestInfo::TestInfo(std::string a_test_suite_name, std::string a_name,
const char* a_type_param, const char* a_value_param,
internal::CodeLocation a_code_location,
internal::TypeId fixture_class_id,
internal::TestFactoryBase* factory)
: test_suite_name_(a_test_suite_name),
// begin()/end() is MSVC 17.3.3 ASAN crash workaround (GitHub issue #3997)
name_(a_name.begin(), a_name.end()),
: test_suite_name_(std::move(a_test_suite_name)),
name_(std::move(a_name)),
type_param_(a_type_param ? new std::string(a_type_param) : nullptr),
value_param_(a_value_param ? new std::string(a_value_param) : nullptr),
location_(a_code_location),
location_(std::move(a_code_location)),
fixture_class_id_(fixture_class_id),
should_run_(false),
is_disabled_(false),
@@ -2761,19 +2811,19 @@ namespace internal {
// The newly created TestInfo instance will assume
// ownership of the factory object.
TestInfo* MakeAndRegisterTestInfo(
const char* test_suite_name, const char* name, const char* type_param,
std::string test_suite_name, const char* name, const char* type_param,
const char* value_param, CodeLocation code_location,
TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc,
TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory) {
TestInfo* const test_info =
new TestInfo(test_suite_name, name, type_param, value_param,
code_location, fixture_class_id, factory);
new TestInfo(std::move(test_suite_name), name, type_param, value_param,
std::move(code_location), fixture_class_id, factory);
GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);
return test_info;
}
void ReportInvalidTestSuiteType(const char* test_suite_name,
CodeLocation code_location) {
const CodeLocation& code_location) {
Message errors;
errors
<< "Attempted redefinition of test suite " << test_suite_name << ".\n"
@@ -2813,14 +2863,13 @@ void TestInfo::Run() {
}
// Tells UnitTest where to store test result.
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
impl->set_current_test_info(this);
UnitTest::GetInstance()->set_current_test_info(this);
// Notifies the unit test event listeners that a test is about to start.
repeater->OnTestStart(*this);
result_.set_start_timestamp(internal::GetTimeInMillis());
internal::Timer timer;
impl->os_stack_trace_getter()->UponLeavingGTest();
UnitTest::GetInstance()->UponLeavingGTest();
// Creates the test object.
Test* const test = internal::HandleExceptionsInMethodIfSupported(
@@ -2838,7 +2887,7 @@ void TestInfo::Run() {
if (test != nullptr) {
// Deletes the test object.
impl->os_stack_trace_getter()->UponLeavingGTest();
UnitTest::GetInstance()->UponLeavingGTest();
internal::HandleExceptionsInMethodIfSupported(
test, &Test::DeleteSelf_, "the test fixture's destructor");
}
@@ -2850,15 +2899,14 @@ void TestInfo::Run() {
// Tells UnitTest to stop associating assertion results to this
// test.
impl->set_current_test_info(nullptr);
UnitTest::GetInstance()->set_current_test_info(nullptr);
}
// Skip and records a skipped test result for this object.
void TestInfo::Skip() {
if (!should_run_) return;
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
impl->set_current_test_info(this);
UnitTest::GetInstance()->set_current_test_info(this);
TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
@@ -2867,12 +2915,13 @@ void TestInfo::Skip() {
const TestPartResult test_part_result =
TestPartResult(TestPartResult::kSkip, this->file(), this->line(), "");
impl->GetTestPartResultReporterForCurrentThread()->ReportTestPartResult(
test_part_result);
internal::GetUnitTestImpl()
->GetTestPartResultReporterForCurrentThread()
->ReportTestPartResult(test_part_result);
// Notifies the unit test event listener that a test has just finished.
repeater->OnTestEnd(*this);
impl->set_current_test_info(nullptr);
UnitTest::GetInstance()->set_current_test_info(nullptr);
}
// class TestSuite
@@ -2926,7 +2975,7 @@ int TestSuite::total_test_count() const {
// this is not a typed or a type-parameterized test suite.
// set_up_tc: pointer to the function that sets up the test suite
// tear_down_tc: pointer to the function that tears down the test suite
TestSuite::TestSuite(const char* a_name, const char* a_type_param,
TestSuite::TestSuite(const std::string& a_name, const char* a_type_param,
internal::SetUpTestSuiteFunc set_up_tc,
internal::TearDownTestSuiteFunc tear_down_tc)
: name_(a_name),
@@ -2968,8 +3017,7 @@ void TestSuite::AddTestInfo(TestInfo* test_info) {
void TestSuite::Run() {
if (!should_run_) return;
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
impl->set_current_test_suite(this);
UnitTest::GetInstance()->set_current_test_suite(this);
TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
@@ -2999,7 +3047,7 @@ void TestSuite::Run() {
repeater->OnTestCaseStart(*this);
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
impl->os_stack_trace_getter()->UponLeavingGTest();
UnitTest::GetInstance()->UponLeavingGTest();
internal::HandleExceptionsInMethodIfSupported(
this, &TestSuite::RunSetUpTestSuite, "SetUpTestSuite()");
@@ -3024,7 +3072,7 @@ void TestSuite::Run() {
}
elapsed_time_ = timer.Elapsed();
impl->os_stack_trace_getter()->UponLeavingGTest();
UnitTest::GetInstance()->UponLeavingGTest();
internal::HandleExceptionsInMethodIfSupported(
this, &TestSuite::RunTearDownTestSuite, "TearDownTestSuite()");
@@ -3035,15 +3083,14 @@ void TestSuite::Run() {
repeater->OnTestCaseEnd(*this);
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
impl->set_current_test_suite(nullptr);
UnitTest::GetInstance()->set_current_test_suite(nullptr);
}
// Skips all tests under this TestSuite.
void TestSuite::Skip() {
if (!should_run_) return;
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
impl->set_current_test_suite(this);
UnitTest::GetInstance()->set_current_test_suite(this);
TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
@@ -3065,7 +3112,7 @@ void TestSuite::Skip() {
repeater->OnTestCaseEnd(*this);
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
impl->set_current_test_suite(nullptr);
UnitTest::GetInstance()->set_current_test_suite(nullptr);
}
// Clears the results of all tests in this test suite.
@@ -3166,9 +3213,9 @@ static void PrintTestPartResult(const TestPartResult& test_part_result) {
}
// class PrettyUnitTestResultPrinter
#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MOBILE) && \
!defined(GTEST_OS_WINDOWS_PHONE) && !defined(GTEST_OS_WINDOWS_RT) && \
!defined(GTEST_OS_WINDOWS_MINGW)
#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MOBILE) && \
!defined(GTEST_OS_WINDOWS_GAMES) && !defined(GTEST_OS_WINDOWS_PHONE) && \
!defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_MINGW)
// Returns the character attribute for the given color.
static WORD GetColorAttribute(GTestColor color) {
@@ -3228,7 +3275,8 @@ static const char* GetAnsiColorCode(GTestColor color) {
case GTestColor::kYellow:
return "3";
default:
return nullptr;
assert(false);
return "9";
}
}
@@ -3251,6 +3299,7 @@ bool ShouldUseColor(bool stdout_is_tty) {
term != nullptr && (String::CStringEquals(term, "xterm") ||
String::CStringEquals(term, "xterm-color") ||
String::CStringEquals(term, "xterm-kitty") ||
String::CStringEquals(term, "alacritty") ||
String::CStringEquals(term, "screen") ||
String::CStringEquals(term, "tmux") ||
String::CStringEquals(term, "rxvt-unicode") ||
@@ -3281,11 +3330,9 @@ static void ColoredPrintf(GTestColor color, const char* fmt, ...) {
va_start(args, fmt);
static const bool in_color_mode =
#if GTEST_HAS_FILE_SYSTEM
// We don't condition this on GTEST_HAS_FILE_SYSTEM because we still need
// to be able to detect terminal I/O regardless.
ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0);
#else
false;
#endif // GTEST_HAS_FILE_SYSTEM
const bool use_color = in_color_mode && (color != GTestColor::kDefault);
@@ -3295,9 +3342,9 @@ static void ColoredPrintf(GTestColor color, const char* fmt, ...) {
return;
}
#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MOBILE) && \
!defined(GTEST_OS_WINDOWS_PHONE) && !defined(GTEST_OS_WINDOWS_RT) && \
!defined(GTEST_OS_WINDOWS_MINGW)
#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MOBILE) && \
!defined(GTEST_OS_WINDOWS_GAMES) && !defined(GTEST_OS_WINDOWS_PHONE) && \
!defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_MINGW)
const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
// Gets the current text color.
@@ -3953,6 +4000,12 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener {
static void OutputXmlTestSuiteForTestResult(::std::ostream* stream,
const TestResult& result);
// Streams a test case XML stanza containing the given test result.
//
// Requires: result.Failed()
static void OutputXmlTestCaseForTestResult(::std::ostream* stream,
const TestResult& result);
// Streams an XML representation of a TestResult object.
static void OutputXmlTestResult(::std::ostream* stream,
const TestResult& result);
@@ -3970,16 +4023,11 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener {
static void PrintXmlUnitTest(::std::ostream* stream,
const UnitTest& unit_test);
// Produces a string representing the test properties in a result as space
// delimited XML attributes based on the property key="value" pairs.
// When the std::string is not empty, it includes a space at the beginning,
// 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);
const TestResult& result,
const std::string& indent);
// The output file.
const std::string output_file_;
@@ -4200,6 +4248,15 @@ void XmlUnitTestResultPrinter::OutputXmlTestSuiteForTestResult(
FormatEpochTimeInMillisAsIso8601(result.start_timestamp()));
*stream << ">";
OutputXmlTestCaseForTestResult(stream, result);
// Complete the test suite.
*stream << " </testsuite>\n";
}
// Streams a test case XML stanza containing the given test result.
void XmlUnitTestResultPrinter::OutputXmlTestCaseForTestResult(
::std::ostream* stream, const TestResult& result) {
// Output the boilerplate for a minimal test case with a single test.
*stream << " <testcase";
OutputXmlAttribute(stream, "testcase", "name", "");
@@ -4214,9 +4271,6 @@ void XmlUnitTestResultPrinter::OutputXmlTestSuiteForTestResult(
// Output the actual test result.
OutputXmlTestResult(stream, result);
// Complete the test suite.
*stream << " </testsuite>\n";
}
// Prints an XML representation of a TestInfo object.
@@ -4307,7 +4361,7 @@ void XmlUnitTestResultPrinter::OutputXmlTestResult(::std::ostream* stream,
if (failures == 0 && skips == 0) {
*stream << ">\n";
}
OutputXmlTestProperties(stream, result);
OutputXmlTestProperties(stream, result, /*indent=*/" ");
*stream << " </testcase>\n";
}
}
@@ -4336,13 +4390,18 @@ void XmlUnitTestResultPrinter::PrintXmlTestSuite(std::ostream* stream,
OutputXmlAttribute(
stream, kTestsuite, "timestamp",
FormatEpochTimeInMillisAsIso8601(test_suite.start_timestamp()));
*stream << TestPropertiesAsXmlAttributes(test_suite.ad_hoc_test_result());
}
*stream << ">\n";
OutputXmlTestProperties(stream, test_suite.ad_hoc_test_result(),
/*indent=*/" ");
for (int i = 0; i < test_suite.total_test_count(); ++i) {
if (test_suite.GetTestInfo(i)->is_reportable())
OutputXmlTestInfo(stream, test_suite.name(), *test_suite.GetTestInfo(i));
}
if (test_suite.ad_hoc_test_result().Failed()) {
OutputXmlTestCaseForTestResult(stream, test_suite.ad_hoc_test_result());
}
*stream << " </" << kTestsuite << ">\n";
}
@@ -4372,11 +4431,12 @@ 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");
*stream << ">\n";
OutputXmlTestProperties(stream, unit_test.ad_hoc_test_result(),
/*indent=*/" ");
for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {
if (unit_test.GetTestSuite(i)->reportable_test_count() > 0)
PrintXmlTestSuite(stream, *unit_test.GetTestSuite(i));
@@ -4413,21 +4473,8 @@ void XmlUnitTestResultPrinter::PrintXmlTestsList(
*stream << "</" << kTestsuites << ">\n";
}
// Produces a string representing the test properties in a result as space
// delimited XML attributes based on the property key="value" pairs.
std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(
const TestResult& result) {
Message attributes;
for (int i = 0; i < result.test_property_count(); ++i) {
const TestProperty& property = result.GetTestProperty(i);
attributes << " " << property.key() << "="
<< "\"" << EscapeXmlAttribute(property.value()) << "\"";
}
return attributes.GetString();
}
void XmlUnitTestResultPrinter::OutputXmlTestProperties(
std::ostream* stream, const TestResult& result) {
std::ostream* stream, const TestResult& result, const std::string& indent) {
const std::string kProperties = "properties";
const std::string kProperty = "property";
@@ -4435,15 +4482,15 @@ void XmlUnitTestResultPrinter::OutputXmlTestProperties(
return;
}
*stream << " <" << kProperties << ">\n";
*stream << indent << "<" << kProperties << ">\n";
for (int i = 0; i < result.test_property_count(); ++i) {
const TestProperty& property = result.GetTestProperty(i);
*stream << " <" << kProperty;
*stream << indent << " <" << kProperty;
*stream << " name=\"" << EscapeXmlAttribute(property.key()) << "\"";
*stream << " value=\"" << EscapeXmlAttribute(property.value()) << "\"";
*stream << "/>\n";
}
*stream << " </" << kProperties << ">\n";
*stream << indent << "</" << kProperties << ">\n";
}
// End XmlUnitTestResultPrinter
@@ -4482,6 +4529,12 @@ class JsonUnitTestResultPrinter : public EmptyTestEventListener {
static void OutputJsonTestSuiteForTestResult(::std::ostream* stream,
const TestResult& result);
// Streams a test case JSON stanza containing the given test result.
//
// Requires: result.Failed()
static void OutputJsonTestCaseForTestResult(::std::ostream* stream,
const TestResult& result);
// Streams a JSON representation of a TestResult object.
static void OutputJsonTestResult(::std::ostream* stream,
const TestResult& result);
@@ -4652,6 +4705,15 @@ void JsonUnitTestResultPrinter::OutputJsonTestSuiteForTestResult(
}
*stream << Indent(6) << "\"testsuite\": [\n";
OutputJsonTestCaseForTestResult(stream, result);
// Finish the test suite.
*stream << "\n" << Indent(6) << "]\n" << Indent(4) << "}";
}
// Streams a test case JSON stanza containing the given test result.
void JsonUnitTestResultPrinter::OutputJsonTestCaseForTestResult(
::std::ostream* stream, const TestResult& result) {
// Output the boilerplate for a new test case.
*stream << Indent(8) << "{\n";
OutputJsonKey(stream, "testcase", "name", "", Indent(10));
@@ -4668,9 +4730,6 @@ void JsonUnitTestResultPrinter::OutputJsonTestSuiteForTestResult(
// Output the actual test result.
OutputJsonTestResult(stream, result);
// Finish the test suite.
*stream << "\n" << Indent(6) << "]\n" << Indent(4) << "}";
}
// Prints a JSON representation of a TestInfo object.
@@ -4725,28 +4784,53 @@ void JsonUnitTestResultPrinter::OutputJsonTestResult(::std::ostream* stream,
const TestResult& result) {
const std::string kIndent = Indent(10);
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";
{
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 << " }";
}
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 << "]";
}
{
int skipped = 0;
for (int i = 0; i < result.total_part_count(); ++i) {
const TestPartResult& part = result.GetTestPartResult(i);
if (part.skipped()) {
*stream << ",\n";
if (++skipped == 1) {
*stream << kIndent << "\"" << "skipped" << "\": [\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 << " \"message\": \"" << message << "\"\n"
<< kIndent << " }";
}
}
if (skipped > 0) *stream << "\n" << kIndent << "]";
}
if (failures > 0) *stream << "\n" << kIndent << "]";
*stream << "\n" << Indent(8) << "}";
}
@@ -4790,6 +4874,16 @@ void JsonUnitTestResultPrinter::PrintJsonTestSuite(
OutputJsonTestInfo(stream, test_suite.name(), *test_suite.GetTestInfo(i));
}
}
// If there was a failure in the test suite setup or teardown include that in
// the output.
if (test_suite.ad_hoc_test_result().Failed()) {
if (comma) {
*stream << ",\n";
}
OutputJsonTestCaseForTestResult(stream, test_suite.ad_hoc_test_result());
}
*stream << "\n" << kIndent << "]\n" << Indent(4) << "}";
}
@@ -4883,8 +4977,8 @@ std::string JsonUnitTestResultPrinter::TestPropertiesAsJson(
for (int i = 0; i < result.test_property_count(); ++i) {
const TestProperty& property = result.GetTestProperty(i);
attributes << ",\n"
<< indent << "\"" << property.key() << "\": "
<< "\"" << EscapeJson(property.value()) << "\"";
<< indent << "\"" << property.key() << "\": " << "\""
<< EscapeJson(property.value()) << "\"";
}
return attributes.GetString();
}
@@ -5282,6 +5376,22 @@ TestSuite* UnitTest::GetMutableTestSuite(int i) {
return impl()->GetMutableSuiteCase(i);
}
void UnitTest::UponLeavingGTest() {
impl()->os_stack_trace_getter()->UponLeavingGTest();
}
// Sets the TestSuite object for the test that's currently running.
void UnitTest::set_current_test_suite(TestSuite* a_current_test_suite) {
internal::MutexLock lock(&mutex_);
impl_->set_current_test_suite(a_current_test_suite);
}
// Sets the TestInfo object for the test that's currently running.
void UnitTest::set_current_test_info(TestInfo* a_current_test_info) {
internal::MutexLock lock(&mutex_);
impl_->set_current_test_info(a_current_test_info);
}
// Returns the list of event listeners that can be used to track events
// inside Google Test.
TestEventListeners& UnitTest::listeners() { return *impl()->listeners(); }
@@ -5399,7 +5509,7 @@ void UnitTest::RecordProperty(const std::string& key,
int UnitTest::Run() {
#ifdef GTEST_HAS_DEATH_TEST
const bool in_death_test_child_process =
GTEST_FLAG_GET(internal_run_death_test).length() > 0;
!GTEST_FLAG_GET(internal_run_death_test).empty();
// Google Test implements this protocol for catching that a test
// program exits before returning control to Google Test:
@@ -5441,7 +5551,7 @@ int UnitTest::Run() {
// about crashes - they are expected.
if (impl()->catch_exceptions() || in_death_test_child_process) {
#if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_WINDOWS_PHONE) && \
!defined(GTEST_OS_WINDOWS_RT)
!defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_GAMES)
// SetErrorMode doesn't exist on CE.
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |
SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
@@ -5711,29 +5821,6 @@ void UnitTestImpl::PostFlagParsingInit() {
}
}
// A predicate that checks the name of a TestSuite against a known
// value.
//
// This is used for implementation of the UnitTest class only. We put
// it in the anonymous namespace to prevent polluting the outer
// namespace.
//
// TestSuiteNameIs is copyable.
class TestSuiteNameIs {
public:
// Constructor.
explicit TestSuiteNameIs(const std::string& name) : name_(name) {}
// Returns true if and only if the name of test_suite matches name_.
bool operator()(const TestSuite* test_suite) const {
return test_suite != nullptr &&
strcmp(test_suite->name(), name_.c_str()) == 0;
}
private:
std::string name_;
};
// Finds and returns a TestSuite with the given name. If one doesn't
// exist, creates one and returns it. It's the CALLER'S
// RESPONSIBILITY to ensure that this function is only called WHEN THE
@@ -5747,19 +5834,27 @@ class TestSuiteNameIs {
// set_up_tc: pointer to the function that sets up the test suite
// tear_down_tc: pointer to the function that tears down the test suite
TestSuite* UnitTestImpl::GetTestSuite(
const char* test_suite_name, const char* type_param,
const std::string& test_suite_name, const char* type_param,
internal::SetUpTestSuiteFunc set_up_tc,
internal::TearDownTestSuiteFunc tear_down_tc) {
// Can we find a TestSuite with the given name?
const auto test_suite =
std::find_if(test_suites_.rbegin(), test_suites_.rend(),
TestSuiteNameIs(test_suite_name));
// During initialization, all TestInfos for a given suite are added in
// sequence. To optimize this case, see if the most recently added suite is
// the one being requested now.
if (!test_suites_.empty() &&
(*test_suites_.rbegin())->name_ == test_suite_name) {
return *test_suites_.rbegin();
}
if (test_suite != test_suites_.rend()) return *test_suite;
// Fall back to searching the collection.
auto item_it = test_suites_by_name_.find(test_suite_name);
if (item_it != test_suites_by_name_.end()) {
return item_it->second;
}
// No. Let's create one.
// Not found. Create a new instance.
auto* const new_test_suite =
new TestSuite(test_suite_name, type_param, set_up_tc, tear_down_tc);
test_suites_by_name_.emplace(test_suite_name, new_test_suite);
const UnitTestFilter death_test_suite_filter(kDeathTestSuiteFilter);
// Is this a death test suite?
@@ -5785,6 +5880,23 @@ TestSuite* UnitTestImpl::GetTestSuite(
static void SetUpEnvironment(Environment* env) { env->SetUp(); }
static void TearDownEnvironment(Environment* env) { env->TearDown(); }
// If the environment variable TEST_WARNINGS_OUTPUT_FILE was provided, appends
// `str` to the file, creating the file if necessary.
#if GTEST_HAS_FILE_SYSTEM
static void AppendToTestWarningsOutputFile(const std::string& str) {
const char* const filename = posix::GetEnv(kTestWarningsOutputFile);
if (filename == nullptr) {
return;
}
auto* const file = posix::FOpen(filename, "a");
if (file == nullptr) {
return;
}
GTEST_CHECK_(fwrite(str.data(), 1, str.size(), file) == str.size());
GTEST_CHECK_(posix::FClose(file) == 0);
}
#endif // GTEST_HAS_FILE_SYSTEM
// Runs all tests in this UnitTest object, prints the result, and
// returns true if all tests are successful. If any exception is
// thrown during a test, the test is considered to be failed, but the
@@ -5806,6 +5918,28 @@ bool UnitTestImpl::RunAllTests() {
// user didn't call InitGoogleTest.
PostFlagParsingInit();
// Handle the case where the program has no tests linked.
// Sometimes this is a programmer mistake, but sometimes it is intended.
if (total_test_count() == 0) {
constexpr char kNoTestLinkedMessage[] =
"This test program does NOT link in any test case.";
constexpr char kNoTestLinkedFatal[] =
"This is INVALID. Please make sure to link in at least one test case.";
constexpr char kNoTestLinkedWarning[] =
"Please make sure this is intended.";
const bool fail_if_no_test_linked = GTEST_FLAG_GET(fail_if_no_test_linked);
ColoredPrintf(
GTestColor::kRed, "%s %s\n", kNoTestLinkedMessage,
fail_if_no_test_linked ? kNoTestLinkedFatal : kNoTestLinkedWarning);
if (fail_if_no_test_linked) {
return false;
}
#if GTEST_HAS_FILE_SYSTEM
AppendToTestWarningsOutputFile(std::string(kNoTestLinkedMessage) + ' ' +
kNoTestLinkedWarning + '\n');
#endif // GTEST_HAS_FILE_SYSTEM
}
#if GTEST_HAS_FILE_SYSTEM
// Even if sharding is not on, test runners may want to use the
// GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding
@@ -5972,6 +6106,23 @@ bool UnitTestImpl::RunAllTests() {
}
repeater->OnTestProgramEnd(*parent_);
// Destroy environments in normal code, not in static teardown.
bool delete_environment_on_teardown = true;
if (delete_environment_on_teardown) {
ForEach(environments_, internal::Delete<Environment>);
environments_.clear();
}
// Try to warn the user if no tests matched the test filter.
if (ShouldWarnIfNoTestsMatchFilter()) {
const std::string filter_warning =
std::string("filter \"") + GTEST_FLAG_GET(filter) +
"\" did not match any test; no tests were run\n";
ColoredPrintf(GTestColor::kRed, "WARNING: %s", filter_warning.c_str());
#if GTEST_HAS_FILE_SYSTEM
AppendToTestWarningsOutputFile(filter_warning);
#endif // GTEST_HAS_FILE_SYSTEM
}
if (!gtest_is_initialized_before_run_all_tests) {
ColoredPrintf(
@@ -6105,12 +6256,11 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
int num_runnable_tests = 0;
int num_selected_tests = 0;
for (auto* test_suite : test_suites_) {
const std::string& test_suite_name = test_suite->name();
const std::string& test_suite_name = test_suite->name_;
test_suite->set_should_run(false);
for (size_t j = 0; j < test_suite->test_info_list().size(); j++) {
TestInfo* const test_info = test_suite->test_info_list()[j];
const std::string test_name(test_info->name());
for (TestInfo* test_info : test_suite->test_info_list()) {
const std::string& test_name = test_info->name_;
// A test is disabled if test suite name or test name matches
// kDisableTestFilter.
const bool is_disabled =
@@ -6142,6 +6292,30 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
return num_selected_tests;
}
// Returns true if a warning should be issued if no tests match the test filter
// flag. We can't simply count the number of tests that ran because, for
// instance, test sharding and death tests might mean no tests are expected to
// run in this process, but will run in another process.
bool UnitTestImpl::ShouldWarnIfNoTestsMatchFilter() const {
if (total_test_count() == 0) {
// No tests were linked in to program.
// This case is handled by a different warning.
return false;
}
const PositiveAndNegativeUnitTestFilter gtest_flag_filter(
GTEST_FLAG_GET(filter));
for (auto* test_suite : test_suites_) {
const std::string& test_suite_name = test_suite->name_;
for (TestInfo* test_info : test_suite->test_info_list()) {
const std::string& test_name = test_info->name_;
if (gtest_flag_filter.MatchesTest(test_suite_name, test_name)) {
return false;
}
}
}
return true;
}
// Prints the given C-string on a single line by replacing all '\n'
// characters with string "\\n". If the output takes more than
// max_length characters, only prints the first max_length characters
@@ -6201,8 +6375,8 @@ void UnitTestImpl::ListTestsMatchingFilter() {
#if GTEST_HAS_FILE_SYSTEM
const std::string& output_format = UnitTestOptions::GetOutputFormat();
if (output_format == "xml" || output_format == "json") {
FILE* fileout = OpenFileForWriting(
UnitTestOptions::GetAbsolutePathToOutputFile().c_str());
FILE* fileout =
OpenFileForWriting(UnitTestOptions::GetAbsolutePathToOutputFile());
std::stringstream stream;
if (output_format == "xml") {
XmlUnitTestResultPrinter(
@@ -6588,6 +6762,7 @@ static bool ParseGoogleTestFlag(const char* const arg) {
GTEST_INTERNAL_PARSE_FLAG(death_test_style);
GTEST_INTERNAL_PARSE_FLAG(death_test_use_fork);
GTEST_INTERNAL_PARSE_FLAG(fail_fast);
GTEST_INTERNAL_PARSE_FLAG(fail_if_no_test_linked);
GTEST_INTERNAL_PARSE_FLAG(filter);
GTEST_INTERNAL_PARSE_FLAG(internal_run_death_test);
GTEST_INTERNAL_PARSE_FLAG(list_tests);
@@ -6651,17 +6826,17 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
}
if (remove_flag) {
// Shift the remainder of the argv list left by one. Note
// that argv has (*argc + 1) elements, the last one always being
// NULL. The following loop moves the trailing NULL element as
// well.
for (int j = i; j != *argc; j++) {
argv[j] = argv[j + 1];
// Shift the remainder of the argv list left by one.
for (int j = i + 1; j < *argc; ++j) {
argv[j - 1] = argv[j];
}
// Decrements the argument count.
(*argc)--;
// Terminate the array with nullptr.
argv[*argc] = nullptr;
// We also need to decrement the iterator as we just removed
// an element.
i--;
@@ -6683,7 +6858,7 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
// remain in place. Unrecognized flags are not reported and do not cause the
// program to exit.
void ParseGoogleTestFlagsOnly(int* argc, char** argv) {
#ifdef GTEST_HAS_ABSL
#ifdef GTEST_HAS_ABSL_FLAGS
if (*argc <= 0) return;
std::vector<char*> positional_args;
@@ -6769,11 +6944,13 @@ void InitGoogleTestImpl(int* argc, CharType** argv) {
#ifdef GTEST_HAS_ABSL
absl::InitializeSymbolizer(g_argvs[0].c_str());
#ifdef GTEST_HAS_ABSL_FLAGS
// When using the Abseil Flags library, set the program usage message to the
// help message, but remove the color-encoding from the message first.
absl::SetProgramUsageMessage(absl::StrReplaceAll(
kColorEncodedHelpMessage,
{{"@D", ""}, {"@R", ""}, {"@G", ""}, {"@Y", ""}, {"@@", "@"}}));
#endif // GTEST_HAS_ABSL_FLAGS
#endif // GTEST_HAS_ABSL
ParseGoogleTestFlagsOnly(argc, argv);