mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-19 06:24:51 +08:00
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:
committed by
Compute-Runtime-Automation
parent
ad767725c5
commit
ebb4f48083
2
third_party/gtest/.version
vendored
2
third_party/gtest/.version
vendored
@@ -1,2 +1,2 @@
|
||||
git_url: https://github.com/google/googletest
|
||||
git_revision: v1.14.0
|
||||
git_revision: v1.17.0
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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.
|
||||
|
||||
19
third_party/gtest/include/gtest/gtest-message.h
vendored
19
third_party/gtest/include/gtest/gtest-message.h
vendored
@@ -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
|
||||
|
||||
136
third_party/gtest/include/gtest/gtest-param-test.h
vendored
136
third_party/gtest/include/gtest/gtest-param-test.h
vendored
@@ -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), \
|
||||
>est_##prefix##test_suite_name##_EvalGenerator_, \
|
||||
>est_##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), \
|
||||
>est_##prefix##test_suite_name##_EvalGenerator_, \
|
||||
>est_##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) \
|
||||
|
||||
136
third_party/gtest/include/gtest/gtest-printers.h
vendored
136
third_party/gtest/include/gtest/gtest-printers.h
vendored
@@ -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>
|
||||
|
||||
@@ -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>:: \
|
||||
|
||||
59
third_party/gtest/include/gtest/gtest.h
vendored
59
third_party/gtest/include/gtest/gtest.h
vendored
@@ -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(); }
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_; }
|
||||
|
||||
|
||||
@@ -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, \
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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(>EST_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_
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
36
third_party/gtest/src/gtest-death-test.cc
vendored
36
third_party/gtest/src/gtest-death-test.cc
vendored
@@ -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]);
|
||||
|
||||
2
third_party/gtest/src/gtest-filepath.cc
vendored
2
third_party/gtest/src/gtest-filepath.cc
vendored
@@ -336,7 +336,7 @@ bool FilePath::CreateDirectoriesRecursively() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pathname_.length() == 0 || this->DirectoryExists()) {
|
||||
if (pathname_.empty() || this->DirectoryExists()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
50
third_party/gtest/src/gtest-internal-inl.h
vendored
50
third_party/gtest/src/gtest-internal-inl.h
vendored
@@ -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
|
||||
|
||||
98
third_party/gtest/src/gtest-port.cc
vendored
98
third_party/gtest/src/gtest-port.cc
vendored
@@ -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;
|
||||
|
||||
481
third_party/gtest/src/gtest.cc
vendored
481
third_party/gtest/src/gtest.cc
vendored
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user