diff options
-rw-r--r-- | googlemock/include/gmock/gmock-matchers.h | 59 | ||||
-rw-r--r-- | googlemock/test/gmock-matchers_test.cc | 45 | ||||
-rw-r--r-- | googletest/include/gtest/gtest-matchers.h | 18 |
3 files changed, 82 insertions, 40 deletions
diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index 08fd6d1..0bc9b36 100644 --- a/googlemock/include/gmock/gmock-matchers.h +++ b/googlemock/include/gmock/gmock-matchers.h @@ -903,9 +903,10 @@ bool CaseInsensitiveStringEquals(const StringType& s1, template <typename StringType> class StrEqualityMatcher { public: - StrEqualityMatcher(const StringType& str, bool expect_eq, - bool case_sensitive) - : string_(str), expect_eq_(expect_eq), case_sensitive_(case_sensitive) {} + StrEqualityMatcher(StringType str, bool expect_eq, bool case_sensitive) + : string_(std::move(str)), + expect_eq_(expect_eq), + case_sensitive_(case_sensitive) {} #if GTEST_INTERNAL_HAS_STRING_VIEW bool MatchAndExplain(const internal::StringView& s, @@ -3990,52 +3991,60 @@ internal::ResultOfMatcher<Callable, InnerMatcher> ResultOf( // String matchers. // Matches a string equal to str. -inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrEq( - const std::string& str) { +template <typename T = std::string> +PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrEq( + const internal::StringLike<T>& str) { return MakePolymorphicMatcher( - internal::StrEqualityMatcher<std::string>(str, true, true)); + internal::StrEqualityMatcher<std::string>(std::string(str), true, true)); } // Matches a string not equal to str. -inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrNe( - const std::string& str) { +template <typename T = std::string> +PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrNe( + const internal::StringLike<T>& str) { return MakePolymorphicMatcher( - internal::StrEqualityMatcher<std::string>(str, false, true)); + internal::StrEqualityMatcher<std::string>(std::string(str), false, true)); } // Matches a string equal to str, ignoring case. -inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseEq( - const std::string& str) { +template <typename T = std::string> +PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseEq( + const internal::StringLike<T>& str) { return MakePolymorphicMatcher( - internal::StrEqualityMatcher<std::string>(str, true, false)); + internal::StrEqualityMatcher<std::string>(std::string(str), true, false)); } // Matches a string not equal to str, ignoring case. -inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseNe( - const std::string& str) { - return MakePolymorphicMatcher( - internal::StrEqualityMatcher<std::string>(str, false, false)); +template <typename T = std::string> +PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseNe( + const internal::StringLike<T>& str) { + return MakePolymorphicMatcher(internal::StrEqualityMatcher<std::string>( + std::string(str), false, false)); } // Creates a matcher that matches any string, std::string, or C string // that contains the given substring. -inline PolymorphicMatcher<internal::HasSubstrMatcher<std::string> > HasSubstr( - const std::string& substring) { +template <typename T = std::string> +PolymorphicMatcher<internal::HasSubstrMatcher<std::string> > HasSubstr( + const internal::StringLike<T>& substring) { return MakePolymorphicMatcher( - internal::HasSubstrMatcher<std::string>(substring)); + internal::HasSubstrMatcher<std::string>(std::string(substring))); } // Matches a string that starts with 'prefix' (case-sensitive). -inline PolymorphicMatcher<internal::StartsWithMatcher<std::string> > StartsWith( - const std::string& prefix) { +template <typename T = std::string> +PolymorphicMatcher<internal::StartsWithMatcher<std::string> > StartsWith( + const internal::StringLike<T>& prefix) { return MakePolymorphicMatcher( - internal::StartsWithMatcher<std::string>(prefix)); + internal::StartsWithMatcher<std::string>(std::string(prefix))); } // Matches a string that ends with 'suffix' (case-sensitive). -inline PolymorphicMatcher<internal::EndsWithMatcher<std::string> > EndsWith( - const std::string& suffix) { - return MakePolymorphicMatcher(internal::EndsWithMatcher<std::string>(suffix)); +template <typename T = std::string> +PolymorphicMatcher<internal::EndsWithMatcher<std::string> > EndsWith( + const internal::StringLike<T>& suffix) { + return MakePolymorphicMatcher( + internal::EndsWithMatcher<std::string>(std::string(suffix))); } #if GTEST_HAS_STD_WSTRING diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc index 5db0a7a..a22ff34 100644 --- a/googlemock/test/gmock-matchers_test.cc +++ b/googlemock/test/gmock-matchers_test.cc @@ -1226,6 +1226,25 @@ TEST(RefTest, ExplainsResult) { // Tests string comparison matchers. +template <typename T = std::string> +std::string FromStringLike(internal::StringLike<T> str) { + return std::string(str); +} + +TEST(StringLike, TestConversions) { + EXPECT_EQ("foo", FromStringLike("foo")); + EXPECT_EQ("foo", FromStringLike(std::string("foo"))); +#if GTEST_INTERNAL_HAS_STRING_VIEW + EXPECT_EQ("foo", FromStringLike(internal::StringView("foo"))); +#endif // GTEST_INTERNAL_HAS_STRING_VIEW + + // Non deducible types. + EXPECT_EQ("", FromStringLike({})); + EXPECT_EQ("foo", FromStringLike({'f', 'o', 'o'})); + const char buf[] = "foo"; + EXPECT_EQ("foo", FromStringLike({buf, buf + 3})); +} + TEST(StrEqTest, MatchesEqualString) { Matcher<const char*> m = StrEq(std::string("Hello")); EXPECT_TRUE(m.Matches("Hello")); @@ -1237,7 +1256,8 @@ TEST(StrEqTest, MatchesEqualString) { EXPECT_FALSE(m2.Matches("Hi")); #if GTEST_INTERNAL_HAS_STRING_VIEW - Matcher<const internal::StringView&> m3 = StrEq("Hello"); + Matcher<const internal::StringView&> m3 = + StrEq(internal::StringView("Hello")); EXPECT_TRUE(m3.Matches(internal::StringView("Hello"))); EXPECT_FALSE(m3.Matches(internal::StringView("hello"))); EXPECT_FALSE(m3.Matches(internal::StringView())); @@ -1274,7 +1294,7 @@ TEST(StrNeTest, MatchesUnequalString) { EXPECT_FALSE(m2.Matches("Hello")); #if GTEST_INTERNAL_HAS_STRING_VIEW - Matcher<const internal::StringView> m3 = StrNe("Hello"); + Matcher<const internal::StringView> m3 = StrNe(internal::StringView("Hello")); EXPECT_TRUE(m3.Matches(internal::StringView(""))); EXPECT_TRUE(m3.Matches(internal::StringView())); EXPECT_FALSE(m3.Matches(internal::StringView("Hello"))); @@ -1298,7 +1318,8 @@ TEST(StrCaseEqTest, MatchesEqualStringIgnoringCase) { EXPECT_FALSE(m2.Matches("Hi")); #if GTEST_INTERNAL_HAS_STRING_VIEW - Matcher<const internal::StringView&> m3 = StrCaseEq(std::string("Hello")); + Matcher<const internal::StringView&> m3 = + StrCaseEq(internal::StringView("Hello")); EXPECT_TRUE(m3.Matches(internal::StringView("Hello"))); EXPECT_TRUE(m3.Matches(internal::StringView("hello"))); EXPECT_FALSE(m3.Matches(internal::StringView("Hi"))); @@ -1348,7 +1369,8 @@ TEST(StrCaseNeTest, MatchesUnequalStringIgnoringCase) { EXPECT_FALSE(m2.Matches("Hello")); #if GTEST_INTERNAL_HAS_STRING_VIEW - Matcher<const internal::StringView> m3 = StrCaseNe("Hello"); + Matcher<const internal::StringView> m3 = + StrCaseNe(internal::StringView("Hello")); EXPECT_TRUE(m3.Matches(internal::StringView("Hi"))); EXPECT_TRUE(m3.Matches(internal::StringView())); EXPECT_FALSE(m3.Matches(internal::StringView("Hello"))); @@ -1397,7 +1419,8 @@ TEST(HasSubstrTest, WorksForCStrings) { #if GTEST_INTERNAL_HAS_STRING_VIEW // Tests that HasSubstr() works for matching StringView-typed values. TEST(HasSubstrTest, WorksForStringViewClasses) { - const Matcher<internal::StringView> m1 = HasSubstr("foo"); + const Matcher<internal::StringView> m1 = + HasSubstr(internal::StringView("foo")); EXPECT_TRUE(m1.Matches(internal::StringView("I love food."))); EXPECT_FALSE(m1.Matches(internal::StringView("tofo"))); EXPECT_FALSE(m1.Matches(internal::StringView())); @@ -1650,7 +1673,8 @@ TEST(StartsWithTest, MatchesStringWithGivenPrefix) { EXPECT_FALSE(m2.Matches(" Hi")); #if GTEST_INTERNAL_HAS_STRING_VIEW - const Matcher<internal::StringView> m_empty = StartsWith(""); + const Matcher<internal::StringView> m_empty = + StartsWith(internal::StringView("")); EXPECT_TRUE(m_empty.Matches(internal::StringView())); EXPECT_TRUE(m_empty.Matches(internal::StringView(""))); EXPECT_TRUE(m_empty.Matches(internal::StringView("not empty"))); @@ -1678,7 +1702,8 @@ TEST(EndsWithTest, MatchesStringWithGivenSuffix) { EXPECT_FALSE(m2.Matches("Hi ")); #if GTEST_INTERNAL_HAS_STRING_VIEW - const Matcher<const internal::StringView&> m4 = EndsWith(""); + const Matcher<const internal::StringView&> m4 = + EndsWith(internal::StringView("")); EXPECT_TRUE(m4.Matches("Hi")); EXPECT_TRUE(m4.Matches("")); EXPECT_TRUE(m4.Matches(internal::StringView())); @@ -1710,7 +1735,8 @@ TEST(MatchesRegexTest, MatchesStringMatchingGivenRegex) { EXPECT_TRUE(m3.Matches(internal::StringView("abcz"))); EXPECT_FALSE(m3.Matches(internal::StringView("1az"))); EXPECT_FALSE(m3.Matches(internal::StringView())); - const Matcher<const internal::StringView&> m4 = MatchesRegex(""); + const Matcher<const internal::StringView&> m4 = + MatchesRegex(internal::StringView("")); EXPECT_TRUE(m4.Matches(internal::StringView(""))); EXPECT_TRUE(m4.Matches(internal::StringView())); #endif // GTEST_INTERNAL_HAS_STRING_VIEW @@ -1749,7 +1775,8 @@ TEST(ContainsRegexTest, MatchesStringContainingGivenRegex) { EXPECT_TRUE(m3.Matches(internal::StringView("az1"))); EXPECT_FALSE(m3.Matches(internal::StringView("1a"))); EXPECT_FALSE(m3.Matches(internal::StringView())); - const Matcher<const internal::StringView&> m4 = ContainsRegex(""); + const Matcher<const internal::StringView&> m4 = + ContainsRegex(internal::StringView("")); EXPECT_TRUE(m4.Matches(internal::StringView(""))); EXPECT_TRUE(m4.Matches(internal::StringView())); #endif // GTEST_INTERNAL_HAS_STRING_VIEW diff --git a/googletest/include/gtest/gtest-matchers.h b/googletest/include/gtest/gtest-matchers.h index a61cef4..04cc63d 100644 --- a/googletest/include/gtest/gtest-matchers.h +++ b/googletest/include/gtest/gtest-matchers.h @@ -612,6 +612,10 @@ class GeMatcher : public ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe> { static const char* NegatedDesc() { return "isn't >="; } }; +template <typename T, typename = typename std::enable_if< + std::is_constructible<std::string, T>::value>::type> +using StringLike = T; + // Implements polymorphic matchers MatchesRegex(regex) and // ContainsRegex(regex), which can be used as a Matcher<T> as long as // T can be converted to a string. @@ -672,9 +676,10 @@ inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex( const internal::RE* regex) { return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true)); } -inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex( - const std::string& regex) { - return MatchesRegex(new internal::RE(regex)); +template <typename T = std::string> +PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex( + const internal::StringLike<T>& regex) { + return MatchesRegex(new internal::RE(std::string(regex))); } // Matches a string that contains regular expression 'regex'. @@ -683,9 +688,10 @@ inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex( const internal::RE* regex) { return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false)); } -inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex( - const std::string& regex) { - return ContainsRegex(new internal::RE(regex)); +template <typename T = std::string> +PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex( + const internal::StringLike<T>& regex) { + return ContainsRegex(new internal::RE(std::string(regex))); } // Creates a polymorphic matcher that matches anything equal to x. |