diff --git a/deps/googletest/include/gtest/gtest-assertion-result.h b/deps/googletest/include/gtest/gtest-assertion-result.h index 56fe128f2a5aa7..74eb2b1f3c712c 100644 --- a/deps/googletest/include/gtest/gtest-assertion-result.h +++ b/deps/googletest/include/gtest/gtest-assertion-result.h @@ -129,7 +129,7 @@ namespace testing { // // Expected: Foo() is even // Actual: it's 5 -// + class GTEST_API_ AssertionResult { public: // Copy constructor. diff --git a/deps/googletest/include/gtest/gtest-param-test.h b/deps/googletest/include/gtest/gtest-param-test.h index 49a47ead03b79e..55ee088b93fb8d 100644 --- a/deps/googletest/include/gtest/gtest-param-test.h +++ b/deps/googletest/include/gtest/gtest-param-test.h @@ -178,7 +178,7 @@ TEST_P(DerivedTest, DoesBlah) { #include #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 { @@ -469,7 +469,7 @@ internal::ParamConverterGenerator ConvertGenerator( ::testing::internal::CodeLocation(__FILE__, __LINE__)); \ return 0; \ } \ - static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \ + GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static int gtest_registering_dummy_; \ }; \ int GTEST_TEST_CLASS_NAME_(test_suite_name, \ test_name)::gtest_registering_dummy_ = \ @@ -514,8 +514,8 @@ internal::ParamConverterGenerator ConvertGenerator( ::testing::internal::DefaultParamName, \ DUMMY_PARAM_))))(info); \ } \ - static int gtest_##prefix##test_suite_name##_dummy_ \ - GTEST_ATTRIBUTE_UNUSED_ = \ + GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static int \ + gtest_##prefix##test_suite_name##_dummy_ = \ ::testing::UnitTest::GetInstance() \ ->parameterized_test_registry() \ .GetTestSuitePatternHolder( \ diff --git a/deps/googletest/include/gtest/gtest-typed-test.h b/deps/googletest/include/gtest/gtest-typed-test.h index 72de536bceec8e..305b0b50dd4cda 100644 --- a/deps/googletest/include/gtest/gtest-typed-test.h +++ b/deps/googletest/include/gtest/gtest-typed-test.h @@ -194,33 +194,34 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes); typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type \ GTEST_NAME_GENERATOR_(CaseName) -#define TYPED_TEST(CaseName, TestName) \ - static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1, \ - "test-name must not be empty"); \ - template \ - class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ - : public CaseName { \ - private: \ - typedef CaseName TestFixture; \ - typedef gtest_TypeParam_ TypeParam; \ - void TestBody() override; \ - }; \ - static bool gtest_##CaseName##_##TestName##_registered_ \ - GTEST_ATTRIBUTE_UNUSED_ = ::testing::internal::TypeParameterizedTest< \ - CaseName, \ - ::testing::internal::TemplateSel, \ - GTEST_TYPE_PARAMS_( \ - CaseName)>::Register("", \ - ::testing::internal::CodeLocation( \ - __FILE__, __LINE__), \ - GTEST_STRINGIFY_(CaseName), \ - GTEST_STRINGIFY_(TestName), 0, \ - ::testing::internal::GenerateNames< \ - GTEST_NAME_GENERATOR_(CaseName), \ - GTEST_TYPE_PARAMS_(CaseName)>()); \ - template \ - void GTEST_TEST_CLASS_NAME_(CaseName, \ +#define TYPED_TEST(CaseName, TestName) \ + static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1, \ + "test-name must not be empty"); \ + template \ + class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ + : public CaseName { \ + private: \ + typedef CaseName TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + void TestBody() override; \ + }; \ + GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool \ + gtest_##CaseName##_##TestName##_registered_ = \ + ::testing::internal::TypeParameterizedTest< \ + CaseName, \ + ::testing::internal::TemplateSel, \ + GTEST_TYPE_PARAMS_( \ + CaseName)>::Register("", \ + ::testing::internal::CodeLocation( \ + __FILE__, __LINE__), \ + GTEST_STRINGIFY_(CaseName), \ + GTEST_STRINGIFY_(TestName), 0, \ + ::testing::internal::GenerateNames< \ + GTEST_NAME_GENERATOR_(CaseName), \ + GTEST_TYPE_PARAMS_(CaseName)>()); \ + template \ + void GTEST_TEST_CLASS_NAME_(CaseName, \ TestName)::TestBody() // Legacy API is deprecated but still available @@ -267,22 +268,23 @@ 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 \ - class TestName : public SuiteName { \ - private: \ - typedef SuiteName 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 \ - void GTEST_SUITE_NAMESPACE_( \ +#define TYPED_TEST_P(SuiteName, TestName) \ + namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \ + template \ + class TestName : public SuiteName { \ + private: \ + typedef SuiteName TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + void TestBody() override; \ + }; \ + GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool \ + gtest_##TestName##_defined_ = \ + GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \ + __FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \ + GTEST_STRINGIFY_(TestName)); \ + } \ + template \ + void GTEST_SUITE_NAMESPACE_( \ SuiteName)::TestName::TestBody() // Note: this won't work correctly if the trailing arguments are macros. @@ -290,8 +292,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_ = \ + GTEST_INTERNAL_ATTRIBUTE_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__) @@ -303,22 +305,24 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes); REGISTER_TYPED_TEST_SUITE_P #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ -#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_ = \ - ::testing::internal::TypeParameterizedTestSuite< \ - SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \ - ::testing::internal::GenerateTypeList::type>:: \ - Register(GTEST_STRINGIFY_(Prefix), \ - ::testing::internal::CodeLocation(__FILE__, __LINE__), \ - >EST_TYPED_TEST_SUITE_P_STATE_(SuiteName), \ - GTEST_STRINGIFY_(SuiteName), \ - GTEST_REGISTERED_TEST_NAMES_(SuiteName), \ - ::testing::internal::GenerateNames< \ - ::testing::internal::NameGeneratorSelector< \ - __VA_ARGS__>::type, \ - ::testing::internal::GenerateTypeList::type>()) +#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \ + static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \ + "test-suit-prefix must not be empty"); \ + GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool \ + gtest_##Prefix##_##SuiteName = \ + ::testing::internal::TypeParameterizedTestSuite< \ + SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \ + ::testing::internal::GenerateTypeList::type>:: \ + Register( \ + GTEST_STRINGIFY_(Prefix), \ + ::testing::internal::CodeLocation(__FILE__, __LINE__), \ + >EST_TYPED_TEST_SUITE_P_STATE_(SuiteName), \ + GTEST_STRINGIFY_(SuiteName), \ + GTEST_REGISTERED_TEST_NAMES_(SuiteName), \ + ::testing::internal::GenerateNames< \ + ::testing::internal::NameGeneratorSelector< \ + __VA_ARGS__>::type, \ + ::testing::internal::GenerateTypeList::type>()) // Legacy API is deprecated but still available #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ diff --git a/deps/googletest/include/gtest/gtest.h b/deps/googletest/include/gtest/gtest.h index 45400fd0b2ccd7..c8996695203357 100644 --- a/deps/googletest/include/gtest/gtest.h +++ b/deps/googletest/include/gtest/gtest.h @@ -60,16 +60,16 @@ #include #include -#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" @@ -607,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, @@ -615,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, @@ -683,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); @@ -1262,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_; } @@ -1270,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; @@ -2308,7 +2324,8 @@ 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. diff --git a/deps/googletest/include/gtest/internal/gtest-death-test-internal.h b/deps/googletest/include/gtest/internal/gtest-death-test-internal.h index 61536d6572d36c..3925e36baf12f5 100644 --- a/deps/googletest/include/gtest/internal/gtest-death-test-internal.h +++ b/deps/googletest/include/gtest/internal/gtest-death-test-internal.h @@ -71,7 +71,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: diff --git a/deps/googletest/include/gtest/internal/gtest-filepath.h b/deps/googletest/include/gtest/internal/gtest-filepath.h index 5189c81dabfa66..6dc47be54ad3e7 100644 --- a/deps/googletest/include/gtest/internal/gtest-filepath.h +++ b/deps/googletest/include/gtest/internal/gtest-filepath.h @@ -43,6 +43,7 @@ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ #include +#include #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_; } diff --git a/deps/googletest/include/gtest/internal/gtest-internal.h b/deps/googletest/include/gtest/internal/gtest-internal.h index 806b08624cb45a..7e55dc605cb996 100644 --- a/deps/googletest/include/gtest/internal/gtest-internal.h +++ b/deps/googletest/include/gtest/internal/gtest-internal.h @@ -474,8 +474,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; @@ -564,7 +564,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); @@ -595,8 +595,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; } @@ -700,7 +699,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& type_names = GenerateNames()) { @@ -712,8 +711,7 @@ class TypeParameterizedTest { // list. MakeAndRegisterTestInfo( (std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name + - "/" + type_names[static_cast(index)]) - .c_str(), + "/" + type_names[static_cast(index)]), StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(), GetTypeName().c_str(), nullptr, // No value parameter. @@ -725,13 +723,9 @@ class TypeParameterizedTest { new TestFactoryImpl); // Next, recurses (at compile time) with the tail of the type list. - return TypeParameterizedTest::Register(prefix, - code_location, - case_name, - test_names, - index + 1, - type_names); + return TypeParameterizedTest:: + Register(prefix, std::move(code_location), case_name, test_names, + index + 1, type_names); } }; @@ -739,7 +733,7 @@ class TypeParameterizedTest { template class TypeParameterizedTest { 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& = @@ -786,7 +780,8 @@ class TypeParameterizedTestSuite { // Next, recurses (at compile time) with the tail of the test list. return TypeParameterizedTestSuite::Register(prefix, code_location, + Types>::Register(prefix, + std::move(code_location), state, case_name, SkipComma(test_names), type_names); @@ -1142,40 +1137,6 @@ class NativeArray { void (NativeArray::*clone_)(const Element*, size_t); }; -// Backport of std::index_sequence. -template -struct IndexSequence { - using type = IndexSequence; -}; - -// Double the IndexSequence, and one if plus_one is true. -template -struct DoubleSequence; -template -struct DoubleSequence, sizeofT> { - using type = IndexSequence; -}; -template -struct DoubleSequence, sizeofT> { - using type = IndexSequence; -}; - -// Backport of std::make_index_sequence. -// It uses O(ln(N)) instantiation depth. -template -struct MakeIndexSequenceImpl - : DoubleSequence::type, - N / 2>::type {}; - -template <> -struct MakeIndexSequenceImpl<0> : IndexSequence<> {}; - -template -using MakeIndexSequence = typename MakeIndexSequenceImpl::type; - -template -using IndexSequenceFor = typename MakeIndexSequence::type; - template struct Ignore { Ignore(...); // NOLINT @@ -1184,7 +1145,7 @@ struct Ignore { template struct ElemFromListImpl; template -struct ElemFromListImpl> { +struct ElemFromListImpl> { // 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. @@ -1195,9 +1156,8 @@ struct ElemFromListImpl> { template struct ElemFromList { - using type = - decltype(ElemFromListImpl::type>::Apply( - static_cast(nullptr)...)); + using type = decltype(ElemFromListImpl>::Apply( + static_cast(nullptr)...)); }; struct FlatTupleConstructTag {}; @@ -1222,9 +1182,9 @@ template struct FlatTupleBase; template -struct FlatTupleBase, IndexSequence> +struct FlatTupleBase, std::index_sequence> : FlatTupleElemBase, Idx>... { - using Indices = IndexSequence; + using Indices = std::index_sequence; FlatTupleBase() = default; template explicit FlatTupleBase(FlatTupleConstructTag, Args&&... args) @@ -1259,14 +1219,15 @@ struct FlatTupleBase, IndexSequence> // 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 class FlatTuple : private FlatTupleBase, - typename MakeIndexSequence::type> { - using Indices = typename FlatTupleBase< - FlatTuple, typename MakeIndexSequence::type>::Indices; + std::make_index_sequence> { + using Indices = + typename FlatTupleBase, + std::make_index_sequence>::Indices; public: FlatTuple() = default; @@ -1540,7 +1501,8 @@ class NeverThrown { \ private: \ void TestBody() override; \ - static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_; \ + GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static ::testing::TestInfo* const \ + test_info_; \ }; \ \ ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \ diff --git a/deps/googletest/include/gtest/internal/gtest-param-util.h b/deps/googletest/include/gtest/internal/gtest-param-util.h index b04f7020636083..cc7ea531738c9d 100644 --- a/deps/googletest/include/gtest/internal/gtest-param-util.h +++ b/deps/googletest/include/gtest/internal/gtest-param-util.h @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -85,7 +86,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 class ParamGeneratorInterface; @@ -379,9 +380,7 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface { // integer test parameter index. template std::string DefaultParamName(const TestParamInfo& info) { - Message name_stream; - name_stream << info.index; - return name_stream.GetString(); + return std::to_string(info.index); } template @@ -513,9 +512,10 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { typedef ParamGenerator(GeneratorCreationFunc)(); using ParamNameGeneratorFunc = std::string(const TestParamInfo&); - 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 +529,21 @@ 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* meta_factory, CodeLocation code_location) { - tests_.push_back(std::shared_ptr(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,34 +554,31 @@ 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 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 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_suite_name; + std::string test_name; + for (const std::shared_ptr& test_info : tests_) { + for (const InstantiationInfo& instantiation : instantiations_) { + const std::string& instantiation_name = instantiation.name; + ParamGenerator generator((*instantiation.generator)()); + ParamNameGeneratorFunc* name_func = instantiation.name_func; + const char* file = instantiation.file; + int line = instantiation.line; + 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 test_param_names; - for (typename ParamGenerator::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(*param_it, i)); + name_func(TestParamInfo(param, i)); GTEST_CHECK_(IsValidParamName(param_name)) << "Parameterized test name '" << param_name @@ -592,23 +590,25 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { << "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::GetSetUpCaseOrSuite(file, line), SuiteApiResolver::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 ... @@ -621,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* 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> test_meta_factory; const CodeLocation code_location; @@ -639,11 +637,10 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { // 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), @@ -704,29 +701,32 @@ class ParameterizedTestSuiteRegistry { // tests and instantiations of a particular test suite. template ParameterizedTestSuiteInfo* GetTestSuitePatternHolder( - const char* test_suite_name, CodeLocation code_location) { + std::string test_suite_name, CodeLocation code_location) { ParameterizedTestSuiteInfo* 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()) { - // 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>(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()) { + // 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>( + test_suite_info); } } if (typed_test_info == nullptr) { typed_test_info = new ParameterizedTestSuiteInfo( - 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; @@ -740,8 +740,9 @@ class ParameterizedTestSuiteRegistry { #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ template ParameterizedTestCaseInfo* GetTestCasePatternHolder( - const char* test_case_name, CodeLocation code_location) { - return GetTestSuitePatternHolder(test_case_name, code_location); + std::string test_case_name, CodeLocation code_location) { + return GetTestSuitePatternHolder(std::move(test_case_name), + std::move(code_location)); } #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ @@ -750,6 +751,7 @@ class ParameterizedTestSuiteRegistry { using TestSuiteInfoContainer = ::std::vector; TestSuiteInfoContainer test_suite_infos_; + ::std::unordered_map suite_name_to_info_index_; ParameterizedTestSuiteRegistry(const ParameterizedTestSuiteRegistry&) = delete; @@ -776,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; @@ -805,12 +807,12 @@ class ValueArray { template operator ParamGenerator() const { // NOLINT - return ValuesIn(MakeVector(MakeIndexSequence())); + return ValuesIn(MakeVector(std::make_index_sequence())); } private: template - std::vector MakeVector(IndexSequence) const { + std::vector MakeVector(std::index_sequence) const { return std::vector{static_cast(v_.template Get())...}; } @@ -840,7 +842,7 @@ class CartesianProductGenerator template class IteratorImpl; template - class IteratorImpl> + class IteratorImpl> : public ParamIteratorInterface { public: IteratorImpl(const ParamGeneratorInterface* base, @@ -931,7 +933,7 @@ class CartesianProductGenerator std::shared_ptr current_value_; }; - using Iterator = IteratorImpl::type>; + using Iterator = IteratorImpl>; std::tuple...> generators_; }; diff --git a/deps/googletest/include/gtest/internal/gtest-port-arch.h b/deps/googletest/include/gtest/internal/gtest-port-arch.h index 3162f2b1cbd229..7ec968f312e4f4 100644 --- a/deps/googletest/include/gtest/internal/gtest-port-arch.h +++ b/deps/googletest/include/gtest/internal/gtest-port-arch.h @@ -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. diff --git a/deps/googletest/include/gtest/internal/gtest-port.h b/deps/googletest/include/gtest/internal/gtest-port.h index fa457b7880e011..cd64edf4fddb3f 100644 --- a/deps/googletest/include/gtest/internal/gtest-port.h +++ b/deps/googletest/include/gtest/internal/gtest-port.h @@ -194,8 +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). @@ -340,8 +338,8 @@ #if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS) #define GTEST_INTERNAL_HAS_ABSL_FLAGS // Used only in this file. -#include "absl/flags/flag.h" #include "absl/flags/declare.h" +#include "absl/flags/flag.h" #include "absl/flags/reflection.h" #endif @@ -609,7 +607,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 @@ -659,9 +658,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 @@ -749,6 +748,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 @@ -760,14 +773,22 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; #endif // Use this annotation after a variable or parameter declaration to tell the -// compiler the variable/parameter does not have to be used. +// compiler the variable/parameter may be used. // Example: // -// GTEST_ATTRIBUTE_UNUSED_ int foo = bar(); -#if GTEST_HAVE_ATTRIBUTE_(unused) -#define GTEST_ATTRIBUTE_UNUSED_ __attribute__((unused)) +// GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED int foo = bar(); +// +// This can be removed once we only support only C++17 or newer and +// [[maybe_unused]] is available on all supported platforms. +#if GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(maybe_unused) +#define GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED [[maybe_unused]] +#elif GTEST_HAVE_ATTRIBUTE_(unused) +// This is inferior to [[maybe_unused]] as it can produce a +// -Wused-but-marked-unused warning on optionally used symbols, but it is all we +// have. +#define GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED __attribute__((__unused__)) #else -#define GTEST_ATTRIBUTE_UNUSED_ +#define GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED #endif // Use this annotation before a function that takes a printf format string. @@ -2108,8 +2129,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) { diff --git a/deps/googletest/src/gtest-death-test.cc b/deps/googletest/src/gtest-death-test.cc index 8417a300f7c73d..15472f1a7929cf 100644 --- a/deps/googletest/src/gtest-death-test.cc +++ b/deps/googletest/src/gtest-death-test.cc @@ -32,6 +32,8 @@ #include "gtest/gtest-death-test.h" +#include + #include #include #include @@ -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 CreateArgvFromArgs( - std::vector& args) { - auto result = std::make_unique(args.size() + 1); - for (size_t i = 0; i < args.size(); ++i) { - result[i] = &args[i][0]; +static std::vector CreateArgvFromArgs(std::vector& args) { + std::vector 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 @@ -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 argv = CreateArgvFromArgs(args); - status = fdio_spawn_etc(child_job, FDIO_SPAWN_CLONE_ALL, argv[0], argv.get(), + std::vector 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 argv = CreateArgvFromArgs(args); - const pid_t child_pid = ExecDeathTestSpawnChild(argv.get(), pipe_fd[0]); + std::vector 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]); diff --git a/deps/googletest/src/gtest-internal-inl.h b/deps/googletest/src/gtest-internal-inl.h index 4799a1e7ba5d09..cc6f00488f9608 100644 --- a/deps/googletest/src/gtest-internal-inl.h +++ b/deps/googletest/src/gtest-internal-inl.h @@ -46,6 +46,7 @@ #include #include #include +#include #include #include "gtest/internal/gtest-port.h" @@ -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,30 @@ class GTEST_API_ UnitTestImpl { bool catch_exceptions() const { return catch_exceptions_; } private: + 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 +882,9 @@ class GTEST_API_ UnitTestImpl { // elements in the vector. std::vector test_suites_; + // The set of TestSuites by name. + std::unordered_map 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 diff --git a/deps/googletest/src/gtest-port.cc b/deps/googletest/src/gtest-port.cc index 3bb7dd450812d5..1038ad7bf60209 100644 --- a/deps/googletest/src/gtest-port.cc +++ b/deps/googletest/src/gtest-port.cc @@ -587,9 +587,11 @@ class ThreadLocalRegistryImpl { // thread's ID. typedef std::map ThreadIdToThreadLocals; - // Holds the thread id and thread handle that we pass from - // StartWatcherThreadFor to WatcherThreadFunc. - typedef std::pair 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(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(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(param); - GTEST_CHECK_(::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0); - OnThreadExit(tah->first); - ::CloseHandle(tah->second); - delete tah; + WatcherThreadParams* watcher_thread_params = + reinterpret_cast(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; } @@ -1033,12 +1048,12 @@ 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) @@ -1333,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; diff --git a/deps/googletest/src/gtest.cc b/deps/googletest/src/gtest.cc index 7dc80594362f5a..d64c18d7fd1a8d 100644 --- a/deps/googletest/src/gtest.cc +++ b/deps/googletest/src/gtest.cc @@ -379,7 +379,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, @@ -451,6 +451,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) @@ -463,10 +476,7 @@ void AssertHelper::operator=(const Message& message) const { UnitTest::GetInstance()->AddTestPartResult( data_->type, data_->file, data_->line, AppendUserMessage(data_->message, message), - // Suppress emission of the stack trace for GTEST_SKIP() since skipping is - // an intentional act by the developer rather than a failure requiring - // investigation. - data_->type != TestPartResult::kSkip + ShouldEmitStackTraceForResultType(data_->type) ? UnitTest::GetInstance()->impl()->CurrentOsStackTraceExceptTop(1) : "" // Skips the stack frame for this function itself. @@ -526,7 +536,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" @@ -567,7 +578,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) { @@ -578,7 +589,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( @@ -605,10 +616,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(" + @@ -788,7 +801,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( @@ -2327,7 +2340,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"}; @@ -2727,18 +2740,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), @@ -2771,19 +2782,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" @@ -2823,14 +2834,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( @@ -2848,7 +2858,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"); } @@ -2860,15 +2870,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(); @@ -2877,12 +2886,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 @@ -2936,7 +2946,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), @@ -2978,8 +2988,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(); @@ -3009,7 +3018,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()"); @@ -3034,7 +3043,7 @@ void TestSuite::Run() { } elapsed_time_ = timer.Elapsed(); - impl->os_stack_trace_getter()->UponLeavingGTest(); + UnitTest::GetInstance()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported( this, &TestSuite::RunTearDownTestSuite, "TearDownTestSuite()"); @@ -3045,15 +3054,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(); @@ -3075,7 +3083,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. @@ -3176,9 +3184,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) { @@ -3262,6 +3270,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") || @@ -3304,9 +3313,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. @@ -4429,8 +4438,8 @@ std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( Message attributes; for (int i = 0; i < result.test_property_count(); ++i) { const TestProperty& property = result.GetTestProperty(i); - attributes << " " << property.key() << "=" - << "\"" << EscapeXmlAttribute(property.value()) << "\""; + attributes << " " << property.key() << "=" << "\"" + << EscapeXmlAttribute(property.value()) << "\""; } return attributes.GetString(); } @@ -4734,28 +4743,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 << " }"; + } + } + + 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 << " }"; } - 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 (skipped > 0) *stream << "\n" << kIndent << "]"; } - if (failures > 0) *stream << "\n" << kIndent << "]"; *stream << "\n" << Indent(8) << "}"; } @@ -4892,8 +4926,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(); } @@ -5291,6 +5325,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(); } @@ -5450,7 +5500,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); @@ -5720,29 +5770,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 @@ -5756,19 +5783,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? @@ -5981,6 +6016,12 @@ 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); + environments_.clear(); + } if (!gtest_is_initialized_before_run_all_tests) { ColoredPrintf( @@ -6114,12 +6155,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 =