aboutsummaryrefslogtreecommitdiffstats
path: root/googlemock
diff options
context:
space:
mode:
Diffstat (limited to 'googlemock')
-rw-r--r--googlemock/CMakeLists.txt63
-rw-r--r--googlemock/configure.ac2
-rw-r--r--googlemock/docs/CheatSheet.md2
-rw-r--r--googlemock/docs/CookBook.md6
-rw-r--r--googlemock/include/gmock/gmock-matchers.h309
-rw-r--r--googlemock/include/gmock/gmock-more-matchers.h16
-rw-r--r--googlemock/include/gmock/gmock-spec-builders.h9
-rw-r--r--googlemock/include/gmock/gmock.h2
-rw-r--r--googlemock/include/gmock/internal/gmock-generated-internal-utils.h25
-rw-r--r--googlemock/include/gmock/internal/gmock-internal-utils.h39
-rw-r--r--googlemock/include/gmock/internal/gmock-port.h18
-rwxr-xr-xgooglemock/scripts/generator/cpp/ast.py6
-rw-r--r--googlemock/src/gmock-internal-utils.cc19
-rw-r--r--googlemock/src/gmock-matchers.cc215
-rw-r--r--googlemock/src/gmock-spec-builders.cc2
-rw-r--r--googlemock/test/BUILD.bazel75
-rw-r--r--googlemock/test/gmock-actions_test.cc2
-rw-r--r--googlemock/test/gmock-internal-utils_test.cc8
-rw-r--r--googlemock/test/gmock-matchers_test.cc105
-rw-r--r--googlemock/test/gmock_link_test.h24
-rwxr-xr-xgooglemock/test/gmock_output_test.py13
-rw-r--r--googlemock/test/gmock_stress_test.cc3
-rw-r--r--googlemock/test/gmock_test.cc5
-rwxr-xr-xgooglemock/test/gmock_test_utils.py12
24 files changed, 713 insertions, 267 deletions
diff --git a/googlemock/CMakeLists.txt b/googlemock/CMakeLists.txt
index 21d61b13..bac2e3bf 100644
--- a/googlemock/CMakeLists.txt
+++ b/googlemock/CMakeLists.txt
@@ -88,16 +88,23 @@ endif()
# Google Mock libraries. We build them using more strict warnings than what
# are used for other targets, to ensure that Google Mock can be compiled by
# a user aggressive about warnings.
-cxx_library(gmock
- "${cxx_strict}"
- "${gtest_dir}/src/gtest-all.cc"
- src/gmock-all.cc)
-
-cxx_library(gmock_main
- "${cxx_strict}"
- "${gtest_dir}/src/gtest-all.cc"
- src/gmock-all.cc
- src/gmock_main.cc)
+if (MSVC)
+ cxx_library(gmock
+ "${cxx_strict}"
+ "${gtest_dir}/src/gtest-all.cc"
+ src/gmock-all.cc)
+
+ cxx_library(gmock_main
+ "${cxx_strict}"
+ "${gtest_dir}/src/gtest-all.cc"
+ src/gmock-all.cc
+ src/gmock_main.cc)
+else()
+ cxx_library(gmock "${cxx_strict}" src/gmock-all.cc)
+ target_link_libraries(gmock gtest)
+ cxx_library(gmock_main "${cxx_strict}" src/gmock_main.cc)
+ target_link_libraries(gmock_main gmock)
+endif()
# If the CMake version supports it, attach header directory information
# to the targets for when we are part of a parent build (ie being pulled
@@ -177,23 +184,33 @@ if (gmock_build_tests)
############################################################
# C++ tests built with non-standard compiler flags.
- cxx_library(gmock_main_no_exception "${cxx_no_exception}"
- "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc)
-
- cxx_library(gmock_main_no_rtti "${cxx_no_rtti}"
- "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc)
+ if (MSVC)
+ cxx_library(gmock_main_no_exception "${cxx_no_exception}"
+ "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc)
- if (NOT MSVC OR MSVC_VERSION LESS 1600) # 1600 is Visual Studio 2010.
- # Visual Studio 2010, 2012, and 2013 define symbols in std::tr1 that
- # conflict with our own definitions. Therefore using our own tuple does not
- # work on those compilers.
- cxx_library(gmock_main_use_own_tuple "${cxx_use_own_tuple}"
+ cxx_library(gmock_main_no_rtti "${cxx_no_rtti}"
"${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc)
- cxx_test_with_flags(gmock_use_own_tuple_test "${cxx_use_own_tuple}"
- gmock_main_use_own_tuple test/gmock-spec-builders_test.cc)
+ if (MSVC_VERSION LESS 1600) # 1600 is Visual Studio 2010.
+ # Visual Studio 2010, 2012, and 2013 define symbols in std::tr1 that
+ # conflict with our own definitions. Therefore using our own tuple does not
+ # work on those compilers.
+ cxx_library(gmock_main_use_own_tuple "${cxx_use_own_tuple}"
+ "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc)
+
+ cxx_test_with_flags(gmock_use_own_tuple_test "${cxx_use_own_tuple}"
+ gmock_main_use_own_tuple test/gmock-spec-builders_test.cc)
+ endif()
+ else()
+ cxx_library(gmock_main_no_exception "${cxx_no_exception}" src/gmock_main.cc)
+ target_link_libraries(gmock_main_no_exception gmock)
+
+ cxx_library(gmock_main_no_rtti "${cxx_no_rtti}" src/gmock_main.cc)
+ target_link_libraries(gmock_main_no_rtti gmock)
+
+ cxx_library(gmock_main_use_own_tuple "${cxx_use_own_tuple}" src/gmock_main.cc)
+ target_link_libraries(gmock_main_use_own_tuple gmock)
endif()
-
cxx_test_with_flags(gmock-more-actions_no_exception_test "${cxx_no_exception}"
gmock_main_no_exception test/gmock-more-actions_test.cc)
diff --git a/googlemock/configure.ac b/googlemock/configure.ac
index c23ed455..cb5e1a6a 100644
--- a/googlemock/configure.ac
+++ b/googlemock/configure.ac
@@ -129,7 +129,7 @@ AS_IF([test "x${HAVE_BUILT_GTEST}" = "xyes"],
GTEST_LDFLAGS=`${GTEST_CONFIG} --ldflags`
GTEST_LIBS=`${GTEST_CONFIG} --libs`
GTEST_VERSION=`${GTEST_CONFIG} --version`],
- [AC_CONFIG_SUBDIRS([../googletest])
+ [
# GTEST_CONFIG needs to be executable both in a Makefile environment and
# in a shell script environment, so resolve an absolute path for it here.
GTEST_CONFIG="`pwd -P`/../googletest/scripts/gtest-config"
diff --git a/googlemock/docs/CheatSheet.md b/googlemock/docs/CheatSheet.md
index c6367fdd..f8bbbfe6 100644
--- a/googlemock/docs/CheatSheet.md
+++ b/googlemock/docs/CheatSheet.md
@@ -178,6 +178,8 @@ divided into several categories:
|`Ne(value)` |`argument != value`|
|`IsNull()` |`argument` is a `NULL` pointer (raw or smart).|
|`NotNull()` |`argument` is a non-null pointer (raw or smart).|
+|`VariantWith<T>(m)` |`argument` is `variant<>` that holds the alternative of
+type T with a value matching `m`.|
|`Ref(variable)` |`argument` is a reference to `variable`.|
|`TypedEq<type>(value)`|`argument` has type `type` and is equal to `value`. You may need to use this instead of `Eq(value)` when the mock function is overloaded.|
diff --git a/googlemock/docs/CookBook.md b/googlemock/docs/CookBook.md
index 3d07e68b..c2565f1e 100644
--- a/googlemock/docs/CookBook.md
+++ b/googlemock/docs/CookBook.md
@@ -1231,7 +1231,7 @@ that references the implementation object dies, the implementation
object will be deleted.
Therefore, if you have some complex matcher that you want to use again
-and again, there is no need to build it everytime. Just assign it to a
+and again, there is no need to build it every time. Just assign it to a
matcher variable and use that variable repeatedly! For example,
```
@@ -1403,7 +1403,7 @@ edge from node A to node B wherever A must occur before B, we can get
a DAG. We use the term "sequence" to mean a directed path in this
DAG. Now, if we decompose the DAG into sequences, we just need to know
which sequences each `EXPECT_CALL()` belongs to in order to be able to
-reconstruct the orginal DAG.
+reconstruct the original DAG.
So, to specify the partial order on the expectations we need to do two
things: first to define some `Sequence` objects, and then for each
@@ -2182,7 +2182,7 @@ the implementation object dies, the implementation object will be
deleted.
If you have some complex action that you want to use again and again,
-you may not have to build it from scratch everytime. If the action
+you may not have to build it from scratch every time. If the action
doesn't have an internal state (i.e. if it always does the same thing
no matter how many times it has been called), you can assign it to an
action variable and use that variable repeatedly. For example:
diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h
index c446bf7d..9522c850 100644
--- a/googlemock/include/gmock/gmock-matchers.h
+++ b/googlemock/include/gmock/gmock-matchers.h
@@ -47,10 +47,9 @@
#include <string>
#include <utility>
#include <vector>
-
+#include "gtest/gtest.h"
#include "gmock/internal/gmock-internal-utils.h"
#include "gmock/internal/gmock-port.h"
-#include "gtest/gtest.h"
#if GTEST_HAS_STD_INITIALIZER_LIST_
# include <initializer_list> // NOLINT -- must be after gtest.h
@@ -515,7 +514,7 @@ template <typename T, typename M>
class MatcherCastImpl {
public:
static Matcher<T> Cast(const M& polymorphic_matcher_or_value) {
- // M can be a polymorhic matcher, in which case we want to use
+ // M can be a polymorphic matcher, in which case we want to use
// its conversion operator to create Matcher<T>. Or it can be a value
// that should be passed to the Matcher<T>'s constructor.
//
@@ -1551,7 +1550,7 @@ class BothOfMatcherImpl : public MatcherInterface<T> {
// MatcherList provides mechanisms for storing a variable number of matchers in
// a list structure (ListType) and creating a combining matcher from such a
// list.
-// The template is defined recursively using the following template paramters:
+// The template is defined recursively using the following template parameters:
// * kSize is the length of the MatcherList.
// * Head is the type of the first matcher of the list.
// * Tail denotes the types of the remaining matchers of the list.
@@ -2380,7 +2379,7 @@ class ResultOfMatcher {
private:
// Functors often define operator() as non-const method even though
- // they are actualy stateless. But we need to use them even when
+ // they are actually stateless. But we need to use them even when
// 'this' is a const pointer. It's the user's responsibility not to
// use stateful callables with ResultOf(), which does't guarantee
// how many times the callable will be invoked.
@@ -3304,14 +3303,23 @@ typedef ::std::vector<ElementMatcherPair> ElementMatcherPairs;
GTEST_API_ ElementMatcherPairs
FindMaxBipartiteMatching(const MatchMatrix& g);
-GTEST_API_ bool FindPairing(const MatchMatrix& matrix,
- MatchResultListener* listener);
+struct UnorderedMatcherRequire {
+ enum Flags {
+ Superset = 1 << 0,
+ Subset = 1 << 1,
+ ExactMatch = Superset | Subset,
+ };
+};
// Untyped base class for implementing UnorderedElementsAre. By
// putting logic that's not specific to the element type here, we
// reduce binary bloat and increase compilation speed.
class GTEST_API_ UnorderedElementsAreMatcherImplBase {
protected:
+ explicit UnorderedElementsAreMatcherImplBase(
+ UnorderedMatcherRequire::Flags matcher_flags)
+ : match_flags_(matcher_flags) {}
+
// A vector of matcher describers, one for each element matcher.
// Does not own the describers (and thus can be used only when the
// element matchers are alive).
@@ -3323,9 +3331,12 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase {
// Describes the negation of this UnorderedElementsAre matcher.
void DescribeNegationToImpl(::std::ostream* os) const;
- bool VerifyAllElementsAndMatchersAreMatched(
- const ::std::vector<std::string>& element_printouts,
- const MatchMatrix& matrix, MatchResultListener* listener) const;
+ bool VerifyMatchMatrix(const ::std::vector<std::string>& element_printouts,
+ const MatchMatrix& matrix,
+ MatchResultListener* listener) const;
+
+ bool FindPairing(const MatchMatrix& matrix,
+ MatchResultListener* listener) const;
MatcherDescriberVec& matcher_describers() {
return matcher_describers_;
@@ -3335,13 +3346,17 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase {
return Message() << n << " element" << (n == 1 ? "" : "s");
}
+ UnorderedMatcherRequire::Flags match_flags() const { return match_flags_; }
+
private:
+ UnorderedMatcherRequire::Flags match_flags_;
MatcherDescriberVec matcher_describers_;
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImplBase);
};
-// Implements unordered ElementsAre and unordered ElementsAreArray.
+// Implements UnorderedElementsAre, UnorderedElementsAreArray, IsSubsetOf, and
+// IsSupersetOf.
template <typename Container>
class UnorderedElementsAreMatcherImpl
: public MatcherInterface<Container>,
@@ -3354,10 +3369,10 @@ class UnorderedElementsAreMatcherImpl
typedef typename StlContainer::const_iterator StlContainerConstIterator;
typedef typename StlContainer::value_type Element;
- // Constructs the matcher from a sequence of element values or
- // element matchers.
template <typename InputIter>
- UnorderedElementsAreMatcherImpl(InputIter first, InputIter last) {
+ UnorderedElementsAreMatcherImpl(UnorderedMatcherRequire::Flags matcher_flags,
+ InputIter first, InputIter last)
+ : UnorderedElementsAreMatcherImplBase(matcher_flags) {
for (; first != last; ++first) {
matchers_.push_back(MatcherCast<const Element&>(*first));
matcher_describers().push_back(matchers_.back().GetDescriber());
@@ -3378,34 +3393,32 @@ class UnorderedElementsAreMatcherImpl
MatchResultListener* listener) const {
StlContainerReference stl_container = View::ConstReference(container);
::std::vector<std::string> element_printouts;
- MatchMatrix matrix = AnalyzeElements(stl_container.begin(),
- stl_container.end(),
- &element_printouts,
- listener);
+ MatchMatrix matrix =
+ AnalyzeElements(stl_container.begin(), stl_container.end(),
+ &element_printouts, listener);
- const size_t actual_count = matrix.LhsSize();
- if (actual_count == 0 && matchers_.empty()) {
+ if (matrix.LhsSize() == 0 && matrix.RhsSize() == 0) {
return true;
}
- if (actual_count != matchers_.size()) {
- // The element count doesn't match. If the container is empty,
- // there's no need to explain anything as Google Mock already
- // prints the empty container. Otherwise we just need to show
- // how many elements there actually are.
- if (actual_count != 0 && listener->IsInterested()) {
- *listener << "which has " << Elements(actual_count);
+
+ if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
+ if (matrix.LhsSize() != matrix.RhsSize()) {
+ // The element count doesn't match. If the container is empty,
+ // there's no need to explain anything as Google Mock already
+ // prints the empty container. Otherwise we just need to show
+ // how many elements there actually are.
+ if (matrix.LhsSize() != 0 && listener->IsInterested()) {
+ *listener << "which has " << Elements(matrix.LhsSize());
+ }
+ return false;
}
- return false;
}
- return VerifyAllElementsAndMatchersAreMatched(element_printouts,
- matrix, listener) &&
+ return VerifyMatchMatrix(element_printouts, matrix, listener) &&
FindPairing(matrix, listener);
}
private:
- typedef ::std::vector<Matcher<const Element&> > MatcherVec;
-
template <typename ElementIter>
MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last,
::std::vector<std::string>* element_printouts,
@@ -3432,7 +3445,7 @@ class UnorderedElementsAreMatcherImpl
return matrix;
}
- MatcherVec matchers_;
+ ::std::vector<Matcher<const Element&> > matchers_;
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImpl);
};
@@ -3465,7 +3478,7 @@ class UnorderedElementsAreMatcher {
TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,
::std::back_inserter(matchers));
return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>(
- matchers.begin(), matchers.end()));
+ UnorderedMatcherRequire::ExactMatch, matchers.begin(), matchers.end()));
}
private:
@@ -3498,24 +3511,23 @@ class ElementsAreMatcher {
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher);
};
-// Implements UnorderedElementsAreArray().
+// Implements UnorderedElementsAreArray(), IsSubsetOf(), and IsSupersetOf().
template <typename T>
class UnorderedElementsAreArrayMatcher {
public:
- UnorderedElementsAreArrayMatcher() {}
-
template <typename Iter>
- UnorderedElementsAreArrayMatcher(Iter first, Iter last)
- : matchers_(first, last) {}
+ UnorderedElementsAreArrayMatcher(UnorderedMatcherRequire::Flags match_flags,
+ Iter first, Iter last)
+ : match_flags_(match_flags), matchers_(first, last) {}
template <typename Container>
operator Matcher<Container>() const {
- return MakeMatcher(
- new UnorderedElementsAreMatcherImpl<Container>(matchers_.begin(),
- matchers_.end()));
+ return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>(
+ match_flags_, matchers_.begin(), matchers_.end()));
}
private:
+ UnorderedMatcherRequire::Flags match_flags_;
::std::vector<T> matchers_;
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreArrayMatcher);
@@ -3624,9 +3636,69 @@ GTEST_API_ std::string FormatMatcherDescription(bool negation,
const char* matcher_name,
const Strings& param_values);
+namespace variant_matcher {
+// Overloads to allow VariantMatcher to do proper ADL lookup.
+template <typename T>
+void holds_alternative() {}
+template <typename T>
+void get() {}
+
+// Implements a matcher that checks the value of a variant<> type variable.
+template <typename T>
+class VariantMatcher {
+ public:
+ explicit VariantMatcher(::testing::Matcher<const T&> matcher)
+ : matcher_(internal::move(matcher)) {}
+
+ template <typename Variant>
+ bool MatchAndExplain(const Variant& value,
+ ::testing::MatchResultListener* listener) const {
+ if (!listener->IsInterested()) {
+ return holds_alternative<T>(value) && matcher_.Matches(get<T>(value));
+ }
+
+ if (!holds_alternative<T>(value)) {
+ *listener << "whose value is not of type '" << GetTypeName() << "'";
+ return false;
+ }
+
+ const T& elem = get<T>(value);
+ StringMatchResultListener elem_listener;
+ const bool match = matcher_.MatchAndExplain(elem, &elem_listener);
+ *listener << "whose value " << PrintToString(elem)
+ << (match ? " matches" : " doesn't match");
+ PrintIfNotEmpty(elem_listener.str(), listener->stream());
+ return match;
+ }
+
+ void DescribeTo(std::ostream* os) const {
+ *os << "is a variant<> with value of type '" << GetTypeName()
+ << "' and the value ";
+ matcher_.DescribeTo(os);
+ }
+
+ void DescribeNegationTo(std::ostream* os) const {
+ *os << "is a variant<> with value of type other than '" << GetTypeName()
+ << "' or the value ";
+ matcher_.DescribeNegationTo(os);
+ }
+
+ private:
+ static string GetTypeName() {
+#if GTEST_HAS_RTTI
+ return internal::GetTypeName<T>();
+#endif
+ return "the element type";
+ }
+
+ const ::testing::Matcher<const T&> matcher_;
+};
+
+} // namespace variant_matcher
+
} // namespace internal
-// ElementsAreArray(first, last)
+// ElementsAreArray(iterator_first, iterator_last)
// ElementsAreArray(pointer, count)
// ElementsAreArray(array)
// ElementsAreArray(container)
@@ -3675,20 +3747,26 @@ ElementsAreArray(::std::initializer_list<T> xs) {
}
#endif
-// UnorderedElementsAreArray(first, last)
+// UnorderedElementsAreArray(iterator_first, iterator_last)
// UnorderedElementsAreArray(pointer, count)
// UnorderedElementsAreArray(array)
// UnorderedElementsAreArray(container)
// UnorderedElementsAreArray({ e1, e2, ..., en })
//
-// The UnorderedElementsAreArray() functions are like
-// ElementsAreArray(...), but allow matching the elements in any order.
+// UnorderedElementsAreArray() verifies that a bijective mapping onto a
+// collection of matchers exists.
+//
+// The matchers can be specified as an array, a pointer and count, a container,
+// an initializer list, or an STL iterator range. In each of these cases, the
+// underlying matchers can be either values or matchers.
+
template <typename Iter>
inline internal::UnorderedElementsAreArrayMatcher<
typename ::std::iterator_traits<Iter>::value_type>
UnorderedElementsAreArray(Iter first, Iter last) {
typedef typename ::std::iterator_traits<Iter>::value_type T;
- return internal::UnorderedElementsAreArrayMatcher<T>(first, last);
+ return internal::UnorderedElementsAreArrayMatcher<T>(
+ internal::UnorderedMatcherRequire::ExactMatch, first, last);
}
template <typename T>
@@ -3730,7 +3808,9 @@ UnorderedElementsAreArray(::std::initializer_list<T> xs) {
const internal::AnythingMatcher _ = {};
// Creates a matcher that matches any value of the given type T.
template <typename T>
-inline Matcher<T> A() { return MakeMatcher(new internal::AnyMatcherImpl<T>()); }
+inline Matcher<T> A() {
+ return Matcher<T>(new internal::AnyMatcherImpl<T>());
+}
// Creates a matcher that matches any value of the given type T.
template <typename T>
@@ -4300,6 +4380,128 @@ inline internal::ContainsMatcher<M> Contains(M matcher) {
return internal::ContainsMatcher<M>(matcher);
}
+// IsSupersetOf(iterator_first, iterator_last)
+// IsSupersetOf(pointer, count)
+// IsSupersetOf(array)
+// IsSupersetOf(container)
+// IsSupersetOf({e1, e2, ..., en})
+//
+// IsSupersetOf() verifies that a surjective partial mapping onto a collection
+// of matchers exists. In other words, a container matches
+// IsSupersetOf({e1, ..., en}) if and only if there is a permutation
+// {y1, ..., yn} of some of the container's elements where y1 matches e1,
+// ..., and yn matches en. Obviously, the size of the container must be >= n
+// in order to have a match. Examples:
+//
+// - {1, 2, 3} matches IsSupersetOf({Ge(3), Ne(0)}), as 3 matches Ge(3) and
+// 1 matches Ne(0).
+// - {1, 2} doesn't match IsSupersetOf({Eq(1), Lt(2)}), even though 1 matches
+// both Eq(1) and Lt(2). The reason is that different matchers must be used
+// for elements in different slots of the container.
+// - {1, 1, 2} matches IsSupersetOf({Eq(1), Lt(2)}), as (the first) 1 matches
+// Eq(1) and (the second) 1 matches Lt(2).
+// - {1, 2, 3} matches IsSupersetOf(Gt(1), Gt(1)), as 2 matches (the first)
+// Gt(1) and 3 matches (the second) Gt(1).
+//
+// The matchers can be specified as an array, a pointer and count, a container,
+// an initializer list, or an STL iterator range. In each of these cases, the
+// underlying matchers can be either values or matchers.
+
+template <typename Iter>
+inline internal::UnorderedElementsAreArrayMatcher<
+ typename ::std::iterator_traits<Iter>::value_type>
+IsSupersetOf(Iter first, Iter last) {
+ typedef typename ::std::iterator_traits<Iter>::value_type T;
+ return internal::UnorderedElementsAreArrayMatcher<T>(
+ internal::UnorderedMatcherRequire::Superset, first, last);
+}
+
+template <typename T>
+inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(
+ const T* pointer, size_t count) {
+ return IsSupersetOf(pointer, pointer + count);
+}
+
+template <typename T, size_t N>
+inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(
+ const T (&array)[N]) {
+ return IsSupersetOf(array, N);
+}
+
+template <typename Container>
+inline internal::UnorderedElementsAreArrayMatcher<
+ typename Container::value_type>
+IsSupersetOf(const Container& container) {
+ return IsSupersetOf(container.begin(), container.end());
+}
+
+#if GTEST_HAS_STD_INITIALIZER_LIST_
+template <typename T>
+inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(
+ ::std::initializer_list<T> xs) {
+ return IsSupersetOf(xs.begin(), xs.end());
+}
+#endif
+
+// IsSubsetOf(iterator_first, iterator_last)
+// IsSubsetOf(pointer, count)
+// IsSubsetOf(array)
+// IsSubsetOf(container)
+// IsSubsetOf({e1, e2, ..., en})
+//
+// IsSubsetOf() verifies that an injective mapping onto a collection of matchers
+// exists. In other words, a container matches IsSubsetOf({e1, ..., en}) if and
+// only if there is a subset of matchers {m1, ..., mk} which would match the
+// container using UnorderedElementsAre. Obviously, the size of the container
+// must be <= n in order to have a match. Examples:
+//
+// - {1} matches IsSubsetOf({Gt(0), Lt(0)}), as 1 matches Gt(0).
+// - {1, -1} matches IsSubsetOf({Lt(0), Gt(0)}), as 1 matches Gt(0) and -1
+// matches Lt(0).
+// - {1, 2} doesn't matches IsSubsetOf({Gt(0), Lt(0)}), even though 1 and 2 both
+// match Gt(0). The reason is that different matchers must be used for
+// elements in different slots of the container.
+//
+// The matchers can be specified as an array, a pointer and count, a container,
+// an initializer list, or an STL iterator range. In each of these cases, the
+// underlying matchers can be either values or matchers.
+
+template <typename Iter>
+inline internal::UnorderedElementsAreArrayMatcher<
+ typename ::std::iterator_traits<Iter>::value_type>
+IsSubsetOf(Iter first, Iter last) {
+ typedef typename ::std::iterator_traits<Iter>::value_type T;
+ return internal::UnorderedElementsAreArrayMatcher<T>(
+ internal::UnorderedMatcherRequire::Subset, first, last);
+}
+
+template <typename T>
+inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(
+ const T* pointer, size_t count) {
+ return IsSubsetOf(pointer, pointer + count);
+}
+
+template <typename T, size_t N>
+inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(
+ const T (&array)[N]) {
+ return IsSubsetOf(array, N);
+}
+
+template <typename Container>
+inline internal::UnorderedElementsAreArrayMatcher<
+ typename Container::value_type>
+IsSubsetOf(const Container& container) {
+ return IsSubsetOf(container.begin(), container.end());
+}
+
+#if GTEST_HAS_STD_INITIALIZER_LIST_
+template <typename T>
+inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(
+ ::std::initializer_list<T> xs) {
+ return IsSubsetOf(xs.begin(), xs.end());
+}
+#endif
+
// Matches an STL-style container or a native array that contains only
// elements matching the given value or matcher.
//
@@ -4398,6 +4600,17 @@ inline internal::AnyOfMatcher<Args...> AnyOf(const Args&... matchers) {
template <typename InnerMatcher>
inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; }
+// Returns a matcher that matches the value of a variant<> type variable.
+// The matcher implementation uses ADL to find the holds_alternative and get
+// functions.
+// It is compatible with std::variant.
+template <typename T>
+PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T> > VariantWith(
+ const Matcher<const T&>& matcher) {
+ return MakePolymorphicMatcher(
+ internal::variant_matcher::VariantMatcher<T>(matcher));
+}
+
// These macros allow using matchers to check values in Google Test
// tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher)
// succeed iff the value matches the matcher. If the assertion fails,
diff --git a/googlemock/include/gmock/gmock-more-matchers.h b/googlemock/include/gmock/gmock-more-matchers.h
index 3db899f4..a5a8bfa5 100644
--- a/googlemock/include/gmock/gmock-more-matchers.h
+++ b/googlemock/include/gmock/gmock-more-matchers.h
@@ -53,6 +53,22 @@ MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") {
return false;
}
+// Define a matcher that matches a value that evaluates in boolean
+// context to true. Useful for types that define "explicit operator
+// bool" operators and so can't be compared for equality with true
+// and false.
+MATCHER(IsTrue, negation ? "is false" : "is true") {
+ return static_cast<bool>(arg);
+}
+
+// Define a matcher that matches a value that evaluates in boolean
+// context to false. Useful for types that define "explicit operator
+// bool" operators and so can't be compared for equality with true
+// and false.
+MATCHER(IsFalse, negation ? "is true" : "is false") {
+ return !static_cast<bool>(arg);
+}
+
} // namespace testing
#endif // GMOCK_GMOCK_MORE_MATCHERS_H_
diff --git a/googlemock/include/gmock/gmock-spec-builders.h b/googlemock/include/gmock/gmock-spec-builders.h
index a8347bd8..c1b63014 100644
--- a/googlemock/include/gmock/gmock-spec-builders.h
+++ b/googlemock/include/gmock/gmock-spec-builders.h
@@ -65,11 +65,6 @@
#include <sstream>
#include <string>
#include <vector>
-
-#if GTEST_HAS_EXCEPTIONS
-# include <stdexcept> // NOLINT
-#endif
-
#include "gmock/gmock-actions.h"
#include "gmock/gmock-cardinalities.h"
#include "gmock/gmock-matchers.h"
@@ -77,6 +72,10 @@
#include "gmock/internal/gmock-port.h"
#include "gtest/gtest.h"
+#if GTEST_HAS_EXCEPTIONS
+# include <stdexcept> // NOLINT
+#endif
+
namespace testing {
// An abstract handle of an expectation.
diff --git a/googlemock/include/gmock/gmock.h b/googlemock/include/gmock/gmock.h
index 5764bc85..6ccb118b 100644
--- a/googlemock/include/gmock/gmock.h
+++ b/googlemock/include/gmock/gmock.h
@@ -59,8 +59,8 @@
#include "gmock/gmock-cardinalities.h"
#include "gmock/gmock-generated-actions.h"
#include "gmock/gmock-generated-function-mockers.h"
-#include "gmock/gmock-generated-nice-strict.h"
#include "gmock/gmock-generated-matchers.h"
+#include "gmock/gmock-generated-nice-strict.h"
#include "gmock/gmock-matchers.h"
#include "gmock/gmock-more-actions.h"
#include "gmock/gmock-more-matchers.h"
diff --git a/googlemock/include/gmock/internal/gmock-generated-internal-utils.h b/googlemock/include/gmock/internal/gmock-generated-internal-utils.h
index 7811e43f..cd94d644 100644
--- a/googlemock/include/gmock/internal/gmock-generated-internal-utils.h
+++ b/googlemock/include/gmock/internal/gmock-generated-internal-utils.h
@@ -90,42 +90,48 @@ struct MatcherTuple< ::testing::tuple<A1, A2, A3> > {
template <typename A1, typename A2, typename A3, typename A4>
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4> > {
- typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>,
- Matcher<A4> > type;
+ typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4> >
+ type;
};
template <typename A1, typename A2, typename A3, typename A4, typename A5>
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5> > {
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
- Matcher<A5> > type;
+ Matcher<A5> >
+ type;
};
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6>
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6> > {
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
- Matcher<A5>, Matcher<A6> > type;
+ Matcher<A5>, Matcher<A6> >
+ type;
};
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7>
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7> > {
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
- Matcher<A5>, Matcher<A6>, Matcher<A7> > type;
+ Matcher<A5>, Matcher<A6>, Matcher<A7> >
+ type;
};
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8>
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8> > {
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
- Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8> > type;
+ Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8> >
+ type;
};
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8, typename A9>
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> > {
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
- Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, Matcher<A9> > type;
+ Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>,
+ Matcher<A9> >
+ type;
};
template <typename A1, typename A2, typename A3, typename A4, typename A5,
@@ -133,8 +139,9 @@ template <typename A1, typename A2, typename A3, typename A4, typename A5,
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
A10> > {
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
- Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, Matcher<A9>,
- Matcher<A10> > type;
+ Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>,
+ Matcher<A9>, Matcher<A10> >
+ type;
};
// Template struct Function<F>, where F must be a function type, contains
diff --git a/googlemock/include/gmock/internal/gmock-internal-utils.h b/googlemock/include/gmock/internal/gmock-internal-utils.h
index 7e65cea8..319b389b 100644
--- a/googlemock/include/gmock/internal/gmock-internal-utils.h
+++ b/googlemock/include/gmock/internal/gmock-internal-utils.h
@@ -41,7 +41,6 @@
#include <stdio.h>
#include <ostream> // NOLINT
#include <string>
-
#include "gmock/internal/gmock-generated-internal-utils.h"
#include "gmock/internal/gmock-port.h"
#include "gtest/gtest.h"
@@ -49,11 +48,15 @@
namespace testing {
namespace internal {
+// Joins a vector of strings as if they are fields of a tuple; returns
+// the joined string.
+GTEST_API_ std::string JoinAsTuple(const Strings& fields);
+
// Converts an identifier name to a space-separated list of lower-case
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
// treated as one word. For example, both "FooBar123" and
// "foo_bar_123" are converted to "foo bar 123".
-GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name);
+GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name);
// PointeeOf<Pointer>::type is the type of a value pointed to by a
// Pointer, which can be either a smart pointer or a raw pointer. The
@@ -503,8 +506,38 @@ struct RemoveConstFromKey<std::pair<const K, V> > {
template <bool kValue>
struct BooleanConstant {};
+// Emit an assertion failure due to incorrect DoDefault() usage. Out-of-lined to
+// reduce code size.
+void IllegalDoDefault(const char* file, int line);
+
+#if GTEST_LANG_CXX11
+// Helper types for Apply() below.
+template <size_t... Is> struct int_pack { typedef int_pack type; };
+
+template <class Pack, size_t I> struct append;
+template <size_t... Is, size_t I>
+struct append<int_pack<Is...>, I> : int_pack<Is..., I> {};
+
+template <size_t C>
+struct make_int_pack : append<typename make_int_pack<C - 1>::type, C - 1> {};
+template <> struct make_int_pack<0> : int_pack<> {};
+
+template <typename F, typename Tuple, size_t... Idx>
+auto ApplyImpl(F&& f, Tuple&& args, int_pack<Idx...>) -> decltype(
+ std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...)) {
+ return std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...);
+}
+
+// Apply the function to a tuple of arguments.
+template <typename F, typename Tuple>
+auto Apply(F&& f, Tuple&& args)
+ -> decltype(ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
+ make_int_pack<std::tuple_size<Tuple>::value>())) {
+ return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
+ make_int_pack<std::tuple_size<Tuple>::value>());
+}
+#endif
} // namespace internal
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
-
diff --git a/googlemock/include/gmock/internal/gmock-port.h b/googlemock/include/gmock/internal/gmock-port.h
index 63f4a680..cb37f260 100644
--- a/googlemock/include/gmock/internal/gmock-port.h
+++ b/googlemock/include/gmock/internal/gmock-port.h
@@ -50,15 +50,11 @@
// portability utilities to Google Test's gtest-port.h instead of
// here, as Google Mock depends on Google Test. Only add a utility
// here if it's truly specific to Google Mock.
+
#include "gtest/internal/gtest-linked_ptr.h"
#include "gtest/internal/gtest-port.h"
#include "gmock/internal/custom/gmock-port.h"
-// To avoid conditional compilation everywhere, we make it
-// gmock-port.h's responsibility to #include the header implementing
-// tr1/tuple. gmock-port.h does this via gtest-port.h, which is
-// guaranteed to pull in the tuple header.
-
// For MS Visual C++, check the compiler version. At least VS 2003 is
// required to compile Google Mock.
#if defined(_MSC_VER) && _MSC_VER < 1310
@@ -72,18 +68,18 @@
#if !defined(GMOCK_DECLARE_bool_)
// Macros for declaring flags.
-#define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name)
-#define GMOCK_DECLARE_int32_(name) \
+# define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name)
+# define GMOCK_DECLARE_int32_(name) \
extern GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name)
-#define GMOCK_DECLARE_string_(name) \
+# define GMOCK_DECLARE_string_(name) \
extern GTEST_API_ ::std::string GMOCK_FLAG(name)
// Macros for defining flags.
-#define GMOCK_DEFINE_bool_(name, default_val, doc) \
+# define GMOCK_DEFINE_bool_(name, default_val, doc) \
GTEST_API_ bool GMOCK_FLAG(name) = (default_val)
-#define GMOCK_DEFINE_int32_(name, default_val, doc) \
+# define GMOCK_DEFINE_int32_(name, default_val, doc) \
GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) = (default_val)
-#define GMOCK_DEFINE_string_(name, default_val, doc) \
+# define GMOCK_DEFINE_string_(name, default_val, doc) \
GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val)
#endif // !defined(GMOCK_DECLARE_bool_)
diff --git a/googlemock/scripts/generator/cpp/ast.py b/googlemock/scripts/generator/cpp/ast.py
index 11cbe912..cce32724 100755
--- a/googlemock/scripts/generator/cpp/ast.py
+++ b/googlemock/scripts/generator/cpp/ast.py
@@ -338,7 +338,7 @@ class Class(_GenericDeclaration):
# TODO(nnorwitz): handle namespaces, etc.
if self.bases:
for token_list in self.bases:
- # TODO(nnorwitz): bases are tokens, do name comparision.
+ # TODO(nnorwitz): bases are tokens, do name comparison.
for token in token_list:
if token.name == node.name:
return True
@@ -381,7 +381,7 @@ class Function(_GenericDeclaration):
def Requires(self, node):
if self.parameters:
- # TODO(nnorwitz): parameters are tokens, do name comparision.
+ # TODO(nnorwitz): parameters are tokens, do name comparison.
for p in self.parameters:
if p.name == node.name:
return True
@@ -858,7 +858,7 @@ class AstBuilder(object):
last_token = self._GetNextToken()
return tokens, last_token
- # TODO(nnorwitz): remove _IgnoreUpTo() it shouldn't be necesary.
+ # TODO(nnorwitz): remove _IgnoreUpTo() it shouldn't be necessary.
def _IgnoreUpTo(self, token_type, token):
unused_tokens = self._GetTokensUpTo(token_type, token)
diff --git a/googlemock/src/gmock-internal-utils.cc b/googlemock/src/gmock-internal-utils.cc
index 91bf3fd9..658fa62d 100644
--- a/googlemock/src/gmock-internal-utils.cc
+++ b/googlemock/src/gmock-internal-utils.cc
@@ -47,6 +47,25 @@
namespace testing {
namespace internal {
+// Joins a vector of strings as if they are fields of a tuple; returns
+// the joined string.
+GTEST_API_ std::string JoinAsTuple(const Strings& fields) {
+ switch (fields.size()) {
+ case 0:
+ return "";
+ case 1:
+ return fields[0];
+ default:
+ std::string result = "(" + fields[0];
+ for (size_t i = 1; i < fields.size(); i++) {
+ result += ", ";
+ result += fields[i];
+ }
+ result += ")";
+ return result;
+ }
+}
+
// Converts an identifier name to a space-separated list of lower-case
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
// treated as one word. For example, both "FooBar123" and
diff --git a/googlemock/src/gmock-matchers.cc b/googlemock/src/gmock-matchers.cc
index 6e40e5e8..88e40088 100644
--- a/googlemock/src/gmock-matchers.cc
+++ b/googlemock/src/gmock-matchers.cc
@@ -38,6 +38,7 @@
#include "gmock/gmock-generated-matchers.h"
#include <string.h>
+#include <iostream>
#include <sstream>
#include <string>
@@ -100,25 +101,6 @@ Matcher<StringPiece>::Matcher(StringPiece s) {
namespace internal {
-// Joins a vector of strings as if they are fields of a tuple; returns
-// the joined string.
-GTEST_API_ string JoinAsTuple(const Strings& fields) {
- switch (fields.size()) {
- case 0:
- return "";
- case 1:
- return fields[0];
- default:
- string result = "(" + fields[0];
- for (size_t i = 1; i < fields.size(); i++) {
- result += ", ";
- result += fields[i];
- }
- result += ")";
- return result;
- }
-}
-
// Returns the description for a matcher defined using the MATCHER*()
// macro where the user-supplied description string is "", if
// 'negation' is false; otherwise returns the description of the
@@ -200,8 +182,7 @@ class MaxBipartiteMatchState {
explicit MaxBipartiteMatchState(const MatchMatrix& graph)
: graph_(&graph),
left_(graph_->LhsSize(), kUnused),
- right_(graph_->RhsSize(), kUnused) {
- }
+ right_(graph_->RhsSize(), kUnused) {}
// Returns the edges of a maximal match, each in the form {left, right}.
ElementMatcherPairs Compute() {
@@ -258,10 +239,8 @@ class MaxBipartiteMatchState {
//
bool TryAugment(size_t ilhs, ::std::vector<char>* seen) {
for (size_t irhs = 0; irhs < graph_->RhsSize(); ++irhs) {
- if ((*seen)[irhs])
- continue;
- if (!graph_->HasEdge(ilhs, irhs))
- continue;
+ if ((*seen)[irhs]) continue;
+ if (!graph_->HasEdge(ilhs, irhs)) continue;
// There's an available edge from ilhs to irhs.
(*seen)[irhs] = 1;
// Next a search is performed to determine whether
@@ -304,8 +283,7 @@ class MaxBipartiteMatchState {
const size_t MaxBipartiteMatchState::kUnused;
-GTEST_API_ ElementMatcherPairs
-FindMaxBipartiteMatching(const MatchMatrix& g) {
+GTEST_API_ ElementMatcherPairs FindMaxBipartiteMatching(const MatchMatrix& g) {
return MaxBipartiteMatchState(g).Compute();
}
@@ -314,7 +292,7 @@ static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs,
typedef ElementMatcherPairs::const_iterator Iter;
::std::ostream& os = *stream;
os << "{";
- const char *sep = "";
+ const char* sep = "";
for (Iter it = pairs.begin(); it != pairs.end(); ++it) {
os << sep << "\n ("
<< "element #" << it->first << ", "
@@ -324,38 +302,6 @@ static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs,
os << "\n}";
}
-// Tries to find a pairing, and explains the result.
-GTEST_API_ bool FindPairing(const MatchMatrix& matrix,
- MatchResultListener* listener) {
- ElementMatcherPairs matches = FindMaxBipartiteMatching(matrix);
-
- size_t max_flow = matches.size();
- bool result = (max_flow == matrix.RhsSize());
-
- if (!result) {
- if (listener->IsInterested()) {
- *listener << "where no permutation of the elements can "
- "satisfy all matchers, and the closest match is "
- << max_flow << " of " << matrix.RhsSize()
- << " matchers with the pairings:\n";
- LogElementMatcherPairVec(matches, listener->stream());
- }
- return false;
- }
-
- if (matches.size() > 1) {
- if (listener->IsInterested()) {
- const char *sep = "where:\n";
- for (size_t mi = 0; mi < matches.size(); ++mi) {
- *listener << sep << " - element #" << matches[mi].first
- << " is matched by matcher #" << matches[mi].second;
- sep = ",\n";
- }
- }
- }
- return true;
-}
-
bool MatchMatrix::NextGraph() {
for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {
@@ -381,7 +327,7 @@ void MatchMatrix::Randomize() {
std::string MatchMatrix::DebugString() const {
::std::stringstream ss;
- const char *sep = "";
+ const char* sep = "";
for (size_t i = 0; i < LhsSize(); ++i) {
ss << sep;
for (size_t j = 0; j < RhsSize(); ++j) {
@@ -394,44 +340,83 @@ std::string MatchMatrix::DebugString() const {
void UnorderedElementsAreMatcherImplBase::DescribeToImpl(
::std::ostream* os) const {
- if (matcher_describers_.empty()) {
- *os << "is empty";
- return;
- }
- if (matcher_describers_.size() == 1) {
- *os << "has " << Elements(1) << " and that element ";
- matcher_describers_[0]->DescribeTo(os);
- return;
+ switch (match_flags()) {
+ case UnorderedMatcherRequire::ExactMatch:
+ if (matcher_describers_.empty()) {
+ *os << "is empty";
+ return;
+ }
+ if (matcher_describers_.size() == 1) {
+ *os << "has " << Elements(1) << " and that element ";
+ matcher_describers_[0]->DescribeTo(os);
+ return;
+ }
+ *os << "has " << Elements(matcher_describers_.size())
+ << " and there exists some permutation of elements such that:\n";
+ break;
+ case UnorderedMatcherRequire::Superset:
+ *os << "a surjection from elements to requirements exists such that:\n";
+ break;
+ case UnorderedMatcherRequire::Subset:
+ *os << "an injection from elements to requirements exists such that:\n";
+ break;
}
- *os << "has " << Elements(matcher_describers_.size())
- << " and there exists some permutation of elements such that:\n";
+
const char* sep = "";
for (size_t i = 0; i != matcher_describers_.size(); ++i) {
- *os << sep << " - element #" << i << " ";
+ *os << sep;
+ if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
+ *os << " - element #" << i << " ";
+ } else {
+ *os << " - an element ";
+ }
matcher_describers_[i]->DescribeTo(os);
- sep = ", and\n";
+ if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
+ sep = ", and\n";
+ } else {
+ sep = "\n";
+ }
}
}
void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(
::std::ostream* os) const {
- if (matcher_describers_.empty()) {
- *os << "isn't empty";
- return;
- }
- if (matcher_describers_.size() == 1) {
- *os << "doesn't have " << Elements(1)
- << ", or has " << Elements(1) << " that ";
- matcher_describers_[0]->DescribeNegationTo(os);
- return;
+ switch (match_flags()) {
+ case UnorderedMatcherRequire::ExactMatch:
+ if (matcher_describers_.empty()) {
+ *os << "isn't empty";
+ return;
+ }
+ if (matcher_describers_.size() == 1) {
+ *os << "doesn't have " << Elements(1) << ", or has " << Elements(1)
+ << " that ";
+ matcher_describers_[0]->DescribeNegationTo(os);
+ return;
+ }
+ *os << "doesn't have " << Elements(matcher_describers_.size())
+ << ", or there exists no permutation of elements such that:\n";
+ break;
+ case UnorderedMatcherRequire::Superset:
+ *os << "no surjection from elements to requirements exists such that:\n";
+ break;
+ case UnorderedMatcherRequire::Subset:
+ *os << "no injection from elements to requirements exists such that:\n";
+ break;
}
- *os << "doesn't have " << Elements(matcher_describers_.size())
- << ", or there exists no permutation of elements such that:\n";
const char* sep = "";
for (size_t i = 0; i != matcher_describers_.size(); ++i) {
- *os << sep << " - element #" << i << " ";
+ *os << sep;
+ if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
+ *os << " - element #" << i << " ";
+ } else {
+ *os << " - an element ";
+ }
matcher_describers_[i]->DescribeTo(os);
- sep = ", and\n";
+ if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
+ sep = ", and\n";
+ } else {
+ sep = "\n";
+ }
}
}
@@ -440,10 +425,9 @@ void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(
// and better error reporting.
// Returns false, writing an explanation to 'listener', if and only
// if the success criteria are not met.
-bool UnorderedElementsAreMatcherImplBase::
- VerifyAllElementsAndMatchersAreMatched(
- const ::std::vector<std::string>& element_printouts,
- const MatchMatrix& matrix, MatchResultListener* listener) const {
+bool UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix(
+ const ::std::vector<std::string>& element_printouts,
+ const MatchMatrix& matrix, MatchResultListener* listener) const {
bool result = true;
::std::vector<char> element_matched(matrix.LhsSize(), 0);
::std::vector<char> matcher_matched(matrix.RhsSize(), 0);
@@ -456,12 +440,11 @@ bool UnorderedElementsAreMatcherImplBase::
}
}
- {
+ if (match_flags() & UnorderedMatcherRequire::Superset) {
const char* sep =
"where the following matchers don't match any elements:\n";
for (size_t mi = 0; mi < matcher_matched.size(); ++mi) {
- if (matcher_matched[mi])
- continue;
+ if (matcher_matched[mi]) continue;
result = false;
if (listener->IsInterested()) {
*listener << sep << "matcher #" << mi << ": ";
@@ -471,7 +454,7 @@ bool UnorderedElementsAreMatcherImplBase::
}
}
- {
+ if (match_flags() & UnorderedMatcherRequire::Subset) {
const char* sep =
"where the following elements don't match any matchers:\n";
const char* outer_sep = "";
@@ -479,8 +462,7 @@ bool UnorderedElementsAreMatcherImplBase::
outer_sep = "\nand ";
}
for (size_t ei = 0; ei < element_matched.size(); ++ei) {
- if (element_matched[ei])
- continue;
+ if (element_matched[ei]) continue;
result = false;
if (listener->IsInterested()) {
*listener << outer_sep << sep << "element #" << ei << ": "
@@ -493,5 +475,46 @@ bool UnorderedElementsAreMatcherImplBase::
return result;
}
+bool UnorderedElementsAreMatcherImplBase::FindPairing(
+ const MatchMatrix& matrix, MatchResultListener* listener) const {
+ ElementMatcherPairs matches = FindMaxBipartiteMatching(matrix);
+
+ size_t max_flow = matches.size();
+ if ((match_flags() & UnorderedMatcherRequire::Superset) &&
+ max_flow < matrix.RhsSize()) {
+ if (listener->IsInterested()) {
+ *listener << "where no permutation of the elements can satisfy all "
+ "matchers, and the closest match is "
+ << max_flow << " of " << matrix.RhsSize()
+ << " matchers with the pairings:\n";
+ LogElementMatcherPairVec(matches, listener->stream());
+ }
+ return false;
+ }
+ if ((match_flags() & UnorderedMatcherRequire::Subset) &&
+ max_flow < matrix.LhsSize()) {
+ if (listener->IsInterested()) {
+ *listener
+ << "where not all elements can be matched, and the closest match is "
+ << max_flow << " of " << matrix.RhsSize()
+ << " matchers with the pairings:\n";
+ LogElementMatcherPairVec(matches, listener->stream());
+ }
+ return false;
+ }
+
+ if (matches.size() > 1) {
+ if (listener->IsInterested()) {
+ const char* sep = "where:\n";
+ for (size_t mi = 0; mi < matches.size(); ++mi) {
+ *listener << sep << " - element #" << matches[mi].first
+ << " is matched by matcher #" << matches[mi].second;
+ sep = ",\n";
+ }
+ }
+ }
+ return true;
+}
+
} // namespace internal
} // namespace testing
diff --git a/googlemock/src/gmock-spec-builders.cc b/googlemock/src/gmock-spec-builders.cc
index fc4968ba..93a83ae5 100644
--- a/googlemock/src/gmock-spec-builders.cc
+++ b/googlemock/src/gmock-spec-builders.cc
@@ -508,7 +508,7 @@ bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()
return expectations_met;
}
-CallReaction intToCallReaction(int mock_behavior) {
+static CallReaction intToCallReaction(int mock_behavior) {
if (mock_behavior >= kAllow && mock_behavior <= kFail) {
return static_cast<internal::CallReaction>(mock_behavior);
}
diff --git a/googlemock/test/BUILD.bazel b/googlemock/test/BUILD.bazel
index 9f1a64d8..0fe72a67 100644
--- a/googlemock/test/BUILD.bazel
+++ b/googlemock/test/BUILD.bazel
@@ -1,4 +1,4 @@
-# Copyright 2017 Google Inc.
+# Copyright 2017 Google Inc.
# All Rights Reserved.
#
#
@@ -29,7 +29,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Author: misterg@google.com (Gennadiy Civil)
-#
+#
# Bazel Build for Google C++ Testing Framework(Google Test)-googlemock
licenses(["notice"])
@@ -45,10 +45,79 @@ cc_test(
],
),
linkopts = select({
- "//:win": [],
+ "//:windows": [],
+ "//:windows_msvc": [],
"//conditions:default": [
"-pthread",
],
}),
deps = ["//:gtest"],
)
+
+# Py tests
+
+py_library(
+ name = "gmock_test_utils",
+ testonly = 1,
+ srcs = ["gmock_test_utils.py"],
+)
+
+cc_binary(
+ name = "gmock_leak_test_",
+ testonly = 1,
+ srcs = ["gmock_leak_test_.cc"],
+ deps = [
+ "//:gtest_main",
+ ],
+)
+
+py_test(
+ name = "gmock_leak_test",
+ size = "medium",
+ srcs = ["gmock_leak_test.py"],
+ data = [
+ ":gmock_leak_test_",
+ ":gmock_test_utils",
+ ],
+)
+
+cc_test(
+ name = "gmock_link_test",
+ size = "small",
+ srcs = [
+ "gmock_link2_test.cc",
+ "gmock_link_test.cc",
+ "gmock_link_test.h",
+ ],
+ deps = [
+ "//:gtest_main",
+ ],
+)
+
+cc_binary(
+ name = "gmock_output_test_",
+ srcs = ["gmock_output_test_.cc"],
+ deps = [
+ "//:gtest",
+ ],
+)
+
+py_test(
+ name = "gmock_output_test",
+ size = "medium",
+ srcs = ["gmock_output_test.py"],
+ data = [
+ ":gmock_output_test_",
+ ":gmock_output_test_golden.txt",
+ ],
+ deps = [":gmock_test_utils"],
+)
+
+cc_test(
+ name = "gmock_test",
+ size = "small",
+ srcs = ["gmock_test.cc"],
+ deps = [
+ "//:gtest_main",
+ ],
+)
diff --git a/googlemock/test/gmock-actions_test.cc b/googlemock/test/gmock-actions_test.cc
index f470de4c..f7218391 100644
--- a/googlemock/test/gmock-actions_test.cc
+++ b/googlemock/test/gmock-actions_test.cc
@@ -751,7 +751,7 @@ TEST(DoDefaultDeathTest, DiesIfUsedInCompositeAction) {
}
// Tests that DoDefault() returns the default value set by
-// DefaultValue<T>::Set() when it's not overriden by an ON_CALL().
+// DefaultValue<T>::Set() when it's not overridden by an ON_CALL().
TEST(DoDefaultTest, ReturnsUserSpecifiedPerTypeDefaultValueWhenThereIsOne) {
DefaultValue<int>::Set(1);
MockClass mock;
diff --git a/googlemock/test/gmock-internal-utils_test.cc b/googlemock/test/gmock-internal-utils_test.cc
index 72d9a854..c7893ae2 100644
--- a/googlemock/test/gmock-internal-utils_test.cc
+++ b/googlemock/test/gmock-internal-utils_test.cc
@@ -44,15 +44,7 @@
#include "gmock/internal/gmock-port.h"
#include "gtest/gtest.h"
#include "gtest/gtest-spi.h"
-
-// Indicates that this translation unit is part of Google Test's
-// implementation. It must come before gtest-internal-inl.h is
-// included, or there will be a compiler error. This trick is to
-// prevent a user from accidentally including gtest-internal-inl.h in
-// their code.
-#define GTEST_IMPLEMENTATION_ 1
#include "src/gtest-internal-inl.h"
-#undef GTEST_IMPLEMENTATION_
#if GTEST_OS_CYGWIN
# include <sys/types.h> // For ssize_t. NOLINT
diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc
index 4beaec4c..829935ef 100644
--- a/googlemock/test/gmock-matchers_test.cc
+++ b/googlemock/test/gmock-matchers_test.cc
@@ -65,10 +65,6 @@
namespace testing {
-namespace internal {
-GTEST_API_ string JoinAsTuple(const Strings& fields);
-} // namespace internal
-
namespace gmock_matchers_test {
using std::greater;
@@ -150,7 +146,6 @@ using testing::internal::ExplainMatchFailureTupleTo;
using testing::internal::FloatingEqMatcher;
using testing::internal::FormatMatcherDescription;
using testing::internal::IsReadableTypeName;
-using testing::internal::JoinAsTuple;
using testing::internal::linked_ptr;
using testing::internal::MatchMatrix;
using testing::internal::RE;
@@ -876,9 +871,9 @@ class Unprintable {
char c_;
};
-inline bool operator==(const Unprintable& /* lhs */,
- const Unprintable& /* rhs */) {
- return true;
+inline bool operator==(const Unprintable& /* lhs */,
+ const Unprintable& /* rhs */) {
+ return true;
}
TEST(EqTest, CanDescribeSelf) {
@@ -919,7 +914,7 @@ TEST(TypedEqTest, CanDescribeSelf) {
// Type<T>::IsTypeOf(v) compiles iff the type of value v is T, where T
// is a "bare" type (i.e. not in the form of const U or U&). If v's
// type is not T, the compiler will generate a message about
-// "undefined referece".
+// "undefined reference".
template <typename T>
struct Type {
static bool IsTypeOf(const T& /* v */) { return true; }
@@ -1428,7 +1423,7 @@ TEST(PairTest, MatchesCorrectly) {
EXPECT_THAT(p, Pair(25, "foo"));
EXPECT_THAT(p, Pair(Ge(20), HasSubstr("o")));
- // 'first' doesnt' match, but 'second' matches.
+ // 'first' does not match, but 'second' matches.
EXPECT_THAT(p, Not(Pair(42, "foo")));
EXPECT_THAT(p, Not(Pair(Lt(25), "foo")));
@@ -4267,7 +4262,7 @@ TYPED_TEST(ContainerEqTest, DuplicateDifference) {
#endif // GTEST_HAS_TYPED_TEST
// Tests that mutliple missing values are reported.
-// Using just vector here, so order is predicatble.
+// Using just vector here, so order is predictable.
TEST(ContainerEqExtraTest, MultipleValuesMissing) {
static const int vals[] = {1, 1, 2, 3, 5, 8};
static const int test_vals[] = {2, 1, 5};
@@ -4280,7 +4275,7 @@ TEST(ContainerEqExtraTest, MultipleValuesMissing) {
}
// Tests that added values are reported.
-// Using just vector here, so order is predicatble.
+// Using just vector here, so order is predictable.
TEST(ContainerEqExtraTest, MultipleValuesAdded) {
static const int vals[] = {1, 1, 2, 3, 5, 8};
static const int test_vals[] = {1, 2, 92, 3, 5, 8, 46};
@@ -5272,28 +5267,6 @@ TEST(IsReadableTypeNameTest, ReturnsFalseForLongFunctionTypeNames) {
EXPECT_FALSE(IsReadableTypeName("void (&)(int, bool, char, float)"));
}
-// Tests JoinAsTuple().
-
-TEST(JoinAsTupleTest, JoinsEmptyTuple) {
- EXPECT_EQ("", JoinAsTuple(Strings()));
-}
-
-TEST(JoinAsTupleTest, JoinsOneTuple) {
- const char* fields[] = {"1"};
- EXPECT_EQ("1", JoinAsTuple(Strings(fields, fields + 1)));
-}
-
-TEST(JoinAsTupleTest, JoinsTwoTuple) {
- const char* fields[] = {"1", "a"};
- EXPECT_EQ("(1, a)", JoinAsTuple(Strings(fields, fields + 2)));
-}
-
-TEST(JoinAsTupleTest, JoinsTenTuple) {
- const char* fields[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"};
- EXPECT_EQ("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)",
- JoinAsTuple(Strings(fields, fields + 10)));
-}
-
// Tests FormatMatcherDescription().
TEST(FormatMatcherDescriptionTest, WorksForEmptyDescription) {
@@ -5682,5 +5655,69 @@ TEST(UnorderedPointwiseTest, AllowsMonomorphicInnerMatcher) {
EXPECT_THAT(lhs, UnorderedPointwise(m2, rhs));
}
+class SampleVariantIntString {
+ public:
+ SampleVariantIntString(int i) : i_(i), has_int_(true) {}
+ SampleVariantIntString(const std::string& s) : s_(s), has_int_(false) {}
+
+ template <typename T>
+ friend bool holds_alternative(const SampleVariantIntString& value) {
+ return value.has_int_ == internal::IsSame<T, int>::value;
+ }
+
+ template <typename T>
+ friend const T& get(const SampleVariantIntString& value) {
+ return value.get_impl(static_cast<T*>(NULL));
+ }
+
+ private:
+ const int& get_impl(int*) const { return i_; }
+ const std::string& get_impl(std::string*) const { return s_; }
+
+ int i_;
+ std::string s_;
+ bool has_int_;
+};
+
+TEST(VariantTest, DescribesSelf) {
+ const Matcher<SampleVariantIntString> m = VariantWith<int>(Eq(1));
+ EXPECT_THAT(Describe(m), ContainsRegex("is a variant<> with value of type "
+ "'.*' and the value is equal to 1"));
+}
+
+TEST(VariantTest, ExplainsSelf) {
+ const Matcher<SampleVariantIntString> m = VariantWith<int>(Eq(1));
+ EXPECT_THAT(Explain(m, SampleVariantIntString(1)),
+ ContainsRegex("whose value 1"));
+ EXPECT_THAT(Explain(m, SampleVariantIntString("A")),
+ HasSubstr("whose value is not of type '"));
+ EXPECT_THAT(Explain(m, SampleVariantIntString(2)),
+ "whose value 2 doesn't match");
+}
+
+TEST(VariantTest, FullMatch) {
+ Matcher<SampleVariantIntString> m = VariantWith<int>(Eq(1));
+ EXPECT_TRUE(m.Matches(SampleVariantIntString(1)));
+
+ m = VariantWith<std::string>(Eq("1"));
+ EXPECT_TRUE(m.Matches(SampleVariantIntString("1")));
+}
+
+TEST(VariantTest, TypeDoesNotMatch) {
+ Matcher<SampleVariantIntString> m = VariantWith<int>(Eq(1));
+ EXPECT_FALSE(m.Matches(SampleVariantIntString("1")));
+
+ m = VariantWith<std::string>(Eq("1"));
+ EXPECT_FALSE(m.Matches(SampleVariantIntString(1)));
+}
+
+TEST(VariantTest, InnerDoesNotMatch) {
+ Matcher<SampleVariantIntString> m = VariantWith<int>(Eq(1));
+ EXPECT_FALSE(m.Matches(SampleVariantIntString(2)));
+
+ m = VariantWith<std::string>(Eq("1"));
+ EXPECT_FALSE(m.Matches(SampleVariantIntString("2")));
+}
+
} // namespace gmock_matchers_test
} // namespace testing
diff --git a/googlemock/test/gmock_link_test.h b/googlemock/test/gmock_link_test.h
index 1f55f5bd..5f855d19 100644
--- a/googlemock/test/gmock_link_test.h
+++ b/googlemock/test/gmock_link_test.h
@@ -120,13 +120,15 @@
# include <errno.h>
#endif
-#include "gmock/internal/gmock-port.h"
-#include "gtest/gtest.h"
#include <iostream>
#include <vector>
+#include "gtest/gtest.h"
+#include "gtest/internal/gtest-port.h"
+
using testing::_;
using testing::A;
+using testing::Action;
using testing::AllOf;
using testing::AnyOf;
using testing::Assign;
@@ -148,6 +150,8 @@ using testing::Invoke;
using testing::InvokeArgument;
using testing::InvokeWithoutArgs;
using testing::IsNull;
+using testing::IsSubsetOf;
+using testing::IsSupersetOf;
using testing::Le;
using testing::Lt;
using testing::Matcher;
@@ -592,6 +596,22 @@ TEST(LinkTest, TestMatcherElementsAreArray) {
ON_CALL(mock, VoidFromVector(ElementsAreArray(arr))).WillByDefault(Return());
}
+// Tests the linkage of the IsSubsetOf matcher.
+TEST(LinkTest, TestMatcherIsSubsetOf) {
+ Mock mock;
+ char arr[] = {'a', 'b'};
+
+ ON_CALL(mock, VoidFromVector(IsSubsetOf(arr))).WillByDefault(Return());
+}
+
+// Tests the linkage of the IsSupersetOf matcher.
+TEST(LinkTest, TestMatcherIsSupersetOf) {
+ Mock mock;
+ char arr[] = {'a', 'b'};
+
+ ON_CALL(mock, VoidFromVector(IsSupersetOf(arr))).WillByDefault(Return());
+}
+
// Tests the linkage of the ContainerEq matcher.
TEST(LinkTest, TestMatcherContainerEq) {
Mock mock;
diff --git a/googlemock/test/gmock_output_test.py b/googlemock/test/gmock_output_test.py
index eced8a81..9d73d570 100755
--- a/googlemock/test/gmock_output_test.py
+++ b/googlemock/test/gmock_output_test.py
@@ -31,11 +31,11 @@
"""Tests the text output of Google C++ Mocking Framework.
-SYNOPSIS
- gmock_output_test.py --build_dir=BUILD/DIR --gengolden
- # where BUILD/DIR contains the built gmock_output_test_ file.
- gmock_output_test.py --gengolden
- gmock_output_test.py
+To update the golden file:
+gmock_output_test.py --build_dir=BUILD/DIR --gengolden
+# where BUILD/DIR contains the built gmock_output_test_ file.
+gmock_output_test.py --gengolden
+gmock_output_test.py
"""
__author__ = 'wan@google.com (Zhanyong Wan)'
@@ -176,5 +176,8 @@ if __name__ == '__main__':
golden_file = open(GOLDEN_PATH, 'wb')
golden_file.write(output)
golden_file.close()
+ # Suppress the error "googletest was imported but a call to its main()
+ # was never detected."
+ os._exit(0)
else:
gmock_test_utils.Main()
diff --git a/googlemock/test/gmock_stress_test.cc b/googlemock/test/gmock_stress_test.cc
index c16badda..b9fdc45c 100644
--- a/googlemock/test/gmock_stress_test.cc
+++ b/googlemock/test/gmock_stress_test.cc
@@ -33,12 +33,13 @@
// threads concurrently.
#include "gmock/gmock.h"
+
#include "gtest/gtest.h"
namespace testing {
namespace {
-// From <gtest/internal/gtest-port.h>.
+// From "gtest/internal/gtest-port.h".
using ::testing::internal::ThreadWithParam;
// The maximum number of test threads (not including helper threads)
diff --git a/googlemock/test/gmock_test.cc b/googlemock/test/gmock_test.cc
index 28995345..70075679 100644
--- a/googlemock/test/gmock_test.cc
+++ b/googlemock/test/gmock_test.cc
@@ -37,6 +37,7 @@
#include <string>
#include "gtest/gtest.h"
+#include "gtest/internal/custom/gtest.h"
#if !defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
@@ -51,9 +52,9 @@ void TestInitGoogleMock(const Char* (&argv)[M], const Char* (&new_argv)[N],
const ::std::string& expected_gmock_verbose) {
const ::std::string old_verbose = GMOCK_FLAG(verbose);
- int argc = M;
+ int argc = M - 1;
InitGoogleMock(&argc, const_cast<Char**>(argv));
- ASSERT_EQ(N, argc) << "The new argv has wrong number of elements.";
+ ASSERT_EQ(N - 1, argc) << "The new argv has wrong number of elements.";
for (int i = 0; i < N; i++) {
EXPECT_STREQ(new_argv[i], argv[i]);
diff --git a/googlemock/test/gmock_test_utils.py b/googlemock/test/gmock_test_utils.py
index 20e3d3d4..b5130001 100755
--- a/googlemock/test/gmock_test_utils.py
+++ b/googlemock/test/gmock_test_utils.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-#
# Copyright 2006, Google Inc.
# All rights reserved.
#
@@ -36,19 +34,19 @@ __author__ = 'wan@google.com (Zhanyong Wan)'
import os
import sys
-
# Determines path to gtest_test_utils and imports it.
SCRIPT_DIR = os.path.dirname(__file__) or '.'
# isdir resolves symbolic links.
-gtest_tests_util_dir = os.path.join(SCRIPT_DIR, '../gtest/test')
+gtest_tests_util_dir = os.path.join(SCRIPT_DIR, '../googletest/test')
if os.path.isdir(gtest_tests_util_dir):
GTEST_TESTS_UTIL_DIR = gtest_tests_util_dir
else:
- GTEST_TESTS_UTIL_DIR = os.path.join(SCRIPT_DIR, '../../gtest/test')
-
+ GTEST_TESTS_UTIL_DIR = os.path.join(SCRIPT_DIR, '../../googletest/test')
sys.path.append(GTEST_TESTS_UTIL_DIR)
-import gtest_test_utils # pylint: disable-msg=C6204
+
+# pylint: disable=C6204
+import gtest_test_utils
def GetSourceDir():