Skip to content

Commit 6dae7eb

Browse files
Abseil Teamcopybara-github
authored andcommitted
Use matcher's description in AnyOf when matcher has no explanation.
PiperOrigin-RevId: 675298308 Change-Id: I32d32cafebc7a63fd03e6d957c3a47043d71e5d9
1 parent 0953a17 commit 6dae7eb

File tree

4 files changed

+71
-45
lines changed

4 files changed

+71
-45
lines changed

googlemock/include/gmock/gmock-matchers.h

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,34 +1419,55 @@ class AnyOfMatcherImpl : public MatcherInterface<const T&> {
14191419

14201420
bool MatchAndExplain(const T& x,
14211421
MatchResultListener* listener) const override {
1422+
// This method uses matcher's explanation when explaining the result.
1423+
// However, if matcher doesn't provide one, this method uses matcher's
1424+
// description.
14221425
std::string no_match_result;
1423-
1424-
// If either matcher1_ or matcher2_ matches x, we just need to
1425-
// explain why *one* of them matches.
1426-
for (size_t i = 0; i < matchers_.size(); ++i) {
1426+
for (const Matcher<T>& matcher : matchers_) {
14271427
StringMatchResultListener slistener;
1428-
if (matchers_[i].MatchAndExplain(x, &slistener)) {
1429-
*listener << slistener.str();
1428+
// Return explanation for first match.
1429+
if (matcher.MatchAndExplain(x, &slistener)) {
1430+
const std::string explanation = slistener.str();
1431+
if (!explanation.empty()) {
1432+
*listener << explanation;
1433+
} else {
1434+
*listener << "which matches (" << Describe(matcher) << ")";
1435+
}
14301436
return true;
1437+
}
1438+
// Keep track of explanations in case there is no match.
1439+
std::string explanation = slistener.str();
1440+
if (explanation.empty()) {
1441+
explanation = DescribeNegation(matcher);
1442+
}
1443+
if (no_match_result.empty()) {
1444+
no_match_result = explanation;
14311445
} else {
1432-
if (no_match_result.empty()) {
1433-
no_match_result = slistener.str();
1434-
} else {
1435-
std::string result = slistener.str();
1436-
if (!result.empty()) {
1437-
no_match_result += ", and ";
1438-
no_match_result += result;
1439-
}
1446+
if (!explanation.empty()) {
1447+
no_match_result += ", and ";
1448+
no_match_result += explanation;
14401449
}
14411450
}
14421451
}
14431452

1444-
// Otherwise we need to explain why *both* of them fail.
14451453
*listener << no_match_result;
14461454
return false;
14471455
}
14481456

14491457
private:
1458+
// Returns matcher description as a string.
1459+
std::string Describe(const Matcher<T>& matcher) const {
1460+
StringMatchResultListener listener;
1461+
matcher.DescribeTo(listener.stream());
1462+
return listener.str();
1463+
}
1464+
1465+
std::string DescribeNegation(const Matcher<T>& matcher) const {
1466+
StringMatchResultListener listener;
1467+
matcher.DescribeNegationTo(listener.stream());
1468+
return listener.str();
1469+
}
1470+
14501471
const std::vector<Matcher<T>> matchers_;
14511472
};
14521473

googlemock/test/gmock-matchers-arithmetic_test.cc

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -776,45 +776,43 @@ TEST(AnyOfTest, AnyOfMatcherSafelyCastsMonomorphicMatchers) {
776776
TEST_P(AnyOfTestP, ExplainsResult) {
777777
Matcher<int> m;
778778

779-
// Failed match. Both matchers need to explain. The second
780-
// matcher doesn't give an explanation, so only the first matcher's
781-
// explanation is printed.
779+
// Failed match. The second matcher have no explanation (description is used).
782780
m = AnyOf(GreaterThan(10), Lt(0));
783-
EXPECT_EQ("which is 5 less than 10", Explain(m, 5));
781+
EXPECT_EQ("which is 5 less than 10, and isn't < 0", Explain(m, 5));
784782

785-
// Failed match. Both matchers need to explain.
783+
// Failed match. Both matchers have explanations.
786784
m = AnyOf(GreaterThan(10), GreaterThan(20));
787785
EXPECT_EQ("which is 5 less than 10, and which is 15 less than 20",
788786
Explain(m, 5));
789787

790-
// Failed match. All matchers need to explain. The second
791-
// matcher doesn't given an explanation.
788+
// Failed match. The middle matcher have no explanation.
792789
m = AnyOf(GreaterThan(10), Gt(20), GreaterThan(30));
793-
EXPECT_EQ("which is 5 less than 10, and which is 25 less than 30",
794-
Explain(m, 5));
790+
EXPECT_EQ(
791+
"which is 5 less than 10, and isn't > 20, and which is 25 less than 30",
792+
Explain(m, 5));
795793

796-
// Failed match. All matchers need to explain.
794+
// Failed match. All three matchers have explanations.
797795
m = AnyOf(GreaterThan(10), GreaterThan(20), GreaterThan(30));
798796
EXPECT_EQ(
799797
"which is 5 less than 10, and which is 15 less than 20, "
800798
"and which is 25 less than 30",
801799
Explain(m, 5));
802800

803-
// Successful match. The first matcher, which succeeded, needs to
804-
// explain.
801+
// Successful match. The first macher succeeded and has explanation.
805802
m = AnyOf(GreaterThan(10), GreaterThan(20));
806803
EXPECT_EQ("which is 5 more than 10", Explain(m, 15));
807804

808-
// Successful match. The second matcher, which succeeded, needs to
809-
// explain. Since it doesn't given an explanation, nothing is
810-
// printed.
811-
m = AnyOf(GreaterThan(10), Lt(30));
812-
EXPECT_EQ("", Explain(m, 0));
813-
814-
// Successful match. The second matcher, which succeeded, needs to
815-
// explain.
805+
// Successful match. The second matcher succeeded and has explanation.
816806
m = AnyOf(GreaterThan(30), GreaterThan(20));
817807
EXPECT_EQ("which is 5 more than 20", Explain(m, 25));
808+
809+
// Successful match. The first matcher succeeded and has no explanation.
810+
m = AnyOf(Gt(10), Lt(20));
811+
EXPECT_EQ("which matches (is > 10)", Explain(m, 15));
812+
813+
// Successful match. The second matcher succeeded and has no explanation.
814+
m = AnyOf(Gt(30), Gt(20));
815+
EXPECT_EQ("which matches (is > 20)", Explain(m, 25));
818816
}
819817

820818
// The following predicate function and predicate functor are for

googlemock/test/gmock-matchers-containers_test.cc

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,13 +1204,16 @@ TEST(SizeIsTest, ExplainsResult) {
12041204
vector<int> container;
12051205
EXPECT_EQ("whose size 0 doesn't match", Explain(m1, container));
12061206
EXPECT_EQ("whose size 0 matches", Explain(m2, container));
1207-
EXPECT_EQ("whose size 0 matches", Explain(m3, container));
1207+
EXPECT_EQ("whose size 0 matches, which matches (is equal to 0)",
1208+
Explain(m3, container));
12081209
EXPECT_EQ("whose size 0 doesn't match", Explain(m4, container));
12091210
container.push_back(0);
12101211
container.push_back(0);
12111212
EXPECT_EQ("whose size 2 matches", Explain(m1, container));
12121213
EXPECT_EQ("whose size 2 doesn't match", Explain(m2, container));
1213-
EXPECT_EQ("whose size 2 doesn't match", Explain(m3, container));
1214+
EXPECT_EQ(
1215+
"whose size 2 doesn't match, isn't equal to 0, and isn't equal to 3",
1216+
Explain(m3, container));
12141217
EXPECT_EQ("whose size 2 matches", Explain(m4, container));
12151218
}
12161219

@@ -1475,8 +1478,10 @@ TEST_P(BeginEndDistanceIsTestP, ExplainsResult) {
14751478
Explain(m1, container));
14761479
EXPECT_EQ("whose distance between begin() and end() 0 matches",
14771480
Explain(m2, container));
1478-
EXPECT_EQ("whose distance between begin() and end() 0 matches",
1479-
Explain(m3, container));
1481+
EXPECT_EQ(
1482+
"whose distance between begin() and end() 0 matches, which matches (is "
1483+
"equal to 0)",
1484+
Explain(m3, container));
14801485
EXPECT_EQ(
14811486
"whose distance between begin() and end() 0 doesn't match, which is 1 "
14821487
"less than 1",
@@ -1487,8 +1492,10 @@ TEST_P(BeginEndDistanceIsTestP, ExplainsResult) {
14871492
Explain(m1, container));
14881493
EXPECT_EQ("whose distance between begin() and end() 2 doesn't match",
14891494
Explain(m2, container));
1490-
EXPECT_EQ("whose distance between begin() and end() 2 doesn't match",
1491-
Explain(m3, container));
1495+
EXPECT_EQ(
1496+
"whose distance between begin() and end() 2 doesn't match, isn't equal "
1497+
"to 0, and isn't equal to 3",
1498+
Explain(m3, container));
14921499
EXPECT_EQ(
14931500
"whose distance between begin() and end() 2 matches, which is 1 more "
14941501
"than 1",

googlemock/test/gmock-matchers-misc_test.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1576,10 +1576,10 @@ TEST_P(AnyOfArrayTestP, ExplainsMatchResultCorrectly) {
15761576
const Matcher<int> m1 = AnyOfArray(v1);
15771577
const Matcher<int> m2 = AnyOfArray(v2);
15781578
EXPECT_EQ("", Explain(m0, 0));
1579-
EXPECT_EQ("", Explain(m1, 1));
1580-
EXPECT_EQ("", Explain(m1, 2));
1581-
EXPECT_EQ("", Explain(m2, 3));
1582-
EXPECT_EQ("", Explain(m2, 4));
1579+
EXPECT_EQ("which matches (is equal to 1)", Explain(m1, 1));
1580+
EXPECT_EQ("isn't equal to 1", Explain(m1, 2));
1581+
EXPECT_EQ("which matches (is equal to 3)", Explain(m2, 3));
1582+
EXPECT_EQ("isn't equal to 2, and isn't equal to 3", Explain(m2, 4));
15831583
EXPECT_EQ("()", Describe(m0));
15841584
EXPECT_EQ("(is equal to 1)", Describe(m1));
15851585
EXPECT_EQ("(is equal to 2) or (is equal to 3)", Describe(m2));

0 commit comments

Comments
 (0)