summaryrefslogtreecommitdiffstats
path: root/googlemock/test
diff options
context:
space:
mode:
authorAbseil Team <absl-team@google.com>2018-12-11 03:46:47 (GMT)
committerGennadiy Civil <misterg@google.com>2018-12-11 15:11:01 (GMT)
commit06bb8d4d6dcfd1a6111794467676500d955cb144 (patch)
treedeb33fc4bb37c5df30b49e91467dfb8e4a61b91f /googlemock/test
parent695cf7c96249de50360a7d2951dc88eb3aea0695 (diff)
downloadgoogletest-06bb8d4d6dcfd1a6111794467676500d955cb144.zip
googletest-06bb8d4d6dcfd1a6111794467676500d955cb144.tar.gz
googletest-06bb8d4d6dcfd1a6111794467676500d955cb144.tar.bz2
Googletest export
The gmock matchers have a concept of MatchAndExpain; where the details of the matching are written to a "result listener". A matcher can avoid creating expensive debug info by checking result_listener->IsInterested(); but, unfortunately, the default matcher code (called from EXPECT_THAT) is always "interested". This change implements EXPECT_THAT matching to first run the matcher in a "not interested" mode; and then run it a second time ("interested") only if the match fails. PiperOrigin-RevId: 224929783
Diffstat (limited to 'googlemock/test')
-rw-r--r--googlemock/test/gmock-matchers_test.cc89
1 files changed, 84 insertions, 5 deletions
diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc
index dd4931b..8181946 100644
--- a/googlemock/test/gmock-matchers_test.cc
+++ b/googlemock/test/gmock-matchers_test.cc
@@ -85,6 +85,7 @@ using std::pair;
using std::set;
using std::stringstream;
using std::vector;
+using testing::_;
using testing::A;
using testing::AllArgs;
using testing::AllOf;
@@ -110,12 +111,12 @@ using testing::Le;
using testing::Lt;
using testing::MakeMatcher;
using testing::MakePolymorphicMatcher;
-using testing::MatchResultListener;
using testing::Matcher;
using testing::MatcherCast;
using testing::MatcherInterface;
using testing::Matches;
using testing::MatchesRegex;
+using testing::MatchResultListener;
using testing::NanSensitiveDoubleEq;
using testing::NanSensitiveDoubleNear;
using testing::NanSensitiveFloatEq;
@@ -135,15 +136,14 @@ using testing::StartsWith;
using testing::StrCaseEq;
using testing::StrCaseNe;
using testing::StrEq;
-using testing::StrNe;
using testing::StringMatchResultListener;
+using testing::StrNe;
using testing::Truly;
using testing::TypedEq;
using testing::UnorderedPointwise;
using testing::Value;
using testing::WhenSorted;
using testing::WhenSortedBy;
-using testing::_;
using testing::internal::DummyMatchResultListener;
using testing::internal::ElementMatcherPair;
using testing::internal::ElementMatcherPairs;
@@ -152,10 +152,11 @@ using testing::internal::FloatingEqMatcher;
using testing::internal::FormatMatcherDescription;
using testing::internal::IsReadableTypeName;
using testing::internal::MatchMatrix;
+using testing::internal::PredicateFormatterFromMatcher;
using testing::internal::RE;
using testing::internal::StreamMatchResultListener;
-using testing::internal::Strings;
using testing::internal::string;
+using testing::internal::Strings;
// For testing ExplainMatchResultTo().
class GreaterThanMatcher : public MatcherInterface<int> {
@@ -4932,7 +4933,7 @@ TYPED_TEST(ContainerEqTest, DuplicateDifference) {
}
#endif // GTEST_HAS_TYPED_TEST
-// Tests that mutliple missing values are reported.
+// Tests that multiple missing values are reported.
// Using just vector here, so order is predictable.
TEST(ContainerEqExtraTest, MultipleValuesMissing) {
static const int vals[] = {1, 1, 2, 3, 5, 8};
@@ -6910,6 +6911,84 @@ TEST(ArgsTest, ExplainsMatchResultWithInnerExplanation) {
Explain(m, std::make_tuple('\0', 42, 43)));
}
+class PredicateFormatterFromMatcherTest : public ::testing::Test {
+ protected:
+ enum Behavior { kInitialSuccess, kAlwaysFail, kFlaky };
+
+ // A matcher that can return different results when used multiple times on the
+ // same input. No real matcher should do this; but this lets us test that we
+ // detect such behavior and fail appropriately.
+ class MockMatcher : public MatcherInterface<Behavior> {
+ public:
+ bool MatchAndExplain(Behavior behavior,
+ MatchResultListener* listener) const override {
+ *listener << "[MatchAndExplain]";
+ switch (behavior) {
+ case kInitialSuccess:
+ // The first call to MatchAndExplain should use a "not interested"
+ // listener; so this is expected to return |true|. There should be no
+ // subsequent calls.
+ return !listener->IsInterested();
+
+ case kAlwaysFail:
+ return false;
+
+ case kFlaky:
+ // The first call to MatchAndExplain should use a "not interested"
+ // listener; so this will return |false|. Subsequent calls should have
+ // an "interested" listener; so this will return |true|, thus
+ // simulating a flaky matcher.
+ return listener->IsInterested();
+ }
+ }
+
+ void DescribeTo(ostream* os) const override { *os << "[DescribeTo]"; }
+
+ void DescribeNegationTo(ostream* os) const override {
+ *os << "[DescribeNegationTo]";
+ }
+ };
+
+ AssertionResult RunPredicateFormatter(Behavior behavior) {
+ auto matcher = MakeMatcher(new MockMatcher);
+ PredicateFormatterFromMatcher<Matcher<Behavior>> predicate_formatter(
+ matcher);
+ return predicate_formatter("dummy-name", behavior);
+ }
+
+ const std::string kMatcherType =
+ "testing::gmock_matchers_test::PredicateFormatterFromMatcherTest::"
+ "Behavior";
+};
+
+TEST_F(PredicateFormatterFromMatcherTest, ShortCircuitOnSuccess) {
+ AssertionResult result = RunPredicateFormatter(kInitialSuccess);
+ EXPECT_TRUE(result); // Implicit cast to bool.
+ EXPECT_EQ("", result.message());
+}
+
+TEST_F(PredicateFormatterFromMatcherTest, NoShortCircuitOnFailure) {
+ AssertionResult result = RunPredicateFormatter(kAlwaysFail);
+ EXPECT_FALSE(result); // Implicit cast to bool.
+ std::string expect =
+ "Value of: dummy-name\nExpected: [DescribeTo]\n"
+ " Actual: 1" +
+ OfType(kMatcherType) + ", [MatchAndExplain]";
+ EXPECT_EQ(expect, result.message());
+}
+
+TEST_F(PredicateFormatterFromMatcherTest, DetectsFlakyShortCircuit) {
+ AssertionResult result = RunPredicateFormatter(kFlaky);
+ EXPECT_FALSE(result); // Implicit cast to bool.
+ std::string expect =
+ "Value of: dummy-name\nExpected: [DescribeTo]\n"
+ " The matcher failed on the initial attempt; but passed when rerun to "
+ "generate the explanation.\n"
+ " Actual: 2" +
+ OfType(kMatcherType) + ", [MatchAndExplain]";
+ EXPECT_EQ(expect, result.message());
+}
+
} // namespace gmock_matchers_test
} // namespace testing