From 149c0d24148da9a339d6c9d03e638a39c59731f6 Mon Sep 17 00:00:00 2001 From: Peter Levine Date: Fri, 14 Sep 2018 19:40:51 -0400 Subject: [PATCH 1/3] Fix Python3 support --- googletest/test/googletest-env-var-test.py | 4 ++-- googletest/test/googletest-filter-unittest.py | 13 ++++++++----- googletest/test/googletest-output-test.py | 2 +- googletest/test/googletest-throw-on-failure-test.py | 2 +- googletest/test/googletest-uninitialized-test.py | 4 ++-- googletest/test/gtest_xml_output_unittest.py | 3 ++- googletest/test/gtest_xml_test_utils.py | 2 +- 7 files changed, 17 insertions(+), 13 deletions(-) diff --git a/googletest/test/googletest-env-var-test.py b/googletest/test/googletest-env-var-test.py index e1efeee1..2f0e406a 100755 --- a/googletest/test/googletest-env-var-test.py +++ b/googletest/test/googletest-env-var-test.py @@ -45,8 +45,8 @@ environ = os.environ.copy() def AssertEq(expected, actual): if expected != actual: - print 'Expected: %s' % (expected,) - print ' Actual: %s' % (actual,) + print('Expected: %s' % (expected,)) + print(' Actual: %s' % (actual,)) raise AssertionError diff --git a/googletest/test/googletest-filter-unittest.py b/googletest/test/googletest-filter-unittest.py index dc0b5bd9..6b32f2d2 100755 --- a/googletest/test/googletest-filter-unittest.py +++ b/googletest/test/googletest-filter-unittest.py @@ -42,7 +42,10 @@ we test that here also. import os import re -import sets +try: + from sets import Set as set # For Python 2.3 compatibility +except ImportError: + pass import sys import gtest_test_utils @@ -57,7 +60,7 @@ CAN_PASS_EMPTY_ENV = False if sys.executable: os.environ['EMPTY_VAR'] = '' child = gtest_test_utils.Subprocess( - [sys.executable, '-c', 'import os; print \'EMPTY_VAR\' in os.environ']) + [sys.executable, '-c', 'import os; print(\'EMPTY_VAR\' in os.environ)']) CAN_PASS_EMPTY_ENV = eval(child.output) @@ -72,7 +75,7 @@ if sys.executable: os.environ['UNSET_VAR'] = 'X' del os.environ['UNSET_VAR'] child = gtest_test_utils.Subprocess( - [sys.executable, '-c', 'import os; print \'UNSET_VAR\' not in os.environ' + [sys.executable, '-c', 'import os; print(\'UNSET_VAR\' not in os.environ)' ]) CAN_UNSET_ENV = eval(child.output) @@ -245,14 +248,14 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): for slice_var in list_of_sets: full_partition.extend(slice_var) self.assertEqual(len(set_var), len(full_partition)) - self.assertEqual(sets.Set(set_var), sets.Set(full_partition)) + self.assertEqual(set(set_var), set(full_partition)) def AdjustForParameterizedTests(self, tests_to_run): """Adjust tests_to_run in case value parameterized tests are disabled.""" global param_tests_present if not param_tests_present: - return list(sets.Set(tests_to_run) - sets.Set(PARAM_TESTS)) + return list(set(tests_to_run) - set(PARAM_TESTS)) else: return tests_to_run diff --git a/googletest/test/googletest-output-test.py b/googletest/test/googletest-output-test.py index 2d69e353..1a9ee6e3 100755 --- a/googletest/test/googletest-output-test.py +++ b/googletest/test/googletest-output-test.py @@ -287,7 +287,7 @@ class GTestOutputTest(gtest_test_utils.TestCase): # sequences when we read the golden file irrespective of an operating # system used. Therefore, we need to strip those \r's from newlines # unconditionally. - golden = ToUnixLineEnding(golden_file.read()) + golden = ToUnixLineEnding(golden_file.read().decode()) golden_file.close() # We want the test to pass regardless of certain features being diff --git a/googletest/test/googletest-throw-on-failure-test.py b/googletest/test/googletest-throw-on-failure-test.py index 46cb9f6d..204e43e7 100755 --- a/googletest/test/googletest-throw-on-failure-test.py +++ b/googletest/test/googletest-throw-on-failure-test.py @@ -68,7 +68,7 @@ def SetEnvVar(env_var, value): def Run(command): """Runs a command; returns True/False if its exit code is/isn't 0.""" - print 'Running "%s". . .' % ' '.join(command) + print('Running "%s". . .' % ' '.join(command)) p = gtest_test_utils.Subprocess(command) return p.exited and p.exit_code == 0 diff --git a/googletest/test/googletest-uninitialized-test.py b/googletest/test/googletest-uninitialized-test.py index 5b7d1e74..69595a0d 100755 --- a/googletest/test/googletest-uninitialized-test.py +++ b/googletest/test/googletest-uninitialized-test.py @@ -43,8 +43,8 @@ def Assert(condition): def AssertEq(expected, actual): if expected != actual: - print 'Expected: %s' % (expected,) - print ' Actual: %s' % (actual,) + print('Expected: %s' % (expected,)) + print(' Actual: %s' % (actual,)) raise AssertionError diff --git a/googletest/test/gtest_xml_output_unittest.py b/googletest/test/gtest_xml_output_unittest.py index faedd4e6..8669f19e 100755 --- a/googletest/test/gtest_xml_output_unittest.py +++ b/googletest/test/gtest_xml_output_unittest.py @@ -266,7 +266,8 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): 'gtest_no_test_unittest') try: os.remove(output_file) - except OSError, e: + except OSError: + e = sys.exc_info()[1] if e.errno != errno.ENOENT: raise diff --git a/googletest/test/gtest_xml_test_utils.py b/googletest/test/gtest_xml_test_utils.py index 1e035859..afcf55e0 100755 --- a/googletest/test/gtest_xml_test_utils.py +++ b/googletest/test/gtest_xml_test_utils.py @@ -94,7 +94,7 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): self.assertEquals( len(expected_children), len(actual_children), 'number of child elements differ in element ' + actual_node.tagName) - for child_id, child in expected_children.iteritems(): + for child_id, child in expected_children.items(): self.assert_(child_id in actual_children, '<%s> is not in <%s> (in element %s)' % (child_id, actual_children, actual_node.tagName)) From 095b3113e7438fd0be901e20b40d376bcd8ef860 Mon Sep 17 00:00:00 2001 From: Filipp Andjelo Date: Thu, 11 Oct 2018 14:09:57 +0200 Subject: [PATCH 2/3] Use pcfiledir for prefix in pkgconfig file Using absolute paths in the pkg-config file makes it not relocatable and leads to problems, when trying to use it with precompiled cross toolchains. Setting prefix to relative path based on pcfiledir makes it more reliable for such cases. --- googlemock/cmake/gmock.pc.in | 5 +++-- googlemock/cmake/gmock_main.pc.in | 5 +++-- googletest/cmake/gtest.pc.in | 5 +++-- googletest/cmake/gtest_main.pc.in | 5 +++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/googlemock/cmake/gmock.pc.in b/googlemock/cmake/gmock.pc.in index 2ef0fbca..08e04547 100644 --- a/googlemock/cmake/gmock.pc.in +++ b/googlemock/cmake/gmock.pc.in @@ -1,5 +1,6 @@ -libdir=@CMAKE_INSTALL_FULL_LIBDIR@ -includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ +prefix=${pcfiledir}/../.. +libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ Name: gmock Description: GoogleMock (without main() function) diff --git a/googlemock/cmake/gmock_main.pc.in b/googlemock/cmake/gmock_main.pc.in index 04658fe2..b22fe614 100644 --- a/googlemock/cmake/gmock_main.pc.in +++ b/googlemock/cmake/gmock_main.pc.in @@ -1,5 +1,6 @@ -libdir=@CMAKE_INSTALL_FULL_LIBDIR@ -includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ +prefix=${pcfiledir}/../.. +libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ Name: gmock_main Description: GoogleMock (with main() function) diff --git a/googletest/cmake/gtest.pc.in b/googletest/cmake/gtest.pc.in index e7967ad5..9aae29e2 100644 --- a/googletest/cmake/gtest.pc.in +++ b/googletest/cmake/gtest.pc.in @@ -1,5 +1,6 @@ -libdir=@CMAKE_INSTALL_FULL_LIBDIR@ -includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ +prefix=${pcfiledir}/../.. +libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ Name: gtest Description: GoogleTest (without main() function) diff --git a/googletest/cmake/gtest_main.pc.in b/googletest/cmake/gtest_main.pc.in index fe25d9c7..915f2973 100644 --- a/googletest/cmake/gtest_main.pc.in +++ b/googletest/cmake/gtest_main.pc.in @@ -1,5 +1,6 @@ -libdir=@CMAKE_INSTALL_FULL_LIBDIR@ -includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ +prefix=${pcfiledir}/../.. +libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ Name: gtest_main Description: GoogleTest (with main() function) From 82987067d8cc6ee034abd18a78bd444cb41fd2c5 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 22 Oct 2018 11:21:18 -0400 Subject: [PATCH 3/3] Googletest export Change ValuesArray to require much less template instantiation depth. PiperOrigin-RevId: 218170842 --- .../include/gtest/internal/gtest-internal.h | 106 ++++++++++++++++++ .../include/gtest/internal/gtest-param-util.h | 46 ++------ googletest/test/gtest_unittest.cc | 78 +++++++++++++ 3 files changed, 193 insertions(+), 37 deletions(-) diff --git a/googletest/include/gtest/internal/gtest-internal.h b/googletest/include/gtest/internal/gtest-internal.h index 0fe05e23..9d1d8634 100644 --- a/googletest/include/gtest/internal/gtest-internal.h +++ b/googletest/include/gtest/internal/gtest-internal.h @@ -1176,6 +1176,112 @@ class NativeArray { GTEST_DISALLOW_ASSIGN_(NativeArray); }; +// 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 MakeIndexSequence + : DoubleSequence::type, + N / 2>::type {}; + +template <> +struct MakeIndexSequence<0> : IndexSequence<> {}; + +// FIXME: This implementation of ElemFromList is O(1) in instantiation depth, +// but it is O(N^2) in total instantiations. Not sure if this is the best +// tradeoff, as it will make it somewhat slow to compile. +template +struct ElemFromListImpl {}; + +template +struct ElemFromListImpl { + using type = T; +}; + +// Get the Nth element from T... +// It uses O(1) instantiation depth. +template +struct ElemFromList; + +template +struct ElemFromList, T...> + : ElemFromListImpl... {}; + +template +class FlatTuple; + +template +struct FlatTupleElemBase; + +template +struct FlatTupleElemBase, I> { + using value_type = + typename ElemFromList::type, + T...>::type; + FlatTupleElemBase() = default; + explicit FlatTupleElemBase(value_type t) : value(std::move(t)) {} + value_type value; +}; + +template +struct FlatTupleBase; + +template +struct FlatTupleBase, IndexSequence> + : FlatTupleElemBase, Idx>... { + using Indices = IndexSequence; + FlatTupleBase() = default; + explicit FlatTupleBase(T... t) + : FlatTupleElemBase, Idx>(std::move(t))... {} +}; + +// Analog to std::tuple but with different tradeoffs. +// This class minimizes the template instantiation depth, thus allowing more +// elements that std::tuple would. std::tuple has been seen to require an +// instantiation depth of more than 10x the number of elements in some +// 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 +// instantiation depth of O(ln(N)). +template +class FlatTuple + : private FlatTupleBase, + typename MakeIndexSequence::type> { + using Indices = typename FlatTuple::FlatTupleBase::Indices; + + public: + FlatTuple() = default; + explicit FlatTuple(T... t) : FlatTuple::FlatTupleBase(std::move(t)...) {} + + template + const typename ElemFromList::type& Get() const { + return static_cast*>(this)->value; + } + + template + typename ElemFromList::type& Get() { + return static_cast*>(this)->value; + } +}; + } // namespace internal } // namespace testing diff --git a/googletest/include/gtest/internal/gtest-param-util.h b/googletest/include/gtest/internal/gtest-param-util.h index 2dea63cc..d5d4da95 100644 --- a/googletest/include/gtest/internal/gtest-param-util.h +++ b/googletest/include/gtest/internal/gtest-param-util.h @@ -74,27 +74,6 @@ namespace internal { // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // Utility Functions -// Block of code creating for_each_in_tuple -template -struct sequence {}; - -template -struct generate_sequence : generate_sequence {}; - -template -struct generate_sequence<0, Is...> : sequence {}; - -template -void ForEachInTupleImpl(T&& t, F f_gtest, sequence) { - int l[] = {(f_gtest(std::get(t)), 0)...}; - (void)l; // silence "unused variable warning" -} -template -void ForEachInTuple(const std::tuple& t, F f_gtest) { - internal::ForEachInTupleImpl(t, f_gtest, - internal::generate_sequence()); -} - // Outputs a message explaining invalid registration of different // fixture class for the same test case. This may happen when // TEST_P macro is used to define two tests with the same name @@ -747,30 +726,23 @@ internal::ParamGenerator ValuesIn( namespace internal { // Used in the Values() function to provide polymorphic capabilities. -template -struct PushBack { - template - void operator()(const U& u) { - v_.push_back(static_cast(u)); - } - std::vector& v_; -}; - template class ValueArray { public: ValueArray(Ts... v) : v_{std::move(v)...} {} - template - operator ParamGenerator() const { - std::vector vc_accumulate; - PushBack fnc{vc_accumulate}; - ForEachInTuple(v_, fnc); - return ValuesIn(std::move(vc_accumulate)); + template + operator ParamGenerator() const { // NOLINT + return ValuesIn(MakeVector(MakeIndexSequence())); } private: - std::tuple v_; + template + std::vector MakeVector(IndexSequence) const { + return std::vector{static_cast(v_.template Get())...}; + } + + FlatTuple v_; }; } // namespace internal diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc index c6280ca2..9aff4f04 100644 --- a/googletest/test/gtest_unittest.cc +++ b/googletest/test/gtest_unittest.cc @@ -7450,6 +7450,84 @@ TEST(NativeArrayTest, WorksForTwoDimensionalArray) { EXPECT_EQ(a, na.begin()); } +// IndexSequence +TEST(IndexSequence, MakeIndexSequence) { + using testing::internal::IndexSequence; + using testing::internal::MakeIndexSequence; + EXPECT_TRUE( + (std::is_same, MakeIndexSequence<0>::type>::value)); + EXPECT_TRUE( + (std::is_same, MakeIndexSequence<1>::type>::value)); + EXPECT_TRUE( + (std::is_same, MakeIndexSequence<2>::type>::value)); + EXPECT_TRUE(( + std::is_same, MakeIndexSequence<3>::type>::value)); + EXPECT_TRUE( + (std::is_base_of, MakeIndexSequence<3>>::value)); +} + +// ElemFromList +TEST(ElemFromList, Basic) { + using testing::internal::ElemFromList; + using Idx = testing::internal::MakeIndexSequence<3>::type; + EXPECT_TRUE(( + std::is_same::type>::value)); + EXPECT_TRUE( + (std::is_same::type>::value)); + EXPECT_TRUE( + (std::is_same::type>::value)); + EXPECT_TRUE( + (std::is_same< + char, ElemFromList<7, testing::internal::MakeIndexSequence<12>::type, + int, int, int, int, int, int, int, char, int, int, + int, int>::type>::value)); +} + +// FlatTuple +TEST(FlatTuple, Basic) { + using testing::internal::FlatTuple; + + FlatTuple tuple = {}; + EXPECT_EQ(0, tuple.Get<0>()); + EXPECT_EQ(0.0, tuple.Get<1>()); + EXPECT_EQ(nullptr, tuple.Get<2>()); + + tuple = FlatTuple(7, 3.2, "Foo"); + EXPECT_EQ(7, tuple.Get<0>()); + EXPECT_EQ(3.2, tuple.Get<1>()); + EXPECT_EQ(std::string("Foo"), tuple.Get<2>()); + + tuple.Get<1>() = 5.1; + EXPECT_EQ(5.1, tuple.Get<1>()); +} + +TEST(FlatTuple, ManyTypes) { + using testing::internal::FlatTuple; + + // Instantiate FlatTuple with 257 ints. + // Tests show that we can do it with thousands of elements, but very long + // compile times makes it unusuitable for this test. +#define GTEST_FLAT_TUPLE_INT8 int, int, int, int, int, int, int, int, +#define GTEST_FLAT_TUPLE_INT16 GTEST_FLAT_TUPLE_INT8 GTEST_FLAT_TUPLE_INT8 +#define GTEST_FLAT_TUPLE_INT32 GTEST_FLAT_TUPLE_INT16 GTEST_FLAT_TUPLE_INT16 +#define GTEST_FLAT_TUPLE_INT64 GTEST_FLAT_TUPLE_INT32 GTEST_FLAT_TUPLE_INT32 +#define GTEST_FLAT_TUPLE_INT128 GTEST_FLAT_TUPLE_INT64 GTEST_FLAT_TUPLE_INT64 +#define GTEST_FLAT_TUPLE_INT256 GTEST_FLAT_TUPLE_INT128 GTEST_FLAT_TUPLE_INT128 + + // Let's make sure that we can have a very long list of types without blowing + // up the template instantiation depth. + FlatTuple tuple; + + tuple.Get<0>() = 7; + tuple.Get<99>() = 17; + tuple.Get<256>() = 1000; + EXPECT_EQ(7, tuple.Get<0>()); + EXPECT_EQ(17, tuple.Get<99>()); + EXPECT_EQ(1000, tuple.Get<256>()); +} + // Tests SkipPrefix(). TEST(SkipPrefixTest, SkipsWhenPrefixMatches) {