Use matcher's description in AllOf if matcher has no explanation.
PiperOrigin-RevId: 655569834 Change-Id: Ia760d74d1cdde766e9719864c5e19c0159da3128
This commit is contained in:
		
				
					committed by
					
						
						Copybara-Service
					
				
			
			
				
	
			
			
			
						parent
						
							352788321f
						
					
				
				
					commit
					5bcb2d78a1
				
			@@ -1300,34 +1300,48 @@ class AllOfMatcherImpl : public MatcherInterface<const T&> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  bool MatchAndExplain(const T& x,
 | 
					  bool MatchAndExplain(const T& x,
 | 
				
			||||||
                       MatchResultListener* listener) const override {
 | 
					                       MatchResultListener* listener) const override {
 | 
				
			||||||
    // If either matcher1_ or matcher2_ doesn't match x, we only need
 | 
					    // This method uses matcher's explanation when explaining the result.
 | 
				
			||||||
    // to explain why one of them fails.
 | 
					    // However, if matcher doesn't provide one, this method uses matcher's
 | 
				
			||||||
 | 
					    // description.
 | 
				
			||||||
    std::string all_match_result;
 | 
					    std::string all_match_result;
 | 
				
			||||||
 | 
					    for (const Matcher<T>& matcher : matchers_) {
 | 
				
			||||||
    for (size_t i = 0; i < matchers_.size(); ++i) {
 | 
					 | 
				
			||||||
      StringMatchResultListener slistener;
 | 
					      StringMatchResultListener slistener;
 | 
				
			||||||
      if (matchers_[i].MatchAndExplain(x, &slistener)) {
 | 
					      // Return explanation for first failed matcher.
 | 
				
			||||||
        if (all_match_result.empty()) {
 | 
					      if (!matcher.MatchAndExplain(x, &slistener)) {
 | 
				
			||||||
          all_match_result = slistener.str();
 | 
					        const std::string explanation = slistener.str();
 | 
				
			||||||
 | 
					        if (!explanation.empty()) {
 | 
				
			||||||
 | 
					          *listener << explanation;
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
          std::string result = slistener.str();
 | 
					          *listener << "which doesn't match (" << Describe(matcher) << ")";
 | 
				
			||||||
          if (!result.empty()) {
 | 
					 | 
				
			||||||
            all_match_result += ", and ";
 | 
					 | 
				
			||||||
            all_match_result += result;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        *listener << slistener.str();
 | 
					 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      // Keep track of explanations in case all matchers succeed.
 | 
				
			||||||
 | 
					      std::string explanation = slistener.str();
 | 
				
			||||||
 | 
					      if (explanation.empty()) {
 | 
				
			||||||
 | 
					        explanation = Describe(matcher);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (all_match_result.empty()) {
 | 
				
			||||||
 | 
					        all_match_result = explanation;
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        if (!explanation.empty()) {
 | 
				
			||||||
 | 
					          all_match_result += ", and ";
 | 
				
			||||||
 | 
					          all_match_result += explanation;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Otherwise we need to explain why *both* of them match.
 | 
					 | 
				
			||||||
    *listener << all_match_result;
 | 
					    *listener << all_match_result;
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 private:
 | 
					 private:
 | 
				
			||||||
 | 
					  // Returns matcher description as a string.
 | 
				
			||||||
 | 
					  std::string Describe(const Matcher<T>& matcher) const {
 | 
				
			||||||
 | 
					    StringMatchResultListener listener;
 | 
				
			||||||
 | 
					    matcher.DescribeTo(listener.stream());
 | 
				
			||||||
 | 
					    return listener.str();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  const std::vector<Matcher<T>> matchers_;
 | 
					  const std::vector<Matcher<T>> matchers_;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -559,10 +559,9 @@ TEST_P(AllOfTestP, ExplainsResult) {
 | 
				
			|||||||
  Matcher<int> m;
 | 
					  Matcher<int> m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Successful match.  Both matchers need to explain.  The second
 | 
					  // Successful match.  Both matchers need to explain.  The second
 | 
				
			||||||
  // matcher doesn't give an explanation, so only the first matcher's
 | 
					  // matcher doesn't give an explanation, so the matcher description is used.
 | 
				
			||||||
  // explanation is printed.
 | 
					 | 
				
			||||||
  m = AllOf(GreaterThan(10), Lt(30));
 | 
					  m = AllOf(GreaterThan(10), Lt(30));
 | 
				
			||||||
  EXPECT_EQ("which is 15 more than 10", Explain(m, 25));
 | 
					  EXPECT_EQ("which is 15 more than 10, and is < 30", Explain(m, 25));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Successful match.  Both matchers need to explain.
 | 
					  // Successful match.  Both matchers need to explain.
 | 
				
			||||||
  m = AllOf(GreaterThan(10), GreaterThan(20));
 | 
					  m = AllOf(GreaterThan(10), GreaterThan(20));
 | 
				
			||||||
@@ -572,8 +571,9 @@ TEST_P(AllOfTestP, ExplainsResult) {
 | 
				
			|||||||
  // Successful match.  All matchers need to explain.  The second
 | 
					  // Successful match.  All matchers need to explain.  The second
 | 
				
			||||||
  // matcher doesn't given an explanation.
 | 
					  // matcher doesn't given an explanation.
 | 
				
			||||||
  m = AllOf(GreaterThan(10), Lt(30), GreaterThan(20));
 | 
					  m = AllOf(GreaterThan(10), Lt(30), GreaterThan(20));
 | 
				
			||||||
  EXPECT_EQ("which is 15 more than 10, and which is 5 more than 20",
 | 
					  EXPECT_EQ(
 | 
				
			||||||
            Explain(m, 25));
 | 
					      "which is 15 more than 10, and is < 30, and which is 5 more than 20",
 | 
				
			||||||
 | 
					      Explain(m, 25));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Successful match.  All matchers need to explain.
 | 
					  // Successful match.  All matchers need to explain.
 | 
				
			||||||
  m = AllOf(GreaterThan(10), GreaterThan(20), GreaterThan(30));
 | 
					  m = AllOf(GreaterThan(10), GreaterThan(20), GreaterThan(30));
 | 
				
			||||||
@@ -588,10 +588,10 @@ TEST_P(AllOfTestP, ExplainsResult) {
 | 
				
			|||||||
  EXPECT_EQ("which is 5 less than 10", Explain(m, 5));
 | 
					  EXPECT_EQ("which is 5 less than 10", Explain(m, 5));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Failed match.  The second matcher, which failed, needs to
 | 
					  // Failed match.  The second matcher, which failed, needs to
 | 
				
			||||||
  // explain.  Since it doesn't given an explanation, nothing is
 | 
					  // explain.  Since it doesn't given an explanation, the matcher text is
 | 
				
			||||||
  // printed.
 | 
					  // printed.
 | 
				
			||||||
  m = AllOf(GreaterThan(10), Lt(30));
 | 
					  m = AllOf(GreaterThan(10), Lt(30));
 | 
				
			||||||
  EXPECT_EQ("", Explain(m, 40));
 | 
					  EXPECT_EQ("which doesn't match (is < 30)", Explain(m, 40));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Failed match.  The second matcher, which failed, needs to
 | 
					  // Failed match.  The second matcher, which failed, needs to
 | 
				
			||||||
  // explain.
 | 
					  // explain.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2333,9 +2333,11 @@ TEST(ExplainMatchResultTest, AllOf_True_True) {
 | 
				
			|||||||
  EXPECT_EQ("which is 0 modulo 2, and which is 0 modulo 3", Explain(m, 6));
 | 
					  EXPECT_EQ("which is 0 modulo 2, and which is 0 modulo 3", Explain(m, 6));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Tests that when AllOf() succeeds, but matchers have no explanation,
 | 
				
			||||||
 | 
					// the matcher description is used.
 | 
				
			||||||
TEST(ExplainMatchResultTest, AllOf_True_True_2) {
 | 
					TEST(ExplainMatchResultTest, AllOf_True_True_2) {
 | 
				
			||||||
  const Matcher<int> m = AllOf(Ge(2), Le(3));
 | 
					  const Matcher<int> m = AllOf(Ge(2), Le(3));
 | 
				
			||||||
  EXPECT_EQ("", Explain(m, 2));
 | 
					  EXPECT_EQ("is >= 2, and is <= 3", Explain(m, 2));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
INSTANTIATE_GTEST_MATCHER_TEST_P(ExplainmatcherResultTest);
 | 
					INSTANTIATE_GTEST_MATCHER_TEST_P(ExplainmatcherResultTest);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user