From 5579c1a8b1591d4932495b8cb3cc61f3edca2555 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 30 Jul 2013 06:16:21 +0000 Subject: [PATCH] Makes UnorderedElementsAre*() work with containers that don't have size() or empty(). --- include/gmock/gmock-matchers.h | 14 +++++++------- test/gmock-matchers_test.cc | 32 +++++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/include/gmock/gmock-matchers.h b/include/gmock/gmock-matchers.h index 18ccdca3..0f52ee45 100644 --- a/include/gmock/gmock-matchers.h +++ b/include/gmock/gmock-matchers.h @@ -3095,8 +3095,13 @@ class UnorderedElementsAreMatcherImpl virtual bool MatchAndExplain(Container container, MatchResultListener* listener) const { StlContainerReference stl_container = View::ConstReference(container); - size_t actual_count = stl_container.size(); + ::std::vector element_printouts; + MatchMatrix matrix = AnalyzeElements(stl_container.begin(), + stl_container.end(), + &element_printouts, + listener); + const size_t actual_count = matrix.LhsSize(); if (actual_count == 0 && matchers_.empty()) { return true; } @@ -3111,12 +3116,6 @@ class UnorderedElementsAreMatcherImpl return false; } - ::std::vector element_printouts; - MatchMatrix matrix = AnalyzeElements(stl_container.begin(), - stl_container.end(), - &element_printouts, - listener); - return VerifyAllElementsAndMatchersAreMatched(element_printouts, matrix, listener) && FindPairing(matrix, listener); @@ -3129,6 +3128,7 @@ class UnorderedElementsAreMatcherImpl MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last, ::std::vector* element_printouts, MatchResultListener* listener) const { + element_printouts->clear(); ::std::vector did_match; size_t num_elements = 0; for (; elem_first != elem_last; ++num_elements, ++elem_first) { diff --git a/test/gmock-matchers_test.cc b/test/gmock-matchers_test.cc index 1c43ecb4..ae97c9e0 100644 --- a/test/gmock-matchers_test.cc +++ b/test/gmock-matchers_test.cc @@ -4430,7 +4430,7 @@ TEST(WhenSortedTest, WorksForStreamlike) { // Streamlike 'container' provides only minimal iterator support. // Its iterators are tagged with input_iterator_tag. const int a[5] = { 2, 1, 4, 5, 3 }; - Streamlike s(a, a + 5); + Streamlike s(a, a + GMOCK_ARRAY_SIZE_(a)); EXPECT_THAT(s, WhenSorted(ElementsAre(1, 2, 3, 4, 5))); EXPECT_THAT(s, Not(WhenSorted(ElementsAre(2, 1, 4, 5, 3)))); } @@ -4465,6 +4465,25 @@ TEST(UnorderedElementsAreArrayTest, VectorBool) { actual, &listener)) << listener.str(); } +TEST(UnorderedElementsAreArrayTest, WorksForStreamlike) { + // Streamlike 'container' provides only minimal iterator support. + // Its iterators are tagged with input_iterator_tag, and it has no + // size() or empty() methods. + const int a[5] = { 2, 1, 4, 5, 3 }; + Streamlike s(a, a + GMOCK_ARRAY_SIZE_(a)); + + ::std::vector expected; + expected.push_back(1); + expected.push_back(2); + expected.push_back(3); + expected.push_back(4); + expected.push_back(5); + EXPECT_THAT(s, UnorderedElementsAreArray(expected)); + + expected.push_back(6); + EXPECT_THAT(s, Not(UnorderedElementsAreArray(expected))); +} + class UnorderedElementsAreTest : public testing::Test { protected: typedef std::vector IntVec; @@ -4493,6 +4512,17 @@ TEST_F(UnorderedElementsAreTest, FailsWhenAnElementMatchesNoMatcher) { s, &listener)) << listener.str(); } +TEST_F(UnorderedElementsAreTest, WorksForStreamlike) { + // Streamlike 'container' provides only minimal iterator support. + // Its iterators are tagged with input_iterator_tag, and it has no + // size() or empty() methods. + const int a[5] = { 2, 1, 4, 5, 3 }; + Streamlike s(a, a + GMOCK_ARRAY_SIZE_(a)); + + EXPECT_THAT(s, UnorderedElementsAre(1, 2, 3, 4, 5)); + EXPECT_THAT(s, Not(UnorderedElementsAre(2, 2, 3, 4, 5))); +} + // One naive implementation of the matcher runs in O(N!) time, which is too // slow for many real-world inputs. This test shows that our matcher can match // 100 inputs very quickly (a few milliseconds). An O(100!) is 10^158