diff --git a/third_party/googletest/googlemock/include/gmock/gmock-matchers.h b/third_party/googletest/googlemock/include/gmock/gmock-matchers.h --- a/third_party/googletest/googlemock/include/gmock/gmock-matchers.h +++ b/third_party/googletest/googlemock/include/gmock/gmock-matchers.h @@ -406,17 +406,26 @@ static Matcher Cast(const Matcher& source_matcher) { return Matcher(new Impl(source_matcher)); } private: - class Impl : public MatcherInterface { + // If it's possible to implicitly convert a `const T&` to U, then `Impl` can + // take that as input to avoid a copy. Otherwise, such as when `T` is a + // non-const reference type or a type explicitly constructible only from a + // non-const reference, then `Impl` must use `T` as-is (potentially copying). + using ImplArgT = + typename std::conditional::value, + const T&, T>::type; + + class Impl : public MatcherInterface { public: explicit Impl(const Matcher& source_matcher) : source_matcher_(source_matcher) {} // We delegate the matching logic to the source matcher. - bool MatchAndExplain(T x, MatchResultListener* listener) const override { + bool MatchAndExplain(ImplArgT x, + MatchResultListener* listener) const override { using FromType = typename std::remove_cv::type>::type>::type; using ToType = typename std::remove_cv::type>::type>::type; // Do not allow implicitly converting base*/& to derived*/&. @@ -429,13 +438,12 @@ !std::is_base_of::value, "Can't implicitly convert from to "); // Do the cast to `U` explicitly if necessary. // Otherwise, let implicit conversions do the trick. - using CastType = - typename std::conditional::value, - T&, U>::type; + using CastType = typename std::conditional< + std::is_convertible::value, ImplArgT&, U>::type; return source_matcher_.MatchAndExplain(static_cast(x), listener); } @@ -526,22 +534,20 @@ // // In general, if type T can be implicitly converted to type U, we can // safely convert a Matcher to a Matcher (i.e. Matcher is // contravariant): just keep a copy of the original Matcher, convert the // argument from type T to U, and then pass it to the underlying Matcher. -// The only exception is when U is a reference and T is not, as the +// The only exception is when U is a non-const reference and T is not, as the // underlying Matcher may be interested in the argument's address, which -// is not preserved in the conversion from T to U. +// cannot be preserved in the conversion from T to U (since a copy of the input +// T argument would be required to provide a non-const reference U). template inline Matcher SafeMatcherCast(const Matcher& matcher) { // Enforce that T can be implicitly converted to U. static_assert(std::is_convertible::value, - "T must be implicitly convertible to U"); - // Enforce that we are not converting a non-reference type T to a reference - // type U. - static_assert(std::is_reference::value || !std::is_reference::value, - "cannot convert non reference arg to reference"); + "T must be implicitly convertible to U (and T must be a " + "non-const reference if U is a non-const reference)"); // In case both T and U are arithmetic types, enforce that the // conversion is not lossy. typedef GTEST_REMOVE_REFERENCE_AND_CONST_(T) RawT; typedef GTEST_REMOVE_REFERENCE_AND_CONST_(U) RawU; constexpr bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther; @@ -2273,18 +2279,21 @@ template class Impl : public MatcherInterface { using ResultType = decltype(CallableTraits::template Invoke( std::declval(), std::declval())); + using InnerType = std::conditional_t< + std::is_lvalue_reference::value, + const typename std::remove_reference::type&, ResultType>; public: template Impl(const std::string& result_description, const CallableStorageType& callable, const M& matcher) : result_description_(result_description), callable_(callable), - matcher_(MatcherCast(matcher)) {} + matcher_(MatcherCast(matcher)) {} void DescribeTo(::std::ostream* os) const override { if (result_description_.empty()) { *os << "is mapped by the given callable to a value that "; } else { @@ -2310,11 +2319,11 @@ } // Cannot pass the return value directly to MatchPrintAndExplain, which // takes a non-const reference as argument. // Also, specifying template argument explicitly is needed because T could // be a non-const reference (e.g. Matcher). - ResultType result = + InnerType result = CallableTraits::template Invoke(callable_, obj); return MatchPrintAndExplain(result, matcher_, listener); } private: @@ -2323,11 +2332,11 @@ // they are actually stateless. But we need to use them even when // 'this' is a const pointer. It's the user's responsibility not to // use stateful callables with ResultOf(), which doesn't guarantee // how many times the callable will be invoked. mutable CallableStorageType callable_; - const Matcher matcher_; + const Matcher matcher_; }; // class Impl const std::string result_description_; const CallableStorageType callable_; const InnerMatcher matcher_; @@ -3289,10 +3298,15 @@ template auto UnpackStructImpl(const T& t, std::make_index_sequence<19>, char) { const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s] = t; return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s); } +template +auto UnpackStructImpl(const T& u, std::make_index_sequence<20>, char) { + const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t] = u; + return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t); +} #endif // defined(__cpp_structured_bindings) template auto UnpackStruct(const T& t) -> decltype((UnpackStructImpl)(t, std::make_index_sequence{}, 0)) { diff --git a/third_party/googletest/googletest/include/gtest/gtest.h b/third_party/googletest/googletest/include/gtest/gtest.h --- a/third_party/googletest/googletest/include/gtest/gtest.h +++ b/third_party/googletest/googletest/include/gtest/gtest.h @@ -71,12 +71,10 @@ #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" -#include "mozilla/Attributes.h" - GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ /* class A needs to have dll-interface to be used by clients of class B */) // Declares the flags. @@ -325,11 +323,11 @@ // // A sub-class must implement this to define the test logic. // // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM. // Instead, use the TEST or TEST_F macro. - MOZ_CAN_RUN_SCRIPT virtual void TestBody() = 0; + virtual void TestBody() = 0; // Sets up, executes, and tears down the test. void Run(); // Deletes self. We deliberately pick an unusual name for this diff --git a/third_party/googletest/googletest/src/gtest.cc b/third_party/googletest/googletest/src/gtest.cc --- a/third_party/googletest/googletest/src/gtest.cc +++ b/third_party/googletest/googletest/src/gtest.cc @@ -4010,20 +4010,15 @@ // Prints an XML summary of unit_test to output stream out. 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_; XmlUnitTestResultPrinter(const XmlUnitTestResultPrinter&) = delete; @@ -4353,11 +4348,11 @@ *stream << " />\n"; } else { if (failures == 0 && skips == 0) { *stream << ">\n"; } - OutputXmlTestProperties(stream, result); + OutputXmlTestProperties(stream, result, /*indent=*/" "); *stream << " \n"; } } // Prints an XML representation of a TestSuite object @@ -4382,13 +4377,14 @@ OutputXmlAttribute(stream, kTestsuite, "time", FormatTimeInMillisAsSeconds(test_suite.elapsed_time())); OutputXmlAttribute( stream, kTestsuite, "timestamp", FormatEpochTimeInMillisAsIso8601(test_suite.start_timestamp())); - *stream << TestPropertiesAsXmlAttributes(test_suite.ad_hoc_test_result()); } *stream << ">\n"; + 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()) { @@ -4422,15 +4418,16 @@ if (GTEST_FLAG_GET(shuffle)) { 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)); } @@ -4463,41 +4460,28 @@ PrintXmlTestSuite(stream, *test_suite); } *stream << "\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"; if (result.test_property_count() <= 0) { 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 << " \n"; + *stream << indent << "\n"; } // End XmlUnitTestResultPrinter #endif // GTEST_HAS_FILE_SYSTEM diff --git a/third_party/googletest/moz.yaml b/third_party/googletest/moz.yaml --- a/third_party/googletest/moz.yaml +++ b/third_party/googletest/moz.yaml @@ -8,13 +8,13 @@ name: googletest description: Google Testing and Mocking Framework url: https://google.github.io/googletest/ - release: 7d76a231b0e29caf86e68d1df858308cd53b2a66 (2024-12-26T23:30:52Z). + release: e235eb34c6c4fed790ccdad4b16394301360dcd4 (2025-01-31T18:23:04Z). - revision: 7d76a231b0e29caf86e68d1df858308cd53b2a66 + revision: e235eb34c6c4fed790ccdad4b16394301360dcd4 license: BSD-3-Clause license-file: LICENSE vendoring: