Makes all container matchers work with (possibly multi-dimensional) native arrays; makes Contains() accept a matcher; adds Value(x, m); improves gmock doctor to diagnose the Type in Template Base disease.

This commit is contained in:
zhanyong.wan
2009-06-04 05:48:20 +00:00
parent c2ad46a5df
commit b82431625d
12 changed files with 1026 additions and 162 deletions

View File

@@ -53,6 +53,7 @@ using std::pair;
using std::set;
using std::stringstream;
using std::vector;
using std::tr1::make_tuple;
using testing::_;
using testing::Contains;
using testing::ElementsAre;
@@ -60,6 +61,7 @@ using testing::ElementsAreArray;
using testing::Eq;
using testing::Ge;
using testing::Gt;
using testing::Lt;
using testing::MakeMatcher;
using testing::Matcher;
using testing::MatcherInterface;
@@ -69,6 +71,7 @@ using testing::Pointee;
using testing::Ref;
using testing::StaticAssertTypeEq;
using testing::StrEq;
using testing::Value;
using testing::internal::string;
// Returns the description of the given matcher.
@@ -330,6 +333,39 @@ TEST(ElementsAreTest, WorksWithContainerPointerUsingPointee) {
EXPECT_THAT(&v, Not(Pointee(ElementsAre(0, _, 3))));
}
TEST(ElementsAreTest, WorksWithNativeArrayPassedByReference) {
int array[] = { 0, 1, 2 };
EXPECT_THAT(array, ElementsAre(0, 1, _));
EXPECT_THAT(array, Not(ElementsAre(1, _, _)));
EXPECT_THAT(array, Not(ElementsAre(0, _)));
}
class NativeArrayPassedAsPointerAndSize {
public:
MOCK_METHOD2(Helper, void(int* array, int size));
};
TEST(ElementsAreTest, WorksWithNativeArrayPassedAsPointerAndSize) {
int array[] = { 0, 1 };
::std::tr1::tuple<int*, size_t> array_as_tuple(array, 2);
EXPECT_THAT(array_as_tuple, ElementsAre(0, 1));
EXPECT_THAT(array_as_tuple, Not(ElementsAre(0)));
NativeArrayPassedAsPointerAndSize helper;
EXPECT_CALL(helper, Helper(_, _))
.WithArguments(ElementsAre(0, 1));
helper.Helper(array, 2);
}
TEST(ElementsAreTest, WorksWithTwoDimensionalNativeArray) {
const char a2[][3] = { "hi", "lo" };
EXPECT_THAT(a2, ElementsAre(ElementsAre('h', 'i', '\0'),
ElementsAre('l', 'o', '\0')));
EXPECT_THAT(a2, ElementsAre(StrEq("hi"), StrEq("lo")));
EXPECT_THAT(a2, ElementsAre(Not(ElementsAre('h', 'o', '\0')),
ElementsAre('l', 'o', '\0')));
}
// Tests for ElementsAreArray(). Since ElementsAreArray() shares most
// of the implementation with ElementsAre(), we don't test it as
// thoroughly here.
@@ -379,6 +415,17 @@ TEST(ElementsAreArrayTest, CanBeCreatedWithMatcherArray) {
EXPECT_THAT(test_vector, Not(ElementsAreArray(kMatcherArray)));
}
// Since ElementsAre() and ElementsAreArray() share much of the
// implementation, we only do a sanity test for native arrays here.
TEST(ElementsAreArrayTest, WorksWithNativeArray) {
::std::string a[] = { "hi", "ho" };
::std::string b[] = { "hi", "ho" };
EXPECT_THAT(a, ElementsAreArray(b));
EXPECT_THAT(a, ElementsAreArray(b, 2));
EXPECT_THAT(a, Not(ElementsAreArray(b, 1)));
}
// Tests for the MATCHER*() macro family.
// Tests that a simple MATCHER() definition works.
@@ -443,12 +490,23 @@ namespace matcher_test {
MATCHER(IsOdd, "") { return (arg % 2) != 0; }
} // namespace matcher_test
TEST(MatcherTest, WorksInNamespace) {
TEST(MatcherMacroTest, WorksInNamespace) {
Matcher<int> m = matcher_test::IsOdd();
EXPECT_FALSE(m.Matches(4));
EXPECT_TRUE(m.Matches(5));
}
// Tests that Value() can be used to compose matchers.
MATCHER(IsPositiveOdd, "") {
return Value(arg, matcher_test::IsOdd()) && arg > 0;
}
TEST(MatcherMacroTest, CanBeComposedUsingValue) {
EXPECT_THAT(3, IsPositiveOdd());
EXPECT_THAT(4, Not(IsPositiveOdd()));
EXPECT_THAT(-1, Not(IsPositiveOdd()));
}
// Tests that a simple MATCHER_P() definition works.
MATCHER_P(IsGreaterThan32And, n, "") { return arg > 32 && arg > n; }
@@ -742,14 +800,31 @@ TEST(MatcherPnMacroTest, TypesAreCorrect) {
EqualsSumOf(1, 2, 3, 4, 5, 6, 7, 8, 9, '0');
}
// Tests that matcher-typed parameters can be used in Value() inside a
// MATCHER_Pn definition.
// Succeeds if arg matches exactly 2 of the 3 matchers.
MATCHER_P3(TwoOf, m1, m2, m3, "") {
const int count = static_cast<int>(Value(arg, m1))
+ static_cast<int>(Value(arg, m2)) + static_cast<int>(Value(arg, m3));
return count == 2;
}
TEST(MatcherPnMacroTest, CanUseMatcherTypedParameterInValue) {
EXPECT_THAT(42, TwoOf(Gt(0), Lt(50), Eq(10)));
EXPECT_THAT(0, Not(TwoOf(Gt(-1), Lt(1), Eq(0))));
}
// Tests Contains().
TEST(ContainsTest, ListMatchesWhenElementIsInContainer) {
list<int> some_list;
some_list.push_back(3);
some_list.push_back(1);
some_list.push_back(2);
EXPECT_THAT(some_list, Contains(1));
EXPECT_THAT(some_list, Contains(3.0));
EXPECT_THAT(some_list, Contains(2.0f));
EXPECT_THAT(some_list, Contains(Gt(2.5)));
EXPECT_THAT(some_list, Contains(Eq(2.0f)));
list<string> another_list;
another_list.push_back("fee");
@@ -771,8 +846,8 @@ TEST(ContainsTest, SetMatchesWhenElementIsInContainer) {
some_set.insert(3);
some_set.insert(1);
some_set.insert(2);
EXPECT_THAT(some_set, Contains(1.0));
EXPECT_THAT(some_set, Contains(3.0f));
EXPECT_THAT(some_set, Contains(Eq(1.0)));
EXPECT_THAT(some_set, Contains(Eq(3.0f)));
EXPECT_THAT(some_set, Contains(2));
set<const char*> another_set;
@@ -780,7 +855,7 @@ TEST(ContainsTest, SetMatchesWhenElementIsInContainer) {
another_set.insert("fie");
another_set.insert("foe");
another_set.insert("fum");
EXPECT_THAT(another_set, Contains(string("fum")));
EXPECT_THAT(another_set, Contains(Eq(string("fum"))));
}
TEST(ContainsTest, SetDoesNotMatchWhenElementIsNotInContainer) {
@@ -795,8 +870,20 @@ TEST(ContainsTest, SetDoesNotMatchWhenElementIsNotInContainer) {
}
TEST(ContainsTest, DescribesItselfCorrectly) {
const int a[2] = { 1, 2 };
Matcher<const int(&)[2]> m = Contains(2);
EXPECT_EQ("element 1 matches", Explain(m, a));
m = Contains(3);
EXPECT_EQ("", Explain(m, a));
}
TEST(ContainsTest, ExplainsMatchResultCorrectly) {
Matcher<vector<int> > m = Contains(1);
EXPECT_EQ("contains 1", Describe(m));
EXPECT_EQ("contains at least one element that is equal to 1", Describe(m));
Matcher<vector<int> > m2 = Not(m);
EXPECT_EQ("doesn't contain any element that is equal to 1", Describe(m2));
}
TEST(ContainsTest, MapMatchesWhenElementIsInContainer) {
@@ -823,7 +910,7 @@ TEST(ContainsTest, MapDoesNotMatchWhenElementIsNotInContainer) {
TEST(ContainsTest, ArrayMatchesWhenElementIsInContainer) {
const char* string_array[] = { "fee", "fie", "foe", "fum" };
EXPECT_THAT(string_array, Contains(string("fum")));
EXPECT_THAT(string_array, Contains(Eq(string("fum"))));
}
TEST(ContainsTest, ArrayDoesNotMatchWhenElementIsNotInContainer) {
@@ -831,4 +918,24 @@ TEST(ContainsTest, ArrayDoesNotMatchWhenElementIsNotInContainer) {
EXPECT_THAT(int_array, Not(Contains(5)));
}
TEST(ContainsTest, AcceptsMatcher) {
const int a[] = { 1, 2, 3 };
EXPECT_THAT(a, Contains(Gt(2)));
EXPECT_THAT(a, Not(Contains(Gt(4))));
}
TEST(ContainsTest, WorksForNativeArrayAsTuple) {
const int a[] = { 1, 2 };
EXPECT_THAT(make_tuple(a, 2), Contains(1));
EXPECT_THAT(make_tuple(a, 2), Not(Contains(Gt(3))));
}
TEST(ContainsTest, WorksForTwoDimensionalNativeArray) {
int a[][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
EXPECT_THAT(a, Contains(ElementsAre(4, 5, 6)));
EXPECT_THAT(a, Contains(Contains(5)));
EXPECT_THAT(a, Not(Contains(ElementsAre(3, 4, 5))));
EXPECT_THAT(a, Contains(Not(Contains(5))));
}
} // namespace