Commit fb25d539 by zhanyong.wan

Adds matchers UnorderedElementsAre[Array]() (by Billy Donahue); pulls in

gtest r660.
parent 2989703e
...@@ -2,7 +2,8 @@ Changes for 1.7.0: ...@@ -2,7 +2,8 @@ Changes for 1.7.0:
* All new improvements in Google Test 1.7.0. * All new improvements in Google Test 1.7.0.
* New feature: matchers DoubleNear(), FloatNear(), * New feature: matchers DoubleNear(), FloatNear(),
NanSensitiveDoubleNear(), NanSensitiveFloatNear(), WhenSorted(), NanSensitiveDoubleNear(), NanSensitiveFloatNear(),
UnorderedElementsAre(), UnorderedElementsAreArray(), WhenSorted(),
WhenSortedBy(), IsEmpty(), and SizeIs(). WhenSortedBy(), IsEmpty(), and SizeIs().
* Improvement: Google Mock can now be built as a DLL. * Improvement: Google Mock can now be built as a DLL.
* Improvement: when compiled by a C++11 compiler, matchers AllOf() * Improvement: when compiled by a C++11 compiler, matchers AllOf()
......
...@@ -187,66 +187,6 @@ class ArgsMatcher { ...@@ -187,66 +187,6 @@ class ArgsMatcher {
GTEST_DISALLOW_ASSIGN_(ArgsMatcher); GTEST_DISALLOW_ASSIGN_(ArgsMatcher);
}; };
// Implements ElementsAre() of 1-$n arguments. The use of DecayArray in
// the implementation allows ElementsAre() to accept string literals, whose
// inferred type is const char[N] while we want to treat them as const char*.
$range i 1..n
$for i [[
$range j 1..i
template <$for j, [[typename T$j]]>
class ElementsAreMatcher$i {
public:
$if i==1 [[explicit ]]ElementsAreMatcher$i($for j, [[const T$j& e$j]])$if i > 0 [[ : ]]
$for j, [[e$j[[]]_(e$j)]] {}
template <typename Container>
operator Matcher<Container>() const {
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
typedef typename internal::StlContainerView<RawContainer>::type::value_type
Element;
$if i==1 [[
// Nokia's Symbian Compiler has a nasty bug where the object put
// in a one-element local array is not destructed when the array
// goes out of scope. This leads to obvious badness as we've
// added the linked_ptr in it to our other linked_ptrs list.
// Hence we implement ElementsAreMatcher1 specially to avoid using
// a local array.
const Matcher<const Element&> matcher =
MatcherCast<const Element&>(e1_);
return MakeMatcher(new ElementsAreMatcherImpl<Container>(&matcher,
&matcher + 1));
]] $else [[
const Matcher<const Element&> matchers[] = {
$for j [[
MatcherCast<const Element&>(e$j[[]]_),
]]
};
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers,
matchers + $i));
]]
}
private:
$for j [[
const typename DecayArray<T$j>::type e$j[[]]_;
]]
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher$i);
};
]]
// A set of metafunctions for computing the result type of AllOf. // A set of metafunctions for computing the result type of AllOf.
// AllOf(m1, ..., mN) returns // AllOf(m1, ..., mN) returns
// AllOfResultN<decltype(m1), ..., decltype(mN)>::type. // AllOfResultN<decltype(m1), ..., decltype(mN)>::type.
...@@ -324,79 +264,72 @@ Args(const InnerMatcher& matcher) { ...@@ -324,79 +264,72 @@ Args(const InnerMatcher& matcher) {
]] ]]
// ElementsAre(e0, e1, ..., e_n) matches an STL-style container with // ElementsAre(e_1, e_2, ... e_n) matches an STL-style container with
// (n + 1) elements, where the i-th element in the container must // n elements, where the i-th element in the container must
// match the i-th argument in the list. Each argument of // match the i-th argument in the list. Each argument of
// ElementsAre() can be either a value or a matcher. We support up to // ElementsAre() can be either a value or a matcher. We support up to
// $n arguments. // $n arguments.
// //
// The use of DecayArray in the implementation allows ElementsAre()
// to accept string literals, whose type is const char[N], but we
// want to treat them as const char*.
//
// NOTE: Since ElementsAre() cares about the order of the elements, it // NOTE: Since ElementsAre() cares about the order of the elements, it
// must not be used with containers whose elements's order is // must not be used with containers whose elements's order is
// undefined (e.g. hash_map). // undefined (e.g. hash_map).
inline internal::ElementsAreMatcher0 ElementsAre() { $range i 0..n
return internal::ElementsAreMatcher0();
}
$range i 1..n
$for i [[ $for i [[
$range j 1..i $range j 1..i
$if i>0 [[
template <$for j, [[typename T$j]]> template <$for j, [[typename T$j]]>
inline internal::ElementsAreMatcher$i<$for j, [[T$j]]> ElementsAre($for j, [[const T$j& e$j]]) { ]]
return internal::ElementsAreMatcher$i<$for j, [[T$j]]>($for j, [[e$j]]);
inline internal::ElementsAreMatcher<
std::tr1::tuple<
$for j, [[
typename internal::DecayArray<T$j[[]]>::type]]> >
ElementsAre($for j, [[const T$j& e$j]]) {
typedef std::tr1::tuple<
$for j, [[
typename internal::DecayArray<T$j[[]]>::type]]> Args;
return internal::ElementsAreMatcher<Args>(Args($for j, [[e$j]]));
} }
]] ]]
// ElementsAreArray(array) // UnorderedElementsAre(e_1, e_2, ..., e_n) is an ElementsAre extension
// ElementsAreArray(pointer, count) // that matches n elements in any order. We support up to n=$n arguments.
// ElementsAreArray(vector)
// ElementsAreArray(first, last)
//
// The ElementsAreArray() functions are like ElementsAre(...), except that
// they are given a sequence of matchers or values rather than taking each
// element as a function argument. The sequence can be specified as a
// C-style array, a pointer and count, a vector, or an STL iterator range.
//
// * The array form infers the size of 'array', which must be of a
// statically-sized C-style array type.
//
// * The (pointer, count) form can take either a statically-sized C-style
// array or a pointer to a dynamically created array. It does not take
// ownership of the pointer.
//
// * The vector form can take a std::vector either of values or of matchers.
//
// * The (first, last) form can take any STL iterator range.
//
// All forms of ElementsAreArray() make a copy of the input sequence.
template <typename T>
inline internal::ElementsAreArrayMatcher<T> ElementsAreArray(
const T* first, size_t count) {
return internal::ElementsAreArrayMatcher<T>(first, first + count);
}
template <typename T, size_t N> $range i 0..n
inline internal::ElementsAreArrayMatcher<T> ElementsAreArray( $for i [[
const T (&array)[N]) {
return internal::ElementsAreArrayMatcher<T>(array, array + N);
}
template <typename T, typename A> $range j 1..i
inline internal::ElementsAreArrayMatcher<T> ElementsAreArray(
const std::vector<T, A>& vec) { $if i>0 [[
return internal::ElementsAreArrayMatcher<T>(vec.begin(), vec.end());
}
template <typename Iter> template <$for j, [[typename T$j]]>
inline internal::ElementsAreArrayMatcher< ]]
typename std::iterator_traits<Iter>::value_type>
ElementsAreArray(Iter first, Iter last) { inline internal::UnorderedElementsAreMatcher<
typedef typename std::iterator_traits<Iter>::value_type T; std::tr1::tuple<
return internal::ElementsAreArrayMatcher<T>(first, last); $for j, [[
typename internal::DecayArray<T$j[[]]>::type]]> >
UnorderedElementsAre($for j, [[const T$j& e$j]]) {
typedef std::tr1::tuple<
$for j, [[
typename internal::DecayArray<T$j[[]]>::type]]> Args;
return internal::UnorderedElementsAreMatcher<Args>(Args($for j, [[e$j]]));
} }
]]
// AllOf(m1, m2, ..., mk) matches any value that matches all of the given // AllOf(m1, m2, ..., mk) matches any value that matches all of the given
// sub-matchers. AllOf is called fully qualified to prevent ADL from firing. // sub-matchers. AllOf is called fully qualified to prevent ADL from firing.
......
...@@ -80,6 +80,9 @@ using testing::Value; ...@@ -80,6 +80,9 @@ using testing::Value;
using testing::internal::ElementsAreArrayMatcher; using testing::internal::ElementsAreArrayMatcher;
using testing::internal::string; using testing::internal::string;
// Evaluates to the number of elements in 'array'.
#define GMOCK_ARRAY_SIZE_(a) (sizeof(a) / sizeof(a[0]))
// Returns the description of the given matcher. // Returns the description of the given matcher.
template <typename T> template <typename T>
string Describe(const Matcher<T>& m) { string Describe(const Matcher<T>& m) {
...@@ -284,9 +287,6 @@ Matcher<int> GreaterThan(int n) { ...@@ -284,9 +287,6 @@ Matcher<int> GreaterThan(int n) {
// Tests for ElementsAre(). // Tests for ElementsAre().
// Evaluates to the number of elements in 'array'.
#define GMOCK_ARRAY_SIZE_(array) (sizeof(array)/sizeof(array[0]))
TEST(ElementsAreTest, CanDescribeExpectingNoElement) { TEST(ElementsAreTest, CanDescribeExpectingNoElement) {
Matcher<const vector<int>&> m = ElementsAre(); Matcher<const vector<int>&> m = ElementsAre();
EXPECT_EQ("is empty", Describe(m)); EXPECT_EQ("is empty", Describe(m));
...@@ -563,8 +563,8 @@ TEST(ElementsAreTest, MakesCopyOfArguments) { ...@@ -563,8 +563,8 @@ TEST(ElementsAreTest, MakesCopyOfArguments) {
int x = 1; int x = 1;
int y = 2; int y = 2;
// This should make a copy of x and y. // This should make a copy of x and y.
::testing::internal::ElementsAreMatcher2<int, int> polymorphic_matcher = ::testing::internal::ElementsAreMatcher<std::tr1::tuple<int, int> >
ElementsAre(x, y); polymorphic_matcher = ElementsAre(x, y);
// Changing x and y now shouldn't affect the meaning of the above matcher. // Changing x and y now shouldn't affect the meaning of the above matcher.
x = y = 0; x = y = 0;
const int array1[] = { 1, 2 }; const int array1[] = { 1, 2 };
...@@ -573,6 +573,7 @@ TEST(ElementsAreTest, MakesCopyOfArguments) { ...@@ -573,6 +573,7 @@ TEST(ElementsAreTest, MakesCopyOfArguments) {
EXPECT_THAT(array2, Not(polymorphic_matcher)); EXPECT_THAT(array2, Not(polymorphic_matcher));
} }
// Tests for ElementsAreArray(). Since ElementsAreArray() shares most // Tests for ElementsAreArray(). Since ElementsAreArray() shares most
// of the implementation with ElementsAre(), we don't test it as // of the implementation with ElementsAre(), we don't test it as
// thoroughly here. // thoroughly here.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment