Adds Each(m) (by Wojtek Moczydlowski); removes scripts/test/Makefile (by Zhanyong Wan); pulls in gtest r424.
This commit is contained in:
parent
090c4830dd
commit
33605ba454
|
@ -137,9 +137,7 @@ EXTRA_DIST += include/gmock/gmock-generated-actions.h.pump \
|
|||
include/gmock/internal/gmock-generated-internal-utils.h.pump
|
||||
|
||||
# Script for fusing Google Mock and Google Test source files.
|
||||
EXTRA_DIST += \
|
||||
scripts/fuse_gmock_files.py \
|
||||
scripts/test/Makefile
|
||||
EXTRA_DIST += scripts/fuse_gmock_files.py
|
||||
|
||||
# The Google Mock Generator tool from the cppclean project.
|
||||
EXTRA_DIST += \
|
||||
|
|
|
@ -1947,9 +1947,9 @@ class ContainerEqMatcher {
|
|||
GTEST_DISALLOW_ASSIGN_(ContainerEqMatcher);
|
||||
};
|
||||
|
||||
// Implements Contains(element_matcher) for the given argument type Container.
|
||||
// Holds the logic common to ContainsMatcherImpl and EachMatcherImpl.
|
||||
template <typename Container>
|
||||
class ContainsMatcherImpl : public MatcherInterface<Container> {
|
||||
class QuantifierMatcherImpl : public MatcherInterface<Container> {
|
||||
public:
|
||||
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container)) RawContainer;
|
||||
typedef StlContainerView<RawContainer> View;
|
||||
|
@ -1958,44 +1958,97 @@ class ContainsMatcherImpl : public MatcherInterface<Container> {
|
|||
typedef typename StlContainer::value_type Element;
|
||||
|
||||
template <typename InnerMatcher>
|
||||
explicit ContainsMatcherImpl(InnerMatcher inner_matcher)
|
||||
explicit QuantifierMatcherImpl(InnerMatcher inner_matcher)
|
||||
: inner_matcher_(
|
||||
testing::SafeMatcherCast<const Element&>(inner_matcher)) {}
|
||||
testing::SafeMatcherCast<const Element&>(inner_matcher)) {}
|
||||
|
||||
// Describes what this matcher does.
|
||||
virtual void DescribeTo(::std::ostream* os) const {
|
||||
*os << "contains at least one element that ";
|
||||
inner_matcher_.DescribeTo(os);
|
||||
}
|
||||
|
||||
// Describes what the negation of this matcher does.
|
||||
virtual void DescribeNegationTo(::std::ostream* os) const {
|
||||
*os << "doesn't contain any element that ";
|
||||
inner_matcher_.DescribeTo(os);
|
||||
}
|
||||
|
||||
virtual bool MatchAndExplain(Container container,
|
||||
MatchResultListener* listener) const {
|
||||
// Checks whether:
|
||||
// * All elements in the container match, if all_elements_should_match.
|
||||
// * Any element in the container matches, if !all_elements_should_match.
|
||||
bool MatchAndExplainImpl(bool all_elements_should_match,
|
||||
Container container,
|
||||
MatchResultListener* listener) const {
|
||||
StlContainerReference stl_container = View::ConstReference(container);
|
||||
size_t i = 0;
|
||||
for (typename StlContainer::const_iterator it = stl_container.begin();
|
||||
it != stl_container.end(); ++it, ++i) {
|
||||
StringMatchResultListener inner_listener;
|
||||
if (inner_matcher_.MatchAndExplain(*it, &inner_listener)) {
|
||||
*listener << "whose element #" << i << " matches";
|
||||
const bool matches = inner_matcher_.MatchAndExplain(*it, &inner_listener);
|
||||
|
||||
if (matches != all_elements_should_match) {
|
||||
*listener << "whose element #" << i
|
||||
<< (matches ? " matches" : " doesn't match");
|
||||
PrintIfNotEmpty(inner_listener.str(), listener->stream());
|
||||
return true;
|
||||
return !all_elements_should_match;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return all_elements_should_match;
|
||||
}
|
||||
|
||||
protected:
|
||||
const Matcher<const Element&> inner_matcher_;
|
||||
|
||||
GTEST_DISALLOW_ASSIGN_(QuantifierMatcherImpl);
|
||||
};
|
||||
|
||||
// Implements Contains(element_matcher) for the given argument type Container.
|
||||
// Symmetric to EachMatcherImpl.
|
||||
template <typename Container>
|
||||
class ContainsMatcherImpl : public QuantifierMatcherImpl<Container> {
|
||||
public:
|
||||
template <typename InnerMatcher>
|
||||
explicit ContainsMatcherImpl(InnerMatcher inner_matcher)
|
||||
: QuantifierMatcherImpl<Container>(inner_matcher) {}
|
||||
|
||||
// Describes what this matcher does.
|
||||
virtual void DescribeTo(::std::ostream* os) const {
|
||||
*os << "contains at least one element that ";
|
||||
this->inner_matcher_.DescribeTo(os);
|
||||
}
|
||||
|
||||
virtual void DescribeNegationTo(::std::ostream* os) const {
|
||||
*os << "doesn't contain any element that ";
|
||||
this->inner_matcher_.DescribeTo(os);
|
||||
}
|
||||
|
||||
virtual bool MatchAndExplain(Container container,
|
||||
MatchResultListener* listener) const {
|
||||
return this->MatchAndExplainImpl(false, container, listener);
|
||||
}
|
||||
|
||||
private:
|
||||
const Matcher<const Element&> inner_matcher_;
|
||||
|
||||
GTEST_DISALLOW_ASSIGN_(ContainsMatcherImpl);
|
||||
};
|
||||
|
||||
// Implements Each(element_matcher) for the given argument type Container.
|
||||
// Symmetric to ContainsMatcherImpl.
|
||||
template <typename Container>
|
||||
class EachMatcherImpl : public QuantifierMatcherImpl<Container> {
|
||||
public:
|
||||
template <typename InnerMatcher>
|
||||
explicit EachMatcherImpl(InnerMatcher inner_matcher)
|
||||
: QuantifierMatcherImpl<Container>(inner_matcher) {}
|
||||
|
||||
// Describes what this matcher does.
|
||||
virtual void DescribeTo(::std::ostream* os) const {
|
||||
*os << "only contains elements that ";
|
||||
this->inner_matcher_.DescribeTo(os);
|
||||
}
|
||||
|
||||
virtual void DescribeNegationTo(::std::ostream* os) const {
|
||||
*os << "contains some element that ";
|
||||
this->inner_matcher_.DescribeNegationTo(os);
|
||||
}
|
||||
|
||||
virtual bool MatchAndExplain(Container container,
|
||||
MatchResultListener* listener) const {
|
||||
return this->MatchAndExplainImpl(true, container, listener);
|
||||
}
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_ASSIGN_(EachMatcherImpl);
|
||||
};
|
||||
|
||||
// Implements polymorphic Contains(element_matcher).
|
||||
template <typename M>
|
||||
class ContainsMatcher {
|
||||
|
@ -2013,6 +2066,23 @@ class ContainsMatcher {
|
|||
GTEST_DISALLOW_ASSIGN_(ContainsMatcher);
|
||||
};
|
||||
|
||||
// Implements polymorphic Each(element_matcher).
|
||||
template <typename M>
|
||||
class EachMatcher {
|
||||
public:
|
||||
explicit EachMatcher(M m) : inner_matcher_(m) {}
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
return MakeMatcher(new EachMatcherImpl<Container>(inner_matcher_));
|
||||
}
|
||||
|
||||
private:
|
||||
const M inner_matcher_;
|
||||
|
||||
GTEST_DISALLOW_ASSIGN_(EachMatcher);
|
||||
};
|
||||
|
||||
// Implements Key(inner_matcher) for the given argument pair type.
|
||||
// Key(inner_matcher) matches an std::pair whose 'first' field matches
|
||||
// inner_matcher. For example, Contains(Key(Ge(5))) can be used to match an
|
||||
|
@ -2855,6 +2925,38 @@ inline internal::ContainsMatcher<M> Contains(M matcher) {
|
|||
return internal::ContainsMatcher<M>(matcher);
|
||||
}
|
||||
|
||||
// Matches an STL-style container or a native array that contains only
|
||||
// elements matching the given value or matcher.
|
||||
//
|
||||
// Each(m) is semantically equivalent to Not(Contains(Not(m))). Only
|
||||
// the messages are different.
|
||||
//
|
||||
// Examples:
|
||||
// ::std::set<int> page_ids;
|
||||
// // Each(m) matches an empty container, regardless of what m is.
|
||||
// EXPECT_THAT(page_ids, Each(Eq(1)));
|
||||
// EXPECT_THAT(page_ids, Each(Eq(77)));
|
||||
//
|
||||
// page_ids.insert(3);
|
||||
// EXPECT_THAT(page_ids, Each(Gt(0)));
|
||||
// EXPECT_THAT(page_ids, Not(Each(Gt(4))));
|
||||
// page_ids.insert(1);
|
||||
// EXPECT_THAT(page_ids, Not(Each(Lt(2))));
|
||||
//
|
||||
// ::std::map<int, size_t> page_lengths;
|
||||
// page_lengths[1] = 100;
|
||||
// page_lengths[2] = 200;
|
||||
// page_lengths[3] = 300;
|
||||
// EXPECT_THAT(page_lengths, Not(Each(Pair(1, 100))));
|
||||
// EXPECT_THAT(page_lengths, Each(Key(Le(3))));
|
||||
//
|
||||
// const char* user_ids[] = { "joe", "mike", "tom" };
|
||||
// EXPECT_THAT(user_ids, Not(Each(Eq(::std::string("tom")))));
|
||||
template <typename M>
|
||||
inline internal::EachMatcher<M> Each(M matcher) {
|
||||
return internal::EachMatcher<M>(matcher);
|
||||
}
|
||||
|
||||
// Key(inner_matcher) matches an std::pair whose 'first' field matches
|
||||
// inner_matcher. For example, Contains(Key(Ge(5))) can be used to match an
|
||||
// std::map that contains at least one element whose key is >= 5.
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
# A Makefile for fusing Google Mock and building a sample test against it.
|
||||
#
|
||||
# SYNOPSIS:
|
||||
#
|
||||
# make [all] - makes everything.
|
||||
# make TARGET - makes the given target.
|
||||
# make check - makes everything and runs the built sample test.
|
||||
# make clean - removes all files generated by make.
|
||||
|
||||
# Points to the root of fused Google Mock, relative to where this file is.
|
||||
FUSED_GMOCK_DIR = output
|
||||
|
||||
# Paths to the fused gmock files.
|
||||
FUSED_GTEST_H = $(FUSED_GMOCK_DIR)/gtest/gtest.h
|
||||
FUSED_GMOCK_H = $(FUSED_GMOCK_DIR)/gmock/gmock.h
|
||||
FUSED_GMOCK_GTEST_ALL_CC = $(FUSED_GMOCK_DIR)/gmock-gtest-all.cc
|
||||
|
||||
# Where to find the gmock_test.cc.
|
||||
GMOCK_TEST_CC = ../../test/gmock_test.cc
|
||||
|
||||
# Where to find gmock_main.cc.
|
||||
GMOCK_MAIN_CC = ../../src/gmock_main.cc
|
||||
|
||||
# Flags passed to the preprocessor.
|
||||
CPPFLAGS += -I$(FUSED_GMOCK_DIR)
|
||||
|
||||
# Flags passed to the C++ compiler.
|
||||
CXXFLAGS += -g
|
||||
|
||||
all : gmock_test
|
||||
|
||||
check : all
|
||||
./gmock_test
|
||||
|
||||
clean :
|
||||
rm -rf $(FUSED_GMOCK_DIR) gmock_test *.o
|
||||
|
||||
$(FUSED_GTEST_H) :
|
||||
../fuse_gmock_files.py $(FUSED_GMOCK_DIR)
|
||||
|
||||
$(FUSED_GMOCK_H) :
|
||||
../fuse_gmock_files.py $(FUSED_GMOCK_DIR)
|
||||
|
||||
$(FUSED_GMOCK_GTEST_ALL_CC) :
|
||||
../fuse_gmock_files.py $(FUSED_GMOCK_DIR)
|
||||
|
||||
gmock-gtest-all.o : $(FUSED_GTEST_H) $(FUSED_GMOCK_H) $(FUSED_GMOCK_GTEST_ALL_CC)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(FUSED_GMOCK_GTEST_ALL_CC)
|
||||
|
||||
gmock_main.o : $(FUSED_GTEST_H) $(FUSED_GMOCK_H) $(GMOCK_MAIN_CC)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(GMOCK_MAIN_CC)
|
||||
|
||||
gmock_test.o : $(FUSED_GTEST_H) $(FUSED_GMOCK_H) $(GMOCK_TEST_CC)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(GMOCK_TEST_CC)
|
||||
|
||||
gmock_test : gmock_test.o gmock-gtest-all.o gmock_main.o
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $^ -o $@
|
|
@ -65,8 +65,10 @@ using std::make_pair;
|
|||
using std::map;
|
||||
using std::multimap;
|
||||
using std::pair;
|
||||
using std::set;
|
||||
using std::stringstream;
|
||||
using std::tr1::make_tuple;
|
||||
using std::vector;
|
||||
using testing::A;
|
||||
using testing::AllArgs;
|
||||
using testing::AllOf;
|
||||
|
@ -363,20 +365,20 @@ TEST(MakeMatcherTest, ConstructsMatcherFromMatcherInterface) {
|
|||
|
||||
// Tests that MakePolymorphicMatcher() can construct a polymorphic
|
||||
// matcher from its implementation using the old API.
|
||||
const int bar = 1;
|
||||
const int g_bar = 1;
|
||||
class ReferencesBarOrIsZeroImpl {
|
||||
public:
|
||||
template <typename T>
|
||||
bool MatchAndExplain(const T& x,
|
||||
MatchResultListener* /* listener */) const {
|
||||
const void* p = &x;
|
||||
return p == &bar || x == 0;
|
||||
return p == &g_bar || x == 0;
|
||||
}
|
||||
|
||||
void DescribeTo(::std::ostream* os) const { *os << "bar or zero"; }
|
||||
void DescribeTo(::std::ostream* os) const { *os << "g_bar or zero"; }
|
||||
|
||||
void DescribeNegationTo(::std::ostream* os) const {
|
||||
*os << "doesn't reference bar and is not zero";
|
||||
*os << "doesn't reference g_bar and is not zero";
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -391,15 +393,15 @@ TEST(MakePolymorphicMatcherTest, ConstructsMatcherUsingOldAPI) {
|
|||
Matcher<const int&> m1 = ReferencesBarOrIsZero();
|
||||
EXPECT_TRUE(m1.Matches(0));
|
||||
// Verifies that the identity of a by-reference argument is preserved.
|
||||
EXPECT_TRUE(m1.Matches(bar));
|
||||
EXPECT_TRUE(m1.Matches(g_bar));
|
||||
EXPECT_FALSE(m1.Matches(1));
|
||||
EXPECT_EQ("bar or zero", Describe(m1));
|
||||
EXPECT_EQ("g_bar or zero", Describe(m1));
|
||||
|
||||
// Using a polymorphic matcher to match a value type.
|
||||
Matcher<double> m2 = ReferencesBarOrIsZero();
|
||||
EXPECT_TRUE(m2.Matches(0.0));
|
||||
EXPECT_FALSE(m2.Matches(0.1));
|
||||
EXPECT_EQ("bar or zero", Describe(m2));
|
||||
EXPECT_EQ("g_bar or zero", Describe(m2));
|
||||
}
|
||||
|
||||
// Tests implementing a polymorphic matcher using MatchAndExplain().
|
||||
|
@ -3984,5 +3986,91 @@ TEST(MatcherTupleTest, ExplainsMatchFailure) {
|
|||
// explanation.
|
||||
}
|
||||
|
||||
// Tests Each().
|
||||
|
||||
TEST(EachTest, ExplainsMatchResultCorrectly) {
|
||||
set<int> a; // empty
|
||||
|
||||
Matcher<set<int> > m = Each(2);
|
||||
EXPECT_EQ("", Explain(m, a));
|
||||
|
||||
Matcher<const int(&)[1]> n = Each(1);
|
||||
|
||||
const int b[1] = { 1 };
|
||||
EXPECT_EQ("", Explain(n, b));
|
||||
|
||||
n = Each(3);
|
||||
EXPECT_EQ("whose element #0 doesn't match", Explain(n, b));
|
||||
|
||||
a.insert(1);
|
||||
a.insert(2);
|
||||
a.insert(3);
|
||||
m = Each(GreaterThan(0));
|
||||
EXPECT_EQ("", Explain(m, a));
|
||||
|
||||
m = Each(GreaterThan(10));
|
||||
EXPECT_EQ("whose element #0 doesn't match, which is 9 less than 10",
|
||||
Explain(m, a));
|
||||
}
|
||||
|
||||
TEST(EachTest, DescribesItselfCorrectly) {
|
||||
Matcher<vector<int> > m = Each(1);
|
||||
EXPECT_EQ("only contains elements that is equal to 1", Describe(m));
|
||||
|
||||
Matcher<vector<int> > m2 = Not(m);
|
||||
EXPECT_EQ("contains some element that isn't equal to 1", Describe(m2));
|
||||
}
|
||||
|
||||
TEST(EachTest, MatchesVectorWhenAllElementsMatch) {
|
||||
vector<int> some_vector;
|
||||
EXPECT_THAT(some_vector, Each(1));
|
||||
some_vector.push_back(3);
|
||||
EXPECT_THAT(some_vector, Not(Each(1)));
|
||||
EXPECT_THAT(some_vector, Each(3));
|
||||
some_vector.push_back(1);
|
||||
some_vector.push_back(2);
|
||||
EXPECT_THAT(some_vector, Not(Each(3)));
|
||||
EXPECT_THAT(some_vector, Each(Lt(3.5)));
|
||||
|
||||
vector<string> another_vector;
|
||||
another_vector.push_back("fee");
|
||||
EXPECT_THAT(another_vector, Each(string("fee")));
|
||||
another_vector.push_back("fie");
|
||||
another_vector.push_back("foe");
|
||||
another_vector.push_back("fum");
|
||||
EXPECT_THAT(another_vector, Not(Each(string("fee"))));
|
||||
}
|
||||
|
||||
TEST(EachTest, MatchesMapWhenAllElementsMatch) {
|
||||
map<const char*, int> my_map;
|
||||
const char* bar = "a string";
|
||||
my_map[bar] = 2;
|
||||
EXPECT_THAT(my_map, Each(make_pair(bar, 2)));
|
||||
|
||||
map<string, int> another_map;
|
||||
EXPECT_THAT(another_map, Each(make_pair(string("fee"), 1)));
|
||||
another_map["fee"] = 1;
|
||||
EXPECT_THAT(another_map, Each(make_pair(string("fee"), 1)));
|
||||
another_map["fie"] = 2;
|
||||
another_map["foe"] = 3;
|
||||
another_map["fum"] = 4;
|
||||
EXPECT_THAT(another_map, Not(Each(make_pair(string("fee"), 1))));
|
||||
EXPECT_THAT(another_map, Not(Each(make_pair(string("fum"), 1))));
|
||||
EXPECT_THAT(another_map, Each(Pair(_, Gt(0))));
|
||||
}
|
||||
|
||||
TEST(EachTest, AcceptsMatcher) {
|
||||
const int a[] = { 1, 2, 3 };
|
||||
EXPECT_THAT(a, Each(Gt(0)));
|
||||
EXPECT_THAT(a, Not(Each(Gt(1))));
|
||||
}
|
||||
|
||||
TEST(EachTest, WorksForNativeArrayAsTuple) {
|
||||
const int a[] = { 1, 2 };
|
||||
const int* const pointer = a;
|
||||
EXPECT_THAT(make_tuple(pointer, 2), Each(Gt(0)));
|
||||
EXPECT_THAT(make_tuple(pointer, 2), Not(Each(Gt(1))));
|
||||
}
|
||||
|
||||
} // namespace gmock_matchers_test
|
||||
} // namespace testing
|
||||
|
|
Loading…
Reference in New Issue
Block a user