Skip to content

Commit 5bcb2d7

Browse files
Abseil Teamcopybara-github
authored andcommitted
Use matcher's description in AllOf if matcher has no explanation.
PiperOrigin-RevId: 655569834 Change-Id: Ia760d74d1cdde766e9719864c5e19c0159da3128
1 parent 3527883 commit 5bcb2d7

File tree

3 files changed

+39
-23
lines changed

3 files changed

+39
-23
lines changed

googlemock/include/gmock/gmock-matchers.h

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,34 +1300,48 @@ class AllOfMatcherImpl : public MatcherInterface<const T&> {
13001300

13011301
bool MatchAndExplain(const T& x,
13021302
MatchResultListener* listener) const override {
1303-
// If either matcher1_ or matcher2_ doesn't match x, we only need
1304-
// to explain why one of them fails.
1303+
// This method uses matcher's explanation when explaining the result.
1304+
// However, if matcher doesn't provide one, this method uses matcher's
1305+
// description.
13051306
std::string all_match_result;
1306-
1307-
for (size_t i = 0; i < matchers_.size(); ++i) {
1307+
for (const Matcher<T>& matcher : matchers_) {
13081308
StringMatchResultListener slistener;
1309-
if (matchers_[i].MatchAndExplain(x, &slistener)) {
1310-
if (all_match_result.empty()) {
1311-
all_match_result = slistener.str();
1309+
// Return explanation for first failed matcher.
1310+
if (!matcher.MatchAndExplain(x, &slistener)) {
1311+
const std::string explanation = slistener.str();
1312+
if (!explanation.empty()) {
1313+
*listener << explanation;
13121314
} else {
1313-
std::string result = slistener.str();
1314-
if (!result.empty()) {
1315-
all_match_result += ", and ";
1316-
all_match_result += result;
1317-
}
1315+
*listener << "which doesn't match (" << Describe(matcher) << ")";
13181316
}
1319-
} else {
1320-
*listener << slistener.str();
13211317
return false;
13221318
}
1319+
// Keep track of explanations in case all matchers succeed.
1320+
std::string explanation = slistener.str();
1321+
if (explanation.empty()) {
1322+
explanation = Describe(matcher);
1323+
}
1324+
if (all_match_result.empty()) {
1325+
all_match_result = explanation;
1326+
} else {
1327+
if (!explanation.empty()) {
1328+
all_match_result += ", and ";
1329+
all_match_result += explanation;
1330+
}
1331+
}
13231332
}
13241333

1325-
// Otherwise we need to explain why *both* of them match.
13261334
*listener << all_match_result;
13271335
return true;
13281336
}
13291337

13301338
private:
1339+
// Returns matcher description as a string.
1340+
std::string Describe(const Matcher<T>& matcher) const {
1341+
StringMatchResultListener listener;
1342+
matcher.DescribeTo(listener.stream());
1343+
return listener.str();
1344+
}
13311345
const std::vector<Matcher<T>> matchers_;
13321346
};
13331347

googlemock/test/gmock-matchers-arithmetic_test.cc

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -559,10 +559,9 @@ TEST_P(AllOfTestP, ExplainsResult) {
559559
Matcher<int> m;
560560

561561
// Successful match. Both matchers need to explain. The second
562-
// matcher doesn't give an explanation, so only the first matcher's
563-
// explanation is printed.
562+
// matcher doesn't give an explanation, so the matcher description is used.
564563
m = AllOf(GreaterThan(10), Lt(30));
565-
EXPECT_EQ("which is 15 more than 10", Explain(m, 25));
564+
EXPECT_EQ("which is 15 more than 10, and is < 30", Explain(m, 25));
566565

567566
// Successful match. Both matchers need to explain.
568567
m = AllOf(GreaterThan(10), GreaterThan(20));
@@ -572,8 +571,9 @@ TEST_P(AllOfTestP, ExplainsResult) {
572571
// Successful match. All matchers need to explain. The second
573572
// matcher doesn't given an explanation.
574573
m = AllOf(GreaterThan(10), Lt(30), GreaterThan(20));
575-
EXPECT_EQ("which is 15 more than 10, and which is 5 more than 20",
576-
Explain(m, 25));
574+
EXPECT_EQ(
575+
"which is 15 more than 10, and is < 30, and which is 5 more than 20",
576+
Explain(m, 25));
577577

578578
// Successful match. All matchers need to explain.
579579
m = AllOf(GreaterThan(10), GreaterThan(20), GreaterThan(30));
@@ -588,10 +588,10 @@ TEST_P(AllOfTestP, ExplainsResult) {
588588
EXPECT_EQ("which is 5 less than 10", Explain(m, 5));
589589

590590
// Failed match. The second matcher, which failed, needs to
591-
// explain. Since it doesn't given an explanation, nothing is
591+
// explain. Since it doesn't given an explanation, the matcher text is
592592
// printed.
593593
m = AllOf(GreaterThan(10), Lt(30));
594-
EXPECT_EQ("", Explain(m, 40));
594+
EXPECT_EQ("which doesn't match (is < 30)", Explain(m, 40));
595595

596596
// Failed match. The second matcher, which failed, needs to
597597
// explain.

googlemock/test/gmock-matchers-comparisons_test.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2333,9 +2333,11 @@ TEST(ExplainMatchResultTest, AllOf_True_True) {
23332333
EXPECT_EQ("which is 0 modulo 2, and which is 0 modulo 3", Explain(m, 6));
23342334
}
23352335

2336+
// Tests that when AllOf() succeeds, but matchers have no explanation,
2337+
// the matcher description is used.
23362338
TEST(ExplainMatchResultTest, AllOf_True_True_2) {
23372339
const Matcher<int> m = AllOf(Ge(2), Le(3));
2338-
EXPECT_EQ("", Explain(m, 2));
2340+
EXPECT_EQ("is >= 2, and is <= 3", Explain(m, 2));
23392341
}
23402342

23412343
INSTANTIATE_GTEST_MATCHER_TEST_P(ExplainmatcherResultTest);

0 commit comments

Comments
 (0)