Commit d22dbec2 authored by zhoux's avatar zhoux
Browse files

Initial commit: release hytlass-0.1.0

parents
# Customization Points
The custom directory is an injection point for custom user configurations.
## Header `gmock-port.h`
The following macros can be defined:
### Flag related macros:
* `GMOCK_DECLARE_bool_(name)`
* `GMOCK_DECLARE_int32_(name)`
* `GMOCK_DECLARE_string_(name)`
* `GMOCK_DEFINE_bool_(name, default_val, doc)`
* `GMOCK_DEFINE_int32_(name, default_val, doc)`
* `GMOCK_DEFINE_string_(name, default_val, doc)`
* `GMOCK_FLAG_GET(flag_name)`
* `GMOCK_FLAG_SET(flag_name, value)`
// IWYU pragma: private, include "gmock/gmock.h"
// IWYU pragma: friend gmock/.*
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Injection point for custom user configurations. See README for details
// IWYU pragma: private, include "gmock/gmock.h"
// IWYU pragma: friend gmock/.*
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Injection point for custom user configurations. See README for details
//
// ** Custom implementation starts here **
// IWYU pragma: private, include "gmock/gmock.h"
// IWYU pragma: friend gmock/.*
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Mock - a framework for writing C++ mock classes.
//
// This file defines some utilities useful for implementing Google
// Mock. They are subject to change without notice, so please DO NOT
// USE THEM IN USER CODE.
// IWYU pragma: private, include "gmock/gmock.h"
// IWYU pragma: friend gmock/.*
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
#include <stdio.h>
#include <ostream> // NOLINT
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
#include "gmock/internal/gmock-port.h"
#include "gtest/gtest.h"
namespace testing {
template <typename>
class Matcher;
namespace internal {
// Silence MSVC C4100 (unreferenced formal parameter) and
// C4805('==': unsafe mix of type 'const int' and type 'const bool')
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100 4805)
// Joins a vector of strings as if they are fields of a tuple; returns
// the joined string.
GTEST_API_ std::string JoinAsKeyValueTuple(
const std::vector<const char*>& names, const Strings& values);
// 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_ std::string ConvertIdentifierNameToWords(const char* id_name);
// GetRawPointer(p) returns the raw pointer underlying p when p is a
// smart pointer, or returns p itself when p is already a raw pointer.
// The following default implementation is for the smart pointer case.
template <typename Pointer>
inline const typename Pointer::element_type* GetRawPointer(const Pointer& p) {
return p.get();
}
// This overload version is for std::reference_wrapper, which does not work with
// the overload above, as it does not have an `element_type`.
template <typename Element>
inline const Element* GetRawPointer(const std::reference_wrapper<Element>& r) {
return &r.get();
}
// This overloaded version is for the raw pointer case.
template <typename Element>
inline Element* GetRawPointer(Element* p) {
return p;
}
// Default definitions for all compilers.
// NOTE: If you implement support for other compilers, make sure to avoid
// unexpected overlaps.
// (e.g., Clang also processes #pragma GCC, and clang-cl also handles _MSC_VER.)
#define GMOCK_INTERNAL_WARNING_PUSH()
#define GMOCK_INTERNAL_WARNING_CLANG(Level, Name)
#define GMOCK_INTERNAL_WARNING_POP()
#if defined(__clang__)
#undef GMOCK_INTERNAL_WARNING_PUSH
#define GMOCK_INTERNAL_WARNING_PUSH() _Pragma("clang diagnostic push")
#undef GMOCK_INTERNAL_WARNING_CLANG
#define GMOCK_INTERNAL_WARNING_CLANG(Level, Warning) \
_Pragma(GMOCK_PP_INTERNAL_STRINGIZE(clang diagnostic Level Warning))
#undef GMOCK_INTERNAL_WARNING_POP
#define GMOCK_INTERNAL_WARNING_POP() _Pragma("clang diagnostic pop")
#endif
// MSVC treats wchar_t as a native type usually, but treats it as the
// same as unsigned short when the compiler option /Zc:wchar_t- is
// specified. It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t
// is a native type.
#if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED)
// wchar_t is a typedef.
#else
#define GMOCK_WCHAR_T_IS_NATIVE_ 1
#endif
// In what follows, we use the term "kind" to indicate whether a type
// is bool, an integer type (excluding bool), a floating-point type,
// or none of them. This categorization is useful for determining
// when a matcher argument type can be safely converted to another
// type in the implementation of SafeMatcherCast.
enum TypeKind { kBool, kInteger, kFloatingPoint, kOther };
// KindOf<T>::value is the kind of type T.
template <typename T>
struct KindOf {
enum { value = kOther }; // The default kind.
};
// This macro declares that the kind of 'type' is 'kind'.
#define GMOCK_DECLARE_KIND_(type, kind) \
template <> \
struct KindOf<type> { \
enum { value = kind }; \
}
GMOCK_DECLARE_KIND_(bool, kBool);
// All standard integer types.
GMOCK_DECLARE_KIND_(char, kInteger);
GMOCK_DECLARE_KIND_(signed char, kInteger);
GMOCK_DECLARE_KIND_(unsigned char, kInteger);
GMOCK_DECLARE_KIND_(short, kInteger); // NOLINT
GMOCK_DECLARE_KIND_(unsigned short, kInteger); // NOLINT
GMOCK_DECLARE_KIND_(int, kInteger);
GMOCK_DECLARE_KIND_(unsigned int, kInteger);
GMOCK_DECLARE_KIND_(long, kInteger); // NOLINT
GMOCK_DECLARE_KIND_(unsigned long, kInteger); // NOLINT
GMOCK_DECLARE_KIND_(long long, kInteger); // NOLINT
GMOCK_DECLARE_KIND_(unsigned long long, kInteger); // NOLINT
#if GMOCK_WCHAR_T_IS_NATIVE_
GMOCK_DECLARE_KIND_(wchar_t, kInteger);
#endif
// All standard floating-point types.
GMOCK_DECLARE_KIND_(float, kFloatingPoint);
GMOCK_DECLARE_KIND_(double, kFloatingPoint);
GMOCK_DECLARE_KIND_(long double, kFloatingPoint);
#undef GMOCK_DECLARE_KIND_
// Evaluates to the kind of 'type'.
#define GMOCK_KIND_OF_(type) \
static_cast< ::testing::internal::TypeKind>( \
::testing::internal::KindOf<type>::value)
// LosslessArithmeticConvertibleImpl<kFromKind, From, kToKind, To>::value
// is true if and only if arithmetic type From can be losslessly converted to
// arithmetic type To.
//
// It's the user's responsibility to ensure that both From and To are
// raw (i.e. has no CV modifier, is not a pointer, and is not a
// reference) built-in arithmetic types, kFromKind is the kind of
// From, and kToKind is the kind of To; the value is
// implementation-defined when the above pre-condition is violated.
template <TypeKind kFromKind, typename From, TypeKind kToKind, typename To>
using LosslessArithmeticConvertibleImpl = std::integral_constant<
bool,
// clang-format off
// Converting from bool is always lossless
(kFromKind == kBool) ? true
// Converting between any other type kinds will be lossy if the type
// kinds are not the same.
: (kFromKind != kToKind) ? false
: (kFromKind == kInteger &&
// Converting between integers of different widths is allowed so long
// as the conversion does not go from signed to unsigned.
(((sizeof(From) < sizeof(To)) &&
!(std::is_signed<From>::value && !std::is_signed<To>::value)) ||
// Converting between integers of the same width only requires the
// two types to have the same signedness.
((sizeof(From) == sizeof(To)) &&
(std::is_signed<From>::value == std::is_signed<To>::value)))
) ? true
// Floating point conversions are lossless if and only if `To` is at least
// as wide as `From`.
: (kFromKind == kFloatingPoint && (sizeof(From) <= sizeof(To))) ? true
: false
// clang-format on
>;
// LosslessArithmeticConvertible<From, To>::value is true if and only if
// arithmetic type From can be losslessly converted to arithmetic type To.
//
// It's the user's responsibility to ensure that both From and To are
// raw (i.e. has no CV modifier, is not a pointer, and is not a
// reference) built-in arithmetic types; the value is
// implementation-defined when the above pre-condition is violated.
template <typename From, typename To>
using LosslessArithmeticConvertible =
LosslessArithmeticConvertibleImpl<GMOCK_KIND_OF_(From), From,
GMOCK_KIND_OF_(To), To>;
// This interface knows how to report a Google Mock failure (either
// non-fatal or fatal).
class FailureReporterInterface {
public:
// The type of a failure (either non-fatal or fatal).
enum FailureType { kNonfatal, kFatal };
virtual ~FailureReporterInterface() = default;
// Reports a failure that occurred at the given source file location.
virtual void ReportFailure(FailureType type, const char* file, int line,
const std::string& message) = 0;
};
// Returns the failure reporter used by Google Mock.
GTEST_API_ FailureReporterInterface* GetFailureReporter();
// Asserts that condition is true; aborts the process with the given
// message if condition is false. We cannot use LOG(FATAL) or CHECK()
// as Google Mock might be used to mock the log sink itself. We
// inline this function to prevent it from showing up in the stack
// trace.
inline void Assert(bool condition, const char* file, int line,
const std::string& msg) {
if (!condition) {
GetFailureReporter()->ReportFailure(FailureReporterInterface::kFatal, file,
line, msg);
}
}
inline void Assert(bool condition, const char* file, int line) {
Assert(condition, file, line, "Assertion failed.");
}
// Verifies that condition is true; generates a non-fatal failure if
// condition is false.
inline void Expect(bool condition, const char* file, int line,
const std::string& msg) {
if (!condition) {
GetFailureReporter()->ReportFailure(FailureReporterInterface::kNonfatal,
file, line, msg);
}
}
inline void Expect(bool condition, const char* file, int line) {
Expect(condition, file, line, "Expectation failed.");
}
// Severity level of a log.
enum LogSeverity { kInfo = 0, kWarning = 1 };
// Valid values for the --gmock_verbose flag.
// All logs (informational and warnings) are printed.
const char kInfoVerbosity[] = "info";
// Only warnings are printed.
const char kWarningVerbosity[] = "warning";
// No logs are printed.
const char kErrorVerbosity[] = "error";
// Returns true if and only if a log with the given severity is visible
// according to the --gmock_verbose flag.
GTEST_API_ bool LogIsVisible(LogSeverity severity);
// Prints the given message to stdout if and only if 'severity' >= the level
// specified by the --gmock_verbose flag. If stack_frames_to_skip >=
// 0, also prints the stack trace excluding the top
// stack_frames_to_skip frames. In opt mode, any positive
// stack_frames_to_skip is treated as 0, since we don't know which
// function calls will be inlined by the compiler and need to be
// conservative.
GTEST_API_ void Log(LogSeverity severity, const std::string& message,
int stack_frames_to_skip);
// A marker class that is used to resolve parameterless expectations to the
// correct overload. This must not be instantiable, to prevent client code from
// accidentally resolving to the overload; for example:
//
// ON_CALL(mock, Method({}, nullptr))...
//
class WithoutMatchers {
private:
WithoutMatchers() {}
friend GTEST_API_ WithoutMatchers GetWithoutMatchers();
};
// Internal use only: access the singleton instance of WithoutMatchers.
GTEST_API_ WithoutMatchers GetWithoutMatchers();
// Invalid<T>() is usable as an expression of type T, but will terminate
// the program with an assertion failure if actually run. This is useful
// when a value of type T is needed for compilation, but the statement
// will not really be executed (or we don't care if the statement
// crashes).
template <typename T>
inline T Invalid() {
Assert(/*condition=*/false, /*file=*/"", /*line=*/-1,
"Internal error: attempt to return invalid value");
#if defined(__GNUC__) || defined(__clang__)
__builtin_unreachable();
#elif defined(_MSC_VER)
__assume(0);
#else
return Invalid<T>();
#endif
}
// Given a raw type (i.e. having no top-level reference or const
// modifier) RawContainer that's either an STL-style container or a
// native array, class StlContainerView<RawContainer> has the
// following members:
//
// - type is a type that provides an STL-style container view to
// (i.e. implements the STL container concept for) RawContainer;
// - const_reference is a type that provides a reference to a const
// RawContainer;
// - ConstReference(raw_container) returns a const reference to an STL-style
// container view to raw_container, which is a RawContainer.
// - Copy(raw_container) returns an STL-style container view of a
// copy of raw_container, which is a RawContainer.
//
// This generic version is used when RawContainer itself is already an
// STL-style container.
template <class RawContainer>
class StlContainerView {
public:
typedef RawContainer type;
typedef const type& const_reference;
static const_reference ConstReference(const RawContainer& container) {
static_assert(!std::is_const<RawContainer>::value,
"RawContainer type must not be const");
return container;
}
static type Copy(const RawContainer& container) { return container; }
};
// This specialization is used when RawContainer is a native array type.
template <typename Element, size_t N>
class StlContainerView<Element[N]> {
public:
typedef typename std::remove_const<Element>::type RawElement;
typedef internal::NativeArray<RawElement> type;
// NativeArray<T> can represent a native array either by value or by
// reference (selected by a constructor argument), so 'const type'
// can be used to reference a const native array. We cannot
// 'typedef const type& const_reference' here, as that would mean
// ConstReference() has to return a reference to a local variable.
typedef const type const_reference;
static const_reference ConstReference(const Element (&array)[N]) {
static_assert(std::is_same<Element, RawElement>::value,
"Element type must not be const");
return type(array, N, RelationToSourceReference());
}
static type Copy(const Element (&array)[N]) {
return type(array, N, RelationToSourceCopy());
}
};
// This specialization is used when RawContainer is a native array
// represented as a (pointer, size) tuple.
template <typename ElementPointer, typename Size>
class StlContainerView< ::std::tuple<ElementPointer, Size> > {
public:
typedef typename std::remove_const<
typename std::pointer_traits<ElementPointer>::element_type>::type
RawElement;
typedef internal::NativeArray<RawElement> type;
typedef const type const_reference;
static const_reference ConstReference(
const ::std::tuple<ElementPointer, Size>& array) {
return type(std::get<0>(array), std::get<1>(array),
RelationToSourceReference());
}
static type Copy(const ::std::tuple<ElementPointer, Size>& array) {
return type(std::get<0>(array), std::get<1>(array), RelationToSourceCopy());
}
};
// The following specialization prevents the user from instantiating
// StlContainer with a reference type.
template <typename T>
class StlContainerView<T&>;
// A type transform to remove constness from the first part of a pair.
// Pairs like that are used as the value_type of associative containers,
// and this transform produces a similar but assignable pair.
template <typename T>
struct RemoveConstFromKey {
typedef T type;
};
// Partially specialized to remove constness from std::pair<const K, V>.
template <typename K, typename V>
struct RemoveConstFromKey<std::pair<const K, V> > {
typedef std::pair<K, V> type;
};
// Emit an assertion failure due to incorrect DoDefault() usage. Out-of-lined to
// reduce code size.
GTEST_API_ void IllegalDoDefault(const char* file, int line);
template <typename F, typename Tuple, size_t... Idx>
auto ApplyImpl(F&& f, Tuple&& args, std::index_sequence<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),
std::make_index_sequence<std::tuple_size<
typename std::remove_reference<Tuple>::type>::value>())) {
return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
std::make_index_sequence<std::tuple_size<
typename std::remove_reference<Tuple>::type>::value>());
}
// Template struct Function<F>, where F must be a function type, contains
// the following typedefs:
//
// Result: the function's return type.
// Arg<N>: the type of the N-th argument, where N starts with 0.
// ArgumentTuple: the tuple type consisting of all parameters of F.
// ArgumentMatcherTuple: the tuple type consisting of Matchers for all
// parameters of F.
// MakeResultVoid: the function type obtained by substituting void
// for the return type of F.
// MakeResultIgnoredValue:
// the function type obtained by substituting Something
// for the return type of F.
template <typename T>
struct Function;
template <typename R, typename... Args>
struct Function<R(Args...)> {
using Result = R;
static constexpr size_t ArgumentCount = sizeof...(Args);
template <size_t I>
using Arg = ElemFromList<I, Args...>;
using ArgumentTuple = std::tuple<Args...>;
using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;
using MakeResultVoid = void(Args...);
using MakeResultIgnoredValue = IgnoredValue(Args...);
};
// Workaround for MSVC error C2039: 'type': is not a member of 'std'
// when std::tuple_element is used.
// See: https://github.com/google/googletest/issues/3931
// Can be replaced with std::tuple_element_t in C++14.
template <size_t I, typename T>
using TupleElement = typename std::tuple_element<I, T>::type;
bool Base64Unescape(const std::string& encoded, std::string* decoded);
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100 4805
} // namespace internal
} // namespace testing
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Low-level types and utilities for porting Google Mock to various
// platforms. All macros ending with _ and symbols defined in an
// internal namespace are subject to change without notice. Code
// outside Google Mock MUST NOT USE THEM DIRECTLY. Macros that don't
// end with _ are part of Google Mock's public API and can be used by
// code outside Google Mock.
// IWYU pragma: private, include "gmock/gmock.h"
// IWYU pragma: friend gmock/.*
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
#include <assert.h>
#include <stdlib.h>
#include <cstdint>
#include <iostream>
// Most of the utilities needed for porting Google Mock are also
// required for Google Test and are defined in gtest-port.h.
//
// Note to maintainers: to reduce code duplication, prefer adding
// 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 "gmock/internal/custom/gmock-port.h"
#include "gtest/internal/gtest-port.h"
#if defined(GTEST_HAS_ABSL)
#include "absl/base/macros.h"
#define GMOCK_DEPRECATE_AND_INLINE() ABSL_DEPRECATE_AND_INLINE()
#if !defined(GTEST_NO_ABSL_FLAGS)
#include "absl/flags/declare.h"
#include "absl/flags/flag.h"
#endif // !defined(GTEST_NO_ABSL_FLAGS)
#else // defined(GTEST_HAS_ABSL)
#define GMOCK_DEPRECATE_AND_INLINE()
#endif // defined(GTEST_HAS_ABSL)
// For MS Visual C++, check the compiler version. At least VS 2015 is
// required to compile Google Mock.
#if defined(_MSC_VER) && _MSC_VER < 1900
#error "At least Visual C++ 2015 (14.0) is required to compile Google Mock."
#endif
// Macro for referencing flags. This is public as we want the user to
// use this syntax to reference Google Mock flags.
#define GMOCK_FLAG_NAME_(name) gmock_##name
#define GMOCK_FLAG(name) FLAGS_gmock_##name
// Pick a command line flags implementation.
#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
// Macros for defining flags.
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
ABSL_FLAG(bool, GMOCK_FLAG_NAME_(name), default_val, doc)
#define GMOCK_DEFINE_int32_(name, default_val, doc) \
ABSL_FLAG(int32_t, GMOCK_FLAG_NAME_(name), default_val, doc)
#define GMOCK_DEFINE_string_(name, default_val, doc) \
ABSL_FLAG(std::string, GMOCK_FLAG_NAME_(name), default_val, doc)
// Macros for declaring flags.
#define GMOCK_DECLARE_bool_(name) \
ABSL_DECLARE_FLAG(bool, GMOCK_FLAG_NAME_(name))
#define GMOCK_DECLARE_int32_(name) \
ABSL_DECLARE_FLAG(int32_t, GMOCK_FLAG_NAME_(name))
#define GMOCK_DECLARE_string_(name) \
ABSL_DECLARE_FLAG(std::string, GMOCK_FLAG_NAME_(name))
#define GMOCK_FLAG_GET(name) ::absl::GetFlag(GMOCK_FLAG(name))
#define GMOCK_FLAG_SET(name, value) \
(void)(::absl::SetFlag(&GMOCK_FLAG(name), value))
#else // defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
// Macros for defining flags.
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
namespace testing { \
GTEST_API_ bool GMOCK_FLAG(name) = (default_val); \
} \
static_assert(true, "no-op to require trailing semicolon")
#define GMOCK_DEFINE_int32_(name, default_val, doc) \
namespace testing { \
GTEST_API_ int32_t GMOCK_FLAG(name) = (default_val); \
} \
static_assert(true, "no-op to require trailing semicolon")
#define GMOCK_DEFINE_string_(name, default_val, doc) \
namespace testing { \
GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val); \
} \
static_assert(true, "no-op to require trailing semicolon")
// Macros for declaring flags.
#define GMOCK_DECLARE_bool_(name) \
namespace testing { \
GTEST_API_ extern bool GMOCK_FLAG(name); \
} \
static_assert(true, "no-op to require trailing semicolon")
#define GMOCK_DECLARE_int32_(name) \
namespace testing { \
GTEST_API_ extern int32_t GMOCK_FLAG(name); \
} \
static_assert(true, "no-op to require trailing semicolon")
#define GMOCK_DECLARE_string_(name) \
namespace testing { \
GTEST_API_ extern ::std::string GMOCK_FLAG(name); \
} \
static_assert(true, "no-op to require trailing semicolon")
#define GMOCK_FLAG_GET(name) ::testing::GMOCK_FLAG(name)
#define GMOCK_FLAG_SET(name, value) (void)(::testing::GMOCK_FLAG(name) = value)
#endif // defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_
// Expands and concatenates the arguments. Constructed macros reevaluate.
#define GMOCK_PP_CAT(_1, _2) GMOCK_PP_INTERNAL_CAT(_1, _2)
// Expands and stringifies the only argument.
#define GMOCK_PP_STRINGIZE(...) GMOCK_PP_INTERNAL_STRINGIZE(__VA_ARGS__)
// Returns empty. Given a variadic number of arguments.
#define GMOCK_PP_EMPTY(...)
// Returns a comma. Given a variadic number of arguments.
#define GMOCK_PP_COMMA(...) ,
// Returns the only argument.
#define GMOCK_PP_IDENTITY(_1) _1
// Evaluates to the number of arguments after expansion.
//
// #define PAIR x, y
//
// GMOCK_PP_NARG() => 1
// GMOCK_PP_NARG(x) => 1
// GMOCK_PP_NARG(x, y) => 2
// GMOCK_PP_NARG(PAIR) => 2
//
// Requires: the number of arguments after expansion is at most 15.
#define GMOCK_PP_NARG(...) \
GMOCK_PP_INTERNAL_16TH( \
(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
// Returns 1 if the expansion of arguments has an unprotected comma. Otherwise
// returns 0. Requires no more than 15 unprotected commas.
#define GMOCK_PP_HAS_COMMA(...) \
GMOCK_PP_INTERNAL_16TH( \
(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0))
// Returns the first argument.
#define GMOCK_PP_HEAD(...) GMOCK_PP_INTERNAL_HEAD((__VA_ARGS__, unusedArg))
// Returns the tail. A variadic list of all arguments minus the first. Requires
// at least one argument.
#define GMOCK_PP_TAIL(...) GMOCK_PP_INTERNAL_TAIL((__VA_ARGS__))
// Calls CAT(_Macro, NARG(__VA_ARGS__))(__VA_ARGS__)
#define GMOCK_PP_VARIADIC_CALL(_Macro, ...) \
GMOCK_PP_IDENTITY( \
GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__))
// If the arguments after expansion have no tokens, evaluates to `1`. Otherwise
// evaluates to `0`.
//
// Requires: * the number of arguments after expansion is at most 15.
// * If the argument is a macro, it must be able to be called with one
// argument.
//
// Implementation details:
//
// There is one case when it generates a compile error: if the argument is macro
// that cannot be called with one argument.
//
// #define M(a, b) // it doesn't matter what it expands to
//
// // Expected: expands to `0`.
// // Actual: compile error.
// GMOCK_PP_IS_EMPTY(M)
//
// There are 4 cases tested:
//
// * __VA_ARGS__ possible expansion has no unparen'd commas. Expected 0.
// * __VA_ARGS__ possible expansion is not enclosed in parenthesis. Expected 0.
// * __VA_ARGS__ possible expansion is not a macro that ()-evaluates to a comma.
// Expected 0
// * __VA_ARGS__ is empty, or has unparen'd commas, or is enclosed in
// parenthesis, or is a macro that ()-evaluates to comma. Expected 1.
//
// We trigger detection on '0001', i.e. on empty.
#define GMOCK_PP_IS_EMPTY(...) \
GMOCK_PP_INTERNAL_IS_EMPTY(GMOCK_PP_HAS_COMMA(__VA_ARGS__), \
GMOCK_PP_HAS_COMMA(GMOCK_PP_COMMA __VA_ARGS__), \
GMOCK_PP_HAS_COMMA(__VA_ARGS__()), \
GMOCK_PP_HAS_COMMA(GMOCK_PP_COMMA __VA_ARGS__()))
// Evaluates to _Then if _Cond is 1 and _Else if _Cond is 0.
#define GMOCK_PP_IF(_Cond, _Then, _Else) \
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IF_, _Cond)(_Then, _Else)
// Similar to GMOCK_PP_IF but takes _Then and _Else in parentheses.
//
// GMOCK_PP_GENERIC_IF(1, (a, b, c), (d, e, f)) => a, b, c
// GMOCK_PP_GENERIC_IF(0, (a, b, c), (d, e, f)) => d, e, f
//
#define GMOCK_PP_GENERIC_IF(_Cond, _Then, _Else) \
GMOCK_PP_REMOVE_PARENS(GMOCK_PP_IF(_Cond, _Then, _Else))
// Evaluates to the number of arguments after expansion. Identifies 'empty' as
// 0.
//
// #define PAIR x, y
//
// GMOCK_PP_NARG0() => 0
// GMOCK_PP_NARG0(x) => 1
// GMOCK_PP_NARG0(x, y) => 2
// GMOCK_PP_NARG0(PAIR) => 2
//
// Requires: * the number of arguments after expansion is at most 15.
// * If the argument is a macro, it must be able to be called with one
// argument.
#define GMOCK_PP_NARG0(...) \
GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(__VA_ARGS__), 0, GMOCK_PP_NARG(__VA_ARGS__))
// Expands to 1 if the first argument starts with something in parentheses,
// otherwise to 0.
#define GMOCK_PP_IS_BEGIN_PARENS(...) \
GMOCK_PP_HEAD(GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_, \
GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C __VA_ARGS__))
// Expands to 1 is there is only one argument and it is enclosed in parentheses.
#define GMOCK_PP_IS_ENCLOSED_PARENS(...) \
GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(__VA_ARGS__), \
GMOCK_PP_IS_EMPTY(GMOCK_PP_EMPTY __VA_ARGS__), 0)
// Remove the parens, requires GMOCK_PP_IS_ENCLOSED_PARENS(args) => 1.
#define GMOCK_PP_REMOVE_PARENS(...) GMOCK_PP_INTERNAL_REMOVE_PARENS __VA_ARGS__
// Expands to _Macro(0, _Data, e1) _Macro(1, _Data, e2) ... _Macro(K -1, _Data,
// eK) as many of GMOCK_INTERNAL_NARG0 _Tuple.
// Requires: * |_Macro| can be called with 3 arguments.
// * |_Tuple| expansion has no more than 15 elements.
#define GMOCK_PP_FOR_EACH(_Macro, _Data, _Tuple) \
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, GMOCK_PP_NARG0 _Tuple) \
(0, _Macro, _Data, _Tuple)
// Expands to _Macro(0, _Data, ) _Macro(1, _Data, ) ... _Macro(K - 1, _Data, )
// Empty if _K = 0.
// Requires: * |_Macro| can be called with 3 arguments.
// * |_K| literal between 0 and 15
#define GMOCK_PP_REPEAT(_Macro, _Data, _N) \
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, _N) \
(0, _Macro, _Data, GMOCK_PP_INTENRAL_EMPTY_TUPLE)
// Increments the argument, requires the argument to be between 0 and 15.
#define GMOCK_PP_INC(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_INC_, _i)
// Returns comma if _i != 0. Requires _i to be between 0 and 15.
#define GMOCK_PP_COMMA_IF(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_COMMA_IF_, _i)
// Internal details follow. Do not use any of these symbols outside of this
// file or we will break your code.
#define GMOCK_PP_INTENRAL_EMPTY_TUPLE (, , , , , , , , , , , , , , , )
#define GMOCK_PP_INTERNAL_CAT(_1, _2) _1##_2
#define GMOCK_PP_INTERNAL_STRINGIZE(...) #__VA_ARGS__
#define GMOCK_PP_INTERNAL_CAT_5(_1, _2, _3, _4, _5) _1##_2##_3##_4##_5
#define GMOCK_PP_INTERNAL_IS_EMPTY(_1, _2, _3, _4) \
GMOCK_PP_HAS_COMMA(GMOCK_PP_INTERNAL_CAT_5(GMOCK_PP_INTERNAL_IS_EMPTY_CASE_, \
_1, _2, _3, _4))
#define GMOCK_PP_INTERNAL_IS_EMPTY_CASE_0001 ,
#define GMOCK_PP_INTERNAL_IF_1(_Then, _Else) _Then
#define GMOCK_PP_INTERNAL_IF_0(_Then, _Else) _Else
// Because of MSVC treating a token with a comma in it as a single token when
// passed to another macro, we need to force it to evaluate it as multiple
// tokens. We do that by using a "IDENTITY(MACRO PARENTHESIZED_ARGS)" macro. We
// define one per possible macro that relies on this behavior. Note "_Args" must
// be parenthesized.
#define GMOCK_PP_INTERNAL_INTERNAL_16TH(_1, _2, _3, _4, _5, _6, _7, _8, _9, \
_10, _11, _12, _13, _14, _15, _16, \
...) \
_16
#define GMOCK_PP_INTERNAL_16TH(_Args) \
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_16TH _Args)
#define GMOCK_PP_INTERNAL_INTERNAL_HEAD(_1, ...) _1
#define GMOCK_PP_INTERNAL_HEAD(_Args) \
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_HEAD _Args)
#define GMOCK_PP_INTERNAL_INTERNAL_TAIL(_1, ...) __VA_ARGS__
#define GMOCK_PP_INTERNAL_TAIL(_Args) \
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_TAIL _Args)
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C(...) 1 _
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_1 1,
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C \
0,
#define GMOCK_PP_INTERNAL_REMOVE_PARENS(...) __VA_ARGS__
#define GMOCK_PP_INTERNAL_INC_0 1
#define GMOCK_PP_INTERNAL_INC_1 2
#define GMOCK_PP_INTERNAL_INC_2 3
#define GMOCK_PP_INTERNAL_INC_3 4
#define GMOCK_PP_INTERNAL_INC_4 5
#define GMOCK_PP_INTERNAL_INC_5 6
#define GMOCK_PP_INTERNAL_INC_6 7
#define GMOCK_PP_INTERNAL_INC_7 8
#define GMOCK_PP_INTERNAL_INC_8 9
#define GMOCK_PP_INTERNAL_INC_9 10
#define GMOCK_PP_INTERNAL_INC_10 11
#define GMOCK_PP_INTERNAL_INC_11 12
#define GMOCK_PP_INTERNAL_INC_12 13
#define GMOCK_PP_INTERNAL_INC_13 14
#define GMOCK_PP_INTERNAL_INC_14 15
#define GMOCK_PP_INTERNAL_INC_15 16
#define GMOCK_PP_INTERNAL_COMMA_IF_0
#define GMOCK_PP_INTERNAL_COMMA_IF_1 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_2 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_3 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_4 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_5 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_6 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_7 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_8 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_9 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_10 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_11 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_12 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_13 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_14 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_15 ,
#define GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, _element) \
_Macro(_i, _Data, _element)
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_0(_i, _Macro, _Data, _Tuple)
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_1(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple)
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_2(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_1(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_3(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_2(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_4(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_3(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_5(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_4(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_6(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_5(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_7(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_6(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_8(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_7(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_9(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_8(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_10(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_9(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_11(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_10(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_12(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_11(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_13(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_12(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_13(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_15(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Google C++ Mocking Framework (Google Mock)
//
// This file #includes all Google Mock implementation .cc files. The
// purpose is to allow a user to build Google Mock by compiling this
// file alone.
// This line ensures that gmock.h can be compiled on its own, even
// when it's fused.
#include "gmock/gmock.h"
// The following lines pull in the real gmock *.cc files.
#include "src/gmock-cardinalities.cc"
#include "src/gmock-internal-utils.cc"
#include "src/gmock-matchers.cc"
#include "src/gmock-spec-builders.cc"
#include "src/gmock.cc"
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements cardinalities.
#include "gmock/gmock-cardinalities.h"
#include <limits.h>
#include <ostream> // NOLINT
#include <sstream>
#include <string>
#include "gmock/internal/gmock-internal-utils.h"
#include "gtest/gtest.h"
namespace testing {
namespace {
// Implements the Between(m, n) cardinality.
class BetweenCardinalityImpl : public CardinalityInterface {
public:
BetweenCardinalityImpl(int min, int max)
: min_(min >= 0 ? min : 0), max_(max >= min_ ? max : min_) {
std::stringstream ss;
if (min < 0) {
ss << "The invocation lower bound must be >= 0, " << "but is actually "
<< min << ".";
internal::Expect(false, __FILE__, __LINE__, ss.str());
} else if (max < 0) {
ss << "The invocation upper bound must be >= 0, " << "but is actually "
<< max << ".";
internal::Expect(false, __FILE__, __LINE__, ss.str());
} else if (min > max) {
ss << "The invocation upper bound (" << max
<< ") must be >= the invocation lower bound (" << min << ").";
internal::Expect(false, __FILE__, __LINE__, ss.str());
}
}
// Conservative estimate on the lower/upper bound of the number of
// calls allowed.
int ConservativeLowerBound() const override { return min_; }
int ConservativeUpperBound() const override { return max_; }
bool IsSatisfiedByCallCount(int call_count) const override {
return min_ <= call_count && call_count <= max_;
}
bool IsSaturatedByCallCount(int call_count) const override {
return call_count >= max_;
}
void DescribeTo(::std::ostream* os) const override;
private:
const int min_;
const int max_;
BetweenCardinalityImpl(const BetweenCardinalityImpl&) = delete;
BetweenCardinalityImpl& operator=(const BetweenCardinalityImpl&) = delete;
};
// Formats "n times" in a human-friendly way.
inline std::string FormatTimes(int n) {
if (n == 1) {
return "once";
} else if (n == 2) {
return "twice";
} else {
std::stringstream ss;
ss << n << " times";
return ss.str();
}
}
// Describes the Between(m, n) cardinality in human-friendly text.
void BetweenCardinalityImpl::DescribeTo(::std::ostream* os) const {
if (min_ == 0) {
if (max_ == 0) {
*os << "never called";
} else if (max_ == INT_MAX) {
*os << "called any number of times";
} else {
*os << "called at most " << FormatTimes(max_);
}
} else if (min_ == max_) {
*os << "called " << FormatTimes(min_);
} else if (max_ == INT_MAX) {
*os << "called at least " << FormatTimes(min_);
} else {
// 0 < min_ < max_ < INT_MAX
*os << "called between " << min_ << " and " << max_ << " times";
}
}
} // Unnamed namespace
// Describes the given call count to an ostream.
void Cardinality::DescribeActualCallCountTo(int actual_call_count,
::std::ostream* os) {
if (actual_call_count > 0) {
*os << "called " << FormatTimes(actual_call_count);
} else {
*os << "never called";
}
}
// Creates a cardinality that allows at least n calls.
GTEST_API_ Cardinality AtLeast(int n) { return Between(n, INT_MAX); }
// Creates a cardinality that allows at most n calls.
GTEST_API_ Cardinality AtMost(int n) { return Between(0, n); }
// Creates a cardinality that allows any number of calls.
GTEST_API_ Cardinality AnyNumber() { return AtLeast(0); }
// Creates a cardinality that allows between min and max calls.
GTEST_API_ Cardinality Between(int min, int max) {
return Cardinality(new BetweenCardinalityImpl(min, max));
}
// Creates a cardinality that allows exactly n calls.
GTEST_API_ Cardinality Exactly(int n) { return Between(n, n); }
} // namespace testing
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Mock - a framework for writing C++ mock classes.
//
// This file defines some utilities useful for implementing Google
// Mock. They are subject to change without notice, so please DO NOT
// USE THEM IN USER CODE.
#include "gmock/internal/gmock-internal-utils.h"
#include <ctype.h>
#include <array>
#include <cctype>
#include <cstdint>
#include <cstring>
#include <iostream>
#include <ostream> // NOLINT
#include <string>
#include <utility>
#include <vector>
#include "gmock/gmock.h"
#include "gmock/internal/gmock-port.h"
#include "gtest/gtest.h"
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 JoinAsKeyValueTuple(
const std::vector<const char*>& names, const Strings& values) {
GTEST_CHECK_(names.size() == values.size());
if (values.empty()) {
return "";
}
const auto build_one = [&](const size_t i) {
return std::string(names[i]) + ": " + values[i];
};
std::string result = "(" + build_one(0);
for (size_t i = 1; i < values.size(); i++) {
result += ", ";
result += build_one(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
// "foo_bar_123" are converted to "foo bar 123".
GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name) {
std::string result;
char prev_char = '\0';
for (const char* p = id_name; *p != '\0'; prev_char = *(p++)) {
// We don't care about the current locale as the input is
// guaranteed to be a valid C++ identifier name.
const bool starts_new_word = IsUpper(*p) ||
(!IsAlpha(prev_char) && IsLower(*p)) ||
(!IsDigit(prev_char) && IsDigit(*p));
if (IsAlNum(*p)) {
if (starts_new_word && !result.empty()) result += ' ';
result += ToLower(*p);
}
}
return result;
}
// This class reports Google Mock failures as Google Test failures. A
// user can define another class in a similar fashion if they intend to
// use Google Mock with a testing framework other than Google Test.
class GoogleTestFailureReporter : public FailureReporterInterface {
public:
void ReportFailure(FailureType type, const char* file, int line,
const std::string& message) override {
AssertHelper(type == kFatal ? TestPartResult::kFatalFailure
: TestPartResult::kNonFatalFailure,
file, line, message.c_str()) = Message();
if (type == kFatal) {
posix::Abort();
}
}
};
// Returns the global failure reporter. Will create a
// GoogleTestFailureReporter and return it the first time called.
GTEST_API_ FailureReporterInterface* GetFailureReporter() {
// Points to the global failure reporter used by Google Mock. gcc
// guarantees that the following use of failure_reporter is
// thread-safe. We may need to add additional synchronization to
// protect failure_reporter if we port Google Mock to other
// compilers.
static FailureReporterInterface* const failure_reporter =
new GoogleTestFailureReporter();
return failure_reporter;
}
// Protects global resources (stdout in particular) used by Log().
static GTEST_DEFINE_STATIC_MUTEX_(g_log_mutex);
// Returns true if and only if a log with the given severity is visible
// according to the --gmock_verbose flag.
GTEST_API_ bool LogIsVisible(LogSeverity severity) {
if (GMOCK_FLAG_GET(verbose) == kInfoVerbosity) {
// Always show the log if --gmock_verbose=info.
return true;
} else if (GMOCK_FLAG_GET(verbose) == kErrorVerbosity) {
// Always hide it if --gmock_verbose=error.
return false;
} else {
// If --gmock_verbose is neither "info" nor "error", we treat it
// as "warning" (its default value).
return severity == kWarning;
}
}
// Prints the given message to stdout if and only if 'severity' >= the level
// specified by the --gmock_verbose flag. If stack_frames_to_skip >=
// 0, also prints the stack trace excluding the top
// stack_frames_to_skip frames. In opt mode, any positive
// stack_frames_to_skip is treated as 0, since we don't know which
// function calls will be inlined by the compiler and need to be
// conservative.
GTEST_API_ void Log(LogSeverity severity, const std::string& message,
int stack_frames_to_skip) {
if (!LogIsVisible(severity)) return;
// Ensures that logs from different threads don't interleave.
MutexLock l(&g_log_mutex);
if (severity == kWarning) {
// Prints a GMOCK WARNING marker to make the warnings easily searchable.
std::cout << "\nGMOCK WARNING:";
}
// Pre-pends a new-line to message if it doesn't start with one.
if (message.empty() || message[0] != '\n') {
std::cout << "\n";
}
std::cout << message;
if (stack_frames_to_skip >= 0) {
#ifdef NDEBUG
// In opt mode, we have to be conservative and skip no stack frame.
const int actual_to_skip = 0;
#else
// In dbg mode, we can do what the caller tell us to do (plus one
// for skipping this function's stack frame).
const int actual_to_skip = stack_frames_to_skip + 1;
#endif // NDEBUG
// Appends a new-line to message if it doesn't end with one.
if (!message.empty() && *message.rbegin() != '\n') {
std::cout << "\n";
}
std::cout << "Stack trace:\n"
<< ::testing::internal::GetCurrentOsStackTraceExceptTop(
actual_to_skip);
}
std::cout << ::std::flush;
}
GTEST_API_ WithoutMatchers GetWithoutMatchers() { return WithoutMatchers(); }
GTEST_API_ void IllegalDoDefault(const char* file, int line) {
internal::Assert(
false, file, line,
"You are using DoDefault() inside a composite action like "
"DoAll() or WithArgs(). This is not supported for technical "
"reasons. Please instead spell out the default action, or "
"assign the default action to an Action variable and use "
"the variable in various places.");
}
constexpr char UndoWebSafeEncoding(char c) {
return c == '-' ? '+' : c == '_' ? '/' : c;
}
constexpr char UnBase64Impl(char c, const char* const base64, char carry) {
return *base64 == 0 ? static_cast<char>(65)
: *base64 == c
? carry
: UnBase64Impl(c, base64 + 1, static_cast<char>(carry + 1));
}
template <size_t... I>
constexpr std::array<char, 256> UnBase64Impl(std::index_sequence<I...>,
const char* const base64) {
return {
{UnBase64Impl(UndoWebSafeEncoding(static_cast<char>(I)), base64, 0)...}};
}
constexpr std::array<char, 256> UnBase64(const char* const base64) {
return UnBase64Impl(std::make_index_sequence<256>{}, base64);
}
static constexpr char kBase64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static constexpr std::array<char, 256> kUnBase64 = UnBase64(kBase64);
bool Base64Unescape(const std::string& encoded, std::string* decoded) {
decoded->clear();
size_t encoded_len = encoded.size();
decoded->reserve(3 * (encoded_len / 4) + (encoded_len % 4));
int bit_pos = 0;
char dst = 0;
for (int src : encoded) {
if (std::isspace(src) || src == '=') {
continue;
}
char src_bin = kUnBase64[static_cast<size_t>(src)];
if (src_bin >= 64) {
decoded->clear();
return false;
}
if (bit_pos == 0) {
dst |= static_cast<char>(src_bin << 2);
bit_pos = 6;
} else {
dst |= static_cast<char>(src_bin >> (bit_pos - 2));
decoded->push_back(dst);
dst = static_cast<char>(src_bin << (10 - bit_pos));
bit_pos = (bit_pos + 6) % 8;
}
}
return true;
}
} // namespace internal
} // namespace testing
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements Matcher<const string&>, Matcher<string>, and
// utilities for defining matchers.
#include "gmock/gmock-matchers.h"
#include <string.h>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
namespace testing {
namespace internal {
// 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
// negation of the matcher. 'param_values' contains a list of strings
// that are the print-out of the matcher's parameters.
GTEST_API_ std::string FormatMatcherDescription(
bool negation, const char* matcher_name,
const std::vector<const char*>& param_names, const Strings& param_values) {
std::string result = ConvertIdentifierNameToWords(matcher_name);
if (!param_values.empty()) {
result += " " + JoinAsKeyValueTuple(param_names, param_values);
}
return negation ? "not (" + result + ")" : result;
}
// FindMaxBipartiteMatching and its helper class.
//
// Uses the well-known Ford-Fulkerson max flow method to find a maximum
// bipartite matching. Flow is considered to be from left to right.
// There is an implicit source node that is connected to all of the left
// nodes, and an implicit sink node that is connected to all of the
// right nodes. All edges have unit capacity.
//
// Neither the flow graph nor the residual flow graph are represented
// explicitly. Instead, they are implied by the information in 'graph' and
// a vector<int> called 'left_' whose elements are initialized to the
// value kUnused. This represents the initial state of the algorithm,
// where the flow graph is empty, and the residual flow graph has the
// following edges:
// - An edge from source to each left_ node
// - An edge from each right_ node to sink
// - An edge from each left_ node to each right_ node, if the
// corresponding edge exists in 'graph'.
//
// When the TryAugment() method adds a flow, it sets left_[l] = r for some
// nodes l and r. This induces the following changes:
// - The edges (source, l), (l, r), and (r, sink) are added to the
// flow graph.
// - The same three edges are removed from the residual flow graph.
// - The reverse edges (l, source), (r, l), and (sink, r) are added
// to the residual flow graph, which is a directional graph
// representing unused flow capacity.
//
// When the method augments a flow (moving left_[l] from some r1 to some
// other r2), this can be thought of as "undoing" the above steps with
// respect to r1 and "redoing" them with respect to r2.
//
// It bears repeating that the flow graph and residual flow graph are
// never represented explicitly, but can be derived by looking at the
// information in 'graph' and in left_.
//
// As an optimization, there is a second vector<int> called right_ which
// does not provide any new information. Instead, it enables more
// efficient queries about edges entering or leaving the right-side nodes
// of the flow or residual flow graphs. The following invariants are
// maintained:
//
// left[l] == kUnused or right[left[l]] == l
// right[r] == kUnused or left[right[r]] == r
//
// . [ source ] .
// . ||| .
// . ||| .
// . ||\--> left[0]=1 ---\ right[0]=-1 ----\ .
// . || | | .
// . |\---> left[1]=-1 \--> right[1]=0 ---\| .
// . | || .
// . \----> left[2]=2 ------> right[2]=2 --\|| .
// . ||| .
// . elements matchers vvv .
// . [ sink ] .
//
// See Also:
// [1] Cormen, et al (2001). "Section 26.2: The Ford-Fulkerson method".
// "Introduction to Algorithms (Second ed.)", pp. 651-664.
// [2] "Ford-Fulkerson algorithm", Wikipedia,
// 'https://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm'
class MaxBipartiteMatchState {
public:
explicit MaxBipartiteMatchState(const MatchMatrix& graph)
: graph_(&graph),
left_(graph_->LhsSize(), kUnused),
right_(graph_->RhsSize(), kUnused) {}
// Returns the edges of a maximal match, each in the form {left, right}.
ElementMatcherPairs Compute() {
// 'seen' is used for path finding { 0: unseen, 1: seen }.
::std::vector<char> seen;
// Searches the residual flow graph for a path from each left node to
// the sink in the residual flow graph, and if one is found, add flow
// to the graph. It's okay to search through the left nodes once. The
// edge from the implicit source node to each previously-visited left
// node will have flow if that left node has any path to the sink
// whatsoever. Subsequent augmentations can only add flow to the
// network, and cannot take away that previous flow unit from the source.
// Since the source-to-left edge can only carry one flow unit (or,
// each element can be matched to only one matcher), there is no need
// to visit the left nodes more than once looking for augmented paths.
// The flow is known to be possible or impossible by looking at the
// node once.
for (size_t ilhs = 0; ilhs < graph_->LhsSize(); ++ilhs) {
// Reset the path-marking vector and try to find a path from
// source to sink starting at the left_[ilhs] node.
GTEST_CHECK_(left_[ilhs] == kUnused)
<< "ilhs: " << ilhs << ", left_[ilhs]: " << left_[ilhs];
// 'seen' initialized to 'graph_->RhsSize()' copies of 0.
seen.assign(graph_->RhsSize(), 0);
TryAugment(ilhs, &seen);
}
ElementMatcherPairs result;
for (size_t ilhs = 0; ilhs < left_.size(); ++ilhs) {
size_t irhs = left_[ilhs];
if (irhs == kUnused) continue;
result.push_back(ElementMatcherPair(ilhs, irhs));
}
return result;
}
private:
static const size_t kUnused = static_cast<size_t>(-1);
// Perform a depth-first search from left node ilhs to the sink. If a
// path is found, flow is added to the network by linking the left and
// right vector elements corresponding each segment of the path.
// Returns true if a path to sink was found, which means that a unit of
// flow was added to the network. The 'seen' vector elements correspond
// to right nodes and are marked to eliminate cycles from the search.
//
// Left nodes will only be explored at most once because they
// are accessible from at most one right node in the residual flow
// graph.
//
// Note that left_[ilhs] is the only element of left_ that TryAugment will
// potentially transition from kUnused to another value. Any other
// left_ element holding kUnused before TryAugment will be holding it
// when TryAugment returns.
//
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;
// There's an available edge from ilhs to irhs.
(*seen)[irhs] = 1;
// Next a search is performed to determine whether
// this edge is a dead end or leads to the sink.
//
// right_[irhs] == kUnused means that there is residual flow from
// right node irhs to the sink, so we can use that to finish this
// flow path and return success.
//
// Otherwise there is residual flow to some ilhs. We push flow
// along that path and call ourselves recursively to see if this
// ultimately leads to sink.
if (right_[irhs] == kUnused || TryAugment(right_[irhs], seen)) {
// Add flow from left_[ilhs] to right_[irhs].
left_[ilhs] = irhs;
right_[irhs] = ilhs;
return true;
}
}
return false;
}
const MatchMatrix* graph_; // not owned
// Each element of the left_ vector represents a left hand side node
// (i.e. an element) and each element of right_ is a right hand side
// node (i.e. a matcher). The values in the left_ vector indicate
// outflow from that node to a node on the right_ side. The values
// in the right_ indicate inflow, and specify which left_ node is
// feeding that right_ node, if any. For example, left_[3] == 1 means
// there's a flow from element #3 to matcher #1. Such a flow would also
// be redundantly represented in the right_ vector as right_[1] == 3.
// Elements of left_ and right_ are either kUnused or mutually
// referent. Mutually referent means that left_[right_[i]] = i and
// right_[left_[i]] = i.
::std::vector<size_t> left_;
::std::vector<size_t> right_;
};
const size_t MaxBipartiteMatchState::kUnused;
GTEST_API_ ElementMatcherPairs FindMaxBipartiteMatching(const MatchMatrix& g) {
return MaxBipartiteMatchState(g).Compute();
}
static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs,
::std::ostream* stream) {
typedef ElementMatcherPairs::const_iterator Iter;
::std::ostream& os = *stream;
os << "{";
const char* sep = "";
for (Iter it = pairs.begin(); it != pairs.end(); ++it) {
os << sep << "\n (" << "element #" << it->first << ", " << "matcher #"
<< it->second << ")";
sep = ",";
}
os << "\n}";
}
bool MatchMatrix::NextGraph() {
for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {
char& b = matched_[SpaceIndex(ilhs, irhs)];
if (!b) {
b = 1;
return true;
}
b = 0;
}
}
return false;
}
void MatchMatrix::Randomize() {
for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {
char& b = matched_[SpaceIndex(ilhs, irhs)];
b = static_cast<char>(rand() & 1); // NOLINT
}
}
}
std::string MatchMatrix::DebugString() const {
::std::stringstream ss;
const char* sep = "";
for (size_t i = 0; i < LhsSize(); ++i) {
ss << sep;
for (size_t j = 0; j < RhsSize(); ++j) {
ss << HasEdge(i, j);
}
sep = ";";
}
return ss.str();
}
void UnorderedElementsAreMatcherImplBase::DescribeToImpl(
::std::ostream* os) const {
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;
}
const char* sep = "";
for (size_t i = 0; i != matcher_describers_.size(); ++i) {
*os << sep;
if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
*os << " - element #" << i << " ";
} else {
*os << " - an element ";
}
matcher_describers_[i]->DescribeTo(os);
if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
sep = ", and\n";
} else {
sep = "\n";
}
}
}
void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(
::std::ostream* os) const {
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;
}
const char* sep = "";
for (size_t i = 0; i != matcher_describers_.size(); ++i) {
*os << sep;
if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
*os << " - element #" << i << " ";
} else {
*os << " - an element ";
}
matcher_describers_[i]->DescribeTo(os);
if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
sep = ", and\n";
} else {
sep = "\n";
}
}
}
// Checks that all matchers match at least one element, and that all
// elements match at least one matcher. This enables faster matching
// and better error reporting.
// Returns false, writing an explanation to 'listener', if and only
// if the success criteria are not met.
bool UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix(
const ::std::vector<std::string>& element_printouts,
const MatchMatrix& matrix, MatchResultListener* listener) const {
if (matrix.LhsSize() == 0 && matrix.RhsSize() == 0) {
return true;
}
const bool is_exact_match_with_size_discrepency =
match_flags() == UnorderedMatcherRequire::ExactMatch &&
matrix.LhsSize() != matrix.RhsSize();
if (is_exact_match_with_size_discrepency) {
// 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()) << "\n";
}
}
bool result = !is_exact_match_with_size_discrepency;
::std::vector<char> element_matched(matrix.LhsSize(), 0);
::std::vector<char> matcher_matched(matrix.RhsSize(), 0);
for (size_t ilhs = 0; ilhs < matrix.LhsSize(); ilhs++) {
for (size_t irhs = 0; irhs < matrix.RhsSize(); irhs++) {
char matched = matrix.HasEdge(ilhs, irhs);
element_matched[ilhs] |= matched;
matcher_matched[irhs] |= matched;
}
}
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;
result = false;
if (listener->IsInterested()) {
*listener << sep << "matcher #" << mi << ": ";
matcher_describers_[mi]->DescribeTo(listener->stream());
sep = ",\n";
}
}
}
if (match_flags() & UnorderedMatcherRequire::Subset) {
const char* sep =
"where the following elements don't match any matchers:\n";
const char* outer_sep = "";
if (!result) {
outer_sep = "\nand ";
}
for (size_t ei = 0; ei < element_matched.size(); ++ei) {
if (element_matched[ei]) continue;
result = false;
if (listener->IsInterested()) {
*listener << outer_sep << sep << "element #" << ei << ": "
<< element_printouts[ei];
sep = ",\n";
outer_sep = "";
}
}
}
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
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements the spec builder syntax (ON_CALL and
// EXPECT_CALL).
#include "gmock/gmock-spec-builders.h"
#include <stdlib.h>
#include <iostream> // NOLINT
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "gtest/internal/gtest-port.h"
#if defined(GTEST_OS_CYGWIN) || defined(GTEST_OS_LINUX) || defined(GTEST_OS_MAC)
#include <unistd.h> // NOLINT
#endif
#ifdef GTEST_OS_QURT
#include <qurt_event.h>
#endif
// Silence C4800 (C4800: 'int *const ': forcing value
// to bool 'true' or 'false') for MSVC 15
#if defined(_MSC_VER) && (_MSC_VER == 1900)
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800)
#endif
namespace testing {
namespace internal {
// Protects the mock object registry (in class Mock), all function
// mockers, and all expectations.
GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_gmock_mutex);
// Logs a message including file and line number information.
GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity,
const char* file, int line,
const std::string& message) {
::std::ostringstream s;
s << internal::FormatFileLocation(file, line) << " " << message
<< ::std::endl;
Log(severity, s.str(), 0);
}
// Constructs an ExpectationBase object.
ExpectationBase::ExpectationBase(const char* a_file, int a_line,
const std::string& a_source_text)
: file_(a_file),
line_(a_line),
source_text_(a_source_text),
cardinality_specified_(false),
cardinality_(Exactly(1)),
call_count_(0),
retired_(false),
extra_matcher_specified_(false),
repeated_action_specified_(false),
retires_on_saturation_(false),
last_clause_(kNone),
action_count_checked_(false) {}
// Destructs an ExpectationBase object.
ExpectationBase::~ExpectationBase() = default;
// Explicitly specifies the cardinality of this expectation. Used by
// the subclasses to implement the .Times() clause.
void ExpectationBase::SpecifyCardinality(const Cardinality& a_cardinality) {
cardinality_specified_ = true;
cardinality_ = a_cardinality;
}
// Retires all pre-requisites of this expectation.
void ExpectationBase::RetireAllPreRequisites()
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
if (is_retired()) {
// We can take this short-cut as we never retire an expectation
// until we have retired all its pre-requisites.
return;
}
::std::vector<ExpectationBase*> expectations(1, this);
while (!expectations.empty()) {
ExpectationBase* exp = expectations.back();
expectations.pop_back();
for (ExpectationSet::const_iterator it =
exp->immediate_prerequisites_.begin();
it != exp->immediate_prerequisites_.end(); ++it) {
ExpectationBase* next = it->expectation_base().get();
if (!next->is_retired()) {
next->Retire();
expectations.push_back(next);
}
}
}
}
// Returns true if and only if all pre-requisites of this expectation
// have been satisfied.
bool ExpectationBase::AllPrerequisitesAreSatisfied() const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
::std::vector<const ExpectationBase*> expectations(1, this);
while (!expectations.empty()) {
const ExpectationBase* exp = expectations.back();
expectations.pop_back();
for (ExpectationSet::const_iterator it =
exp->immediate_prerequisites_.begin();
it != exp->immediate_prerequisites_.end(); ++it) {
const ExpectationBase* next = it->expectation_base().get();
if (!next->IsSatisfied()) return false;
expectations.push_back(next);
}
}
return true;
}
// Adds unsatisfied pre-requisites of this expectation to 'result'.
void ExpectationBase::FindUnsatisfiedPrerequisites(ExpectationSet* result) const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
::std::vector<const ExpectationBase*> expectations(1, this);
while (!expectations.empty()) {
const ExpectationBase* exp = expectations.back();
expectations.pop_back();
for (ExpectationSet::const_iterator it =
exp->immediate_prerequisites_.begin();
it != exp->immediate_prerequisites_.end(); ++it) {
const ExpectationBase* next = it->expectation_base().get();
if (next->IsSatisfied()) {
// If *it is satisfied and has a call count of 0, some of its
// pre-requisites may not be satisfied yet.
if (next->call_count_ == 0) {
expectations.push_back(next);
}
} else {
// Now that we know next is unsatisfied, we are not so interested
// in whether its pre-requisites are satisfied. Therefore we
// don't iterate into it here.
*result += *it;
}
}
}
}
// Describes how many times a function call matching this
// expectation has occurred.
void ExpectationBase::DescribeCallCountTo(::std::ostream* os) const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
// Describes how many times the function is expected to be called.
*os << " Expected: to be ";
cardinality().DescribeTo(os);
*os << "\n Actual: ";
Cardinality::DescribeActualCallCountTo(call_count(), os);
// Describes the state of the expectation (e.g. is it satisfied?
// is it active?).
*os << " - "
<< (IsOverSaturated() ? "over-saturated"
: IsSaturated() ? "saturated"
: IsSatisfied() ? "satisfied"
: "unsatisfied")
<< " and " << (is_retired() ? "retired" : "active");
}
// Checks the action count (i.e. the number of WillOnce() and
// WillRepeatedly() clauses) against the cardinality if this hasn't
// been done before. Prints a warning if there are too many or too
// few actions.
void ExpectationBase::CheckActionCountIfNotDone() const
GTEST_LOCK_EXCLUDED_(mutex_) {
bool should_check = false;
{
MutexLock l(&mutex_);
if (!action_count_checked_) {
action_count_checked_ = true;
should_check = true;
}
}
if (should_check) {
if (!cardinality_specified_) {
// The cardinality was inferred - no need to check the action
// count against it.
return;
}
// The cardinality was explicitly specified.
const int action_count = static_cast<int>(untyped_actions_.size());
const int upper_bound = cardinality().ConservativeUpperBound();
const int lower_bound = cardinality().ConservativeLowerBound();
bool too_many; // True if there are too many actions, or false
// if there are too few.
if (action_count > upper_bound ||
(action_count == upper_bound && repeated_action_specified_)) {
too_many = true;
} else if (0 < action_count && action_count < lower_bound &&
!repeated_action_specified_) {
too_many = false;
} else {
return;
}
::std::stringstream ss;
DescribeLocationTo(&ss);
ss << "Too " << (too_many ? "many" : "few") << " actions specified in "
<< source_text() << "...\n"
<< "Expected to be ";
cardinality().DescribeTo(&ss);
ss << ", but has " << (too_many ? "" : "only ") << action_count
<< " WillOnce()" << (action_count == 1 ? "" : "s");
if (repeated_action_specified_) {
ss << " and a WillRepeatedly()";
}
ss << ".";
Log(kWarning, ss.str(), -1); // -1 means "don't print stack trace".
}
}
// Implements the .Times() clause.
void ExpectationBase::UntypedTimes(const Cardinality& a_cardinality) {
if (last_clause_ == kTimes) {
ExpectSpecProperty(false,
".Times() cannot appear "
"more than once in an EXPECT_CALL().");
} else {
ExpectSpecProperty(
last_clause_ < kTimes,
".Times() may only appear *before* .InSequence(), .WillOnce(), "
".WillRepeatedly(), or .RetiresOnSaturation(), not after.");
}
last_clause_ = kTimes;
SpecifyCardinality(a_cardinality);
}
// Points to the implicit sequence introduced by a living InSequence
// object (if any) in the current thread or NULL.
GTEST_API_ ThreadLocal<Sequence*> g_gmock_implicit_sequence;
// Reports an uninteresting call (whose description is in msg) in the
// manner specified by 'reaction'.
void ReportUninterestingCall(CallReaction reaction, const std::string& msg) {
// Include a stack trace only if --gmock_verbose=info is specified.
const int stack_frames_to_skip =
GMOCK_FLAG_GET(verbose) == kInfoVerbosity ? 3 : -1;
switch (reaction) {
case kAllow:
Log(kInfo, msg, stack_frames_to_skip);
break;
case kWarn:
Log(kWarning,
msg +
"\nNOTE: You can safely ignore the above warning unless this "
"call should not happen. Do not suppress it by adding "
"an EXPECT_CALL() if you don't mean to enforce the call. "
"See "
"https://github.com/google/googletest/blob/main/docs/"
"gmock_cook_book.md#"
"knowing-when-to-expect-useoncall for details.\n",
stack_frames_to_skip);
break;
default: // FAIL
Expect(false, nullptr, -1, msg);
}
}
UntypedFunctionMockerBase::UntypedFunctionMockerBase()
: mock_obj_(nullptr), name_("") {}
UntypedFunctionMockerBase::~UntypedFunctionMockerBase() = default;
// Sets the mock object this mock method belongs to, and registers
// this information in the global mock registry. Will be called
// whenever an EXPECT_CALL() or ON_CALL() is executed on this mock
// method.
void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj)
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
{
MutexLock l(&g_gmock_mutex);
mock_obj_ = mock_obj;
}
Mock::Register(mock_obj, this);
}
// Sets the mock object this mock method belongs to, and sets the name
// of the mock function. Will be called upon each invocation of this
// mock function.
void UntypedFunctionMockerBase::SetOwnerAndName(const void* mock_obj,
const char* name)
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
// We protect name_ under g_gmock_mutex in case this mock function
// is called from two threads concurrently.
MutexLock l(&g_gmock_mutex);
mock_obj_ = mock_obj;
name_ = name;
}
// Returns the name of the function being mocked. Must be called
// after RegisterOwner() or SetOwnerAndName() has been called.
const void* UntypedFunctionMockerBase::MockObject() const
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
const void* mock_obj;
{
// We protect mock_obj_ under g_gmock_mutex in case this mock
// function is called from two threads concurrently.
MutexLock l(&g_gmock_mutex);
Assert(mock_obj_ != nullptr, __FILE__, __LINE__,
"MockObject() must not be called before RegisterOwner() or "
"SetOwnerAndName() has been called.");
mock_obj = mock_obj_;
}
return mock_obj;
}
// Returns the name of this mock method. Must be called after
// SetOwnerAndName() has been called.
const char* UntypedFunctionMockerBase::Name() const
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
const char* name;
{
// We protect name_ under g_gmock_mutex in case this mock
// function is called from two threads concurrently.
MutexLock l(&g_gmock_mutex);
Assert(name_ != nullptr, __FILE__, __LINE__,
"Name() must not be called before SetOwnerAndName() has "
"been called.");
name = name_;
}
return name;
}
// Returns an Expectation object that references and co-owns exp,
// which must be an expectation on this mock function.
Expectation UntypedFunctionMockerBase::GetHandleOf(ExpectationBase* exp) {
// See the definition of untyped_expectations_ for why access to it
// is unprotected here.
for (UntypedExpectations::const_iterator it = untyped_expectations_.begin();
it != untyped_expectations_.end(); ++it) {
if (it->get() == exp) {
return Expectation(*it);
}
}
Assert(false, __FILE__, __LINE__, "Cannot find expectation.");
return Expectation();
// The above statement is just to make the code compile, and will
// never be executed.
}
// Verifies that all expectations on this mock function have been
// satisfied. Reports one or more Google Test non-fatal failures
// and returns false if not.
bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
bool expectations_met = true;
for (UntypedExpectations::const_iterator it = untyped_expectations_.begin();
it != untyped_expectations_.end(); ++it) {
ExpectationBase* const untyped_expectation = it->get();
if (untyped_expectation->IsOverSaturated()) {
// There was an upper-bound violation. Since the error was
// already reported when it occurred, there is no need to do
// anything here.
expectations_met = false;
} else if (!untyped_expectation->IsSatisfied()) {
expectations_met = false;
::std::stringstream ss;
const ::std::string& expectation_name =
untyped_expectation->GetDescription();
ss << "Actual function ";
if (!expectation_name.empty()) {
ss << "\"" << expectation_name << "\" ";
}
ss << "call count doesn't match " << untyped_expectation->source_text()
<< "...\n";
// No need to show the source file location of the expectation
// in the description, as the Expect() call that follows already
// takes care of it.
untyped_expectation->MaybeDescribeExtraMatcherTo(&ss);
untyped_expectation->DescribeCallCountTo(&ss);
Expect(false, untyped_expectation->file(), untyped_expectation->line(),
ss.str());
}
}
// Deleting our expectations may trigger other mock objects to be deleted, for
// example if an action contains a reference counted smart pointer to that
// mock object, and that is the last reference. So if we delete our
// expectations within the context of the global mutex we may deadlock when
// this method is called again. Instead, make a copy of the set of
// expectations to delete, clear our set within the mutex, and then clear the
// copied set outside of it.
UntypedExpectations expectations_to_delete;
untyped_expectations_.swap(expectations_to_delete);
g_gmock_mutex.Unlock();
expectations_to_delete.clear();
g_gmock_mutex.Lock();
return expectations_met;
}
static CallReaction intToCallReaction(int mock_behavior) {
if (mock_behavior >= kAllow && mock_behavior <= kFail) {
return static_cast<internal::CallReaction>(mock_behavior);
}
return kWarn;
}
} // namespace internal
// Class Mock.
namespace {
typedef std::set<internal::UntypedFunctionMockerBase*> FunctionMockers;
// The current state of a mock object. Such information is needed for
// detecting leaked mock objects and explicitly verifying a mock's
// expectations.
struct MockObjectState {
MockObjectState()
: first_used_file(nullptr), first_used_line(-1), leakable(false) {}
// Where in the source file an ON_CALL or EXPECT_CALL is first
// invoked on this mock object.
const char* first_used_file;
int first_used_line;
::std::string first_used_test_suite;
::std::string first_used_test;
bool leakable; // true if and only if it's OK to leak the object.
FunctionMockers function_mockers; // All registered methods of the object.
};
// A global registry holding the state of all mock objects that are
// alive. A mock object is added to this registry the first time
// Mock::AllowLeak(), ON_CALL(), or EXPECT_CALL() is called on it. It
// is removed from the registry in the mock object's destructor.
class MockObjectRegistry {
public:
// Maps a mock object (identified by its address) to its state.
typedef std::map<const void*, MockObjectState> StateMap;
// This destructor will be called when a program exits, after all
// tests in it have been run. By then, there should be no mock
// object alive. Therefore we report any living object as test
// failure, unless the user explicitly asked us to ignore it.
~MockObjectRegistry() {
if (!GMOCK_FLAG_GET(catch_leaked_mocks)) return;
internal::MutexLock l(&internal::g_gmock_mutex);
int leaked_count = 0;
for (StateMap::const_iterator it = states_.begin(); it != states_.end();
++it) {
if (it->second.leakable) // The user said it's fine to leak this object.
continue;
// FIXME: Print the type of the leaked object.
// This can help the user identify the leaked object.
std::cout << "\n";
const MockObjectState& state = it->second;
std::cout << internal::FormatFileLocation(state.first_used_file,
state.first_used_line);
std::cout << " ERROR: this mock object";
if (!state.first_used_test.empty()) {
std::cout << " (used in test " << state.first_used_test_suite << "."
<< state.first_used_test << ")";
}
std::cout << " should be deleted but never is. Its address is @"
<< it->first << ".";
leaked_count++;
}
if (leaked_count > 0) {
std::cout << "\nERROR: " << leaked_count << " leaked mock "
<< (leaked_count == 1 ? "object" : "objects")
<< " found at program exit. Expectations on a mock object are "
"verified when the object is destructed. Leaking a mock "
"means that its expectations aren't verified, which is "
"usually a test bug. If you really intend to leak a mock, "
"you can suppress this error using "
"testing::Mock::AllowLeak(mock_object), or you may use a "
"fake or stub instead of a mock.\n";
std::cout.flush();
::std::cerr.flush();
// RUN_ALL_TESTS() has already returned when this destructor is
// called. Therefore we cannot use the normal Google Test
// failure reporting mechanism.
#ifdef GTEST_OS_QURT
qurt_exception_raise_fatal();
#else
_Exit(1); // We cannot call exit() as it is not reentrant and
// may already have been called.
#endif
}
}
StateMap& states() { return states_; }
private:
StateMap states_;
};
// Protected by g_gmock_mutex.
MockObjectRegistry g_mock_object_registry;
// Maps a mock object to the reaction Google Mock should have when an
// uninteresting method is called. Protected by g_gmock_mutex.
std::unordered_map<uintptr_t, internal::CallReaction>&
UninterestingCallReactionMap() {
static auto* map = new std::unordered_map<uintptr_t, internal::CallReaction>;
return *map;
}
// Sets the reaction Google Mock should have when an uninteresting
// method of the given mock object is called.
void SetReactionOnUninterestingCalls(uintptr_t mock_obj,
internal::CallReaction reaction)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
UninterestingCallReactionMap()[mock_obj] = reaction;
}
} // namespace
// Tells Google Mock to allow uninteresting calls on the given mock
// object.
void Mock::AllowUninterestingCalls(uintptr_t mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
SetReactionOnUninterestingCalls(mock_obj, internal::kAllow);
}
// Tells Google Mock to warn the user about uninteresting calls on the
// given mock object.
void Mock::WarnUninterestingCalls(uintptr_t mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
SetReactionOnUninterestingCalls(mock_obj, internal::kWarn);
}
// Tells Google Mock to fail uninteresting calls on the given mock
// object.
void Mock::FailUninterestingCalls(uintptr_t mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
SetReactionOnUninterestingCalls(mock_obj, internal::kFail);
}
// Tells Google Mock the given mock object is being destroyed and its
// entry in the call-reaction table should be removed.
void Mock::UnregisterCallReaction(uintptr_t mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
UninterestingCallReactionMap().erase(static_cast<uintptr_t>(mock_obj));
}
// Returns the reaction Google Mock will have on uninteresting calls
// made on the given mock object.
internal::CallReaction Mock::GetReactionOnUninterestingCalls(
const void* mock_obj) GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
return (UninterestingCallReactionMap().count(
reinterpret_cast<uintptr_t>(mock_obj)) == 0)
? internal::intToCallReaction(
GMOCK_FLAG_GET(default_mock_behavior))
: UninterestingCallReactionMap()[reinterpret_cast<uintptr_t>(
mock_obj)];
}
// Tells Google Mock to ignore mock_obj when checking for leaked mock
// objects.
void Mock::AllowLeak(const void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
g_mock_object_registry.states()[mock_obj].leakable = true;
}
// Verifies and clears all expectations on the given mock object. If
// the expectations aren't satisfied, generates one or more Google
// Test non-fatal failures and returns false.
bool Mock::VerifyAndClearExpectations(void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
return VerifyAndClearExpectationsLocked(mock_obj);
}
// Verifies all expectations on the given mock object and clears its
// default actions and expectations. Returns true if and only if the
// verification was successful.
bool Mock::VerifyAndClear(void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
ClearDefaultActionsLocked(mock_obj);
return VerifyAndClearExpectationsLocked(mock_obj);
}
// Verifies and clears all expectations on the given mock object. If
// the expectations aren't satisfied, generates one or more Google
// Test non-fatal failures and returns false.
bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj)
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
internal::g_gmock_mutex.AssertHeld();
if (g_mock_object_registry.states().count(mock_obj) == 0) {
// No EXPECT_CALL() was set on the given mock object.
return true;
}
// Verifies and clears the expectations on each mock method in the
// given mock object.
bool expectations_met = true;
FunctionMockers& mockers =
g_mock_object_registry.states()[mock_obj].function_mockers;
for (FunctionMockers::const_iterator it = mockers.begin();
it != mockers.end(); ++it) {
if (!(*it)->VerifyAndClearExpectationsLocked()) {
expectations_met = false;
}
}
// We don't clear the content of mockers, as they may still be
// needed by ClearDefaultActionsLocked().
return expectations_met;
}
bool Mock::IsNaggy(void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kWarn;
}
bool Mock::IsNice(void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kAllow;
}
bool Mock::IsStrict(void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kFail;
}
// Registers a mock object and a mock method it owns.
void Mock::Register(const void* mock_obj,
internal::UntypedFunctionMockerBase* mocker)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker);
}
// Tells Google Mock where in the source code mock_obj is used in an
// ON_CALL or EXPECT_CALL. In case mock_obj is leaked, this
// information helps the user identify which object it is.
void Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj,
const char* file, int line)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
MockObjectState& state = g_mock_object_registry.states()[mock_obj];
if (state.first_used_file == nullptr) {
state.first_used_file = file;
state.first_used_line = line;
const TestInfo* const test_info =
UnitTest::GetInstance()->current_test_info();
if (test_info != nullptr) {
state.first_used_test_suite = test_info->test_suite_name();
state.first_used_test = test_info->name();
}
}
}
// Unregisters a mock method; removes the owning mock object from the
// registry when the last mock method associated with it has been
// unregistered. This is called only in the destructor of
// FunctionMockerBase.
void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker)
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
internal::g_gmock_mutex.AssertHeld();
for (MockObjectRegistry::StateMap::iterator it =
g_mock_object_registry.states().begin();
it != g_mock_object_registry.states().end(); ++it) {
FunctionMockers& mockers = it->second.function_mockers;
if (mockers.erase(mocker) > 0) {
// mocker was in mockers and has been just removed.
if (mockers.empty()) {
g_mock_object_registry.states().erase(it);
}
return;
}
}
}
// Clears all ON_CALL()s set on the given mock object.
void Mock::ClearDefaultActionsLocked(void* mock_obj)
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
internal::g_gmock_mutex.AssertHeld();
if (g_mock_object_registry.states().count(mock_obj) == 0) {
// No ON_CALL() was set on the given mock object.
return;
}
// Clears the default actions for each mock method in the given mock
// object.
FunctionMockers& mockers =
g_mock_object_registry.states()[mock_obj].function_mockers;
for (FunctionMockers::const_iterator it = mockers.begin();
it != mockers.end(); ++it) {
(*it)->ClearDefaultActionsLocked();
}
// We don't clear the content of mockers, as they may still be
// needed by VerifyAndClearExpectationsLocked().
}
Expectation::Expectation() = default;
Expectation::Expectation(
const std::shared_ptr<internal::ExpectationBase>& an_expectation_base)
: expectation_base_(an_expectation_base) {}
Expectation::~Expectation() = default;
// Adds an expectation to a sequence.
void Sequence::AddExpectation(const Expectation& expectation) const {
if (*last_expectation_ != expectation) {
if (last_expectation_->expectation_base() != nullptr) {
expectation.expectation_base()->immediate_prerequisites_ +=
*last_expectation_;
}
*last_expectation_ = expectation;
}
}
// Creates the implicit sequence if there isn't one.
InSequence::InSequence() {
if (internal::g_gmock_implicit_sequence.get() == nullptr) {
internal::g_gmock_implicit_sequence.set(new Sequence);
sequence_created_ = true;
} else {
sequence_created_ = false;
}
}
// Deletes the implicit sequence if it was created by the constructor
// of this object.
InSequence::~InSequence() {
if (sequence_created_) {
delete internal::g_gmock_implicit_sequence.get();
internal::g_gmock_implicit_sequence.set(nullptr);
}
}
} // namespace testing
#if defined(_MSC_VER) && (_MSC_VER == 1900)
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4800
#endif
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "gmock/gmock.h"
#include <string>
#include "gmock/internal/gmock-port.h"
GMOCK_DEFINE_bool_(catch_leaked_mocks, true,
"true if and only if Google Mock should report leaked "
"mock objects as failures.");
GMOCK_DEFINE_string_(verbose, testing::internal::kWarningVerbosity,
"Controls how verbose Google Mock's output is."
" Valid values:\n"
" info - prints all messages.\n"
" warning - prints warnings and errors.\n"
" error - prints errors only.");
GMOCK_DEFINE_int32_(default_mock_behavior, 1,
"Controls the default behavior of mocks."
" Valid values:\n"
" 0 - by default, mocks act as NiceMocks.\n"
" 1 - by default, mocks act as NaggyMocks.\n"
" 2 - by default, mocks act as StrictMocks.");
namespace testing {
namespace internal {
// Parses a string as a command line flag. The string should have the
// format "--gmock_flag=value". When def_optional is true, the
// "=value" part can be omitted.
//
// Returns the value of the flag, or NULL if the parsing failed.
static const char* ParseGoogleMockFlagValue(const char* str,
const char* flag_name,
bool def_optional) {
// str and flag must not be NULL.
if (str == nullptr || flag_name == nullptr) return nullptr;
// The flag must start with "--gmock_".
const std::string flag_name_str = std::string("--gmock_") + flag_name;
const size_t flag_name_len = flag_name_str.length();
if (strncmp(str, flag_name_str.c_str(), flag_name_len) != 0) return nullptr;
// Skips the flag name.
const char* flag_end = str + flag_name_len;
// When def_optional is true, it's OK to not have a "=value" part.
if (def_optional && (flag_end[0] == '\0')) {
return flag_end;
}
// If def_optional is true and there are more characters after the
// flag name, or if def_optional is false, there must be a '=' after
// the flag name.
if (flag_end[0] != '=') return nullptr;
// Returns the string after "=".
return flag_end + 1;
}
// Parses a string for a Google Mock bool flag, in the form of
// "--gmock_flag=value".
//
// On success, stores the value of the flag in *value, and returns
// true. On failure, returns false without changing *value.
static bool ParseGoogleMockFlag(const char* str, const char* flag_name,
bool* value) {
// Gets the value of the flag as a string.
const char* const value_str = ParseGoogleMockFlagValue(str, flag_name, true);
// Aborts if the parsing failed.
if (value_str == nullptr) return false;
// Converts the string value to a bool.
*value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');
return true;
}
// Parses a string for a Google Mock string flag, in the form of
// "--gmock_flag=value".
//
// On success, stores the value of the flag in *value, and returns
// true. On failure, returns false without changing *value.
template <typename String>
static bool ParseGoogleMockFlag(const char* str, const char* flag_name,
String* value) {
// Gets the value of the flag as a string.
const char* const value_str = ParseGoogleMockFlagValue(str, flag_name, false);
// Aborts if the parsing failed.
if (value_str == nullptr) return false;
// Sets *value to the value of the flag.
*value = value_str;
return true;
}
static bool ParseGoogleMockFlag(const char* str, const char* flag_name,
int32_t* value) {
// Gets the value of the flag as a string.
const char* const value_str = ParseGoogleMockFlagValue(str, flag_name, true);
// Aborts if the parsing failed.
if (value_str == nullptr) return false;
// Sets *value to the value of the flag.
return ParseInt32(Message() << "The value of flag --" << flag_name, value_str,
value);
}
// The internal implementation of InitGoogleMock().
//
// The type parameter CharType can be instantiated to either char or
// wchar_t.
template <typename CharType>
void InitGoogleMockImpl(int* argc, CharType** argv) {
// Makes sure Google Test is initialized. InitGoogleTest() is
// idempotent, so it's fine if the user has already called it.
InitGoogleTest(argc, argv);
if (*argc <= 0) return;
for (int i = 1; i != *argc; i++) {
const std::string arg_string = StreamableToString(argv[i]);
const char* const arg = arg_string.c_str();
// Do we see a Google Mock flag?
bool found_gmock_flag = false;
#define GMOCK_INTERNAL_PARSE_FLAG(flag_name) \
if (!found_gmock_flag) { \
auto value = GMOCK_FLAG_GET(flag_name); \
if (ParseGoogleMockFlag(arg, #flag_name, &value)) { \
GMOCK_FLAG_SET(flag_name, value); \
found_gmock_flag = true; \
} \
}
GMOCK_INTERNAL_PARSE_FLAG(catch_leaked_mocks)
GMOCK_INTERNAL_PARSE_FLAG(verbose)
GMOCK_INTERNAL_PARSE_FLAG(default_mock_behavior)
if (found_gmock_flag) {
// Yes. Shift the remainder of the argv list left by one. Note
// that argv has (*argc + 1) elements, the last one always being
// NULL. The following loop moves the trailing NULL element as
// well.
for (int j = i; j != *argc; j++) {
argv[j] = argv[j + 1];
}
// Decrements the argument count.
(*argc)--;
// We also need to decrement the iterator as we just removed
// an element.
i--;
}
}
}
} // namespace internal
// Initializes Google Mock. This must be called before running the
// tests. In particular, it parses a command line for the flags that
// Google Mock recognizes. Whenever a Google Mock flag is seen, it is
// removed from argv, and *argc is decremented.
//
// No value is returned. Instead, the Google Mock flag variables are
// updated.
//
// Since Google Test is needed for Google Mock to work, this function
// also initializes Google Test and parses its flags, if that hasn't
// been done.
GTEST_API_ void InitGoogleMock(int* argc, char** argv) {
internal::InitGoogleMockImpl(argc, argv);
}
// This overloaded version can be used in Windows programs compiled in
// UNICODE mode.
GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv) {
internal::InitGoogleMockImpl(argc, argv);
}
// This overloaded version can be used on Arduino/embedded platforms where
// there is no argc/argv.
GTEST_API_ void InitGoogleMock() {
// Since Arduino doesn't have a command line, fake out the argc/argv arguments
int argc = 1;
const auto arg0 = "dummy";
char* argv0 = const_cast<char*>(arg0);
char** argv = &argv0;
internal::InitGoogleMockImpl(&argc, argv);
}
} // namespace testing
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <iostream>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#if defined(GTEST_OS_ESP8266) || defined(GTEST_OS_ESP32) || \
(defined(GTEST_OS_NRF52) && defined(ARDUINO))
#ifdef GTEST_OS_ESP8266
extern "C" {
#endif
void setup() {
// Since Google Mock depends on Google Test, InitGoogleMock() is
// also responsible for initializing Google Test. Therefore there's
// no need for calling testing::InitGoogleTest() separately.
testing::InitGoogleMock();
}
void loop() { RUN_ALL_TESTS(); }
#ifdef GTEST_OS_ESP8266
}
#endif
#else
// MS C++ compiler/linker has a bug on Windows (not on Windows CE), which
// causes a link error when _tmain is defined in a static library and UNICODE
// is enabled. For this reason instead of _tmain, main function is used on
// Windows. See the following link to track the current status of this bug:
// https://web.archive.org/web/20170912203238/connect.microsoft.com/VisualStudio/feedback/details/394464/wmain-link-error-in-the-static-library
// // NOLINT
#ifdef GTEST_OS_WINDOWS_MOBILE
#include <tchar.h> // NOLINT
GTEST_API_ int _tmain(int argc, TCHAR** argv) {
#else
GTEST_API_ int main(int argc, char** argv) {
#endif // GTEST_OS_WINDOWS_MOBILE
std::cout << "Running main() from gmock_main.cc\n";
// Since Google Mock depends on Google Test, InitGoogleMock() is
// also responsible for initializing Google Test. Therefore there's
// no need for calling testing::InitGoogleTest() separately.
testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}
#endif
# Copyright 2017 Google Inc.
# All Rights Reserved.
#
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Bazel Build for Google C++ Testing Framework(Google Test)-googlemock
load("@rules_python//python:defs.bzl", "py_library", "py_test")
licenses(["notice"])
# Tests for GMock itself
cc_test(
name = "gmock_all_test",
size = "small",
srcs = glob(include = ["gmock-*.cc"]) + ["gmock-matchers_test.h"],
linkopts = select({
"//:qnx": [],
"//:windows": [],
"//conditions:default": ["-pthread"],
}),
deps = ["//:gtest"],
)
# Python tests
py_library(
name = "gmock_test_utils",
testonly = 1,
srcs = ["gmock_test_utils.py"],
deps = [
"//googletest/test:gtest_test_utils",
],
)
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",
],
tags = [
"no_test_msvc2015",
"no_test_msvc2017",
],
)
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",
],
tags = [
"no_test_msvc2015",
"no_test_msvc2017",
],
deps = [":gmock_test_utils"],
)
cc_test(
name = "gmock_test",
size = "small",
srcs = ["gmock_test.cc"],
deps = ["//:gtest_main"],
)
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Mock - a framework for writing C++ mock classes.
//
// This file tests the built-in actions.
#include "gmock/gmock-actions.h"
#include <algorithm>
#include <functional>
#include <iterator>
#include <memory>
#include <sstream>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
#include <vector>
#include "gmock/gmock.h"
#include "gmock/internal/gmock-port.h"
#include "gtest/gtest-spi.h"
#include "gtest/gtest.h"
#include "gtest/internal/gtest-port.h"
// Silence C4100 (unreferenced formal parameter) and C4503 (decorated name
// length exceeded) for MSVC.
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100 4503)
#if defined(_MSC_VER) && (_MSC_VER == 1900)
// and silence C4800 (C4800: 'int *const ': forcing value
// to bool 'true' or 'false') for MSVC 15
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800)
#endif
namespace testing {
namespace {
using ::testing::internal::BuiltInDefaultValue;
TEST(TypeTraits, Negation) {
// Direct use with std types.
static_assert(std::is_base_of<std::false_type,
internal::negation<std::true_type>>::value,
"");
static_assert(std::is_base_of<std::true_type,
internal::negation<std::false_type>>::value,
"");
// With other types that fit the requirement of a value member that is
// convertible to bool.
static_assert(std::is_base_of<
std::true_type,
internal::negation<std::integral_constant<int, 0>>>::value,
"");
static_assert(std::is_base_of<
std::false_type,
internal::negation<std::integral_constant<int, 1>>>::value,
"");
static_assert(std::is_base_of<
std::false_type,
internal::negation<std::integral_constant<int, -1>>>::value,
"");
}
// Weird false/true types that aren't actually bool constants (but should still
// be legal according to [meta.logical] because `bool(T::value)` is valid), are
// distinct from std::false_type and std::true_type, and are distinct from other
// instantiations of the same template.
//
// These let us check finicky details mandated by the standard like
// "std::conjunction should evaluate to a type that inherits from the first
// false-y input".
template <int>
struct MyFalse : std::integral_constant<int, 0> {};
template <int>
struct MyTrue : std::integral_constant<int, -1> {};
TEST(TypeTraits, Conjunction) {
// Base case: always true.
static_assert(std::is_base_of<std::true_type, internal::conjunction<>>::value,
"");
// One predicate: inherits from that predicate, regardless of value.
static_assert(
std::is_base_of<MyFalse<0>, internal::conjunction<MyFalse<0>>>::value,
"");
static_assert(
std::is_base_of<MyTrue<0>, internal::conjunction<MyTrue<0>>>::value, "");
// Multiple predicates, with at least one false: inherits from that one.
static_assert(
std::is_base_of<MyFalse<1>, internal::conjunction<MyTrue<0>, MyFalse<1>,
MyTrue<2>>>::value,
"");
static_assert(
std::is_base_of<MyFalse<1>, internal::conjunction<MyTrue<0>, MyFalse<1>,
MyFalse<2>>>::value,
"");
// Short circuiting: in the case above, additional predicates need not even
// define a value member.
struct Empty {};
static_assert(
std::is_base_of<MyFalse<1>, internal::conjunction<MyTrue<0>, MyFalse<1>,
Empty>>::value,
"");
// All predicates true: inherits from the last.
static_assert(
std::is_base_of<MyTrue<2>, internal::conjunction<MyTrue<0>, MyTrue<1>,
MyTrue<2>>>::value,
"");
}
TEST(TypeTraits, Disjunction) {
// Base case: always false.
static_assert(
std::is_base_of<std::false_type, internal::disjunction<>>::value, "");
// One predicate: inherits from that predicate, regardless of value.
static_assert(
std::is_base_of<MyFalse<0>, internal::disjunction<MyFalse<0>>>::value,
"");
static_assert(
std::is_base_of<MyTrue<0>, internal::disjunction<MyTrue<0>>>::value, "");
// Multiple predicates, with at least one true: inherits from that one.
static_assert(
std::is_base_of<MyTrue<1>, internal::disjunction<MyFalse<0>, MyTrue<1>,
MyFalse<2>>>::value,
"");
static_assert(
std::is_base_of<MyTrue<1>, internal::disjunction<MyFalse<0>, MyTrue<1>,
MyTrue<2>>>::value,
"");
// Short circuiting: in the case above, additional predicates need not even
// define a value member.
struct Empty {};
static_assert(
std::is_base_of<MyTrue<1>, internal::disjunction<MyFalse<0>, MyTrue<1>,
Empty>>::value,
"");
// All predicates false: inherits from the last.
static_assert(
std::is_base_of<MyFalse<2>, internal::disjunction<MyFalse<0>, MyFalse<1>,
MyFalse<2>>>::value,
"");
}
TEST(TypeTraits, IsInvocableRV) {
struct C {
int operator()() const { return 0; }
void operator()(int) & {}
std::string operator()(int) && { return ""; }
};
// The first overload is callable for const and non-const rvalues and lvalues.
// It can be used to obtain an int, cv void, or anything int is convertible
// to.
static_assert(internal::is_callable_r<int, C>::value, "");
static_assert(internal::is_callable_r<int, C&>::value, "");
static_assert(internal::is_callable_r<int, const C>::value, "");
static_assert(internal::is_callable_r<int, const C&>::value, "");
static_assert(internal::is_callable_r<void, C>::value, "");
static_assert(internal::is_callable_r<const volatile void, C>::value, "");
static_assert(internal::is_callable_r<char, C>::value, "");
// It's possible to provide an int. If it's given to an lvalue, the result is
// void. Otherwise it is std::string (which is also treated as allowed for a
// void result type).
static_assert(internal::is_callable_r<void, C&, int>::value, "");
static_assert(!internal::is_callable_r<int, C&, int>::value, "");
static_assert(!internal::is_callable_r<std::string, C&, int>::value, "");
static_assert(!internal::is_callable_r<void, const C&, int>::value, "");
static_assert(internal::is_callable_r<std::string, C, int>::value, "");
static_assert(internal::is_callable_r<void, C, int>::value, "");
static_assert(!internal::is_callable_r<int, C, int>::value, "");
// It's not possible to provide other arguments.
static_assert(!internal::is_callable_r<void, C, std::string>::value, "");
static_assert(!internal::is_callable_r<void, C, int, int>::value, "");
// In C++17 and above, where it's guaranteed that functions can return
// non-moveable objects, everything should work fine for non-moveable rsult
// types too.
// TODO(b/396121064) - Fix this test under MSVC
#ifndef _MSC_VER
{
struct NonMoveable {
NonMoveable() = default;
NonMoveable(NonMoveable&&) = delete;
};
static_assert(!std::is_move_constructible_v<NonMoveable>);
struct Callable {
NonMoveable operator()() { return NonMoveable(); }
};
static_assert(internal::is_callable_r<NonMoveable, Callable>::value);
static_assert(internal::is_callable_r<void, Callable>::value);
static_assert(
internal::is_callable_r<const volatile void, Callable>::value);
static_assert(!internal::is_callable_r<int, Callable>::value);
static_assert(!internal::is_callable_r<NonMoveable, Callable, int>::value);
}
#endif // _MSC_VER
// Nothing should choke when we try to call other arguments besides directly
// callable objects, but they should not show up as callable.
static_assert(!internal::is_callable_r<void, int>::value, "");
static_assert(!internal::is_callable_r<void, void (C::*)()>::value, "");
static_assert(!internal::is_callable_r<void, void (C::*)(), C*>::value, "");
}
// Tests that BuiltInDefaultValue<T*>::Get() returns NULL.
TEST(BuiltInDefaultValueTest, IsNullForPointerTypes) {
EXPECT_TRUE(BuiltInDefaultValue<int*>::Get() == nullptr);
EXPECT_TRUE(BuiltInDefaultValue<const char*>::Get() == nullptr);
EXPECT_TRUE(BuiltInDefaultValue<void*>::Get() == nullptr);
}
// Tests that BuiltInDefaultValue<T*>::Exists() return true.
TEST(BuiltInDefaultValueTest, ExistsForPointerTypes) {
EXPECT_TRUE(BuiltInDefaultValue<int*>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<const char*>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<void*>::Exists());
}
// Tests that BuiltInDefaultValue<T>::Get() returns 0 when T is a
// built-in numeric type.
TEST(BuiltInDefaultValueTest, IsZeroForNumericTypes) {
EXPECT_EQ(0U, BuiltInDefaultValue<unsigned char>::Get());
EXPECT_EQ(0, BuiltInDefaultValue<signed char>::Get());
EXPECT_EQ(0, BuiltInDefaultValue<char>::Get());
#if GMOCK_WCHAR_T_IS_NATIVE_
#if !defined(__WCHAR_UNSIGNED__)
EXPECT_EQ(0, BuiltInDefaultValue<wchar_t>::Get());
#else
EXPECT_EQ(0U, BuiltInDefaultValue<wchar_t>::Get());
#endif
#endif
EXPECT_EQ(0U, BuiltInDefaultValue<unsigned short>::Get()); // NOLINT
EXPECT_EQ(0, BuiltInDefaultValue<signed short>::Get()); // NOLINT
EXPECT_EQ(0, BuiltInDefaultValue<short>::Get()); // NOLINT
EXPECT_EQ(0U, BuiltInDefaultValue<unsigned int>::Get());
EXPECT_EQ(0, BuiltInDefaultValue<signed int>::Get());
EXPECT_EQ(0, BuiltInDefaultValue<int>::Get());
EXPECT_EQ(0U, BuiltInDefaultValue<unsigned long>::Get()); // NOLINT
EXPECT_EQ(0, BuiltInDefaultValue<signed long>::Get()); // NOLINT
EXPECT_EQ(0, BuiltInDefaultValue<long>::Get()); // NOLINT
EXPECT_EQ(0U, BuiltInDefaultValue<unsigned long long>::Get()); // NOLINT
EXPECT_EQ(0, BuiltInDefaultValue<signed long long>::Get()); // NOLINT
EXPECT_EQ(0, BuiltInDefaultValue<long long>::Get()); // NOLINT
EXPECT_EQ(0, BuiltInDefaultValue<float>::Get());
EXPECT_EQ(0, BuiltInDefaultValue<double>::Get());
}
// Tests that BuiltInDefaultValue<T>::Exists() returns true when T is a
// built-in numeric type.
TEST(BuiltInDefaultValueTest, ExistsForNumericTypes) {
EXPECT_TRUE(BuiltInDefaultValue<unsigned char>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<signed char>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<char>::Exists());
#if GMOCK_WCHAR_T_IS_NATIVE_
EXPECT_TRUE(BuiltInDefaultValue<wchar_t>::Exists());
#endif
EXPECT_TRUE(BuiltInDefaultValue<unsigned short>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<signed short>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<short>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<unsigned int>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<signed int>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<int>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<unsigned long>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<signed long>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<long>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<unsigned long long>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<signed long long>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<long long>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<float>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<double>::Exists());
}
// Tests that BuiltInDefaultValue<bool>::Get() returns false.
TEST(BuiltInDefaultValueTest, IsFalseForBool) {
EXPECT_FALSE(BuiltInDefaultValue<bool>::Get());
}
// Tests that BuiltInDefaultValue<bool>::Exists() returns true.
TEST(BuiltInDefaultValueTest, BoolExists) {
EXPECT_TRUE(BuiltInDefaultValue<bool>::Exists());
}
// Tests that BuiltInDefaultValue<T>::Get() returns "" when T is a
// string type.
TEST(BuiltInDefaultValueTest, IsEmptyStringForString) {
EXPECT_EQ("", BuiltInDefaultValue<::std::string>::Get());
}
// Tests that BuiltInDefaultValue<T>::Exists() returns true when T is a
// string type.
TEST(BuiltInDefaultValueTest, ExistsForString) {
EXPECT_TRUE(BuiltInDefaultValue<::std::string>::Exists());
}
// Tests that BuiltInDefaultValue<const T>::Get() returns the same
// value as BuiltInDefaultValue<T>::Get() does.
TEST(BuiltInDefaultValueTest, WorksForConstTypes) {
EXPECT_EQ("", BuiltInDefaultValue<const std::string>::Get());
EXPECT_EQ(0, BuiltInDefaultValue<const int>::Get());
EXPECT_TRUE(BuiltInDefaultValue<char* const>::Get() == nullptr);
EXPECT_FALSE(BuiltInDefaultValue<const bool>::Get());
}
// A type that's default constructible.
class MyDefaultConstructible {
public:
MyDefaultConstructible() : value_(42) {}
int value() const { return value_; }
private:
int value_;
};
// A type that's not default constructible.
class MyNonDefaultConstructible {
public:
// Does not have a default ctor.
explicit MyNonDefaultConstructible(int a_value) : value_(a_value) {}
int value() const { return value_; }
private:
int value_;
};
TEST(BuiltInDefaultValueTest, ExistsForDefaultConstructibleType) {
EXPECT_TRUE(BuiltInDefaultValue<MyDefaultConstructible>::Exists());
}
TEST(BuiltInDefaultValueTest, IsDefaultConstructedForDefaultConstructibleType) {
EXPECT_EQ(42, BuiltInDefaultValue<MyDefaultConstructible>::Get().value());
}
TEST(BuiltInDefaultValueTest, DoesNotExistForNonDefaultConstructibleType) {
EXPECT_FALSE(BuiltInDefaultValue<MyNonDefaultConstructible>::Exists());
}
// Tests that BuiltInDefaultValue<T&>::Get() aborts the program.
TEST(BuiltInDefaultValueDeathTest, IsUndefinedForReferences) {
EXPECT_DEATH_IF_SUPPORTED({ BuiltInDefaultValue<int&>::Get(); }, "");
EXPECT_DEATH_IF_SUPPORTED({ BuiltInDefaultValue<const char&>::Get(); }, "");
}
TEST(BuiltInDefaultValueDeathTest, IsUndefinedForNonDefaultConstructibleType) {
EXPECT_DEATH_IF_SUPPORTED(
{ BuiltInDefaultValue<MyNonDefaultConstructible>::Get(); }, "");
}
// Tests that DefaultValue<T>::IsSet() is false initially.
TEST(DefaultValueTest, IsInitiallyUnset) {
EXPECT_FALSE(DefaultValue<int>::IsSet());
EXPECT_FALSE(DefaultValue<MyDefaultConstructible>::IsSet());
EXPECT_FALSE(DefaultValue<const MyNonDefaultConstructible>::IsSet());
}
// Tests that DefaultValue<T> can be set and then unset.
TEST(DefaultValueTest, CanBeSetAndUnset) {
EXPECT_TRUE(DefaultValue<int>::Exists());
EXPECT_FALSE(DefaultValue<const MyNonDefaultConstructible>::Exists());
DefaultValue<int>::Set(1);
DefaultValue<const MyNonDefaultConstructible>::Set(
MyNonDefaultConstructible(42));
EXPECT_EQ(1, DefaultValue<int>::Get());
EXPECT_EQ(42, DefaultValue<const MyNonDefaultConstructible>::Get().value());
EXPECT_TRUE(DefaultValue<int>::Exists());
EXPECT_TRUE(DefaultValue<const MyNonDefaultConstructible>::Exists());
DefaultValue<int>::Clear();
DefaultValue<const MyNonDefaultConstructible>::Clear();
EXPECT_FALSE(DefaultValue<int>::IsSet());
EXPECT_FALSE(DefaultValue<const MyNonDefaultConstructible>::IsSet());
EXPECT_TRUE(DefaultValue<int>::Exists());
EXPECT_FALSE(DefaultValue<const MyNonDefaultConstructible>::Exists());
}
// Tests that DefaultValue<T>::Get() returns the
// BuiltInDefaultValue<T>::Get() when DefaultValue<T>::IsSet() is
// false.
TEST(DefaultValueDeathTest, GetReturnsBuiltInDefaultValueWhenUnset) {
EXPECT_FALSE(DefaultValue<int>::IsSet());
EXPECT_TRUE(DefaultValue<int>::Exists());
EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible>::IsSet());
EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible>::Exists());
EXPECT_EQ(0, DefaultValue<int>::Get());
EXPECT_DEATH_IF_SUPPORTED(
{ DefaultValue<MyNonDefaultConstructible>::Get(); }, "");
}
TEST(DefaultValueTest, GetWorksForMoveOnlyIfSet) {
EXPECT_TRUE(DefaultValue<std::unique_ptr<int>>::Exists());
EXPECT_TRUE(DefaultValue<std::unique_ptr<int>>::Get() == nullptr);
DefaultValue<std::unique_ptr<int>>::SetFactory(
[] { return std::make_unique<int>(42); });
EXPECT_TRUE(DefaultValue<std::unique_ptr<int>>::Exists());
std::unique_ptr<int> i = DefaultValue<std::unique_ptr<int>>::Get();
EXPECT_EQ(42, *i);
}
// Tests that DefaultValue<void>::Get() returns void.
TEST(DefaultValueTest, GetWorksForVoid) { return DefaultValue<void>::Get(); }
// Tests using DefaultValue with a reference type.
// Tests that DefaultValue<T&>::IsSet() is false initially.
TEST(DefaultValueOfReferenceTest, IsInitiallyUnset) {
EXPECT_FALSE(DefaultValue<int&>::IsSet());
EXPECT_FALSE(DefaultValue<MyDefaultConstructible&>::IsSet());
EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible&>::IsSet());
}
// Tests that DefaultValue<T&>::Exists is false initially.
TEST(DefaultValueOfReferenceTest, IsInitiallyNotExisting) {
EXPECT_FALSE(DefaultValue<int&>::Exists());
EXPECT_FALSE(DefaultValue<MyDefaultConstructible&>::Exists());
EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible&>::Exists());
}
// Tests that DefaultValue<T&> can be set and then unset.
TEST(DefaultValueOfReferenceTest, CanBeSetAndUnset) {
int n = 1;
DefaultValue<const int&>::Set(n);
MyNonDefaultConstructible x(42);
DefaultValue<MyNonDefaultConstructible&>::Set(x);
EXPECT_TRUE(DefaultValue<const int&>::Exists());
EXPECT_TRUE(DefaultValue<MyNonDefaultConstructible&>::Exists());
EXPECT_EQ(&n, &(DefaultValue<const int&>::Get()));
EXPECT_EQ(&x, &(DefaultValue<MyNonDefaultConstructible&>::Get()));
DefaultValue<const int&>::Clear();
DefaultValue<MyNonDefaultConstructible&>::Clear();
EXPECT_FALSE(DefaultValue<const int&>::Exists());
EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible&>::Exists());
EXPECT_FALSE(DefaultValue<const int&>::IsSet());
EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible&>::IsSet());
}
// Tests that DefaultValue<T&>::Get() returns the
// BuiltInDefaultValue<T&>::Get() when DefaultValue<T&>::IsSet() is
// false.
TEST(DefaultValueOfReferenceDeathTest, GetReturnsBuiltInDefaultValueWhenUnset) {
EXPECT_FALSE(DefaultValue<int&>::IsSet());
EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible&>::IsSet());
EXPECT_DEATH_IF_SUPPORTED({ DefaultValue<int&>::Get(); }, "");
EXPECT_DEATH_IF_SUPPORTED(
{ DefaultValue<MyNonDefaultConstructible>::Get(); }, "");
}
// Tests that ActionInterface can be implemented by defining the
// Perform method.
typedef int MyGlobalFunction(bool, int);
class MyActionImpl : public ActionInterface<MyGlobalFunction> {
public:
int Perform(const std::tuple<bool, int>& args) override {
return std::get<0>(args) ? std::get<1>(args) : 0;
}
};
TEST(ActionInterfaceTest, CanBeImplementedByDefiningPerform) {
MyActionImpl my_action_impl;
(void)my_action_impl;
}
TEST(ActionInterfaceTest, MakeAction) {
Action<MyGlobalFunction> action = MakeAction(new MyActionImpl);
// When exercising the Perform() method of Action<F>, we must pass
// it a tuple whose size and type are compatible with F's argument
// types. For example, if F is int(), then Perform() takes a
// 0-tuple; if F is void(bool, int), then Perform() takes a
// std::tuple<bool, int>, and so on.
EXPECT_EQ(5, action.Perform(std::make_tuple(true, 5)));
}
// Tests that Action<F> can be constructed from a pointer to
// ActionInterface<F>.
TEST(ActionTest, CanBeConstructedFromActionInterface) {
Action<MyGlobalFunction> action(new MyActionImpl);
}
// Tests that Action<F> delegates actual work to ActionInterface<F>.
TEST(ActionTest, DelegatesWorkToActionInterface) {
const Action<MyGlobalFunction> action(new MyActionImpl);
EXPECT_EQ(5, action.Perform(std::make_tuple(true, 5)));
EXPECT_EQ(0, action.Perform(std::make_tuple(false, 1)));
}
// Tests that Action<F> can be copied.
TEST(ActionTest, IsCopyable) {
Action<MyGlobalFunction> a1(new MyActionImpl);
Action<MyGlobalFunction> a2(a1); // Tests the copy constructor.
// a1 should continue to work after being copied from.
EXPECT_EQ(5, a1.Perform(std::make_tuple(true, 5)));
EXPECT_EQ(0, a1.Perform(std::make_tuple(false, 1)));
// a2 should work like the action it was copied from.
EXPECT_EQ(5, a2.Perform(std::make_tuple(true, 5)));
EXPECT_EQ(0, a2.Perform(std::make_tuple(false, 1)));
a2 = a1; // Tests the assignment operator.
// a1 should continue to work after being copied from.
EXPECT_EQ(5, a1.Perform(std::make_tuple(true, 5)));
EXPECT_EQ(0, a1.Perform(std::make_tuple(false, 1)));
// a2 should work like the action it was copied from.
EXPECT_EQ(5, a2.Perform(std::make_tuple(true, 5)));
EXPECT_EQ(0, a2.Perform(std::make_tuple(false, 1)));
}
// Tests that an Action<From> object can be converted to a
// compatible Action<To> object.
class IsNotZero : public ActionInterface<bool(int)> { // NOLINT
public:
bool Perform(const std::tuple<int>& arg) override {
return std::get<0>(arg) != 0;
}
};
TEST(ActionTest, CanBeConvertedToOtherActionType) {
const Action<bool(int)> a1(new IsNotZero); // NOLINT
const Action<int(char)> a2 = Action<int(char)>(a1); // NOLINT
EXPECT_EQ(1, a2.Perform(std::make_tuple('a')));
EXPECT_EQ(0, a2.Perform(std::make_tuple('\0')));
}
// The following two classes are for testing MakePolymorphicAction().
// Implements a polymorphic action that returns the second of the
// arguments it receives.
class ReturnSecondArgumentAction {
public:
// We want to verify that MakePolymorphicAction() can work with a
// polymorphic action whose Perform() method template is either
// const or not. This lets us verify the non-const case.
template <typename Result, typename ArgumentTuple>
Result Perform(const ArgumentTuple& args) {
return std::get<1>(args);
}
};
// Implements a polymorphic action that can be used in a nullary
// function to return 0.
class ReturnZeroFromNullaryFunctionAction {
public:
// For testing that MakePolymorphicAction() works when the
// implementation class' Perform() method template takes only one
// template parameter.
//
// We want to verify that MakePolymorphicAction() can work with a
// polymorphic action whose Perform() method template is either
// const or not. This lets us verify the const case.
template <typename Result>
Result Perform(const std::tuple<>&) const {
return 0;
}
};
// These functions verify that MakePolymorphicAction() returns a
// PolymorphicAction<T> where T is the argument's type.
PolymorphicAction<ReturnSecondArgumentAction> ReturnSecondArgument() {
return MakePolymorphicAction(ReturnSecondArgumentAction());
}
PolymorphicAction<ReturnZeroFromNullaryFunctionAction>
ReturnZeroFromNullaryFunction() {
return MakePolymorphicAction(ReturnZeroFromNullaryFunctionAction());
}
// Tests that MakePolymorphicAction() turns a polymorphic action
// implementation class into a polymorphic action.
TEST(MakePolymorphicActionTest, ConstructsActionFromImpl) {
Action<int(bool, int, double)> a1 = ReturnSecondArgument(); // NOLINT
EXPECT_EQ(5, a1.Perform(std::make_tuple(false, 5, 2.0)));
}
// Tests that MakePolymorphicAction() works when the implementation
// class' Perform() method template has only one template parameter.
TEST(MakePolymorphicActionTest, WorksWhenPerformHasOneTemplateParameter) {
Action<int()> a1 = ReturnZeroFromNullaryFunction();
EXPECT_EQ(0, a1.Perform(std::make_tuple()));
Action<void*()> a2 = ReturnZeroFromNullaryFunction();
EXPECT_TRUE(a2.Perform(std::make_tuple()) == nullptr);
}
// Tests that Return() works as an action for void-returning
// functions.
TEST(ReturnTest, WorksForVoid) {
const Action<void(int)> ret = Return(); // NOLINT
return ret.Perform(std::make_tuple(1));
}
// Tests that Return(v) returns v.
TEST(ReturnTest, ReturnsGivenValue) {
Action<int()> ret = Return(1); // NOLINT
EXPECT_EQ(1, ret.Perform(std::make_tuple()));
ret = Return(-5);
EXPECT_EQ(-5, ret.Perform(std::make_tuple()));
}
// Tests that Return("string literal") works.
TEST(ReturnTest, AcceptsStringLiteral) {
Action<const char*()> a1 = Return("Hello");
EXPECT_STREQ("Hello", a1.Perform(std::make_tuple()));
Action<std::string()> a2 = Return("world");
EXPECT_EQ("world", a2.Perform(std::make_tuple()));
}
// Return(x) should work fine when the mock function's return type is a
// reference-like wrapper for decltype(x), as when x is a std::string and the
// mock function returns std::string_view.
TEST(ReturnTest, SupportsReferenceLikeReturnType) {
// A reference wrapper for std::vector<int>, implicitly convertible from it.
struct Result {
const std::vector<int>* v;
Result(const std::vector<int>& vec) : v(&vec) {} // NOLINT
};
// Set up an action for a mock function that returns the reference wrapper
// type, initializing it with an actual vector.
//
// The returned wrapper should be initialized with a copy of that vector
// that's embedded within the action itself (which should stay alive as long
// as the mock object is alive), rather than e.g. a reference to the temporary
// we feed to Return. This should work fine both for WillOnce and
// WillRepeatedly.
MockFunction<Result()> mock;
EXPECT_CALL(mock, Call)
.WillOnce(Return(std::vector<int>{17, 19, 23}))
.WillRepeatedly(Return(std::vector<int>{29, 31, 37}));
EXPECT_THAT(mock.AsStdFunction()(),
Field(&Result::v, Pointee(ElementsAre(17, 19, 23))));
EXPECT_THAT(mock.AsStdFunction()(),
Field(&Result::v, Pointee(ElementsAre(29, 31, 37))));
}
TEST(ReturnTest, PrefersConversionOperator) {
// Define types In and Out such that:
//
// * In is implicitly convertible to Out.
// * Out also has an explicit constructor from In.
//
struct In;
struct Out {
int x;
explicit Out(const int val) : x(val) {}
explicit Out(const In&) : x(0) {}
};
struct In {
operator Out() const { return Out{19}; } // NOLINT
};
// Assumption check: the C++ language rules are such that a function that
// returns Out which uses In a return statement will use the implicit
// conversion path rather than the explicit constructor.
EXPECT_THAT([]() -> Out { return In(); }(), Field(&Out::x, 19));
// Return should work the same way: if the mock function's return type is Out
// and we feed Return an In value, then the Out should be created through the
// implicit conversion path rather than the explicit constructor.
MockFunction<Out()> mock;
EXPECT_CALL(mock, Call).WillOnce(Return(In()));
EXPECT_THAT(mock.AsStdFunction()(), Field(&Out::x, 19));
}
// It should be possible to use Return(R) with a mock function result type U
// that is convertible from const R& but *not* R (such as
// std::reference_wrapper). This should work for both WillOnce and
// WillRepeatedly.
TEST(ReturnTest, ConversionRequiresConstLvalueReference) {
using R = int;
using U = std::reference_wrapper<const int>;
static_assert(std::is_convertible<const R&, U>::value, "");
static_assert(!std::is_convertible<R, U>::value, "");
MockFunction<U()> mock;
EXPECT_CALL(mock, Call).WillOnce(Return(17)).WillRepeatedly(Return(19));
EXPECT_EQ(17, mock.AsStdFunction()());
EXPECT_EQ(19, mock.AsStdFunction()());
}
// Return(x) should not be usable with a mock function result type that's
// implicitly convertible from decltype(x) but requires a non-const lvalue
// reference to the input. It doesn't make sense for the conversion operator to
// modify the input.
TEST(ReturnTest, ConversionRequiresMutableLvalueReference) {
// Set up a type that is implicitly convertible from std::string&, but not
// std::string&& or `const std::string&`.
//
// Avoid asserting about conversion from std::string on MSVC, which seems to
// implement std::is_convertible incorrectly in this case.
struct S {
S(std::string&) {} // NOLINT
};
static_assert(std::is_convertible<std::string&, S>::value, "");
#ifndef _MSC_VER
static_assert(!std::is_convertible<std::string&&, S>::value, "");
#endif
static_assert(!std::is_convertible<const std::string&, S>::value, "");
// It shouldn't be possible to use the result of Return(std::string) in a
// context where an S is needed.
//
// Here too we disable the assertion for MSVC, since its incorrect
// implementation of is_convertible causes our SFINAE to be wrong.
using RA = decltype(Return(std::string()));
static_assert(!std::is_convertible<RA, Action<S()>>::value, "");
#ifndef _MSC_VER
static_assert(!std::is_convertible<RA, OnceAction<S()>>::value, "");
#endif
}
TEST(ReturnTest, MoveOnlyResultType) {
// Return should support move-only result types when used with WillOnce.
{
MockFunction<std::unique_ptr<int>()> mock;
EXPECT_CALL(mock, Call)
// NOLINTNEXTLINE
.WillOnce(Return(std::unique_ptr<int>(new int(17))));
EXPECT_THAT(mock.AsStdFunction()(), Pointee(17));
}
// The result of Return should not be convertible to Action (so it can't be
// used with WillRepeatedly).
static_assert(!std::is_convertible<decltype(Return(std::unique_ptr<int>())),
Action<std::unique_ptr<int>()>>::value,
"");
}
// Tests that Return(v) is covariant.
struct Base {
bool operator==(const Base&) { return true; }
};
struct Derived : public Base {
bool operator==(const Derived&) { return true; }
};
TEST(ReturnTest, IsCovariant) {
Base base;
Derived derived;
Action<Base*()> ret = Return(&base);
EXPECT_EQ(&base, ret.Perform(std::make_tuple()));
ret = Return(&derived);
EXPECT_EQ(&derived, ret.Perform(std::make_tuple()));
}
// Tests that the type of the value passed into Return is converted into T
// when the action is cast to Action<T(...)> rather than when the action is
// performed. See comments on testing::internal::ReturnAction in
// gmock-actions.h for more information.
class FromType {
public:
explicit FromType(bool* is_converted) : converted_(is_converted) {}
bool* converted() const { return converted_; }
private:
bool* const converted_;
};
class ToType {
public:
// Must allow implicit conversion due to use in ImplicitCast_<T>.
ToType(const FromType& x) { *x.converted() = true; } // NOLINT
};
TEST(ReturnTest, ConvertsArgumentWhenConverted) {
bool converted = false;
FromType x(&converted);
Action<ToType()> action(Return(x));
EXPECT_TRUE(converted) << "Return must convert its argument in its own "
<< "conversion operator.";
converted = false;
action.Perform(std::tuple<>());
EXPECT_FALSE(converted) << "Action must NOT convert its argument "
<< "when performed.";
}
// Tests that ReturnNull() returns NULL in a pointer-returning function.
TEST(ReturnNullTest, WorksInPointerReturningFunction) {
const Action<int*()> a1 = ReturnNull();
EXPECT_TRUE(a1.Perform(std::make_tuple()) == nullptr);
const Action<const char*(bool)> a2 = ReturnNull(); // NOLINT
EXPECT_TRUE(a2.Perform(std::make_tuple(true)) == nullptr);
}
// Tests that ReturnNull() returns NULL for shared_ptr and unique_ptr returning
// functions.
TEST(ReturnNullTest, WorksInSmartPointerReturningFunction) {
const Action<std::unique_ptr<const int>()> a1 = ReturnNull();
EXPECT_TRUE(a1.Perform(std::make_tuple()) == nullptr);
const Action<std::shared_ptr<int>(std::string)> a2 = ReturnNull();
EXPECT_TRUE(a2.Perform(std::make_tuple("foo")) == nullptr);
}
// Tests that ReturnRef(v) works for reference types.
TEST(ReturnRefTest, WorksForReference) {
const int n = 0;
const Action<const int&(bool)> ret = ReturnRef(n); // NOLINT
EXPECT_EQ(&n, &ret.Perform(std::make_tuple(true)));
}
// Tests that ReturnRef(v) is covariant.
TEST(ReturnRefTest, IsCovariant) {
Base base;
Derived derived;
Action<Base&()> a = ReturnRef(base);
EXPECT_EQ(&base, &a.Perform(std::make_tuple()));
a = ReturnRef(derived);
EXPECT_EQ(&derived, &a.Perform(std::make_tuple()));
}
template <typename T, typename = decltype(ReturnRef(std::declval<T&&>()))>
bool CanCallReturnRef(T&&) {
return true;
}
bool CanCallReturnRef(Unused) { return false; }
// Tests that ReturnRef(v) is working with non-temporaries (T&)
TEST(ReturnRefTest, WorksForNonTemporary) {
int scalar_value = 123;
EXPECT_TRUE(CanCallReturnRef(scalar_value));
std::string non_scalar_value("ABC");
EXPECT_TRUE(CanCallReturnRef(non_scalar_value));
const int const_scalar_value{321};
EXPECT_TRUE(CanCallReturnRef(const_scalar_value));
const std::string const_non_scalar_value("CBA");
EXPECT_TRUE(CanCallReturnRef(const_non_scalar_value));
}
// Tests that ReturnRef(v) is not working with temporaries (T&&)
TEST(ReturnRefTest, DoesNotWorkForTemporary) {
auto scalar_value = []() -> int { return 123; };
EXPECT_FALSE(CanCallReturnRef(scalar_value()));
auto non_scalar_value = []() -> std::string { return "ABC"; };
EXPECT_FALSE(CanCallReturnRef(non_scalar_value()));
// cannot use here callable returning "const scalar type",
// because such const for scalar return type is ignored
EXPECT_FALSE(CanCallReturnRef(static_cast<const int>(321)));
auto const_non_scalar_value = []() -> const std::string { return "CBA"; };
EXPECT_FALSE(CanCallReturnRef(const_non_scalar_value()));
}
// Tests that ReturnRefOfCopy(v) works for reference types.
TEST(ReturnRefOfCopyTest, WorksForReference) {
int n = 42;
const Action<const int&()> ret = ReturnRefOfCopy(n);
EXPECT_NE(&n, &ret.Perform(std::make_tuple()));
EXPECT_EQ(42, ret.Perform(std::make_tuple()));
n = 43;
EXPECT_NE(&n, &ret.Perform(std::make_tuple()));
EXPECT_EQ(42, ret.Perform(std::make_tuple()));
}
// Tests that ReturnRefOfCopy(v) is covariant.
TEST(ReturnRefOfCopyTest, IsCovariant) {
Base base;
Derived derived;
Action<Base&()> a = ReturnRefOfCopy(base);
EXPECT_NE(&base, &a.Perform(std::make_tuple()));
a = ReturnRefOfCopy(derived);
EXPECT_NE(&derived, &a.Perform(std::make_tuple()));
}
// Tests that ReturnRoundRobin(v) works with initializer lists
TEST(ReturnRoundRobinTest, WorksForInitList) {
Action<int()> ret = ReturnRoundRobin({1, 2, 3});
EXPECT_EQ(1, ret.Perform(std::make_tuple()));
EXPECT_EQ(2, ret.Perform(std::make_tuple()));
EXPECT_EQ(3, ret.Perform(std::make_tuple()));
EXPECT_EQ(1, ret.Perform(std::make_tuple()));
EXPECT_EQ(2, ret.Perform(std::make_tuple()));
EXPECT_EQ(3, ret.Perform(std::make_tuple()));
}
// Tests that ReturnRoundRobin(v) works with vectors
TEST(ReturnRoundRobinTest, WorksForVector) {
std::vector<double> v = {4.4, 5.5, 6.6};
Action<double()> ret = ReturnRoundRobin(v);
EXPECT_EQ(4.4, ret.Perform(std::make_tuple()));
EXPECT_EQ(5.5, ret.Perform(std::make_tuple()));
EXPECT_EQ(6.6, ret.Perform(std::make_tuple()));
EXPECT_EQ(4.4, ret.Perform(std::make_tuple()));
EXPECT_EQ(5.5, ret.Perform(std::make_tuple()));
EXPECT_EQ(6.6, ret.Perform(std::make_tuple()));
}
// Tests that DoDefault() does the default action for the mock method.
class MockClass {
public:
MockClass() = default;
MOCK_METHOD1(IntFunc, int(bool flag)); // NOLINT
MOCK_METHOD0(Foo, MyNonDefaultConstructible());
MOCK_METHOD0(MakeUnique, std::unique_ptr<int>());
MOCK_METHOD0(MakeUniqueBase, std::unique_ptr<Base>());
MOCK_METHOD0(MakeVectorUnique, std::vector<std::unique_ptr<int>>());
MOCK_METHOD1(TakeUnique, int(std::unique_ptr<int>));
MOCK_METHOD2(TakeUnique,
int(const std::unique_ptr<int>&, std::unique_ptr<int>));
private:
MockClass(const MockClass&) = delete;
MockClass& operator=(const MockClass&) = delete;
};
// Tests that DoDefault() returns the built-in default value for the
// return type by default.
TEST(DoDefaultTest, ReturnsBuiltInDefaultValueByDefault) {
MockClass mock;
EXPECT_CALL(mock, IntFunc(_)).WillOnce(DoDefault());
EXPECT_EQ(0, mock.IntFunc(true));
}
// Tests that DoDefault() throws (when exceptions are enabled) or aborts
// the process when there is no built-in default value for the return type.
TEST(DoDefaultDeathTest, DiesForUnknowType) {
MockClass mock;
EXPECT_CALL(mock, Foo()).WillRepeatedly(DoDefault());
#if GTEST_HAS_EXCEPTIONS
EXPECT_ANY_THROW(mock.Foo());
#else
EXPECT_DEATH_IF_SUPPORTED({ mock.Foo(); }, "");
#endif
}
// Tests that using DoDefault() inside a composite action leads to a
// run-time error.
void VoidFunc(bool /* flag */) {}
TEST(DoDefaultDeathTest, DiesIfUsedInCompositeAction) {
MockClass mock;
EXPECT_CALL(mock, IntFunc(_)).WillRepeatedly(DoAll(VoidFunc, DoDefault()));
// Ideally we should verify the error message as well. Sadly,
// EXPECT_DEATH() can only capture stderr, while Google Mock's
// errors are printed on stdout. Therefore we have to settle for
// not verifying the message.
EXPECT_DEATH_IF_SUPPORTED({ mock.IntFunc(true); }, "");
}
// Tests that DoDefault() returns the default value set by
// DefaultValue<T>::Set() when it's not overridden by an ON_CALL().
TEST(DoDefaultTest, ReturnsUserSpecifiedPerTypeDefaultValueWhenThereIsOne) {
DefaultValue<int>::Set(1);
MockClass mock;
EXPECT_CALL(mock, IntFunc(_)).WillOnce(DoDefault());
EXPECT_EQ(1, mock.IntFunc(false));
DefaultValue<int>::Clear();
}
// Tests that DoDefault() does the action specified by ON_CALL().
TEST(DoDefaultTest, DoesWhatOnCallSpecifies) {
MockClass mock;
ON_CALL(mock, IntFunc(_)).WillByDefault(Return(2));
EXPECT_CALL(mock, IntFunc(_)).WillOnce(DoDefault());
EXPECT_EQ(2, mock.IntFunc(false));
}
// Tests that using DoDefault() in ON_CALL() leads to a run-time failure.
TEST(DoDefaultTest, CannotBeUsedInOnCall) {
MockClass mock;
EXPECT_NONFATAL_FAILURE(
{ // NOLINT
ON_CALL(mock, IntFunc(_)).WillByDefault(DoDefault());
},
"DoDefault() cannot be used in ON_CALL()");
}
// Tests that SetArgPointee<N>(v) sets the variable pointed to by
// the N-th (0-based) argument to v.
TEST(SetArgPointeeTest, SetsTheNthPointee) {
typedef void MyFunction(bool, int*, char*);
Action<MyFunction> a = SetArgPointee<1>(2);
int n = 0;
char ch = '\0';
a.Perform(std::make_tuple(true, &n, &ch));
EXPECT_EQ(2, n);
EXPECT_EQ('\0', ch);
a = SetArgPointee<2>('a');
n = 0;
ch = '\0';
a.Perform(std::make_tuple(true, &n, &ch));
EXPECT_EQ(0, n);
EXPECT_EQ('a', ch);
}
// Tests that SetArgPointee<N>() accepts a string literal.
TEST(SetArgPointeeTest, AcceptsStringLiteral) {
typedef void MyFunction(std::string*, const char**);
Action<MyFunction> a = SetArgPointee<0>("hi");
std::string str;
const char* ptr = nullptr;
a.Perform(std::make_tuple(&str, &ptr));
EXPECT_EQ("hi", str);
EXPECT_TRUE(ptr == nullptr);
a = SetArgPointee<1>("world");
str = "";
a.Perform(std::make_tuple(&str, &ptr));
EXPECT_EQ("", str);
EXPECT_STREQ("world", ptr);
}
TEST(SetArgPointeeTest, AcceptsWideStringLiteral) {
typedef void MyFunction(const wchar_t**);
Action<MyFunction> a = SetArgPointee<0>(L"world");
const wchar_t* ptr = nullptr;
a.Perform(std::make_tuple(&ptr));
EXPECT_STREQ(L"world", ptr);
#if GTEST_HAS_STD_WSTRING
typedef void MyStringFunction(std::wstring*);
Action<MyStringFunction> a2 = SetArgPointee<0>(L"world");
std::wstring str = L"";
a2.Perform(std::make_tuple(&str));
EXPECT_EQ(L"world", str);
#endif
}
// Tests that SetArgPointee<N>() accepts a char pointer.
TEST(SetArgPointeeTest, AcceptsCharPointer) {
typedef void MyFunction(bool, std::string*, const char**);
const char* const hi = "hi";
Action<MyFunction> a = SetArgPointee<1>(hi);
std::string str;
const char* ptr = nullptr;
a.Perform(std::make_tuple(true, &str, &ptr));
EXPECT_EQ("hi", str);
EXPECT_TRUE(ptr == nullptr);
char world_array[] = "world";
char* const world = world_array;
a = SetArgPointee<2>(world);
str = "";
a.Perform(std::make_tuple(true, &str, &ptr));
EXPECT_EQ("", str);
EXPECT_EQ(world, ptr);
}
TEST(SetArgPointeeTest, AcceptsWideCharPointer) {
typedef void MyFunction(bool, const wchar_t**);
const wchar_t* const hi = L"hi";
Action<MyFunction> a = SetArgPointee<1>(hi);
const wchar_t* ptr = nullptr;
a.Perform(std::make_tuple(true, &ptr));
EXPECT_EQ(hi, ptr);
#if GTEST_HAS_STD_WSTRING
typedef void MyStringFunction(bool, std::wstring*);
wchar_t world_array[] = L"world";
wchar_t* const world = world_array;
Action<MyStringFunction> a2 = SetArgPointee<1>(world);
std::wstring str;
a2.Perform(std::make_tuple(true, &str));
EXPECT_EQ(world_array, str);
#endif
}
// Tests that SetArgumentPointee<N>(v) sets the variable pointed to by
// the N-th (0-based) argument to v.
TEST(SetArgumentPointeeTest, SetsTheNthPointee) {
typedef void MyFunction(bool, int*, char*);
Action<MyFunction> a = SetArgumentPointee<1>(2);
int n = 0;
char ch = '\0';
a.Perform(std::make_tuple(true, &n, &ch));
EXPECT_EQ(2, n);
EXPECT_EQ('\0', ch);
a = SetArgumentPointee<2>('a');
n = 0;
ch = '\0';
a.Perform(std::make_tuple(true, &n, &ch));
EXPECT_EQ(0, n);
EXPECT_EQ('a', ch);
}
// Sample functions and functors for testing Invoke() and etc.
int Nullary() { return 1; }
class NullaryFunctor {
public:
int operator()() { return 2; }
};
bool g_done = false;
void VoidNullary() { g_done = true; }
class VoidNullaryFunctor {
public:
void operator()() { g_done = true; }
};
short Short(short n) { return n; } // NOLINT
char Char(char ch) { return ch; }
const char* CharPtr(const char* s) { return s; }
bool Unary(int x) { return x < 0; }
const char* Binary(const char* input, short n) { return input + n; } // NOLINT
void VoidBinary(int, char) { g_done = true; }
int Ternary(int x, char y, short z) { return x + y + z; } // NOLINT
int SumOf4(int a, int b, int c, int d) { return a + b + c + d; }
class Foo {
public:
Foo() : value_(123) {}
int Nullary() const { return value_; }
private:
int value_;
};
// Tests InvokeWithoutArgs(function).
TEST(InvokeWithoutArgsTest, Function) {
// As an action that takes one argument.
Action<int(int)> a = InvokeWithoutArgs(Nullary); // NOLINT
EXPECT_EQ(1, a.Perform(std::make_tuple(2)));
// As an action that takes two arguments.
Action<int(int, double)> a2 = InvokeWithoutArgs(Nullary); // NOLINT
EXPECT_EQ(1, a2.Perform(std::make_tuple(2, 3.5)));
// As an action that returns void.
Action<void(int)> a3 = InvokeWithoutArgs(VoidNullary); // NOLINT
g_done = false;
a3.Perform(std::make_tuple(1));
EXPECT_TRUE(g_done);
}
// Tests InvokeWithoutArgs(functor).
TEST(InvokeWithoutArgsTest, Functor) {
// As an action that takes no argument.
Action<int()> a = InvokeWithoutArgs(NullaryFunctor()); // NOLINT
EXPECT_EQ(2, a.Perform(std::make_tuple()));
// As an action that takes three arguments.
Action<int(int, double, char)> a2 = // NOLINT
InvokeWithoutArgs(NullaryFunctor());
EXPECT_EQ(2, a2.Perform(std::make_tuple(3, 3.5, 'a')));
// As an action that returns void.
Action<void()> a3 = InvokeWithoutArgs(VoidNullaryFunctor());
g_done = false;
a3.Perform(std::make_tuple());
EXPECT_TRUE(g_done);
}
// Tests InvokeWithoutArgs(obj_ptr, method).
TEST(InvokeWithoutArgsTest, Method) {
Foo foo;
Action<int(bool, char)> a = // NOLINT
InvokeWithoutArgs(&foo, &Foo::Nullary);
EXPECT_EQ(123, a.Perform(std::make_tuple(true, 'a')));
}
// Tests using IgnoreResult() on a polymorphic action.
TEST(IgnoreResultTest, PolymorphicAction) {
Action<void(int)> a = IgnoreResult(Return(5)); // NOLINT
a.Perform(std::make_tuple(1));
}
// Tests using IgnoreResult() on a monomorphic action.
int ReturnOne() {
g_done = true;
return 1;
}
TEST(IgnoreResultTest, MonomorphicAction) {
g_done = false;
Action<void()> a = IgnoreResult(&ReturnOne);
a.Perform(std::make_tuple());
EXPECT_TRUE(g_done);
}
// Tests using IgnoreResult() on an action that returns a class type.
MyNonDefaultConstructible ReturnMyNonDefaultConstructible(double /* x */) {
g_done = true;
return MyNonDefaultConstructible(42);
}
TEST(IgnoreResultTest, ActionReturningClass) {
g_done = false;
Action<void(int)> a =
IgnoreResult(&ReturnMyNonDefaultConstructible); // NOLINT
a.Perform(std::make_tuple(2));
EXPECT_TRUE(g_done);
}
TEST(AssignTest, Int) {
int x = 0;
Action<void(int)> a = Assign(&x, 5);
a.Perform(std::make_tuple(0));
EXPECT_EQ(5, x);
}
TEST(AssignTest, String) {
::std::string x;
Action<void(void)> a = Assign(&x, "Hello, world");
a.Perform(std::make_tuple());
EXPECT_EQ("Hello, world", x);
}
TEST(AssignTest, CompatibleTypes) {
double x = 0;
Action<void(int)> a = Assign(&x, 5);
a.Perform(std::make_tuple(0));
EXPECT_DOUBLE_EQ(5, x);
}
// DoAll should support &&-qualified actions when used with WillOnce.
TEST(DoAll, SupportsRefQualifiedActions) {
struct InitialAction {
void operator()(const int arg) && { EXPECT_EQ(17, arg); }
};
struct FinalAction {
int operator()() && { return 19; }
};
MockFunction<int(int)> mock;
EXPECT_CALL(mock, Call).WillOnce(DoAll(InitialAction{}, FinalAction{}));
EXPECT_EQ(19, mock.AsStdFunction()(17));
}
// DoAll should never provide rvalue references to the initial actions. If the
// mock action itself accepts an rvalue reference or a non-scalar object by
// value then the final action should receive an rvalue reference, but initial
// actions should receive only lvalue references.
TEST(DoAll, ProvidesLvalueReferencesToInitialActions) {
struct Obj {};
// Mock action accepts by value: the initial action should be fed a const
// lvalue reference, and the final action an rvalue reference.
{
struct InitialAction {
void operator()(Obj&) const { FAIL() << "Unexpected call"; }
void operator()(const Obj&) const {}
void operator()(Obj&&) const { FAIL() << "Unexpected call"; }
void operator()(const Obj&&) const { FAIL() << "Unexpected call"; }
};
MockFunction<void(Obj)> mock;
EXPECT_CALL(mock, Call)
.WillOnce(DoAll(InitialAction{}, InitialAction{}, [](Obj&&) {}))
.WillRepeatedly(DoAll(InitialAction{}, InitialAction{}, [](Obj&&) {}));
mock.AsStdFunction()(Obj{});
mock.AsStdFunction()(Obj{});
}
// Mock action accepts by const lvalue reference: both actions should receive
// a const lvalue reference.
{
struct InitialAction {
void operator()(Obj&) const { FAIL() << "Unexpected call"; }
void operator()(const Obj&) const {}
void operator()(Obj&&) const { FAIL() << "Unexpected call"; }
void operator()(const Obj&&) const { FAIL() << "Unexpected call"; }
};
MockFunction<void(const Obj&)> mock;
EXPECT_CALL(mock, Call)
.WillOnce(DoAll(InitialAction{}, InitialAction{}, [](const Obj&) {}))
.WillRepeatedly(
DoAll(InitialAction{}, InitialAction{}, [](const Obj&) {}));
mock.AsStdFunction()(Obj{});
mock.AsStdFunction()(Obj{});
}
// Mock action accepts by non-const lvalue reference: both actions should get
// a non-const lvalue reference if they want them.
{
struct InitialAction {
void operator()(Obj&) const {}
void operator()(Obj&&) const { FAIL() << "Unexpected call"; }
};
MockFunction<void(Obj&)> mock;
EXPECT_CALL(mock, Call)
.WillOnce(DoAll(InitialAction{}, InitialAction{}, [](Obj&) {}))
.WillRepeatedly(DoAll(InitialAction{}, InitialAction{}, [](Obj&) {}));
Obj obj;
mock.AsStdFunction()(obj);
mock.AsStdFunction()(obj);
}
// Mock action accepts by rvalue reference: the initial actions should receive
// a non-const lvalue reference if it wants it, and the final action an rvalue
// reference.
{
struct InitialAction {
void operator()(Obj&) const {}
void operator()(Obj&&) const { FAIL() << "Unexpected call"; }
};
MockFunction<void(Obj&&)> mock;
EXPECT_CALL(mock, Call)
.WillOnce(DoAll(InitialAction{}, InitialAction{}, [](Obj&&) {}))
.WillRepeatedly(DoAll(InitialAction{}, InitialAction{}, [](Obj&&) {}));
mock.AsStdFunction()(Obj{});
mock.AsStdFunction()(Obj{});
}
// &&-qualified initial actions should also be allowed with WillOnce.
{
struct InitialAction {
void operator()(Obj&) && {}
};
MockFunction<void(Obj&)> mock;
EXPECT_CALL(mock, Call)
.WillOnce(DoAll(InitialAction{}, InitialAction{}, [](Obj&) {}));
Obj obj;
mock.AsStdFunction()(obj);
}
{
struct InitialAction {
void operator()(Obj&) && {}
};
MockFunction<void(Obj&&)> mock;
EXPECT_CALL(mock, Call)
.WillOnce(DoAll(InitialAction{}, InitialAction{}, [](Obj&&) {}));
mock.AsStdFunction()(Obj{});
}
}
// DoAll should support being used with type-erased Action objects, both through
// WillOnce and WillRepeatedly.
TEST(DoAll, SupportsTypeErasedActions) {
// With only type-erased actions.
const Action<void()> initial_action = [] {};
const Action<int()> final_action = [] { return 17; };
MockFunction<int()> mock;
EXPECT_CALL(mock, Call)
.WillOnce(DoAll(initial_action, initial_action, final_action))
.WillRepeatedly(DoAll(initial_action, initial_action, final_action));
EXPECT_EQ(17, mock.AsStdFunction()());
// With &&-qualified and move-only final action.
{
struct FinalAction {
FinalAction() = default;
FinalAction(FinalAction&&) = default;
int operator()() && { return 17; }
};
EXPECT_CALL(mock, Call)
.WillOnce(DoAll(initial_action, initial_action, FinalAction{}));
EXPECT_EQ(17, mock.AsStdFunction()());
}
}
// A multi-action DoAll action should be convertible to a OnceAction, even when
// its component sub-actions are user-provided types that define only an Action
// conversion operator. If they supposed being called more than once then they
// also support being called at most once.
//
// Single-arg DoAll just returns its argument, so will prefer the Action<F>
// overload for WillOnce.
TEST(DoAll, ConvertibleToOnceActionWithUserProvidedActionConversion) {
// Final action.
struct CustomFinal final {
operator Action<int()>() { // NOLINT
return Return(17);
}
operator Action<int(int, char)>() { // NOLINT
return Return(19);
}
};
// Sub-actions.
struct CustomInitial final {
operator Action<void()>() { // NOLINT
return [] {};
}
operator Action<void(int, char)>() { // NOLINT
return [] {};
}
};
{
OnceAction<int()> action = DoAll(CustomInitial{}, CustomFinal{});
EXPECT_EQ(17, std::move(action).Call());
}
{
OnceAction<int(int, char)> action = DoAll(CustomInitial{}, CustomFinal{});
EXPECT_EQ(19, std::move(action).Call(0, 0));
}
}
// Tests using WithArgs and with an action that takes 1 argument.
TEST(WithArgsTest, OneArg) {
Action<bool(double x, int n)> a = WithArgs<1>(Unary);
EXPECT_TRUE(a.Perform(std::make_tuple(1.5, -1)));
EXPECT_FALSE(a.Perform(std::make_tuple(1.5, 1)));
}
// Tests using WithArgs with an action that takes 2 arguments.
TEST(WithArgsTest, TwoArgs) {
Action<const char*(const char* s, double x, short n)> a = // NOLINT
WithArgs<0, 2>(Binary);
const char s[] = "Hello";
EXPECT_EQ(s + 2, a.Perform(std::make_tuple(CharPtr(s), 0.5, Short(2))));
}
struct ConcatAll {
std::string operator()() const { return {}; }
template <typename... I>
std::string operator()(const char* a, I... i) const {
return a + ConcatAll()(i...);
}
};
// Tests using WithArgs with an action that takes 10 arguments.
TEST(WithArgsTest, TenArgs) {
Action<std::string(const char*, const char*, const char*, const char*)> a =
WithArgs<0, 1, 2, 3, 2, 1, 0, 1, 2, 3>(ConcatAll{});
EXPECT_EQ("0123210123",
a.Perform(std::make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
CharPtr("3"))));
}
// Tests using WithArgs with an action that is not Invoke().
class SubtractAction : public ActionInterface<int(int, int)> {
public:
int Perform(const std::tuple<int, int>& args) override {
return std::get<0>(args) - std::get<1>(args);
}
};
TEST(WithArgsTest, NonInvokeAction) {
Action<int(const std::string&, int, int)> a =
WithArgs<2, 1>(MakeAction(new SubtractAction));
std::tuple<std::string, int, int> dummy =
std::make_tuple(std::string("hi"), 2, 10);
EXPECT_EQ(8, a.Perform(dummy));
}
// Tests using WithArgs to pass all original arguments in the original order.
TEST(WithArgsTest, Identity) {
Action<int(int x, char y, short z)> a = // NOLINT
WithArgs<0, 1, 2>(Ternary);
EXPECT_EQ(123, a.Perform(std::make_tuple(100, Char(20), Short(3))));
}
// Tests using WithArgs with repeated arguments.
TEST(WithArgsTest, RepeatedArguments) {
Action<int(bool, int m, int n)> a = // NOLINT
WithArgs<1, 1, 1, 1>(SumOf4);
EXPECT_EQ(4, a.Perform(std::make_tuple(false, 1, 10)));
}
// Tests using WithArgs with reversed argument order.
TEST(WithArgsTest, ReversedArgumentOrder) {
Action<const char*(short n, const char* input)> a = // NOLINT
WithArgs<1, 0>(Binary);
const char s[] = "Hello";
EXPECT_EQ(s + 2, a.Perform(std::make_tuple(Short(2), CharPtr(s))));
}
// Tests using WithArgs with compatible, but not identical, argument types.
TEST(WithArgsTest, ArgsOfCompatibleTypes) {
Action<long(short x, char y, double z, char c)> a = // NOLINT
WithArgs<0, 1, 3>(Ternary);
EXPECT_EQ(123,
a.Perform(std::make_tuple(Short(100), Char(20), 5.6, Char(3))));
}
// Tests using WithArgs with an action that returns void.
TEST(WithArgsTest, VoidAction) {
Action<void(double x, char c, int n)> a = WithArgs<2, 1>(VoidBinary);
g_done = false;
a.Perform(std::make_tuple(1.5, 'a', 3));
EXPECT_TRUE(g_done);
}
TEST(WithArgsTest, ReturnReference) {
Action<int&(int&, void*)> aa = WithArgs<0>([](int& a) -> int& { return a; });
int i = 0;
const int& res = aa.Perform(std::forward_as_tuple(i, nullptr));
EXPECT_EQ(&i, &res);
}
TEST(WithArgsTest, InnerActionWithConversion) {
Action<Derived*()> inner = [] { return nullptr; };
MockFunction<Base*(double)> mock;
EXPECT_CALL(mock, Call)
.WillOnce(WithoutArgs(inner))
.WillRepeatedly(WithoutArgs(inner));
EXPECT_EQ(nullptr, mock.AsStdFunction()(1.1));
EXPECT_EQ(nullptr, mock.AsStdFunction()(1.1));
}
// It should be possible to use an &&-qualified inner action as long as the
// whole shebang is used as an rvalue with WillOnce.
TEST(WithArgsTest, RefQualifiedInnerAction) {
struct SomeAction {
int operator()(const int arg) && {
EXPECT_EQ(17, arg);
return 19;
}
};
MockFunction<int(int, int)> mock;
EXPECT_CALL(mock, Call).WillOnce(WithArg<1>(SomeAction{}));
EXPECT_EQ(19, mock.AsStdFunction()(0, 17));
}
// It should be fine to provide an lvalue WithArgsAction to WillOnce, even when
// the inner action only wants to convert to OnceAction.
TEST(WithArgsTest, ProvideAsLvalueToWillOnce) {
struct SomeAction {
operator OnceAction<int(int)>() const { // NOLINT
return [](const int arg) { return arg + 2; };
}
};
const auto wa = WithArg<1>(SomeAction{});
MockFunction<int(int, int)> mock;
EXPECT_CALL(mock, Call).WillOnce(wa);
EXPECT_EQ(19, mock.AsStdFunction()(0, 17));
}
#ifndef GTEST_OS_WINDOWS_MOBILE
class SetErrnoAndReturnTest : public testing::Test {
protected:
void SetUp() override { errno = 0; }
void TearDown() override { errno = 0; }
};
TEST_F(SetErrnoAndReturnTest, Int) {
Action<int(void)> a = SetErrnoAndReturn(ENOTTY, -5);
EXPECT_EQ(-5, a.Perform(std::make_tuple()));
EXPECT_EQ(ENOTTY, errno);
}
TEST_F(SetErrnoAndReturnTest, Ptr) {
int x;
Action<int*(void)> a = SetErrnoAndReturn(ENOTTY, &x);
EXPECT_EQ(&x, a.Perform(std::make_tuple()));
EXPECT_EQ(ENOTTY, errno);
}
TEST_F(SetErrnoAndReturnTest, CompatibleTypes) {
Action<double()> a = SetErrnoAndReturn(EINVAL, 5);
EXPECT_DOUBLE_EQ(5.0, a.Perform(std::make_tuple()));
EXPECT_EQ(EINVAL, errno);
}
#endif // !GTEST_OS_WINDOWS_MOBILE
// Tests ByRef().
// Tests that the result of ByRef() is copyable.
TEST(ByRefTest, IsCopyable) {
const std::string s1 = "Hi";
const std::string s2 = "Hello";
auto ref_wrapper = ByRef(s1);
const std::string& r1 = ref_wrapper;
EXPECT_EQ(&s1, &r1);
// Assigns a new value to ref_wrapper.
ref_wrapper = ByRef(s2);
const std::string& r2 = ref_wrapper;
EXPECT_EQ(&s2, &r2);
auto ref_wrapper1 = ByRef(s1);
// Copies ref_wrapper1 to ref_wrapper.
ref_wrapper = ref_wrapper1;
const std::string& r3 = ref_wrapper;
EXPECT_EQ(&s1, &r3);
}
// Tests using ByRef() on a const value.
TEST(ByRefTest, ConstValue) {
const int n = 0;
// int& ref = ByRef(n); // This shouldn't compile - we have a
// negative compilation test to catch it.
const int& const_ref = ByRef(n);
EXPECT_EQ(&n, &const_ref);
}
// Tests using ByRef() on a non-const value.
TEST(ByRefTest, NonConstValue) {
int n = 0;
// ByRef(n) can be used as either an int&,
int& ref = ByRef(n);
EXPECT_EQ(&n, &ref);
// or a const int&.
const int& const_ref = ByRef(n);
EXPECT_EQ(&n, &const_ref);
}
// Tests explicitly specifying the type when using ByRef().
TEST(ByRefTest, ExplicitType) {
int n = 0;
const int& r1 = ByRef<const int>(n);
EXPECT_EQ(&n, &r1);
// ByRef<char>(n); // This shouldn't compile - we have a negative
// compilation test to catch it.
Derived d;
Derived& r2 = ByRef<Derived>(d);
EXPECT_EQ(&d, &r2);
const Derived& r3 = ByRef<const Derived>(d);
EXPECT_EQ(&d, &r3);
Base& r4 = ByRef<Base>(d);
EXPECT_EQ(&d, &r4);
const Base& r5 = ByRef<const Base>(d);
EXPECT_EQ(&d, &r5);
// The following shouldn't compile - we have a negative compilation
// test for it.
//
// Base b;
// ByRef<Derived>(b);
}
// Tests that Google Mock prints expression ByRef(x) as a reference to x.
TEST(ByRefTest, PrintsCorrectly) {
int n = 42;
::std::stringstream expected, actual;
testing::internal::UniversalPrinter<const int&>::Print(n, &expected);
testing::internal::UniversalPrint(ByRef(n), &actual);
EXPECT_EQ(expected.str(), actual.str());
}
struct UnaryConstructorClass {
explicit UnaryConstructorClass(int v) : value(v) {}
int value;
};
// Tests using ReturnNew() with a unary constructor.
TEST(ReturnNewTest, Unary) {
Action<UnaryConstructorClass*()> a = ReturnNew<UnaryConstructorClass>(4000);
UnaryConstructorClass* c = a.Perform(std::make_tuple());
EXPECT_EQ(4000, c->value);
delete c;
}
TEST(ReturnNewTest, UnaryWorksWhenMockMethodHasArgs) {
Action<UnaryConstructorClass*(bool, int)> a =
ReturnNew<UnaryConstructorClass>(4000);
UnaryConstructorClass* c = a.Perform(std::make_tuple(false, 5));
EXPECT_EQ(4000, c->value);
delete c;
}
TEST(ReturnNewTest, UnaryWorksWhenMockMethodReturnsPointerToConst) {
Action<const UnaryConstructorClass*()> a =
ReturnNew<UnaryConstructorClass>(4000);
const UnaryConstructorClass* c = a.Perform(std::make_tuple());
EXPECT_EQ(4000, c->value);
delete c;
}
class TenArgConstructorClass {
public:
TenArgConstructorClass(int a1, int a2, int a3, int a4, int a5, int a6, int a7,
int a8, int a9, int a10)
: value_(a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10) {}
int value_;
};
// Tests using ReturnNew() with a 10-argument constructor.
TEST(ReturnNewTest, ConstructorThatTakes10Arguments) {
Action<TenArgConstructorClass*()> a = ReturnNew<TenArgConstructorClass>(
1000000000, 200000000, 30000000, 4000000, 500000, 60000, 7000, 800, 90,
0);
TenArgConstructorClass* c = a.Perform(std::make_tuple());
EXPECT_EQ(1234567890, c->value_);
delete c;
}
std::unique_ptr<int> UniquePtrSource() { return std::make_unique<int>(19); }
std::vector<std::unique_ptr<int>> VectorUniquePtrSource() {
std::vector<std::unique_ptr<int>> out;
out.emplace_back(new int(7));
return out;
}
TEST(MockMethodTest, CanReturnMoveOnlyValue_Return) {
MockClass mock;
std::unique_ptr<int> i(new int(19));
EXPECT_CALL(mock, MakeUnique()).WillOnce(Return(ByMove(std::move(i))));
EXPECT_CALL(mock, MakeVectorUnique())
.WillOnce(Return(ByMove(VectorUniquePtrSource())));
Derived* d = new Derived;
EXPECT_CALL(mock, MakeUniqueBase())
.WillOnce(Return(ByMove(std::unique_ptr<Derived>(d))));
std::unique_ptr<int> result1 = mock.MakeUnique();
EXPECT_EQ(19, *result1);
std::vector<std::unique_ptr<int>> vresult = mock.MakeVectorUnique();
EXPECT_EQ(1u, vresult.size());
EXPECT_NE(nullptr, vresult[0]);
EXPECT_EQ(7, *vresult[0]);
std::unique_ptr<Base> result2 = mock.MakeUniqueBase();
EXPECT_EQ(d, result2.get());
}
TEST(MockMethodTest, CanReturnMoveOnlyValue_DoAllReturn) {
testing::MockFunction<void()> mock_function;
MockClass mock;
std::unique_ptr<int> i(new int(19));
EXPECT_CALL(mock_function, Call());
EXPECT_CALL(mock, MakeUnique())
.WillOnce(DoAll(InvokeWithoutArgs(&mock_function,
&testing::MockFunction<void()>::Call),
Return(ByMove(std::move(i)))));
std::unique_ptr<int> result1 = mock.MakeUnique();
EXPECT_EQ(19, *result1);
}
TEST(MockMethodTest, CanReturnMoveOnlyValue_Invoke) {
MockClass mock;
// Check default value
DefaultValue<std::unique_ptr<int>>::SetFactory(
[] { return std::make_unique<int>(42); });
EXPECT_EQ(42, *mock.MakeUnique());
EXPECT_CALL(mock, MakeUnique()).WillRepeatedly(UniquePtrSource);
EXPECT_CALL(mock, MakeVectorUnique()).WillRepeatedly(VectorUniquePtrSource);
std::unique_ptr<int> result1 = mock.MakeUnique();
EXPECT_EQ(19, *result1);
std::unique_ptr<int> result2 = mock.MakeUnique();
EXPECT_EQ(19, *result2);
EXPECT_NE(result1, result2);
std::vector<std::unique_ptr<int>> vresult = mock.MakeVectorUnique();
EXPECT_EQ(1u, vresult.size());
EXPECT_NE(nullptr, vresult[0]);
EXPECT_EQ(7, *vresult[0]);
}
TEST(MockMethodTest, CanTakeMoveOnlyValue) {
MockClass mock;
auto make = [](int i) { return std::make_unique<int>(i); };
EXPECT_CALL(mock, TakeUnique(_)).WillRepeatedly([](std::unique_ptr<int> i) {
return *i;
});
// DoAll() does not compile, since it would move from its arguments twice.
// EXPECT_CALL(mock, TakeUnique(_, _))
// .WillRepeatedly(DoAll([](std::unique_ptr<int> j) {})),
// Return(1)));
EXPECT_CALL(mock, TakeUnique(testing::Pointee(7)))
.WillOnce(Return(-7))
.RetiresOnSaturation();
EXPECT_CALL(mock, TakeUnique(testing::IsNull()))
.WillOnce(Return(-1))
.RetiresOnSaturation();
EXPECT_EQ(5, mock.TakeUnique(make(5)));
EXPECT_EQ(-7, mock.TakeUnique(make(7)));
EXPECT_EQ(7, mock.TakeUnique(make(7)));
EXPECT_EQ(7, mock.TakeUnique(make(7)));
EXPECT_EQ(-1, mock.TakeUnique({}));
// Some arguments are moved, some passed by reference.
auto lvalue = make(6);
EXPECT_CALL(mock, TakeUnique(_, _))
.WillOnce([](const std::unique_ptr<int>& i, std::unique_ptr<int> j) {
return *i * *j;
});
EXPECT_EQ(42, mock.TakeUnique(lvalue, make(7)));
// The unique_ptr can be saved by the action.
std::unique_ptr<int> saved;
EXPECT_CALL(mock, TakeUnique(_)).WillOnce([&saved](std::unique_ptr<int> i) {
saved = std::move(i);
return 0;
});
EXPECT_EQ(0, mock.TakeUnique(make(42)));
EXPECT_EQ(42, *saved);
}
// It should be possible to use callables with an &&-qualified call operator
// with WillOnce, since they will be called only once. This allows actions to
// contain and manipulate move-only types.
TEST(MockMethodTest, ActionHasRvalueRefQualifiedCallOperator) {
struct Return17 {
int operator()() && { return 17; }
};
// Action is directly compatible with mocked function type.
{
MockFunction<int()> mock;
EXPECT_CALL(mock, Call).WillOnce(Return17());
EXPECT_EQ(17, mock.AsStdFunction()());
}
// Action doesn't want mocked function arguments.
{
MockFunction<int(int)> mock;
EXPECT_CALL(mock, Call).WillOnce(Return17());
EXPECT_EQ(17, mock.AsStdFunction()(0));
}
}
// Edge case: if an action has both a const-qualified and an &&-qualified call
// operator, there should be no "ambiguous call" errors. The &&-qualified
// operator should be used by WillOnce (since it doesn't need to retain the
// action beyond one call), and the const-qualified one by WillRepeatedly.
TEST(MockMethodTest, ActionHasMultipleCallOperators) {
struct ReturnInt {
int operator()() && { return 17; }
int operator()() const& { return 19; }
};
// Directly compatible with mocked function type.
{
MockFunction<int()> mock;
EXPECT_CALL(mock, Call).WillOnce(ReturnInt()).WillRepeatedly(ReturnInt());
EXPECT_EQ(17, mock.AsStdFunction()());
EXPECT_EQ(19, mock.AsStdFunction()());
EXPECT_EQ(19, mock.AsStdFunction()());
}
// Ignores function arguments.
{
MockFunction<int(int)> mock;
EXPECT_CALL(mock, Call).WillOnce(ReturnInt()).WillRepeatedly(ReturnInt());
EXPECT_EQ(17, mock.AsStdFunction()(0));
EXPECT_EQ(19, mock.AsStdFunction()(0));
EXPECT_EQ(19, mock.AsStdFunction()(0));
}
}
// WillOnce should have no problem coping with a move-only action, whether it is
// &&-qualified or not.
TEST(MockMethodTest, MoveOnlyAction) {
// &&-qualified
{
struct Return17 {
Return17() = default;
Return17(Return17&&) = default;
Return17(const Return17&) = delete;
Return17 operator=(const Return17&) = delete;
int operator()() && { return 17; }
};
MockFunction<int()> mock;
EXPECT_CALL(mock, Call).WillOnce(Return17());
EXPECT_EQ(17, mock.AsStdFunction()());
}
// Not &&-qualified
{
struct Return17 {
Return17() = default;
Return17(Return17&&) = default;
Return17(const Return17&) = delete;
Return17 operator=(const Return17&) = delete;
int operator()() const { return 17; }
};
MockFunction<int()> mock;
EXPECT_CALL(mock, Call).WillOnce(Return17());
EXPECT_EQ(17, mock.AsStdFunction()());
}
}
// It should be possible to use an action that returns a value with a mock
// function that doesn't, both through WillOnce and WillRepeatedly.
TEST(MockMethodTest, ActionReturnsIgnoredValue) {
struct ReturnInt {
int operator()() const { return 0; }
};
MockFunction<void()> mock;
EXPECT_CALL(mock, Call).WillOnce(ReturnInt()).WillRepeatedly(ReturnInt());
mock.AsStdFunction()();
mock.AsStdFunction()();
}
// Despite the fanciness around move-only actions and so on, it should still be
// possible to hand an lvalue reference to a copyable action to WillOnce.
TEST(MockMethodTest, WillOnceCanAcceptLvalueReference) {
MockFunction<int()> mock;
const auto action = [] { return 17; };
EXPECT_CALL(mock, Call).WillOnce(action);
EXPECT_EQ(17, mock.AsStdFunction()());
}
// A callable that doesn't use SFINAE to restrict its call operator's overload
// set, but is still picky about which arguments it will accept.
struct StaticAssertSingleArgument {
template <typename... Args>
static constexpr bool CheckArgs() {
static_assert(sizeof...(Args) == 1, "");
return true;
}
template <typename... Args, bool = CheckArgs<Args...>()>
int operator()(Args...) const {
return 17;
}
};
// WillOnce and WillRepeatedly should both work fine with naïve implementations
// of actions that don't use SFINAE to limit the overload set for their call
// operator. If they are compatible with the actual mocked signature, we
// shouldn't probe them with no arguments and trip a static_assert.
TEST(MockMethodTest, ActionSwallowsAllArguments) {
MockFunction<int(int)> mock;
EXPECT_CALL(mock, Call)
.WillOnce(StaticAssertSingleArgument{})
.WillRepeatedly(StaticAssertSingleArgument{});
EXPECT_EQ(17, mock.AsStdFunction()(0));
EXPECT_EQ(17, mock.AsStdFunction()(0));
}
struct ActionWithTemplatedConversionOperators {
template <typename... Args>
operator OnceAction<int(Args...)>() && { // NOLINT
return [] { return 17; };
}
template <typename... Args>
operator Action<int(Args...)>() const { // NOLINT
return [] { return 19; };
}
};
// It should be fine to hand both WillOnce and WillRepeatedly a function that
// defines templated conversion operators to OnceAction and Action. WillOnce
// should prefer the OnceAction version.
TEST(MockMethodTest, ActionHasTemplatedConversionOperators) {
MockFunction<int()> mock;
EXPECT_CALL(mock, Call)
.WillOnce(ActionWithTemplatedConversionOperators{})
.WillRepeatedly(ActionWithTemplatedConversionOperators{});
EXPECT_EQ(17, mock.AsStdFunction()());
EXPECT_EQ(19, mock.AsStdFunction()());
}
// Tests for std::function based action.
int Add(int val, int& ref, int* ptr) { // NOLINT
int result = val + ref + *ptr;
ref = 42;
*ptr = 43;
return result;
}
int Deref(std::unique_ptr<int> ptr) { return *ptr; }
struct Double {
template <typename T>
T operator()(T t) {
return 2 * t;
}
};
std::unique_ptr<int> UniqueInt(int i) { return std::make_unique<int>(i); }
TEST(FunctorActionTest, ActionFromFunction) {
Action<int(int, int&, int*)> a = &Add;
int x = 1, y = 2, z = 3;
EXPECT_EQ(6, a.Perform(std::forward_as_tuple(x, y, &z)));
EXPECT_EQ(42, y);
EXPECT_EQ(43, z);
Action<int(std::unique_ptr<int>)> a1 = &Deref;
EXPECT_EQ(7, a1.Perform(std::make_tuple(UniqueInt(7))));
}
TEST(FunctorActionTest, ActionFromLambda) {
Action<int(bool, int)> a1 = [](bool b, int i) { return b ? i : 0; };
EXPECT_EQ(5, a1.Perform(std::make_tuple(true, 5)));
EXPECT_EQ(0, a1.Perform(std::make_tuple(false, 5)));
std::unique_ptr<int> saved;
Action<void(std::unique_ptr<int>)> a2 = [&saved](std::unique_ptr<int> p) {
saved = std::move(p);
};
a2.Perform(std::make_tuple(UniqueInt(5)));
EXPECT_EQ(5, *saved);
}
TEST(FunctorActionTest, PolymorphicFunctor) {
Action<int(int)> ai = Double();
EXPECT_EQ(2, ai.Perform(std::make_tuple(1)));
Action<double(double)> ad = Double(); // Double? Double double!
EXPECT_EQ(3.0, ad.Perform(std::make_tuple(1.5)));
}
TEST(FunctorActionTest, TypeConversion) {
// Numeric promotions are allowed.
const Action<bool(int)> a1 = [](int i) { return i > 1; };
const Action<int(bool)> a2 = Action<int(bool)>(a1);
EXPECT_EQ(1, a1.Perform(std::make_tuple(42)));
EXPECT_EQ(0, a2.Perform(std::make_tuple(42)));
// Implicit constructors are allowed.
const Action<bool(std::string)> s1 = [](std::string s) { return !s.empty(); };
const Action<int(const char*)> s2 = Action<int(const char*)>(s1);
EXPECT_EQ(0, s2.Perform(std::make_tuple("")));
EXPECT_EQ(1, s2.Perform(std::make_tuple("hello")));
// Also between the lambda and the action itself.
const Action<bool(std::string)> x1 = [](Unused) { return 42; };
const Action<bool(std::string)> x2 = [] { return 42; };
EXPECT_TRUE(x1.Perform(std::make_tuple("hello")));
EXPECT_TRUE(x2.Perform(std::make_tuple("hello")));
// Ensure decay occurs where required.
std::function<int()> f = [] { return 7; };
Action<int(int)> d = f;
f = nullptr;
EXPECT_EQ(7, d.Perform(std::make_tuple(1)));
// Ensure creation of an empty action succeeds.
Action<void(int)>(nullptr);
}
TEST(FunctorActionTest, UnusedArguments) {
// Verify that users can ignore uninteresting arguments.
Action<int(int, double y, double z)> a = [](int i, Unused, Unused) {
return 2 * i;
};
std::tuple<int, double, double> dummy = std::make_tuple(3, 7.3, 9.44);
EXPECT_EQ(6, a.Perform(dummy));
}
// Test that basic built-in actions work with move-only arguments.
TEST(MoveOnlyArgumentsTest, ReturningActions) {
Action<int(std::unique_ptr<int>)> a = Return(1);
EXPECT_EQ(1, a.Perform(std::make_tuple(nullptr)));
a = testing::WithoutArgs([]() { return 7; });
EXPECT_EQ(7, a.Perform(std::make_tuple(nullptr)));
Action<void(std::unique_ptr<int>, int*)> a2 = testing::SetArgPointee<1>(3);
int x = 0;
a2.Perform(std::make_tuple(nullptr, &x));
EXPECT_EQ(x, 3);
}
ACTION(ReturnArity) { return std::tuple_size<args_type>::value; }
TEST(ActionMacro, LargeArity) {
EXPECT_EQ(
1, testing::Action<int(int)>(ReturnArity()).Perform(std::make_tuple(0)));
EXPECT_EQ(
10,
testing::Action<int(int, int, int, int, int, int, int, int, int, int)>(
ReturnArity())
.Perform(std::make_tuple(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)));
EXPECT_EQ(
20,
testing::Action<int(int, int, int, int, int, int, int, int, int, int, int,
int, int, int, int, int, int, int, int, int)>(
ReturnArity())
.Perform(std::make_tuple(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19)));
}
} // namespace
} // namespace testing
#if defined(_MSC_VER) && (_MSC_VER == 1900)
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4800
#endif
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100 4503
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Mock - a framework for writing C++ mock classes.
//
// This file tests the built-in cardinalities.
#include <ostream>
#include "gmock/gmock.h"
#include "gtest/gtest-spi.h"
#include "gtest/gtest.h"
namespace {
using std::stringstream;
using testing::AnyNumber;
using testing::AtLeast;
using testing::AtMost;
using testing::Between;
using testing::Cardinality;
using testing::CardinalityInterface;
using testing::Exactly;
using testing::IsSubstring;
using testing::MakeCardinality;
class MockFoo {
public:
MockFoo() = default;
MOCK_METHOD0(Bar, int()); // NOLINT
private:
MockFoo(const MockFoo&) = delete;
MockFoo& operator=(const MockFoo&) = delete;
};
// Tests that Cardinality objects can be default constructed.
TEST(CardinalityTest, IsDefaultConstructable) { Cardinality c; }
// Tests that Cardinality objects are copyable.
TEST(CardinalityTest, IsCopyable) {
// Tests the copy constructor.
Cardinality c = Exactly(1);
EXPECT_FALSE(c.IsSatisfiedByCallCount(0));
EXPECT_TRUE(c.IsSatisfiedByCallCount(1));
EXPECT_TRUE(c.IsSaturatedByCallCount(1));
// Tests the assignment operator.
c = Exactly(2);
EXPECT_FALSE(c.IsSatisfiedByCallCount(1));
EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
EXPECT_TRUE(c.IsSaturatedByCallCount(2));
}
TEST(CardinalityTest, IsOverSaturatedByCallCountWorks) {
const Cardinality c = AtMost(5);
EXPECT_FALSE(c.IsOverSaturatedByCallCount(4));
EXPECT_FALSE(c.IsOverSaturatedByCallCount(5));
EXPECT_TRUE(c.IsOverSaturatedByCallCount(6));
}
// Tests that Cardinality::DescribeActualCallCountTo() creates the
// correct description.
TEST(CardinalityTest, CanDescribeActualCallCount) {
stringstream ss0;
Cardinality::DescribeActualCallCountTo(0, &ss0);
EXPECT_EQ("never called", ss0.str());
stringstream ss1;
Cardinality::DescribeActualCallCountTo(1, &ss1);
EXPECT_EQ("called once", ss1.str());
stringstream ss2;
Cardinality::DescribeActualCallCountTo(2, &ss2);
EXPECT_EQ("called twice", ss2.str());
stringstream ss3;
Cardinality::DescribeActualCallCountTo(3, &ss3);
EXPECT_EQ("called 3 times", ss3.str());
}
// Tests AnyNumber()
TEST(AnyNumber, Works) {
const Cardinality c = AnyNumber();
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
EXPECT_FALSE(c.IsSaturatedByCallCount(0));
EXPECT_TRUE(c.IsSatisfiedByCallCount(1));
EXPECT_FALSE(c.IsSaturatedByCallCount(1));
EXPECT_TRUE(c.IsSatisfiedByCallCount(9));
EXPECT_FALSE(c.IsSaturatedByCallCount(9));
stringstream ss;
c.DescribeTo(&ss);
EXPECT_PRED_FORMAT2(IsSubstring, "called any number of times", ss.str());
}
TEST(AnyNumberTest, HasCorrectBounds) {
const Cardinality c = AnyNumber();
EXPECT_EQ(0, c.ConservativeLowerBound());
EXPECT_EQ(INT_MAX, c.ConservativeUpperBound());
}
// Tests AtLeast(n).
TEST(AtLeastTest, OnNegativeNumber) {
EXPECT_NONFATAL_FAILURE(
{ // NOLINT
AtLeast(-1);
},
"The invocation lower bound must be >= 0");
}
TEST(AtLeastTest, OnZero) {
const Cardinality c = AtLeast(0);
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
EXPECT_FALSE(c.IsSaturatedByCallCount(0));
EXPECT_TRUE(c.IsSatisfiedByCallCount(1));
EXPECT_FALSE(c.IsSaturatedByCallCount(1));
stringstream ss;
c.DescribeTo(&ss);
EXPECT_PRED_FORMAT2(IsSubstring, "any number of times", ss.str());
}
TEST(AtLeastTest, OnPositiveNumber) {
const Cardinality c = AtLeast(2);
EXPECT_FALSE(c.IsSatisfiedByCallCount(0));
EXPECT_FALSE(c.IsSaturatedByCallCount(0));
EXPECT_FALSE(c.IsSatisfiedByCallCount(1));
EXPECT_FALSE(c.IsSaturatedByCallCount(1));
EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
EXPECT_FALSE(c.IsSaturatedByCallCount(2));
stringstream ss1;
AtLeast(1).DescribeTo(&ss1);
EXPECT_PRED_FORMAT2(IsSubstring, "at least once", ss1.str());
stringstream ss2;
c.DescribeTo(&ss2);
EXPECT_PRED_FORMAT2(IsSubstring, "at least twice", ss2.str());
stringstream ss3;
AtLeast(3).DescribeTo(&ss3);
EXPECT_PRED_FORMAT2(IsSubstring, "at least 3 times", ss3.str());
}
TEST(AtLeastTest, HasCorrectBounds) {
const Cardinality c = AtLeast(2);
EXPECT_EQ(2, c.ConservativeLowerBound());
EXPECT_EQ(INT_MAX, c.ConservativeUpperBound());
}
// Tests AtMost(n).
TEST(AtMostTest, OnNegativeNumber) {
EXPECT_NONFATAL_FAILURE(
{ // NOLINT
AtMost(-1);
},
"The invocation upper bound must be >= 0");
}
TEST(AtMostTest, OnZero) {
const Cardinality c = AtMost(0);
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
EXPECT_TRUE(c.IsSaturatedByCallCount(0));
EXPECT_FALSE(c.IsSatisfiedByCallCount(1));
EXPECT_TRUE(c.IsSaturatedByCallCount(1));
stringstream ss;
c.DescribeTo(&ss);
EXPECT_PRED_FORMAT2(IsSubstring, "never called", ss.str());
}
TEST(AtMostTest, OnPositiveNumber) {
const Cardinality c = AtMost(2);
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
EXPECT_FALSE(c.IsSaturatedByCallCount(0));
EXPECT_TRUE(c.IsSatisfiedByCallCount(1));
EXPECT_FALSE(c.IsSaturatedByCallCount(1));
EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
EXPECT_TRUE(c.IsSaturatedByCallCount(2));
stringstream ss1;
AtMost(1).DescribeTo(&ss1);
EXPECT_PRED_FORMAT2(IsSubstring, "called at most once", ss1.str());
stringstream ss2;
c.DescribeTo(&ss2);
EXPECT_PRED_FORMAT2(IsSubstring, "called at most twice", ss2.str());
stringstream ss3;
AtMost(3).DescribeTo(&ss3);
EXPECT_PRED_FORMAT2(IsSubstring, "called at most 3 times", ss3.str());
}
TEST(AtMostTest, HasCorrectBounds) {
const Cardinality c = AtMost(2);
EXPECT_EQ(0, c.ConservativeLowerBound());
EXPECT_EQ(2, c.ConservativeUpperBound());
}
// Tests Between(m, n).
TEST(BetweenTest, OnNegativeStart) {
EXPECT_NONFATAL_FAILURE(
{ // NOLINT
Between(-1, 2);
},
"The invocation lower bound must be >= 0, but is actually -1");
}
TEST(BetweenTest, OnNegativeEnd) {
EXPECT_NONFATAL_FAILURE(
{ // NOLINT
Between(1, -2);
},
"The invocation upper bound must be >= 0, but is actually -2");
}
TEST(BetweenTest, OnStartBiggerThanEnd) {
EXPECT_NONFATAL_FAILURE(
{ // NOLINT
Between(2, 1);
},
"The invocation upper bound (1) must be >= "
"the invocation lower bound (2)");
}
TEST(BetweenTest, OnZeroStartAndZeroEnd) {
const Cardinality c = Between(0, 0);
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
EXPECT_TRUE(c.IsSaturatedByCallCount(0));
EXPECT_FALSE(c.IsSatisfiedByCallCount(1));
EXPECT_TRUE(c.IsSaturatedByCallCount(1));
stringstream ss;
c.DescribeTo(&ss);
EXPECT_PRED_FORMAT2(IsSubstring, "never called", ss.str());
}
TEST(BetweenTest, OnZeroStartAndNonZeroEnd) {
const Cardinality c = Between(0, 2);
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
EXPECT_FALSE(c.IsSaturatedByCallCount(0));
EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
EXPECT_TRUE(c.IsSaturatedByCallCount(2));
EXPECT_FALSE(c.IsSatisfiedByCallCount(4));
EXPECT_TRUE(c.IsSaturatedByCallCount(4));
stringstream ss;
c.DescribeTo(&ss);
EXPECT_PRED_FORMAT2(IsSubstring, "called at most twice", ss.str());
}
TEST(BetweenTest, OnSameStartAndEnd) {
const Cardinality c = Between(3, 3);
EXPECT_FALSE(c.IsSatisfiedByCallCount(2));
EXPECT_FALSE(c.IsSaturatedByCallCount(2));
EXPECT_TRUE(c.IsSatisfiedByCallCount(3));
EXPECT_TRUE(c.IsSaturatedByCallCount(3));
EXPECT_FALSE(c.IsSatisfiedByCallCount(4));
EXPECT_TRUE(c.IsSaturatedByCallCount(4));
stringstream ss;
c.DescribeTo(&ss);
EXPECT_PRED_FORMAT2(IsSubstring, "called 3 times", ss.str());
}
TEST(BetweenTest, OnDifferentStartAndEnd) {
const Cardinality c = Between(3, 5);
EXPECT_FALSE(c.IsSatisfiedByCallCount(2));
EXPECT_FALSE(c.IsSaturatedByCallCount(2));
EXPECT_TRUE(c.IsSatisfiedByCallCount(3));
EXPECT_FALSE(c.IsSaturatedByCallCount(3));
EXPECT_TRUE(c.IsSatisfiedByCallCount(5));
EXPECT_TRUE(c.IsSaturatedByCallCount(5));
EXPECT_FALSE(c.IsSatisfiedByCallCount(6));
EXPECT_TRUE(c.IsSaturatedByCallCount(6));
stringstream ss;
c.DescribeTo(&ss);
EXPECT_PRED_FORMAT2(IsSubstring, "called between 3 and 5 times", ss.str());
}
TEST(BetweenTest, HasCorrectBounds) {
const Cardinality c = Between(3, 5);
EXPECT_EQ(3, c.ConservativeLowerBound());
EXPECT_EQ(5, c.ConservativeUpperBound());
}
// Tests Exactly(n).
TEST(ExactlyTest, OnNegativeNumber) {
EXPECT_NONFATAL_FAILURE(
{ // NOLINT
Exactly(-1);
},
"The invocation lower bound must be >= 0");
}
TEST(ExactlyTest, OnZero) {
const Cardinality c = Exactly(0);
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
EXPECT_TRUE(c.IsSaturatedByCallCount(0));
EXPECT_FALSE(c.IsSatisfiedByCallCount(1));
EXPECT_TRUE(c.IsSaturatedByCallCount(1));
stringstream ss;
c.DescribeTo(&ss);
EXPECT_PRED_FORMAT2(IsSubstring, "never called", ss.str());
}
TEST(ExactlyTest, OnPositiveNumber) {
const Cardinality c = Exactly(2);
EXPECT_FALSE(c.IsSatisfiedByCallCount(0));
EXPECT_FALSE(c.IsSaturatedByCallCount(0));
EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
EXPECT_TRUE(c.IsSaturatedByCallCount(2));
stringstream ss1;
Exactly(1).DescribeTo(&ss1);
EXPECT_PRED_FORMAT2(IsSubstring, "called once", ss1.str());
stringstream ss2;
c.DescribeTo(&ss2);
EXPECT_PRED_FORMAT2(IsSubstring, "called twice", ss2.str());
stringstream ss3;
Exactly(3).DescribeTo(&ss3);
EXPECT_PRED_FORMAT2(IsSubstring, "called 3 times", ss3.str());
}
TEST(ExactlyTest, HasCorrectBounds) {
const Cardinality c = Exactly(3);
EXPECT_EQ(3, c.ConservativeLowerBound());
EXPECT_EQ(3, c.ConservativeUpperBound());
}
// Tests that a user can make their own cardinality by implementing
// CardinalityInterface and calling MakeCardinality().
class EvenCardinality : public CardinalityInterface {
public:
// Returns true if and only if call_count calls will satisfy this
// cardinality.
bool IsSatisfiedByCallCount(int call_count) const override {
return (call_count % 2 == 0);
}
// Returns true if and only if call_count calls will saturate this
// cardinality.
bool IsSaturatedByCallCount(int /* call_count */) const override {
return false;
}
// Describes self to an ostream.
void DescribeTo(::std::ostream* ss) const override {
*ss << "called even number of times";
}
};
TEST(MakeCardinalityTest, ConstructsCardinalityFromInterface) {
const Cardinality c = MakeCardinality(new EvenCardinality);
EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
EXPECT_FALSE(c.IsSatisfiedByCallCount(3));
EXPECT_FALSE(c.IsSaturatedByCallCount(10000));
stringstream ss;
c.DescribeTo(&ss);
EXPECT_EQ("called even number of times", ss.str());
}
} // Unnamed namespace
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Mock - a framework for writing C++ mock classes.
//
// This file tests the function mocker classes.
#include "gmock/gmock-function-mocker.h"
// Silence C4503 (decorated name length exceeded) for MSVC.
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4503)
#ifdef GTEST_OS_WINDOWS
// MSDN says the header file to be included for STDMETHOD is BaseTyps.h but
// we are getting compiler errors if we use basetyps.h, hence including
// objbase.h for definition of STDMETHOD.
#include <objbase.h>
#endif // GTEST_OS_WINDOWS
#include <functional>
#include <map>
#include <string>
#include <type_traits>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
namespace testing {
namespace gmock_function_mocker_test {
using testing::_;
using testing::A;
using testing::An;
using testing::AnyNumber;
using testing::Const;
using testing::DoDefault;
using testing::Eq;
using testing::Lt;
using testing::MockFunction;
using testing::Ref;
using testing::Return;
using testing::ReturnRef;
using testing::TypedEq;
template <typename T>
class TemplatedCopyable {
public:
TemplatedCopyable() = default;
template <typename U>
TemplatedCopyable(const U& other) {} // NOLINT
};
class FooInterface {
public:
virtual ~FooInterface() = default;
virtual void VoidReturning(int x) = 0;
virtual int Nullary() = 0;
virtual bool Unary(int x) = 0;
virtual long Binary(short x, int y) = 0; // NOLINT
virtual int Decimal(bool b, char c, short d, int e, long f, // NOLINT
float g, double h, unsigned i, char* j,
const std::string& k) = 0;
virtual bool TakesNonConstReference(int& n) = 0; // NOLINT
virtual std::string TakesConstReference(const int& n) = 0;
virtual bool TakesConst(int x) = 0;
virtual int OverloadedOnArgumentNumber() = 0;
virtual int OverloadedOnArgumentNumber(int n) = 0;
virtual int OverloadedOnArgumentType(int n) = 0;
virtual char OverloadedOnArgumentType(char c) = 0;
virtual int OverloadedOnConstness() = 0;
virtual char OverloadedOnConstness() const = 0;
virtual int TypeWithHole(int (*func)()) = 0;
virtual int TypeWithComma(const std::map<int, std::string>& a_map) = 0;
virtual int TypeWithTemplatedCopyCtor(const TemplatedCopyable<int>&) = 0;
virtual int (*ReturnsFunctionPointer1(int))(bool) = 0;
using fn_ptr = int (*)(bool);
virtual fn_ptr ReturnsFunctionPointer2(int) = 0;
virtual int RefQualifiedConstRef() const& = 0;
virtual int RefQualifiedConstRefRef() const&& = 0;
virtual int RefQualifiedRef() & = 0;
virtual int RefQualifiedRefRef() && = 0;
virtual int RefQualifiedOverloaded() const& = 0;
virtual int RefQualifiedOverloaded() const&& = 0;
virtual int RefQualifiedOverloaded() & = 0;
virtual int RefQualifiedOverloaded() && = 0;
#ifdef GTEST_OS_WINDOWS
STDMETHOD_(int, CTNullary)() = 0;
STDMETHOD_(bool, CTUnary)(int x) = 0;
STDMETHOD_(int, CTDecimal)
(bool b, char c, short d, int e, long f, // NOLINT
float g, double h, unsigned i, char* j, const std::string& k) = 0;
STDMETHOD_(char, CTConst)(int x) const = 0;
#endif // GTEST_OS_WINDOWS
};
// Const qualifiers on arguments were once (incorrectly) considered
// significant in determining whether two virtual functions had the same
// signature. This was fixed in Visual Studio 2008. However, the compiler
// still emits a warning that alerts about this change in behavior.
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4373)
class MockFoo : public FooInterface {
public:
MockFoo() = default;
// Makes sure that a mock function parameter can be named.
MOCK_METHOD(void, VoidReturning, (int n)); // NOLINT
MOCK_METHOD(int, Nullary, ()); // NOLINT
// Makes sure that a mock function parameter can be unnamed.
MOCK_METHOD(bool, Unary, (int)); // NOLINT
MOCK_METHOD(long, Binary, (short, int)); // NOLINT
MOCK_METHOD(int, Decimal,
(bool, char, short, int, long, float, // NOLINT
double, unsigned, char*, const std::string& str),
(override));
MOCK_METHOD(bool, TakesNonConstReference, (int&)); // NOLINT
MOCK_METHOD(std::string, TakesConstReference, (const int&));
MOCK_METHOD(bool, TakesConst, (const int)); // NOLINT
// Tests that the function return type can contain unprotected comma.
MOCK_METHOD((std::map<int, std::string>), ReturnTypeWithComma, (), ());
MOCK_METHOD((std::map<int, std::string>), ReturnTypeWithComma, (int),
(const)); // NOLINT
MOCK_METHOD(int, OverloadedOnArgumentNumber, ()); // NOLINT
MOCK_METHOD(int, OverloadedOnArgumentNumber, (int)); // NOLINT
MOCK_METHOD(int, OverloadedOnArgumentType, (int)); // NOLINT
MOCK_METHOD(char, OverloadedOnArgumentType, (char)); // NOLINT
MOCK_METHOD(int, OverloadedOnConstness, (), (override)); // NOLINT
MOCK_METHOD(char, OverloadedOnConstness, (), (override, const)); // NOLINT
MOCK_METHOD(int, TypeWithHole, (int (*)()), ()); // NOLINT
MOCK_METHOD(int, TypeWithComma, ((const std::map<int, std::string>&)));
MOCK_METHOD(int, TypeWithTemplatedCopyCtor,
(const TemplatedCopyable<int>&)); // NOLINT
MOCK_METHOD(int (*)(bool), ReturnsFunctionPointer1, (int), ());
MOCK_METHOD(fn_ptr, ReturnsFunctionPointer2, (int), ());
#ifdef GTEST_OS_WINDOWS
MOCK_METHOD(int, CTNullary, (), (Calltype(STDMETHODCALLTYPE)));
MOCK_METHOD(bool, CTUnary, (int), (Calltype(STDMETHODCALLTYPE)));
MOCK_METHOD(int, CTDecimal,
(bool b, char c, short d, int e, long f, float g, double h,
unsigned i, char* j, const std::string& k),
(Calltype(STDMETHODCALLTYPE)));
MOCK_METHOD(char, CTConst, (int), (const, Calltype(STDMETHODCALLTYPE)));
MOCK_METHOD((std::map<int, std::string>), CTReturnTypeWithComma, (),
(Calltype(STDMETHODCALLTYPE)));
#endif // GTEST_OS_WINDOWS
// Test reference qualified functions.
MOCK_METHOD(int, RefQualifiedConstRef, (), (const, ref(&), override));
MOCK_METHOD(int, RefQualifiedConstRefRef, (), (const, ref(&&), override));
MOCK_METHOD(int, RefQualifiedRef, (), (ref(&), override));
MOCK_METHOD(int, RefQualifiedRefRef, (), (ref(&&), override));
MOCK_METHOD(int, RefQualifiedOverloaded, (), (const, ref(&), override));
MOCK_METHOD(int, RefQualifiedOverloaded, (), (const, ref(&&), override));
MOCK_METHOD(int, RefQualifiedOverloaded, (), (ref(&), override));
MOCK_METHOD(int, RefQualifiedOverloaded, (), (ref(&&), override));
private:
MockFoo(const MockFoo&) = delete;
MockFoo& operator=(const MockFoo&) = delete;
};
class LegacyMockFoo : public FooInterface {
public:
LegacyMockFoo() = default;
// Makes sure that a mock function parameter can be named.
MOCK_METHOD1(VoidReturning, void(int n)); // NOLINT
MOCK_METHOD0(Nullary, int()); // NOLINT
// Makes sure that a mock function parameter can be unnamed.
MOCK_METHOD1(Unary, bool(int)); // NOLINT
MOCK_METHOD2(Binary, long(short, int)); // NOLINT
MOCK_METHOD10(Decimal, int(bool, char, short, int, long, float, // NOLINT
double, unsigned, char*, const std::string& str));
MOCK_METHOD1(TakesNonConstReference, bool(int&)); // NOLINT
MOCK_METHOD1(TakesConstReference, std::string(const int&));
MOCK_METHOD1(TakesConst, bool(const int)); // NOLINT
// Tests that the function return type can contain unprotected comma.
MOCK_METHOD0(ReturnTypeWithComma, std::map<int, std::string>());
MOCK_CONST_METHOD1(ReturnTypeWithComma,
std::map<int, std::string>(int)); // NOLINT
MOCK_METHOD0(OverloadedOnArgumentNumber, int()); // NOLINT
MOCK_METHOD1(OverloadedOnArgumentNumber, int(int)); // NOLINT
MOCK_METHOD1(OverloadedOnArgumentType, int(int)); // NOLINT
MOCK_METHOD1(OverloadedOnArgumentType, char(char)); // NOLINT
MOCK_METHOD0(OverloadedOnConstness, int()); // NOLINT
MOCK_CONST_METHOD0(OverloadedOnConstness, char()); // NOLINT
MOCK_METHOD1(TypeWithHole, int(int (*)())); // NOLINT
MOCK_METHOD1(TypeWithComma,
int(const std::map<int, std::string>&)); // NOLINT
MOCK_METHOD1(TypeWithTemplatedCopyCtor,
int(const TemplatedCopyable<int>&)); // NOLINT
MOCK_METHOD1(ReturnsFunctionPointer1, int (*(int))(bool));
MOCK_METHOD1(ReturnsFunctionPointer2, fn_ptr(int));
#ifdef GTEST_OS_WINDOWS
MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTNullary, int());
MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTUnary, bool(int)); // NOLINT
MOCK_METHOD10_WITH_CALLTYPE(STDMETHODCALLTYPE, CTDecimal,
int(bool b, char c, short d, int e, // NOLINT
long f, float g, double h, // NOLINT
unsigned i, char* j, const std::string& k));
MOCK_CONST_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTConst,
char(int)); // NOLINT
// Tests that the function return type can contain unprotected comma.
MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTReturnTypeWithComma,
std::map<int, std::string>());
#endif // GTEST_OS_WINDOWS
// We can't mock these with the old macros, but we need to define them to make
// it concrete.
int RefQualifiedConstRef() const& override { return 0; }
int RefQualifiedConstRefRef() const&& override { return 0; }
int RefQualifiedRef() & override { return 0; }
int RefQualifiedRefRef() && override { return 0; }
int RefQualifiedOverloaded() const& override { return 0; }
int RefQualifiedOverloaded() const&& override { return 0; }
int RefQualifiedOverloaded() & override { return 0; }
int RefQualifiedOverloaded() && override { return 0; }
private:
LegacyMockFoo(const LegacyMockFoo&) = delete;
LegacyMockFoo& operator=(const LegacyMockFoo&) = delete;
};
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4373
template <class T>
class FunctionMockerTest : public testing::Test {
protected:
FunctionMockerTest() : foo_(&mock_foo_) {}
FooInterface* const foo_;
T mock_foo_;
};
using FunctionMockerTestTypes = ::testing::Types<MockFoo, LegacyMockFoo>;
TYPED_TEST_SUITE(FunctionMockerTest, FunctionMockerTestTypes);
// Tests mocking a void-returning function.
TYPED_TEST(FunctionMockerTest, MocksVoidFunction) {
EXPECT_CALL(this->mock_foo_, VoidReturning(Lt(100)));
this->foo_->VoidReturning(0);
}
// Tests mocking a nullary function.
TYPED_TEST(FunctionMockerTest, MocksNullaryFunction) {
EXPECT_CALL(this->mock_foo_, Nullary())
.WillOnce(DoDefault())
.WillOnce(Return(1));
EXPECT_EQ(0, this->foo_->Nullary());
EXPECT_EQ(1, this->foo_->Nullary());
}
// Tests mocking a unary function.
TYPED_TEST(FunctionMockerTest, MocksUnaryFunction) {
EXPECT_CALL(this->mock_foo_, Unary(Eq(2))).Times(2).WillOnce(Return(true));
EXPECT_TRUE(this->foo_->Unary(2));
EXPECT_FALSE(this->foo_->Unary(2));
}
// Tests mocking a binary function.
TYPED_TEST(FunctionMockerTest, MocksBinaryFunction) {
EXPECT_CALL(this->mock_foo_, Binary(2, _)).WillOnce(Return(3));
EXPECT_EQ(3, this->foo_->Binary(2, 1));
}
// Tests mocking a decimal function.
TYPED_TEST(FunctionMockerTest, MocksDecimalFunction) {
EXPECT_CALL(this->mock_foo_, Decimal(true, 'a', 0, 0, 1L, A<float>(), Lt(100),
5U, nullptr, "hi"))
.WillOnce(Return(5));
EXPECT_EQ(5, this->foo_->Decimal(true, 'a', 0, 0, 1, 0, 0, 5, nullptr, "hi"));
}
// Tests mocking a function that takes a non-const reference.
TYPED_TEST(FunctionMockerTest, MocksFunctionWithNonConstReferenceArgument) {
int a = 0;
EXPECT_CALL(this->mock_foo_, TakesNonConstReference(Ref(a)))
.WillOnce(Return(true));
EXPECT_TRUE(this->foo_->TakesNonConstReference(a));
}
// Tests mocking a function that takes a const reference.
TYPED_TEST(FunctionMockerTest, MocksFunctionWithConstReferenceArgument) {
int a = 0;
EXPECT_CALL(this->mock_foo_, TakesConstReference(Ref(a)))
.WillOnce(Return("Hello"));
EXPECT_EQ("Hello", this->foo_->TakesConstReference(a));
}
// Tests mocking a function that takes a const variable.
TYPED_TEST(FunctionMockerTest, MocksFunctionWithConstArgument) {
EXPECT_CALL(this->mock_foo_, TakesConst(Lt(10))).WillOnce(DoDefault());
EXPECT_FALSE(this->foo_->TakesConst(5));
}
// Tests mocking functions overloaded on the number of arguments.
TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentNumber) {
EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentNumber())
.WillOnce(Return(1));
EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentNumber(_))
.WillOnce(Return(2));
EXPECT_EQ(2, this->foo_->OverloadedOnArgumentNumber(1));
EXPECT_EQ(1, this->foo_->OverloadedOnArgumentNumber());
}
// Tests mocking functions overloaded on the types of argument.
TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentType) {
EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentType(An<int>()))
.WillOnce(Return(1));
EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentType(TypedEq<char>('a')))
.WillOnce(Return('b'));
EXPECT_EQ(1, this->foo_->OverloadedOnArgumentType(0));
EXPECT_EQ('b', this->foo_->OverloadedOnArgumentType('a'));
}
// Tests mocking functions overloaded on the const-ness of this object.
TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnConstnessOfThis) {
EXPECT_CALL(this->mock_foo_, OverloadedOnConstness());
EXPECT_CALL(Const(this->mock_foo_), OverloadedOnConstness())
.WillOnce(Return('a'));
EXPECT_EQ(0, this->foo_->OverloadedOnConstness());
EXPECT_EQ('a', Const(*this->foo_).OverloadedOnConstness());
}
TYPED_TEST(FunctionMockerTest, MocksReturnTypeWithComma) {
const std::map<int, std::string> a_map;
EXPECT_CALL(this->mock_foo_, ReturnTypeWithComma()).WillOnce(Return(a_map));
EXPECT_CALL(this->mock_foo_, ReturnTypeWithComma(42)).WillOnce(Return(a_map));
EXPECT_EQ(a_map, this->mock_foo_.ReturnTypeWithComma());
EXPECT_EQ(a_map, this->mock_foo_.ReturnTypeWithComma(42));
}
TYPED_TEST(FunctionMockerTest, MocksTypeWithTemplatedCopyCtor) {
EXPECT_CALL(this->mock_foo_, TypeWithTemplatedCopyCtor(_))
.WillOnce(Return(true));
EXPECT_TRUE(this->foo_->TypeWithTemplatedCopyCtor(TemplatedCopyable<int>()));
}
#ifdef GTEST_OS_WINDOWS
// Tests mocking a nullary function with calltype.
TYPED_TEST(FunctionMockerTest, MocksNullaryFunctionWithCallType) {
EXPECT_CALL(this->mock_foo_, CTNullary())
.WillOnce(Return(-1))
.WillOnce(Return(0));
EXPECT_EQ(-1, this->foo_->CTNullary());
EXPECT_EQ(0, this->foo_->CTNullary());
}
// Tests mocking a unary function with calltype.
TYPED_TEST(FunctionMockerTest, MocksUnaryFunctionWithCallType) {
EXPECT_CALL(this->mock_foo_, CTUnary(Eq(2)))
.Times(2)
.WillOnce(Return(true))
.WillOnce(Return(false));
EXPECT_TRUE(this->foo_->CTUnary(2));
EXPECT_FALSE(this->foo_->CTUnary(2));
}
// Tests mocking a decimal function with calltype.
TYPED_TEST(FunctionMockerTest, MocksDecimalFunctionWithCallType) {
EXPECT_CALL(this->mock_foo_, CTDecimal(true, 'a', 0, 0, 1L, A<float>(),
Lt(100), 5U, NULL, "hi"))
.WillOnce(Return(10));
EXPECT_EQ(10, this->foo_->CTDecimal(true, 'a', 0, 0, 1, 0, 0, 5, NULL, "hi"));
}
// Tests mocking functions overloaded on the const-ness of this object.
TYPED_TEST(FunctionMockerTest, MocksFunctionsConstFunctionWithCallType) {
EXPECT_CALL(Const(this->mock_foo_), CTConst(_)).WillOnce(Return('a'));
EXPECT_EQ('a', Const(*this->foo_).CTConst(0));
}
TYPED_TEST(FunctionMockerTest, MocksReturnTypeWithCommaAndCallType) {
const std::map<int, std::string> a_map;
EXPECT_CALL(this->mock_foo_, CTReturnTypeWithComma()).WillOnce(Return(a_map));
EXPECT_EQ(a_map, this->mock_foo_.CTReturnTypeWithComma());
}
#endif // GTEST_OS_WINDOWS
TEST(FunctionMockerTest, RefQualified) {
MockFoo mock_foo;
EXPECT_CALL(mock_foo, RefQualifiedConstRef).WillOnce(Return(1));
EXPECT_CALL(std::move(mock_foo), // NOLINT
RefQualifiedConstRefRef)
.WillOnce(Return(2));
EXPECT_CALL(mock_foo, RefQualifiedRef).WillOnce(Return(3));
EXPECT_CALL(std::move(mock_foo), // NOLINT
RefQualifiedRefRef)
.WillOnce(Return(4));
EXPECT_CALL(static_cast<const MockFoo&>(mock_foo), RefQualifiedOverloaded())
.WillOnce(Return(5));
EXPECT_CALL(static_cast<const MockFoo&&>(mock_foo), RefQualifiedOverloaded())
.WillOnce(Return(6));
EXPECT_CALL(static_cast<MockFoo&>(mock_foo), RefQualifiedOverloaded())
.WillOnce(Return(7));
EXPECT_CALL(static_cast<MockFoo&&>(mock_foo), RefQualifiedOverloaded())
.WillOnce(Return(8));
EXPECT_EQ(mock_foo.RefQualifiedConstRef(), 1);
EXPECT_EQ(std::move(mock_foo).RefQualifiedConstRefRef(), 2); // NOLINT
EXPECT_EQ(mock_foo.RefQualifiedRef(), 3);
EXPECT_EQ(std::move(mock_foo).RefQualifiedRefRef(), 4); // NOLINT
EXPECT_EQ(std::cref(mock_foo).get().RefQualifiedOverloaded(), 5);
EXPECT_EQ(std::move(std::cref(mock_foo).get()) // NOLINT
.RefQualifiedOverloaded(),
6);
EXPECT_EQ(mock_foo.RefQualifiedOverloaded(), 7);
EXPECT_EQ(std::move(mock_foo).RefQualifiedOverloaded(), 8); // NOLINT
}
class MockB {
public:
MockB() = default;
MOCK_METHOD(void, DoB, ());
private:
MockB(const MockB&) = delete;
MockB& operator=(const MockB&) = delete;
};
class LegacyMockB {
public:
LegacyMockB() = default;
MOCK_METHOD0(DoB, void());
private:
LegacyMockB(const LegacyMockB&) = delete;
LegacyMockB& operator=(const LegacyMockB&) = delete;
};
template <typename T>
class ExpectCallTest : public ::testing::Test {};
using ExpectCallTestTypes = ::testing::Types<MockB, LegacyMockB>;
TYPED_TEST_SUITE(ExpectCallTest, ExpectCallTestTypes);
// Tests that functions with no EXPECT_CALL() rules can be called any
// number of times.
TYPED_TEST(ExpectCallTest, UnmentionedFunctionCanBeCalledAnyNumberOfTimes) {
{ TypeParam b; }
{
TypeParam b;
b.DoB();
}
{
TypeParam b;
b.DoB();
b.DoB();
}
}
// Tests mocking template interfaces.
template <typename T>
class StackInterface {
public:
virtual ~StackInterface() = default;
// Template parameter appears in function parameter.
virtual void Push(const T& value) = 0;
virtual void Pop() = 0;
virtual int GetSize() const = 0;
// Template parameter appears in function return type.
virtual const T& GetTop() const = 0;
};
template <typename T>
class MockStack : public StackInterface<T> {
public:
MockStack() = default;
MOCK_METHOD(void, Push, (const T& elem), ());
MOCK_METHOD(void, Pop, (), (final));
MOCK_METHOD(int, GetSize, (), (const, override));
MOCK_METHOD(const T&, GetTop, (), (const));
// Tests that the function return type can contain unprotected comma.
MOCK_METHOD((std::map<int, int>), ReturnTypeWithComma, (), ());
MOCK_METHOD((std::map<int, int>), ReturnTypeWithComma, (int), (const));
private:
MockStack(const MockStack&) = delete;
MockStack& operator=(const MockStack&) = delete;
};
template <typename T>
class LegacyMockStack : public StackInterface<T> {
public:
LegacyMockStack() = default;
MOCK_METHOD1_T(Push, void(const T& elem));
MOCK_METHOD0_T(Pop, void());
MOCK_CONST_METHOD0_T(GetSize, int()); // NOLINT
MOCK_CONST_METHOD0_T(GetTop, const T&());
// Tests that the function return type can contain unprotected comma.
MOCK_METHOD0_T(ReturnTypeWithComma, std::map<int, int>());
MOCK_CONST_METHOD1_T(ReturnTypeWithComma, std::map<int, int>(int)); // NOLINT
private:
LegacyMockStack(const LegacyMockStack&) = delete;
LegacyMockStack& operator=(const LegacyMockStack&) = delete;
};
template <typename T>
class TemplateMockTest : public ::testing::Test {};
using TemplateMockTestTypes =
::testing::Types<MockStack<int>, LegacyMockStack<int>>;
TYPED_TEST_SUITE(TemplateMockTest, TemplateMockTestTypes);
// Tests that template mock works.
TYPED_TEST(TemplateMockTest, Works) {
TypeParam mock;
EXPECT_CALL(mock, GetSize())
.WillOnce(Return(0))
.WillOnce(Return(1))
.WillOnce(Return(0));
EXPECT_CALL(mock, Push(_));
int n = 5;
EXPECT_CALL(mock, GetTop()).WillOnce(ReturnRef(n));
EXPECT_CALL(mock, Pop()).Times(AnyNumber());
EXPECT_EQ(0, mock.GetSize());
mock.Push(5);
EXPECT_EQ(1, mock.GetSize());
EXPECT_EQ(5, mock.GetTop());
mock.Pop();
EXPECT_EQ(0, mock.GetSize());
}
TYPED_TEST(TemplateMockTest, MethodWithCommaInReturnTypeWorks) {
TypeParam mock;
const std::map<int, int> a_map;
EXPECT_CALL(mock, ReturnTypeWithComma()).WillOnce(Return(a_map));
EXPECT_CALL(mock, ReturnTypeWithComma(1)).WillOnce(Return(a_map));
EXPECT_EQ(a_map, mock.ReturnTypeWithComma());
EXPECT_EQ(a_map, mock.ReturnTypeWithComma(1));
}
#ifdef GTEST_OS_WINDOWS
// Tests mocking template interfaces with calltype.
template <typename T>
class StackInterfaceWithCallType {
public:
virtual ~StackInterfaceWithCallType() {}
// Template parameter appears in function parameter.
STDMETHOD_(void, Push)(const T& value) = 0;
STDMETHOD_(void, Pop)() = 0;
STDMETHOD_(int, GetSize)() const = 0;
// Template parameter appears in function return type.
STDMETHOD_(const T&, GetTop)() const = 0;
};
template <typename T>
class MockStackWithCallType : public StackInterfaceWithCallType<T> {
public:
MockStackWithCallType() {}
MOCK_METHOD(void, Push, (const T& elem),
(Calltype(STDMETHODCALLTYPE), override));
MOCK_METHOD(void, Pop, (), (Calltype(STDMETHODCALLTYPE), override));
MOCK_METHOD(int, GetSize, (), (Calltype(STDMETHODCALLTYPE), override, const));
MOCK_METHOD(const T&, GetTop, (),
(Calltype(STDMETHODCALLTYPE), override, const));
private:
MockStackWithCallType(const MockStackWithCallType&) = delete;
MockStackWithCallType& operator=(const MockStackWithCallType&) = delete;
};
template <typename T>
class LegacyMockStackWithCallType : public StackInterfaceWithCallType<T> {
public:
LegacyMockStackWithCallType() {}
MOCK_METHOD1_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Push, void(const T& elem));
MOCK_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Pop, void());
MOCK_CONST_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, GetSize, int());
MOCK_CONST_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, GetTop, const T&());
private:
LegacyMockStackWithCallType(const LegacyMockStackWithCallType&) = delete;
LegacyMockStackWithCallType& operator=(const LegacyMockStackWithCallType&) =
delete;
};
template <typename T>
class TemplateMockTestWithCallType : public ::testing::Test {};
using TemplateMockTestWithCallTypeTypes =
::testing::Types<MockStackWithCallType<int>,
LegacyMockStackWithCallType<int>>;
TYPED_TEST_SUITE(TemplateMockTestWithCallType,
TemplateMockTestWithCallTypeTypes);
// Tests that template mock with calltype works.
TYPED_TEST(TemplateMockTestWithCallType, Works) {
TypeParam mock;
EXPECT_CALL(mock, GetSize())
.WillOnce(Return(0))
.WillOnce(Return(1))
.WillOnce(Return(0));
EXPECT_CALL(mock, Push(_));
int n = 5;
EXPECT_CALL(mock, GetTop()).WillOnce(ReturnRef(n));
EXPECT_CALL(mock, Pop()).Times(AnyNumber());
EXPECT_EQ(0, mock.GetSize());
mock.Push(5);
EXPECT_EQ(1, mock.GetSize());
EXPECT_EQ(5, mock.GetTop());
mock.Pop();
EXPECT_EQ(0, mock.GetSize());
}
#endif // GTEST_OS_WINDOWS
#define MY_MOCK_METHODS1_ \
MOCK_METHOD(void, Overloaded, ()); \
MOCK_METHOD(int, Overloaded, (int), (const)); \
MOCK_METHOD(bool, Overloaded, (bool f, int n))
#define LEGACY_MY_MOCK_METHODS1_ \
MOCK_METHOD0(Overloaded, void()); \
MOCK_CONST_METHOD1(Overloaded, int(int n)); \
MOCK_METHOD2(Overloaded, bool(bool f, int n))
class MockOverloadedOnArgNumber {
public:
MockOverloadedOnArgNumber() = default;
MY_MOCK_METHODS1_;
private:
MockOverloadedOnArgNumber(const MockOverloadedOnArgNumber&) = delete;
MockOverloadedOnArgNumber& operator=(const MockOverloadedOnArgNumber&) =
delete;
};
class LegacyMockOverloadedOnArgNumber {
public:
LegacyMockOverloadedOnArgNumber() = default;
LEGACY_MY_MOCK_METHODS1_;
private:
LegacyMockOverloadedOnArgNumber(const LegacyMockOverloadedOnArgNumber&) =
delete;
LegacyMockOverloadedOnArgNumber& operator=(
const LegacyMockOverloadedOnArgNumber&) = delete;
};
template <typename T>
class OverloadedMockMethodTest : public ::testing::Test {};
using OverloadedMockMethodTestTypes =
::testing::Types<MockOverloadedOnArgNumber,
LegacyMockOverloadedOnArgNumber>;
TYPED_TEST_SUITE(OverloadedMockMethodTest, OverloadedMockMethodTestTypes);
TYPED_TEST(OverloadedMockMethodTest, CanOverloadOnArgNumberInMacroBody) {
TypeParam mock;
EXPECT_CALL(mock, Overloaded());
EXPECT_CALL(mock, Overloaded(1)).WillOnce(Return(2));
EXPECT_CALL(mock, Overloaded(true, 1)).WillOnce(Return(true));
mock.Overloaded();
EXPECT_EQ(2, mock.Overloaded(1));
EXPECT_TRUE(mock.Overloaded(true, 1));
}
#define MY_MOCK_METHODS2_ \
MOCK_CONST_METHOD1(Overloaded, int(int n)); \
MOCK_METHOD1(Overloaded, int(int n))
class MockOverloadedOnConstness {
public:
MockOverloadedOnConstness() = default;
MY_MOCK_METHODS2_;
private:
MockOverloadedOnConstness(const MockOverloadedOnConstness&) = delete;
MockOverloadedOnConstness& operator=(const MockOverloadedOnConstness&) =
delete;
};
TEST(MockMethodOverloadedMockMethodTest, CanOverloadOnConstnessInMacroBody) {
MockOverloadedOnConstness mock;
const MockOverloadedOnConstness* const_mock = &mock;
EXPECT_CALL(mock, Overloaded(1)).WillOnce(Return(2));
EXPECT_CALL(*const_mock, Overloaded(1)).WillOnce(Return(3));
EXPECT_EQ(2, mock.Overloaded(1));
EXPECT_EQ(3, const_mock->Overloaded(1));
}
TEST(MockMethodMockFunctionTest, WorksForVoidNullary) {
MockFunction<void()> foo;
EXPECT_CALL(foo, Call());
foo.Call();
}
TEST(MockMethodMockFunctionTest, WorksForNonVoidNullary) {
MockFunction<int()> foo;
EXPECT_CALL(foo, Call()).WillOnce(Return(1)).WillOnce(Return(2));
EXPECT_EQ(1, foo.Call());
EXPECT_EQ(2, foo.Call());
}
TEST(MockMethodMockFunctionTest, WorksForVoidUnary) {
MockFunction<void(int)> foo;
EXPECT_CALL(foo, Call(1));
foo.Call(1);
}
TEST(MockMethodMockFunctionTest, WorksForNonVoidBinary) {
MockFunction<int(bool, int)> foo;
EXPECT_CALL(foo, Call(false, 42)).WillOnce(Return(1)).WillOnce(Return(2));
EXPECT_CALL(foo, Call(true, Ge(100))).WillOnce(Return(3));
EXPECT_EQ(1, foo.Call(false, 42));
EXPECT_EQ(2, foo.Call(false, 42));
EXPECT_EQ(3, foo.Call(true, 120));
}
TEST(MockMethodMockFunctionTest, WorksFor10Arguments) {
MockFunction<int(bool a0, char a1, int a2, int a3, int a4, int a5, int a6,
char a7, int a8, bool a9)>
foo;
EXPECT_CALL(foo, Call(_, 'a', _, _, _, _, _, _, _, _))
.WillOnce(Return(1))
.WillOnce(Return(2));
EXPECT_EQ(1, foo.Call(false, 'a', 0, 0, 0, 0, 0, 'b', 0, true));
EXPECT_EQ(2, foo.Call(true, 'a', 0, 0, 0, 0, 0, 'b', 1, false));
}
TEST(MockMethodMockFunctionTest, AsStdFunction) {
MockFunction<int(int)> foo;
auto call = [](const std::function<int(int)>& f, int i) { return f(i); };
EXPECT_CALL(foo, Call(1)).WillOnce(Return(-1));
EXPECT_CALL(foo, Call(2)).WillOnce(Return(-2));
EXPECT_EQ(-1, call(foo.AsStdFunction(), 1));
EXPECT_EQ(-2, call(foo.AsStdFunction(), 2));
}
TEST(MockMethodMockFunctionTest, AsStdFunctionReturnsReference) {
MockFunction<int&()> foo;
int value = 1;
EXPECT_CALL(foo, Call()).WillOnce(ReturnRef(value));
int& ref = foo.AsStdFunction()();
EXPECT_EQ(1, ref);
value = 2;
EXPECT_EQ(2, ref);
}
TEST(MockMethodMockFunctionTest, AsStdFunctionWithReferenceParameter) {
MockFunction<int(int&)> foo;
auto call = [](const std::function<int(int&)>& f, int& i) { return f(i); };
int i = 42;
EXPECT_CALL(foo, Call(i)).WillOnce(Return(-1));
EXPECT_EQ(-1, call(foo.AsStdFunction(), i));
}
namespace {
template <typename Expected, typename F>
static constexpr bool IsMockFunctionTemplateArgumentDeducedTo(
const internal::MockFunction<F>&) {
return std::is_same<F, Expected>::value;
}
} // namespace
template <typename F>
class MockMethodMockFunctionSignatureTest : public Test {};
using MockMethodMockFunctionSignatureTypes =
Types<void(), int(), void(int), int(int), int(bool, int),
int(bool, char, int, int, int, int, int, char, int, bool)>;
TYPED_TEST_SUITE(MockMethodMockFunctionSignatureTest,
MockMethodMockFunctionSignatureTypes);
TYPED_TEST(MockMethodMockFunctionSignatureTest,
IsMockFunctionTemplateArgumentDeducedForRawSignature) {
using Argument = TypeParam;
MockFunction<Argument> foo;
EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<TypeParam>(foo));
}
TYPED_TEST(MockMethodMockFunctionSignatureTest,
IsMockFunctionTemplateArgumentDeducedForStdFunction) {
using Argument = std::function<TypeParam>;
MockFunction<Argument> foo;
EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<TypeParam>(foo));
}
TYPED_TEST(
MockMethodMockFunctionSignatureTest,
IsMockFunctionCallMethodSignatureTheSameForRawSignatureAndStdFunction) {
using ForRawSignature = decltype(&MockFunction<TypeParam>::Call);
using ForStdFunction =
decltype(&MockFunction<std::function<TypeParam>>::Call);
EXPECT_TRUE((std::is_same<ForRawSignature, ForStdFunction>::value));
}
template <typename F>
struct AlternateCallable {};
TYPED_TEST(MockMethodMockFunctionSignatureTest,
IsMockFunctionTemplateArgumentDeducedForAlternateCallable) {
using Argument = AlternateCallable<TypeParam>;
MockFunction<Argument> foo;
EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<TypeParam>(foo));
}
TYPED_TEST(MockMethodMockFunctionSignatureTest,
IsMockFunctionCallMethodSignatureTheSameForAlternateCallable) {
using ForRawSignature = decltype(&MockFunction<TypeParam>::Call);
using ForStdFunction =
decltype(&MockFunction<std::function<TypeParam>>::Call);
EXPECT_TRUE((std::is_same<ForRawSignature, ForStdFunction>::value));
}
struct MockMethodSizes0 {
MOCK_METHOD(void, func, ());
};
struct MockMethodSizes1 {
MOCK_METHOD(void, func, (int));
};
struct MockMethodSizes2 {
MOCK_METHOD(void, func, (int, int));
};
struct MockMethodSizes3 {
MOCK_METHOD(void, func, (int, int, int));
};
struct MockMethodSizes4 {
MOCK_METHOD(void, func, (int, int, int, int));
};
struct LegacyMockMethodSizes0 {
MOCK_METHOD0(func, void());
};
struct LegacyMockMethodSizes1 {
MOCK_METHOD1(func, void(int));
};
struct LegacyMockMethodSizes2 {
MOCK_METHOD2(func, void(int, int));
};
struct LegacyMockMethodSizes3 {
MOCK_METHOD3(func, void(int, int, int));
};
struct LegacyMockMethodSizes4 {
MOCK_METHOD4(func, void(int, int, int, int));
};
TEST(MockMethodMockFunctionTest, MockMethodSizeOverhead) {
EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes1));
EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes2));
EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes3));
EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes4));
EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes1));
EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes2));
EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes3));
EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes4));
EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(MockMethodSizes0));
}
TEST(MockMethodMockFunctionTest, EnsureNoUnusedMemberFunction) {
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic error "-Wunused-member-function"
#endif
// https://github.com/google/googletest/issues/4052
struct Foo {
MOCK_METHOD(void, foo, ());
};
EXPECT_CALL(Foo(), foo()).Times(0);
#ifdef __clang__
#pragma clang diagnostic pop
#endif
}
void hasTwoParams(int, int);
void MaybeThrows();
void DoesntThrow() noexcept;
struct MockMethodNoexceptSpecifier {
MOCK_METHOD(void, func1, (), (noexcept));
MOCK_METHOD(void, func2, (), (noexcept(true)));
MOCK_METHOD(void, func3, (), (noexcept(false)));
MOCK_METHOD(void, func4, (), (noexcept(noexcept(MaybeThrows()))));
MOCK_METHOD(void, func5, (), (noexcept(noexcept(DoesntThrow()))));
MOCK_METHOD(void, func6, (), (noexcept(noexcept(DoesntThrow())), const));
MOCK_METHOD(void, func7, (), (const, noexcept(noexcept(DoesntThrow()))));
// Put commas in the noexcept expression
MOCK_METHOD(void, func8, (), (noexcept(noexcept(hasTwoParams(1, 2))), const));
};
TEST(MockMethodMockFunctionTest, NoexceptSpecifierPreserved) {
EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func1()));
EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func2()));
EXPECT_FALSE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func3()));
EXPECT_FALSE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func4()));
EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func5()));
EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func6()));
EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func7()));
EXPECT_EQ(noexcept(std::declval<MockMethodNoexceptSpecifier>().func8()),
noexcept(hasTwoParams(1, 2)));
}
} // namespace gmock_function_mocker_test
} // namespace testing
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4503
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Mock - a framework for writing C++ mock classes.
//
// This file tests the internal utilities.
#include "gmock/internal/gmock-internal-utils.h"
#include <stdlib.h>
#include <cstdint>
#include <map>
#include <memory>
#include <sstream>
#include <string>
#include <tuple>
#include <vector>
#include "gmock/gmock.h"
#include "gmock/internal/gmock-port.h"
#include "gtest/gtest-spi.h"
#include "gtest/gtest.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_
#ifdef GTEST_OS_CYGWIN
#include <sys/types.h> // For ssize_t. NOLINT
#endif
namespace proto2 {
class Message;
} // namespace proto2
namespace testing {
namespace internal {
namespace {
TEST(JoinAsKeyValueTupleTest, JoinsEmptyTuple) {
EXPECT_EQ("", JoinAsKeyValueTuple({}, Strings()));
}
TEST(JoinAsKeyValueTupleTest, JoinsOneTuple) {
EXPECT_EQ("(a: 1)", JoinAsKeyValueTuple({"a"}, {"1"}));
}
TEST(JoinAsKeyValueTupleTest, JoinsTwoTuple) {
EXPECT_EQ("(a: 1, b: 2)", JoinAsKeyValueTuple({"a", "b"}, {"1", "2"}));
}
TEST(JoinAsKeyValueTupleTest, JoinsTenTuple) {
EXPECT_EQ(
"(a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10)",
JoinAsKeyValueTuple({"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"},
{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}));
}
TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameContainsNoWord) {
EXPECT_EQ("", ConvertIdentifierNameToWords(""));
EXPECT_EQ("", ConvertIdentifierNameToWords("_"));
EXPECT_EQ("", ConvertIdentifierNameToWords("__"));
}
TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameContainsDigits) {
EXPECT_EQ("1", ConvertIdentifierNameToWords("_1"));
EXPECT_EQ("2", ConvertIdentifierNameToWords("2_"));
EXPECT_EQ("34", ConvertIdentifierNameToWords("_34_"));
EXPECT_EQ("34 56", ConvertIdentifierNameToWords("_34_56"));
}
TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameContainsCamelCaseWords) {
EXPECT_EQ("a big word", ConvertIdentifierNameToWords("ABigWord"));
EXPECT_EQ("foo bar", ConvertIdentifierNameToWords("FooBar"));
EXPECT_EQ("foo", ConvertIdentifierNameToWords("Foo_"));
EXPECT_EQ("foo bar", ConvertIdentifierNameToWords("_Foo_Bar_"));
EXPECT_EQ("foo and bar", ConvertIdentifierNameToWords("_Foo__And_Bar"));
}
TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameContains_SeparatedWords) {
EXPECT_EQ("foo bar", ConvertIdentifierNameToWords("foo_bar"));
EXPECT_EQ("foo", ConvertIdentifierNameToWords("_foo_"));
EXPECT_EQ("foo bar", ConvertIdentifierNameToWords("_foo_bar_"));
EXPECT_EQ("foo and bar", ConvertIdentifierNameToWords("_foo__and_bar"));
}
TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameIsMixture) {
EXPECT_EQ("foo bar 123", ConvertIdentifierNameToWords("Foo_bar123"));
EXPECT_EQ("chapter 11 section 1",
ConvertIdentifierNameToWords("_Chapter11Section_1_"));
}
TEST(GetRawPointerTest, WorksForSmartPointers) {
const char* const raw_p1 = new const char('a'); // NOLINT
const std::unique_ptr<const char> p1(raw_p1);
EXPECT_EQ(raw_p1, GetRawPointer(p1));
double* const raw_p2 = new double(2.5); // NOLINT
const std::shared_ptr<double> p2(raw_p2);
EXPECT_EQ(raw_p2, GetRawPointer(p2));
}
TEST(GetRawPointerTest, WorksForRawPointers) {
int* p = nullptr;
EXPECT_TRUE(nullptr == GetRawPointer(p));
int n = 1;
EXPECT_EQ(&n, GetRawPointer(&n));
}
TEST(GetRawPointerTest, WorksForStdReferenceWrapper) {
int n = 1;
EXPECT_EQ(&n, GetRawPointer(std::ref(n)));
EXPECT_EQ(&n, GetRawPointer(std::cref(n)));
}
// Tests KindOf<T>.
class Base {};
class Derived : public Base {};
TEST(KindOfTest, Bool) {
EXPECT_EQ(kBool, GMOCK_KIND_OF_(bool)); // NOLINT
}
TEST(KindOfTest, Integer) {
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(char)); // NOLINT
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(signed char)); // NOLINT
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(unsigned char)); // NOLINT
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(short)); // NOLINT
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(unsigned short)); // NOLINT
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(int)); // NOLINT
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(unsigned int)); // NOLINT
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(long)); // NOLINT
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(unsigned long)); // NOLINT
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(long long)); // NOLINT
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(unsigned long long)); // NOLINT
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(wchar_t)); // NOLINT
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(size_t)); // NOLINT
#if defined(GTEST_OS_LINUX) || defined(GTEST_OS_MAC) || defined(GTEST_OS_CYGWIN)
// ssize_t is not defined on Windows and possibly some other OSes.
EXPECT_EQ(kInteger, GMOCK_KIND_OF_(ssize_t)); // NOLINT
#endif
}
TEST(KindOfTest, FloatingPoint) {
EXPECT_EQ(kFloatingPoint, GMOCK_KIND_OF_(float)); // NOLINT
EXPECT_EQ(kFloatingPoint, GMOCK_KIND_OF_(double)); // NOLINT
EXPECT_EQ(kFloatingPoint, GMOCK_KIND_OF_(long double)); // NOLINT
}
TEST(KindOfTest, Other) {
EXPECT_EQ(kOther, GMOCK_KIND_OF_(void*)); // NOLINT
EXPECT_EQ(kOther, GMOCK_KIND_OF_(char**)); // NOLINT
EXPECT_EQ(kOther, GMOCK_KIND_OF_(Base)); // NOLINT
}
// Tests LosslessArithmeticConvertible<T, U>.
TEST(LosslessArithmeticConvertibleTest, BoolToBool) {
EXPECT_TRUE((LosslessArithmeticConvertible<bool, bool>::value));
}
TEST(LosslessArithmeticConvertibleTest, BoolToInteger) {
EXPECT_TRUE((LosslessArithmeticConvertible<bool, char>::value));
EXPECT_TRUE((LosslessArithmeticConvertible<bool, int>::value));
EXPECT_TRUE(
(LosslessArithmeticConvertible<bool, unsigned long>::value)); // NOLINT
}
TEST(LosslessArithmeticConvertibleTest, BoolToFloatingPoint) {
EXPECT_TRUE((LosslessArithmeticConvertible<bool, float>::value));
EXPECT_TRUE((LosslessArithmeticConvertible<bool, double>::value));
}
TEST(LosslessArithmeticConvertibleTest, IntegerToBool) {
EXPECT_FALSE((LosslessArithmeticConvertible<unsigned char, bool>::value));
EXPECT_FALSE((LosslessArithmeticConvertible<int, bool>::value));
}
TEST(LosslessArithmeticConvertibleTest, IntegerToInteger) {
// Unsigned => larger signed is fine.
EXPECT_TRUE((LosslessArithmeticConvertible<unsigned char, int>::value));
// Unsigned => larger unsigned is fine.
EXPECT_TRUE((LosslessArithmeticConvertible<unsigned short,
uint64_t>::value)); // NOLINT
// Signed => unsigned is not fine.
EXPECT_FALSE(
(LosslessArithmeticConvertible<short, uint64_t>::value)); // NOLINT
EXPECT_FALSE((LosslessArithmeticConvertible<signed char,
unsigned int>::value)); // NOLINT
// Same size and same signedness: fine too.
EXPECT_TRUE(
(LosslessArithmeticConvertible<unsigned char, unsigned char>::value));
EXPECT_TRUE((LosslessArithmeticConvertible<int, int>::value));
EXPECT_TRUE((LosslessArithmeticConvertible<wchar_t, wchar_t>::value));
EXPECT_TRUE((LosslessArithmeticConvertible<unsigned long,
unsigned long>::value)); // NOLINT
// Same size, different signedness: not fine.
EXPECT_FALSE(
(LosslessArithmeticConvertible<unsigned char, signed char>::value));
EXPECT_FALSE((LosslessArithmeticConvertible<int, unsigned int>::value));
EXPECT_FALSE((LosslessArithmeticConvertible<uint64_t, int64_t>::value));
// Larger size => smaller size is not fine.
EXPECT_FALSE((LosslessArithmeticConvertible<long, char>::value)); // NOLINT
EXPECT_FALSE((LosslessArithmeticConvertible<int, signed char>::value));
EXPECT_FALSE((LosslessArithmeticConvertible<int64_t, unsigned int>::value));
}
TEST(LosslessArithmeticConvertibleTest, IntegerToFloatingPoint) {
// Integers cannot be losslessly converted to floating-points, as
// the format of the latter is implementation-defined.
EXPECT_FALSE((LosslessArithmeticConvertible<char, float>::value));
EXPECT_FALSE((LosslessArithmeticConvertible<int, double>::value));
EXPECT_FALSE(
(LosslessArithmeticConvertible<short, long double>::value)); // NOLINT
}
TEST(LosslessArithmeticConvertibleTest, FloatingPointToBool) {
EXPECT_FALSE((LosslessArithmeticConvertible<float, bool>::value));
EXPECT_FALSE((LosslessArithmeticConvertible<double, bool>::value));
}
TEST(LosslessArithmeticConvertibleTest, FloatingPointToInteger) {
EXPECT_FALSE((LosslessArithmeticConvertible<float, long>::value)); // NOLINT
EXPECT_FALSE((LosslessArithmeticConvertible<double, int64_t>::value));
EXPECT_FALSE((LosslessArithmeticConvertible<long double, int>::value));
}
TEST(LosslessArithmeticConvertibleTest, FloatingPointToFloatingPoint) {
// Smaller size => larger size is fine.
EXPECT_TRUE((LosslessArithmeticConvertible<float, double>::value));
EXPECT_TRUE((LosslessArithmeticConvertible<float, long double>::value));
EXPECT_TRUE((LosslessArithmeticConvertible<double, long double>::value));
// Same size: fine.
EXPECT_TRUE((LosslessArithmeticConvertible<float, float>::value));
EXPECT_TRUE((LosslessArithmeticConvertible<double, double>::value));
// Larger size => smaller size is not fine.
EXPECT_FALSE((LosslessArithmeticConvertible<double, float>::value));
GTEST_INTENTIONAL_CONST_COND_PUSH_()
if (sizeof(double) == sizeof(long double)) { // NOLINT
GTEST_INTENTIONAL_CONST_COND_POP_()
// In some implementations (e.g. MSVC), double and long double
// have the same size.
EXPECT_TRUE((LosslessArithmeticConvertible<long double, double>::value));
} else {
EXPECT_FALSE((LosslessArithmeticConvertible<long double, double>::value));
}
}
// Tests the TupleMatches() template function.
TEST(TupleMatchesTest, WorksForSize0) {
std::tuple<> matchers;
std::tuple<> values;
EXPECT_TRUE(TupleMatches(matchers, values));
}
TEST(TupleMatchesTest, WorksForSize1) {
std::tuple<Matcher<int>> matchers(Eq(1));
std::tuple<int> values1(1), values2(2);
EXPECT_TRUE(TupleMatches(matchers, values1));
EXPECT_FALSE(TupleMatches(matchers, values2));
}
TEST(TupleMatchesTest, WorksForSize2) {
std::tuple<Matcher<int>, Matcher<char>> matchers(Eq(1), Eq('a'));
std::tuple<int, char> values1(1, 'a'), values2(1, 'b'), values3(2, 'a'),
values4(2, 'b');
EXPECT_TRUE(TupleMatches(matchers, values1));
EXPECT_FALSE(TupleMatches(matchers, values2));
EXPECT_FALSE(TupleMatches(matchers, values3));
EXPECT_FALSE(TupleMatches(matchers, values4));
}
TEST(TupleMatchesTest, WorksForSize5) {
std::tuple<Matcher<int>, Matcher<char>, Matcher<bool>,
Matcher<long>, // NOLINT
Matcher<std::string>>
matchers(Eq(1), Eq('a'), Eq(true), Eq(2L), Eq("hi"));
std::tuple<int, char, bool, long, std::string> // NOLINT
values1(1, 'a', true, 2L, "hi"), values2(1, 'a', true, 2L, "hello"),
values3(2, 'a', true, 2L, "hi");
EXPECT_TRUE(TupleMatches(matchers, values1));
EXPECT_FALSE(TupleMatches(matchers, values2));
EXPECT_FALSE(TupleMatches(matchers, values3));
}
// Tests that Assert(true, ...) succeeds.
TEST(AssertTest, SucceedsOnTrue) {
Assert(true, __FILE__, __LINE__, "This should succeed.");
Assert(true, __FILE__, __LINE__); // This should succeed too.
}
// Tests that Assert(false, ...) generates a fatal failure.
TEST(AssertTest, FailsFatallyOnFalse) {
EXPECT_DEATH_IF_SUPPORTED(
{ Assert(false, __FILE__, __LINE__, "This should fail."); }, "");
EXPECT_DEATH_IF_SUPPORTED({ Assert(false, __FILE__, __LINE__); }, "");
}
// Tests that Expect(true, ...) succeeds.
TEST(ExpectTest, SucceedsOnTrue) {
Expect(true, __FILE__, __LINE__, "This should succeed.");
Expect(true, __FILE__, __LINE__); // This should succeed too.
}
// Tests that Expect(false, ...) generates a non-fatal failure.
TEST(ExpectTest, FailsNonfatallyOnFalse) {
EXPECT_NONFATAL_FAILURE(
{ // NOLINT
Expect(false, __FILE__, __LINE__, "This should fail.");
},
"This should fail");
EXPECT_NONFATAL_FAILURE(
{ // NOLINT
Expect(false, __FILE__, __LINE__);
},
"Expectation failed");
}
// Tests LogIsVisible().
class LogIsVisibleTest : public ::testing::Test {
protected:
void SetUp() override { original_verbose_ = GMOCK_FLAG_GET(verbose); }
void TearDown() override { GMOCK_FLAG_SET(verbose, original_verbose_); }
std::string original_verbose_;
};
TEST_F(LogIsVisibleTest, AlwaysReturnsTrueIfVerbosityIsInfo) {
GMOCK_FLAG_SET(verbose, kInfoVerbosity);
EXPECT_TRUE(LogIsVisible(kInfo));
EXPECT_TRUE(LogIsVisible(kWarning));
}
TEST_F(LogIsVisibleTest, AlwaysReturnsFalseIfVerbosityIsError) {
GMOCK_FLAG_SET(verbose, kErrorVerbosity);
EXPECT_FALSE(LogIsVisible(kInfo));
EXPECT_FALSE(LogIsVisible(kWarning));
}
TEST_F(LogIsVisibleTest, WorksWhenVerbosityIsWarning) {
GMOCK_FLAG_SET(verbose, kWarningVerbosity);
EXPECT_FALSE(LogIsVisible(kInfo));
EXPECT_TRUE(LogIsVisible(kWarning));
}
#if GTEST_HAS_STREAM_REDIRECTION
// Tests the Log() function.
// Verifies that Log() behaves correctly for the given verbosity level
// and log severity.
void TestLogWithSeverity(const std::string& verbosity, LogSeverity severity,
bool should_print) {
const std::string old_flag = GMOCK_FLAG_GET(verbose);
GMOCK_FLAG_SET(verbose, verbosity);
CaptureStdout();
Log(severity, "Test log.\n", 0);
if (should_print) {
EXPECT_THAT(
GetCapturedStdout().c_str(),
ContainsRegex(severity == kWarning
? "^\nGMOCK WARNING:\nTest log\\.\nStack trace:\n"
: "^\nTest log\\.\nStack trace:\n"));
} else {
EXPECT_STREQ("", GetCapturedStdout().c_str());
}
GMOCK_FLAG_SET(verbose, old_flag);
}
// Tests that when the stack_frames_to_skip parameter is negative,
// Log() doesn't include the stack trace in the output.
TEST(LogTest, NoStackTraceWhenStackFramesToSkipIsNegative) {
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
GMOCK_FLAG_SET(verbose, kInfoVerbosity);
CaptureStdout();
Log(kInfo, "Test log.\n", -1);
EXPECT_STREQ("\nTest log.\n", GetCapturedStdout().c_str());
GMOCK_FLAG_SET(verbose, saved_flag);
}
struct MockStackTraceGetter : testing::internal::OsStackTraceGetterInterface {
std::string CurrentStackTrace(int max_depth, int skip_count) override {
return (testing::Message() << max_depth << "::" << skip_count << "\n")
.GetString();
}
void UponLeavingGTest() override {}
};
// Tests that in opt mode, a positive stack_frames_to_skip argument is
// treated as 0.
TEST(LogTest, NoSkippingStackFrameInOptMode) {
MockStackTraceGetter* mock_os_stack_trace_getter = new MockStackTraceGetter;
GetUnitTestImpl()->set_os_stack_trace_getter(mock_os_stack_trace_getter);
CaptureStdout();
Log(kWarning, "Test log.\n", 100);
const std::string log = GetCapturedStdout();
std::string expected_trace =
(testing::Message() << GTEST_FLAG_GET(stack_trace_depth) << "::")
.GetString();
std::string expected_message =
"\nGMOCK WARNING:\n"
"Test log.\n"
"Stack trace:\n" +
expected_trace;
EXPECT_THAT(log, HasSubstr(expected_message));
int skip_count = atoi(log.substr(expected_message.size()).c_str());
#if defined(NDEBUG)
// In opt mode, no stack frame should be skipped.
const int expected_skip_count = 0;
#else
// In dbg mode, the stack frames should be skipped.
const int expected_skip_count = 100;
#endif
// Note that each inner implementation layer will +1 the number to remove
// itself from the trace. This means that the value is a little higher than
// expected, but close enough.
EXPECT_THAT(skip_count,
AllOf(Ge(expected_skip_count), Le(expected_skip_count + 10)));
// Restores the default OS stack trace getter.
GetUnitTestImpl()->set_os_stack_trace_getter(nullptr);
}
// Tests that all logs are printed when the value of the
// --gmock_verbose flag is "info".
TEST(LogTest, AllLogsArePrintedWhenVerbosityIsInfo) {
TestLogWithSeverity(kInfoVerbosity, kInfo, true);
TestLogWithSeverity(kInfoVerbosity, kWarning, true);
}
// Tests that only warnings are printed when the value of the
// --gmock_verbose flag is "warning".
TEST(LogTest, OnlyWarningsArePrintedWhenVerbosityIsWarning) {
TestLogWithSeverity(kWarningVerbosity, kInfo, false);
TestLogWithSeverity(kWarningVerbosity, kWarning, true);
}
// Tests that no logs are printed when the value of the
// --gmock_verbose flag is "error".
TEST(LogTest, NoLogsArePrintedWhenVerbosityIsError) {
TestLogWithSeverity(kErrorVerbosity, kInfo, false);
TestLogWithSeverity(kErrorVerbosity, kWarning, false);
}
// Tests that only warnings are printed when the value of the
// --gmock_verbose flag is invalid.
TEST(LogTest, OnlyWarningsArePrintedWhenVerbosityIsInvalid) {
TestLogWithSeverity("invalid", kInfo, false);
TestLogWithSeverity("invalid", kWarning, true);
}
// Verifies that Log() behaves correctly for the given verbosity level
// and log severity.
std::string GrabOutput(void (*logger)(), const char* verbosity) {
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
GMOCK_FLAG_SET(verbose, verbosity);
CaptureStdout();
logger();
GMOCK_FLAG_SET(verbose, saved_flag);
return GetCapturedStdout();
}
class DummyMock {
public:
MOCK_METHOD0(TestMethod, void());
MOCK_METHOD1(TestMethodArg, void(int dummy));
};
void ExpectCallLogger() {
DummyMock mock;
EXPECT_CALL(mock, TestMethod());
mock.TestMethod();
}
// Verifies that EXPECT_CALL logs if the --gmock_verbose flag is set to "info".
TEST(ExpectCallTest, LogsWhenVerbosityIsInfo) {
EXPECT_THAT(std::string(GrabOutput(ExpectCallLogger, kInfoVerbosity)),
HasSubstr("EXPECT_CALL(mock, TestMethod())"));
}
// Verifies that EXPECT_CALL doesn't log
// if the --gmock_verbose flag is set to "warning".
TEST(ExpectCallTest, DoesNotLogWhenVerbosityIsWarning) {
EXPECT_STREQ("", GrabOutput(ExpectCallLogger, kWarningVerbosity).c_str());
}
// Verifies that EXPECT_CALL doesn't log
// if the --gmock_verbose flag is set to "error".
TEST(ExpectCallTest, DoesNotLogWhenVerbosityIsError) {
EXPECT_STREQ("", GrabOutput(ExpectCallLogger, kErrorVerbosity).c_str());
}
void OnCallLogger() {
DummyMock mock;
ON_CALL(mock, TestMethod());
}
// Verifies that ON_CALL logs if the --gmock_verbose flag is set to "info".
TEST(OnCallTest, LogsWhenVerbosityIsInfo) {
EXPECT_THAT(std::string(GrabOutput(OnCallLogger, kInfoVerbosity)),
HasSubstr("ON_CALL(mock, TestMethod())"));
}
// Verifies that ON_CALL doesn't log
// if the --gmock_verbose flag is set to "warning".
TEST(OnCallTest, DoesNotLogWhenVerbosityIsWarning) {
EXPECT_STREQ("", GrabOutput(OnCallLogger, kWarningVerbosity).c_str());
}
// Verifies that ON_CALL doesn't log if
// the --gmock_verbose flag is set to "error".
TEST(OnCallTest, DoesNotLogWhenVerbosityIsError) {
EXPECT_STREQ("", GrabOutput(OnCallLogger, kErrorVerbosity).c_str());
}
void OnCallAnyArgumentLogger() {
DummyMock mock;
ON_CALL(mock, TestMethodArg(_));
}
// Verifies that ON_CALL prints provided _ argument.
TEST(OnCallTest, LogsAnythingArgument) {
EXPECT_THAT(std::string(GrabOutput(OnCallAnyArgumentLogger, kInfoVerbosity)),
HasSubstr("ON_CALL(mock, TestMethodArg(_)"));
}
#endif // GTEST_HAS_STREAM_REDIRECTION
// Tests StlContainerView.
TEST(StlContainerViewTest, WorksForStlContainer) {
StaticAssertTypeEq<std::vector<int>,
StlContainerView<std::vector<int>>::type>();
StaticAssertTypeEq<const std::vector<double>&,
StlContainerView<std::vector<double>>::const_reference>();
typedef std::vector<char> Chars;
Chars v1;
const Chars& v2(StlContainerView<Chars>::ConstReference(v1));
EXPECT_EQ(&v1, &v2);
v1.push_back('a');
Chars v3 = StlContainerView<Chars>::Copy(v1);
EXPECT_THAT(v3, Eq(v3));
}
TEST(StlContainerViewTest, WorksForStaticNativeArray) {
StaticAssertTypeEq<NativeArray<int>, StlContainerView<int[3]>::type>();
StaticAssertTypeEq<NativeArray<double>,
StlContainerView<const double[4]>::type>();
StaticAssertTypeEq<NativeArray<char[3]>,
StlContainerView<const char[2][3]>::type>();
StaticAssertTypeEq<const NativeArray<int>,
StlContainerView<int[2]>::const_reference>();
int a1[3] = {0, 1, 2};
NativeArray<int> a2 = StlContainerView<int[3]>::ConstReference(a1);
EXPECT_EQ(3U, a2.size());
EXPECT_EQ(a1, a2.begin());
const NativeArray<int> a3 = StlContainerView<int[3]>::Copy(a1);
ASSERT_EQ(3U, a3.size());
EXPECT_EQ(0, a3.begin()[0]);
EXPECT_EQ(1, a3.begin()[1]);
EXPECT_EQ(2, a3.begin()[2]);
// Makes sure a1 and a3 aren't aliases.
a1[0] = 3;
EXPECT_EQ(0, a3.begin()[0]);
}
TEST(StlContainerViewTest, WorksForDynamicNativeArray) {
StaticAssertTypeEq<NativeArray<int>,
StlContainerView<std::tuple<const int*, size_t>>::type>();
StaticAssertTypeEq<
NativeArray<double>,
StlContainerView<std::tuple<std::shared_ptr<double>, int>>::type>();
StaticAssertTypeEq<
const NativeArray<int>,
StlContainerView<std::tuple<const int*, int>>::const_reference>();
int a1[3] = {0, 1, 2};
const int* const p1 = a1;
NativeArray<int> a2 =
StlContainerView<std::tuple<const int*, int>>::ConstReference(
std::make_tuple(p1, 3));
EXPECT_EQ(3U, a2.size());
EXPECT_EQ(a1, a2.begin());
const NativeArray<int> a3 = StlContainerView<std::tuple<int*, size_t>>::Copy(
std::make_tuple(static_cast<int*>(a1), 3));
ASSERT_EQ(3U, a3.size());
EXPECT_EQ(0, a3.begin()[0]);
EXPECT_EQ(1, a3.begin()[1]);
EXPECT_EQ(2, a3.begin()[2]);
// Makes sure a1 and a3 aren't aliases.
a1[0] = 3;
EXPECT_EQ(0, a3.begin()[0]);
}
// Tests the Function template struct.
TEST(FunctionTest, Nullary) {
typedef Function<int()> F; // NOLINT
EXPECT_EQ(0u, F::ArgumentCount);
EXPECT_TRUE((std::is_same<int, F::Result>::value));
EXPECT_TRUE((std::is_same<std::tuple<>, F::ArgumentTuple>::value));
EXPECT_TRUE((std::is_same<std::tuple<>, F::ArgumentMatcherTuple>::value));
EXPECT_TRUE((std::is_same<void(), F::MakeResultVoid>::value));
EXPECT_TRUE((std::is_same<IgnoredValue(), F::MakeResultIgnoredValue>::value));
}
TEST(FunctionTest, Unary) {
typedef Function<int(bool)> F; // NOLINT
EXPECT_EQ(1u, F::ArgumentCount);
EXPECT_TRUE((std::is_same<int, F::Result>::value));
EXPECT_TRUE((std::is_same<bool, F::Arg<0>::type>::value));
EXPECT_TRUE((std::is_same<std::tuple<bool>, F::ArgumentTuple>::value));
EXPECT_TRUE((
std::is_same<std::tuple<Matcher<bool>>, F::ArgumentMatcherTuple>::value));
EXPECT_TRUE((std::is_same<void(bool), F::MakeResultVoid>::value)); // NOLINT
EXPECT_TRUE((std::is_same<IgnoredValue(bool), // NOLINT
F::MakeResultIgnoredValue>::value));
}
TEST(FunctionTest, Binary) {
typedef Function<int(bool, const long&)> F; // NOLINT
EXPECT_EQ(2u, F::ArgumentCount);
EXPECT_TRUE((std::is_same<int, F::Result>::value));
EXPECT_TRUE((std::is_same<bool, F::Arg<0>::type>::value));
EXPECT_TRUE((std::is_same<const long&, F::Arg<1>::type>::value)); // NOLINT
EXPECT_TRUE((std::is_same<std::tuple<bool, const long&>, // NOLINT
F::ArgumentTuple>::value));
EXPECT_TRUE(
(std::is_same<std::tuple<Matcher<bool>, Matcher<const long&>>, // NOLINT
F::ArgumentMatcherTuple>::value));
EXPECT_TRUE((std::is_same<void(bool, const long&), // NOLINT
F::MakeResultVoid>::value));
EXPECT_TRUE((std::is_same<IgnoredValue(bool, const long&), // NOLINT
F::MakeResultIgnoredValue>::value));
}
TEST(FunctionTest, LongArgumentList) {
typedef Function<char(bool, int, char*, int&, const long&)> F; // NOLINT
EXPECT_EQ(5u, F::ArgumentCount);
EXPECT_TRUE((std::is_same<char, F::Result>::value));
EXPECT_TRUE((std::is_same<bool, F::Arg<0>::type>::value));
EXPECT_TRUE((std::is_same<int, F::Arg<1>::type>::value));
EXPECT_TRUE((std::is_same<char*, F::Arg<2>::type>::value));
EXPECT_TRUE((std::is_same<int&, F::Arg<3>::type>::value));
EXPECT_TRUE((std::is_same<const long&, F::Arg<4>::type>::value)); // NOLINT
EXPECT_TRUE(
(std::is_same<std::tuple<bool, int, char*, int&, const long&>, // NOLINT
F::ArgumentTuple>::value));
EXPECT_TRUE(
(std::is_same<
std::tuple<Matcher<bool>, Matcher<int>, Matcher<char*>, Matcher<int&>,
Matcher<const long&>>, // NOLINT
F::ArgumentMatcherTuple>::value));
EXPECT_TRUE(
(std::is_same<void(bool, int, char*, int&, const long&), // NOLINT
F::MakeResultVoid>::value));
EXPECT_TRUE((
std::is_same<IgnoredValue(bool, int, char*, int&, const long&), // NOLINT
F::MakeResultIgnoredValue>::value));
}
TEST(Base64Unescape, InvalidString) {
std::string unescaped;
EXPECT_FALSE(Base64Unescape("(invalid)", &unescaped));
}
TEST(Base64Unescape, ShortString) {
std::string unescaped;
EXPECT_TRUE(Base64Unescape("SGVsbG8gd29ybGQh", &unescaped));
EXPECT_EQ("Hello world!", unescaped);
}
TEST(Base64Unescape, ShortStringWithPadding) {
std::string unescaped;
EXPECT_TRUE(Base64Unescape("SGVsbG8gd29ybGQ=", &unescaped));
EXPECT_EQ("Hello world", unescaped);
}
TEST(Base64Unescape, ShortStringWithoutPadding) {
std::string unescaped;
EXPECT_TRUE(Base64Unescape("SGVsbG8gd29ybGQ", &unescaped));
EXPECT_EQ("Hello world", unescaped);
}
TEST(Base64Unescape, LongStringWithWhiteSpaces) {
std::string escaped =
R"(TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz
IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg
dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu
dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo
ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=)";
std::string expected =
"Man is distinguished, not only by his reason, but by this singular "
"passion from other animals, which is a lust of the mind, that by a "
"perseverance of delight in the continued and indefatigable generation "
"of knowledge, exceeds the short vehemence of any carnal pleasure.";
std::string unescaped;
EXPECT_TRUE(Base64Unescape(escaped, &unescaped));
EXPECT_EQ(expected, unescaped);
}
} // namespace
} // namespace internal
} // namespace testing
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Mock - a framework for writing C++ mock classes.
//
// This file tests some commonly used argument matchers.
#include <cmath>
#include <limits>
#include <memory>
#include <ostream>
#include <string>
#include "gmock/gmock.h"
#include "test/gmock-matchers_test.h"
#include "gtest/gtest.h"
// Silence warning C4244: 'initializing': conversion from 'int' to 'short',
// possible loss of data and C4100, unreferenced local parameter
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4244 4100)
namespace testing {
namespace gmock_matchers_test {
namespace {
typedef ::std::tuple<long, int> Tuple2; // NOLINT
// Tests that Eq() matches a 2-tuple where the first field == the
// second field.
TEST(Eq2Test, MatchesEqualArguments) {
Matcher<const Tuple2&> m = Eq();
EXPECT_TRUE(m.Matches(Tuple2(5L, 5)));
EXPECT_FALSE(m.Matches(Tuple2(5L, 6)));
}
// Tests that Eq() describes itself properly.
TEST(Eq2Test, CanDescribeSelf) {
Matcher<const Tuple2&> m = Eq();
EXPECT_EQ("are an equal pair", Describe(m));
}
// Tests that Ge() matches a 2-tuple where the first field >= the
// second field.
TEST(Ge2Test, MatchesGreaterThanOrEqualArguments) {
Matcher<const Tuple2&> m = Ge();
EXPECT_TRUE(m.Matches(Tuple2(5L, 4)));
EXPECT_TRUE(m.Matches(Tuple2(5L, 5)));
EXPECT_FALSE(m.Matches(Tuple2(5L, 6)));
}
// Tests that Ge() describes itself properly.
TEST(Ge2Test, CanDescribeSelf) {
Matcher<const Tuple2&> m = Ge();
EXPECT_EQ("are a pair where the first >= the second", Describe(m));
}
// Tests that Gt() matches a 2-tuple where the first field > the
// second field.
TEST(Gt2Test, MatchesGreaterThanArguments) {
Matcher<const Tuple2&> m = Gt();
EXPECT_TRUE(m.Matches(Tuple2(5L, 4)));
EXPECT_FALSE(m.Matches(Tuple2(5L, 5)));
EXPECT_FALSE(m.Matches(Tuple2(5L, 6)));
}
// Tests that Gt() describes itself properly.
TEST(Gt2Test, CanDescribeSelf) {
Matcher<const Tuple2&> m = Gt();
EXPECT_EQ("are a pair where the first > the second", Describe(m));
}
// Tests that Le() matches a 2-tuple where the first field <= the
// second field.
TEST(Le2Test, MatchesLessThanOrEqualArguments) {
Matcher<const Tuple2&> m = Le();
EXPECT_TRUE(m.Matches(Tuple2(5L, 6)));
EXPECT_TRUE(m.Matches(Tuple2(5L, 5)));
EXPECT_FALSE(m.Matches(Tuple2(5L, 4)));
}
// Tests that Le() describes itself properly.
TEST(Le2Test, CanDescribeSelf) {
Matcher<const Tuple2&> m = Le();
EXPECT_EQ("are a pair where the first <= the second", Describe(m));
}
// Tests that Lt() matches a 2-tuple where the first field < the
// second field.
TEST(Lt2Test, MatchesLessThanArguments) {
Matcher<const Tuple2&> m = Lt();
EXPECT_TRUE(m.Matches(Tuple2(5L, 6)));
EXPECT_FALSE(m.Matches(Tuple2(5L, 5)));
EXPECT_FALSE(m.Matches(Tuple2(5L, 4)));
}
// Tests that Lt() describes itself properly.
TEST(Lt2Test, CanDescribeSelf) {
Matcher<const Tuple2&> m = Lt();
EXPECT_EQ("are a pair where the first < the second", Describe(m));
}
// Tests that Ne() matches a 2-tuple where the first field != the
// second field.
TEST(Ne2Test, MatchesUnequalArguments) {
Matcher<const Tuple2&> m = Ne();
EXPECT_TRUE(m.Matches(Tuple2(5L, 6)));
EXPECT_TRUE(m.Matches(Tuple2(5L, 4)));
EXPECT_FALSE(m.Matches(Tuple2(5L, 5)));
}
// Tests that Ne() describes itself properly.
TEST(Ne2Test, CanDescribeSelf) {
Matcher<const Tuple2&> m = Ne();
EXPECT_EQ("are an unequal pair", Describe(m));
}
TEST(PairMatchBaseTest, WorksWithMoveOnly) {
using Pointers = std::tuple<std::unique_ptr<int>, std::unique_ptr<int>>;
Matcher<Pointers> matcher = Eq();
Pointers pointers;
// Tested values don't matter; the point is that matcher does not copy the
// matched values.
EXPECT_TRUE(matcher.Matches(pointers));
}
// Tests that IsNan() matches a NaN, with float.
TEST(IsNan, FloatMatchesNan) {
float quiet_nan = std::numeric_limits<float>::quiet_NaN();
float other_nan = std::nanf("1");
float real_value = 1.0f;
Matcher<float> m = IsNan();
EXPECT_TRUE(m.Matches(quiet_nan));
EXPECT_TRUE(m.Matches(other_nan));
EXPECT_FALSE(m.Matches(real_value));
Matcher<float&> m_ref = IsNan();
EXPECT_TRUE(m_ref.Matches(quiet_nan));
EXPECT_TRUE(m_ref.Matches(other_nan));
EXPECT_FALSE(m_ref.Matches(real_value));
Matcher<const float&> m_cref = IsNan();
EXPECT_TRUE(m_cref.Matches(quiet_nan));
EXPECT_TRUE(m_cref.Matches(other_nan));
EXPECT_FALSE(m_cref.Matches(real_value));
}
// Tests that IsNan() matches a NaN, with double.
TEST(IsNan, DoubleMatchesNan) {
double quiet_nan = std::numeric_limits<double>::quiet_NaN();
double other_nan = std::nan("1");
double real_value = 1.0;
Matcher<double> m = IsNan();
EXPECT_TRUE(m.Matches(quiet_nan));
EXPECT_TRUE(m.Matches(other_nan));
EXPECT_FALSE(m.Matches(real_value));
Matcher<double&> m_ref = IsNan();
EXPECT_TRUE(m_ref.Matches(quiet_nan));
EXPECT_TRUE(m_ref.Matches(other_nan));
EXPECT_FALSE(m_ref.Matches(real_value));
Matcher<const double&> m_cref = IsNan();
EXPECT_TRUE(m_cref.Matches(quiet_nan));
EXPECT_TRUE(m_cref.Matches(other_nan));
EXPECT_FALSE(m_cref.Matches(real_value));
}
// Tests that IsNan() matches a NaN, with long double.
TEST(IsNan, LongDoubleMatchesNan) {
long double quiet_nan = std::numeric_limits<long double>::quiet_NaN();
long double other_nan = std::nan("1");
long double real_value = 1.0;
Matcher<long double> m = IsNan();
EXPECT_TRUE(m.Matches(quiet_nan));
EXPECT_TRUE(m.Matches(other_nan));
EXPECT_FALSE(m.Matches(real_value));
Matcher<long double&> m_ref = IsNan();
EXPECT_TRUE(m_ref.Matches(quiet_nan));
EXPECT_TRUE(m_ref.Matches(other_nan));
EXPECT_FALSE(m_ref.Matches(real_value));
Matcher<const long double&> m_cref = IsNan();
EXPECT_TRUE(m_cref.Matches(quiet_nan));
EXPECT_TRUE(m_cref.Matches(other_nan));
EXPECT_FALSE(m_cref.Matches(real_value));
}
// Tests that IsNan() works with Not.
TEST(IsNan, NotMatchesNan) {
Matcher<float> mf = Not(IsNan());
EXPECT_FALSE(mf.Matches(std::numeric_limits<float>::quiet_NaN()));
EXPECT_FALSE(mf.Matches(std::nanf("1")));
EXPECT_TRUE(mf.Matches(1.0));
Matcher<double> md = Not(IsNan());
EXPECT_FALSE(md.Matches(std::numeric_limits<double>::quiet_NaN()));
EXPECT_FALSE(md.Matches(std::nan("1")));
EXPECT_TRUE(md.Matches(1.0));
Matcher<long double> mld = Not(IsNan());
EXPECT_FALSE(mld.Matches(std::numeric_limits<long double>::quiet_NaN()));
EXPECT_FALSE(mld.Matches(std::nanl("1")));
EXPECT_TRUE(mld.Matches(1.0));
}
// Tests that IsNan() can describe itself.
TEST(IsNan, CanDescribeSelf) {
Matcher<float> mf = IsNan();
EXPECT_EQ("is NaN", Describe(mf));
Matcher<double> md = IsNan();
EXPECT_EQ("is NaN", Describe(md));
Matcher<long double> mld = IsNan();
EXPECT_EQ("is NaN", Describe(mld));
}
// Tests that IsNan() can describe itself with Not.
TEST(IsNan, CanDescribeSelfWithNot) {
Matcher<float> mf = Not(IsNan());
EXPECT_EQ("isn't NaN", Describe(mf));
Matcher<double> md = Not(IsNan());
EXPECT_EQ("isn't NaN", Describe(md));
Matcher<long double> mld = Not(IsNan());
EXPECT_EQ("isn't NaN", Describe(mld));
}
// Tests that FloatEq() matches a 2-tuple where
// FloatEq(first field) matches the second field.
TEST(FloatEq2Test, MatchesEqualArguments) {
typedef ::std::tuple<float, float> Tpl;
Matcher<const Tpl&> m = FloatEq();
EXPECT_TRUE(m.Matches(Tpl(1.0f, 1.0f)));
EXPECT_TRUE(m.Matches(Tpl(0.3f, 0.1f + 0.1f + 0.1f)));
EXPECT_FALSE(m.Matches(Tpl(1.1f, 1.0f)));
}
// Tests that FloatEq() describes itself properly.
TEST(FloatEq2Test, CanDescribeSelf) {
Matcher<const ::std::tuple<float, float>&> m = FloatEq();
EXPECT_EQ("are an almost-equal pair", Describe(m));
}
// Tests that NanSensitiveFloatEq() matches a 2-tuple where
// NanSensitiveFloatEq(first field) matches the second field.
TEST(NanSensitiveFloatEqTest, MatchesEqualArgumentsWithNaN) {
typedef ::std::tuple<float, float> Tpl;
Matcher<const Tpl&> m = NanSensitiveFloatEq();
EXPECT_TRUE(m.Matches(Tpl(1.0f, 1.0f)));
EXPECT_TRUE(m.Matches(Tpl(std::numeric_limits<float>::quiet_NaN(),
std::numeric_limits<float>::quiet_NaN())));
EXPECT_FALSE(m.Matches(Tpl(1.1f, 1.0f)));
EXPECT_FALSE(m.Matches(Tpl(1.0f, std::numeric_limits<float>::quiet_NaN())));
EXPECT_FALSE(m.Matches(Tpl(std::numeric_limits<float>::quiet_NaN(), 1.0f)));
}
// Tests that NanSensitiveFloatEq() describes itself properly.
TEST(NanSensitiveFloatEqTest, CanDescribeSelfWithNaNs) {
Matcher<const ::std::tuple<float, float>&> m = NanSensitiveFloatEq();
EXPECT_EQ("are an almost-equal pair", Describe(m));
}
// Tests that DoubleEq() matches a 2-tuple where
// DoubleEq(first field) matches the second field.
TEST(DoubleEq2Test, MatchesEqualArguments) {
typedef ::std::tuple<double, double> Tpl;
Matcher<const Tpl&> m = DoubleEq();
EXPECT_TRUE(m.Matches(Tpl(1.0, 1.0)));
EXPECT_TRUE(m.Matches(Tpl(0.3, 0.1 + 0.1 + 0.1)));
EXPECT_FALSE(m.Matches(Tpl(1.1, 1.0)));
}
// Tests that DoubleEq() describes itself properly.
TEST(DoubleEq2Test, CanDescribeSelf) {
Matcher<const ::std::tuple<double, double>&> m = DoubleEq();
EXPECT_EQ("are an almost-equal pair", Describe(m));
}
// Tests that NanSensitiveDoubleEq() matches a 2-tuple where
// NanSensitiveDoubleEq(first field) matches the second field.
TEST(NanSensitiveDoubleEqTest, MatchesEqualArgumentsWithNaN) {
typedef ::std::tuple<double, double> Tpl;
Matcher<const Tpl&> m = NanSensitiveDoubleEq();
EXPECT_TRUE(m.Matches(Tpl(1.0f, 1.0f)));
EXPECT_TRUE(m.Matches(Tpl(std::numeric_limits<double>::quiet_NaN(),
std::numeric_limits<double>::quiet_NaN())));
EXPECT_FALSE(m.Matches(Tpl(1.1f, 1.0f)));
EXPECT_FALSE(m.Matches(Tpl(1.0f, std::numeric_limits<double>::quiet_NaN())));
EXPECT_FALSE(m.Matches(Tpl(std::numeric_limits<double>::quiet_NaN(), 1.0f)));
}
// Tests that DoubleEq() describes itself properly.
TEST(NanSensitiveDoubleEqTest, CanDescribeSelfWithNaNs) {
Matcher<const ::std::tuple<double, double>&> m = NanSensitiveDoubleEq();
EXPECT_EQ("are an almost-equal pair", Describe(m));
}
// Tests that FloatEq() matches a 2-tuple where
// FloatNear(first field, max_abs_error) matches the second field.
TEST(FloatNear2Test, MatchesEqualArguments) {
typedef ::std::tuple<float, float> Tpl;
Matcher<const Tpl&> m = FloatNear(0.5f);
EXPECT_TRUE(m.Matches(Tpl(1.0f, 1.0f)));
EXPECT_TRUE(m.Matches(Tpl(1.3f, 1.0f)));
EXPECT_FALSE(m.Matches(Tpl(1.8f, 1.0f)));
}
// Tests that FloatNear() describes itself properly.
TEST(FloatNear2Test, CanDescribeSelf) {
Matcher<const ::std::tuple<float, float>&> m = FloatNear(0.5f);
EXPECT_EQ("are an almost-equal pair", Describe(m));
}
// Tests that NanSensitiveFloatNear() matches a 2-tuple where
// NanSensitiveFloatNear(first field) matches the second field.
TEST(NanSensitiveFloatNearTest, MatchesNearbyArgumentsWithNaN) {
typedef ::std::tuple<float, float> Tpl;
Matcher<const Tpl&> m = NanSensitiveFloatNear(0.5f);
EXPECT_TRUE(m.Matches(Tpl(1.0f, 1.0f)));
EXPECT_TRUE(m.Matches(Tpl(1.1f, 1.0f)));
EXPECT_TRUE(m.Matches(Tpl(std::numeric_limits<float>::quiet_NaN(),
std::numeric_limits<float>::quiet_NaN())));
EXPECT_FALSE(m.Matches(Tpl(1.6f, 1.0f)));
EXPECT_FALSE(m.Matches(Tpl(1.0f, std::numeric_limits<float>::quiet_NaN())));
EXPECT_FALSE(m.Matches(Tpl(std::numeric_limits<float>::quiet_NaN(), 1.0f)));
}
// Tests that NanSensitiveFloatNear() describes itself properly.
TEST(NanSensitiveFloatNearTest, CanDescribeSelfWithNaNs) {
Matcher<const ::std::tuple<float, float>&> m = NanSensitiveFloatNear(0.5f);
EXPECT_EQ("are an almost-equal pair", Describe(m));
}
// Tests that FloatEq() matches a 2-tuple where
// DoubleNear(first field, max_abs_error) matches the second field.
TEST(DoubleNear2Test, MatchesEqualArguments) {
typedef ::std::tuple<double, double> Tpl;
Matcher<const Tpl&> m = DoubleNear(0.5);
EXPECT_TRUE(m.Matches(Tpl(1.0, 1.0)));
EXPECT_TRUE(m.Matches(Tpl(1.3, 1.0)));
EXPECT_FALSE(m.Matches(Tpl(1.8, 1.0)));
}
// Tests that DoubleNear() describes itself properly.
TEST(DoubleNear2Test, CanDescribeSelf) {
Matcher<const ::std::tuple<double, double>&> m = DoubleNear(0.5);
EXPECT_EQ("are an almost-equal pair", Describe(m));
}
// Tests that NanSensitiveDoubleNear() matches a 2-tuple where
// NanSensitiveDoubleNear(first field) matches the second field.
TEST(NanSensitiveDoubleNearTest, MatchesNearbyArgumentsWithNaN) {
typedef ::std::tuple<double, double> Tpl;
Matcher<const Tpl&> m = NanSensitiveDoubleNear(0.5f);
EXPECT_TRUE(m.Matches(Tpl(1.0f, 1.0f)));
EXPECT_TRUE(m.Matches(Tpl(1.1f, 1.0f)));
EXPECT_TRUE(m.Matches(Tpl(std::numeric_limits<double>::quiet_NaN(),
std::numeric_limits<double>::quiet_NaN())));
EXPECT_FALSE(m.Matches(Tpl(1.6f, 1.0f)));
EXPECT_FALSE(m.Matches(Tpl(1.0f, std::numeric_limits<double>::quiet_NaN())));
EXPECT_FALSE(m.Matches(Tpl(std::numeric_limits<double>::quiet_NaN(), 1.0f)));
}
// Tests that NanSensitiveDoubleNear() describes itself properly.
TEST(NanSensitiveDoubleNearTest, CanDescribeSelfWithNaNs) {
Matcher<const ::std::tuple<double, double>&> m = NanSensitiveDoubleNear(0.5f);
EXPECT_EQ("are an almost-equal pair", Describe(m));
}
// Tests that DistanceFrom() can describe itself properly.
TEST(DistanceFrom, CanDescribeSelf) {
Matcher<double> m = DistanceFrom(1.5, Lt(0.1));
EXPECT_EQ(Describe(m), "is < 0.1 away from 1.5");
m = DistanceFrom(2.5, Gt(0.2));
EXPECT_EQ(Describe(m), "is > 0.2 away from 2.5");
}
// Tests that DistanceFrom() can explain match failure.
TEST(DistanceFrom, CanExplainMatchFailure) {
Matcher<double> m = DistanceFrom(1.5, Lt(0.1));
EXPECT_EQ(Explain(m, 2.0), "which is 0.5 away from 1.5");
}
// Tests that DistanceFrom() matches a double that is within the given range of
// the given value.
TEST(DistanceFrom, MatchesDoubleWithinRange) {
const Matcher<double> m = DistanceFrom(0.5, Le(0.1));
EXPECT_TRUE(m.Matches(0.45));
EXPECT_TRUE(m.Matches(0.5));
EXPECT_TRUE(m.Matches(0.55));
EXPECT_FALSE(m.Matches(0.39));
EXPECT_FALSE(m.Matches(0.61));
}
// Tests that DistanceFrom() matches a double reference that is within the given
// range of the given value.
TEST(DistanceFrom, MatchesDoubleRefWithinRange) {
const Matcher<const double&> m = DistanceFrom(0.5, Le(0.1));
EXPECT_TRUE(m.Matches(0.45));
EXPECT_TRUE(m.Matches(0.5));
EXPECT_TRUE(m.Matches(0.55));
EXPECT_FALSE(m.Matches(0.39));
EXPECT_FALSE(m.Matches(0.61));
}
// Tests that DistanceFrom() can be implicitly converted to a matcher depending
// on the type of the argument.
TEST(DistanceFrom, CanBeImplicitlyConvertedToMatcher) {
EXPECT_THAT(0.58, DistanceFrom(0.5, Le(0.1)));
EXPECT_THAT(0.2, Not(DistanceFrom(0.5, Le(0.1))));
EXPECT_THAT(0.58f, DistanceFrom(0.5f, Le(0.1f)));
EXPECT_THAT(0.7f, Not(DistanceFrom(0.5f, Le(0.1f))));
}
// Tests that DistanceFrom() can be used on compatible types (i.e. not
// everything has to be of the same type).
TEST(DistanceFrom, CanBeUsedOnCompatibleTypes) {
EXPECT_THAT(0.58, DistanceFrom(0.5, Le(0.1f)));
EXPECT_THAT(0.2, Not(DistanceFrom(0.5, Le(0.1f))));
EXPECT_THAT(0.58, DistanceFrom(0.5f, Le(0.1)));
EXPECT_THAT(0.2, Not(DistanceFrom(0.5f, Le(0.1))));
EXPECT_THAT(0.58, DistanceFrom(0.5f, Le(0.1f)));
EXPECT_THAT(0.2, Not(DistanceFrom(0.5f, Le(0.1f))));
EXPECT_THAT(0.58f, DistanceFrom(0.5, Le(0.1)));
EXPECT_THAT(0.2f, Not(DistanceFrom(0.5, Le(0.1))));
EXPECT_THAT(0.58f, DistanceFrom(0.5, Le(0.1f)));
EXPECT_THAT(0.2f, Not(DistanceFrom(0.5, Le(0.1f))));
EXPECT_THAT(0.58f, DistanceFrom(0.5f, Le(0.1)));
EXPECT_THAT(0.2f, Not(DistanceFrom(0.5f, Le(0.1))));
}
// A 2-dimensional point. For testing using DistanceFrom() with a custom type
// that doesn't have a built-in distance function.
class Point {
public:
Point(double x, double y) : x_(x), y_(y) {}
double x() const { return x_; }
double y() const { return y_; }
private:
double x_;
double y_;
};
// Returns the distance between two points.
double PointDistance(const Point& lhs, const Point& rhs) {
return std::sqrt(std::pow(lhs.x() - rhs.x(), 2) +
std::pow(lhs.y() - rhs.y(), 2));
}
// Tests that DistanceFrom() can be used on a type with a custom distance
// function.
TEST(DistanceFrom, CanBeUsedOnTypeWithCustomDistanceFunction) {
const Matcher<Point> m =
DistanceFrom(Point(0.5, 0.5), PointDistance, Le(0.1));
EXPECT_THAT(Point(0.45, 0.45), m);
EXPECT_THAT(Point(0.2, 0.45), Not(m));
}
// A wrapper around a double value. For testing using DistanceFrom() with a
// custom type that has neither a built-in distance function nor a built-in
// distance comparator.
class Double {
public:
explicit Double(double value) : value_(value) {}
Double(const Double& other) = default;
double value() const { return value_; }
// Defines how to print a Double value. We don't use the AbslStringify API
// because googletest doesn't require absl yet.
friend void PrintTo(const Double& value, std::ostream* os) {
*os << "Double(" << value.value() << ")";
}
private:
double value_;
};
// Returns the distance between two Double values.
Double DoubleDistance(Double lhs, Double rhs) {
return Double(std::abs(lhs.value() - rhs.value()));
}
MATCHER_P(DoubleLe, rhs, (negation ? "is > " : "is <= ") + PrintToString(rhs)) {
return arg.value() <= rhs.value();
}
// Tests that DistanceFrom() can describe itself properly for a type with a
// custom printer.
TEST(DistanceFrom, CanDescribeWithCustomPrinter) {
const Matcher<Double> m =
DistanceFrom(Double(0.5), DoubleDistance, DoubleLe(Double(0.1)));
EXPECT_EQ(Describe(m), "is <= Double(0.1) away from Double(0.5)");
EXPECT_EQ(DescribeNegation(m), "is > Double(0.1) away from Double(0.5)");
}
// Tests that DistanceFrom() can be used with a custom distance function and
// comparator.
TEST(DistanceFrom, CanCustomizeDistanceAndComparator) {
const Matcher<Double> m =
DistanceFrom(Double(0.5), DoubleDistance, DoubleLe(Double(0.1)));
EXPECT_TRUE(m.Matches(Double(0.45)));
EXPECT_TRUE(m.Matches(Double(0.5)));
EXPECT_FALSE(m.Matches(Double(0.39)));
EXPECT_FALSE(m.Matches(Double(0.61)));
}
// For testing using DistanceFrom() with a type that supports both - and abs.
class Float {
public:
explicit Float(float value) : value_(value) {}
Float(const Float& other) = default;
float value() const { return value_; }
private:
float value_ = 0.0f;
};
// Returns the difference between two Float values. This must be defined in the
// same namespace as Float.
Float operator-(const Float& lhs, const Float& rhs) {
return Float(lhs.value() - rhs.value());
}
// Returns the absolute value of a Float value. This must be defined in the
// same namespace as Float.
Float abs(Float value) { return Float(std::abs(value.value())); }
// Returns true if and only if the first Float value is less than the second
// Float value. This must be defined in the same namespace as Float.
bool operator<(const Float& lhs, const Float& rhs) {
return lhs.value() < rhs.value();
}
// Tests that DistanceFrom() can be used with a type that supports both - and
// abs.
TEST(DistanceFrom, CanBeUsedWithTypeThatSupportsBothMinusAndAbs) {
const Matcher<Float> m = DistanceFrom(Float(0.5f), Lt(Float(0.1f)));
EXPECT_TRUE(m.Matches(Float(0.45f)));
EXPECT_TRUE(m.Matches(Float(0.55f)));
EXPECT_FALSE(m.Matches(Float(0.39f)));
EXPECT_FALSE(m.Matches(Float(0.61f)));
}
// Tests that Not(m) matches any value that doesn't match m.
TEST(NotTest, NegatesMatcher) {
Matcher<int> m;
m = Not(Eq(2));
EXPECT_TRUE(m.Matches(3));
EXPECT_FALSE(m.Matches(2));
}
// Tests that Not(m) describes itself properly.
TEST(NotTest, CanDescribeSelf) {
Matcher<int> m = Not(Eq(5));
EXPECT_EQ("isn't equal to 5", Describe(m));
}
// Tests that monomorphic matchers are safely cast by the Not matcher.
TEST(NotTest, NotMatcherSafelyCastsMonomorphicMatchers) {
// greater_than_5 is a monomorphic matcher.
Matcher<int> greater_than_5 = Gt(5);
Matcher<const int&> m = Not(greater_than_5);
Matcher<int&> m2 = Not(greater_than_5);
Matcher<int&> m3 = Not(m);
}
// Helper to allow easy testing of AllOf matchers with num parameters.
void AllOfMatches(int num, const Matcher<int>& m) {
SCOPED_TRACE(Describe(m));
EXPECT_TRUE(m.Matches(0));
for (int i = 1; i <= num; ++i) {
EXPECT_FALSE(m.Matches(i));
}
EXPECT_TRUE(m.Matches(num + 1));
}
INSTANTIATE_GTEST_MATCHER_TEST_P(AllOfTest);
// Tests that AllOf(m1, ..., mn) matches any value that matches all of
// the given matchers.
TEST(AllOfTest, MatchesWhenAllMatch) {
Matcher<int> m;
m = AllOf(Le(2), Ge(1));
EXPECT_TRUE(m.Matches(1));
EXPECT_TRUE(m.Matches(2));
EXPECT_FALSE(m.Matches(0));
EXPECT_FALSE(m.Matches(3));
m = AllOf(Gt(0), Ne(1), Ne(2));
EXPECT_TRUE(m.Matches(3));
EXPECT_FALSE(m.Matches(2));
EXPECT_FALSE(m.Matches(1));
EXPECT_FALSE(m.Matches(0));
m = AllOf(Gt(0), Ne(1), Ne(2), Ne(3));
EXPECT_TRUE(m.Matches(4));
EXPECT_FALSE(m.Matches(3));
EXPECT_FALSE(m.Matches(2));
EXPECT_FALSE(m.Matches(1));
EXPECT_FALSE(m.Matches(0));
m = AllOf(Ge(0), Lt(10), Ne(3), Ne(5), Ne(7));
EXPECT_TRUE(m.Matches(0));
EXPECT_TRUE(m.Matches(1));
EXPECT_FALSE(m.Matches(3));
// The following tests for varying number of sub-matchers. Due to the way
// the sub-matchers are handled it is enough to test every sub-matcher once
// with sub-matchers using the same matcher type. Varying matcher types are
// checked for above.
AllOfMatches(2, AllOf(Ne(1), Ne(2)));
AllOfMatches(3, AllOf(Ne(1), Ne(2), Ne(3)));
AllOfMatches(4, AllOf(Ne(1), Ne(2), Ne(3), Ne(4)));
AllOfMatches(5, AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5)));
AllOfMatches(6, AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5), Ne(6)));
AllOfMatches(7, AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5), Ne(6), Ne(7)));
AllOfMatches(8,
AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5), Ne(6), Ne(7), Ne(8)));
AllOfMatches(
9, AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5), Ne(6), Ne(7), Ne(8), Ne(9)));
AllOfMatches(10, AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5), Ne(6), Ne(7), Ne(8),
Ne(9), Ne(10)));
AllOfMatches(
50, AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5), Ne(6), Ne(7), Ne(8), Ne(9),
Ne(10), Ne(11), Ne(12), Ne(13), Ne(14), Ne(15), Ne(16), Ne(17),
Ne(18), Ne(19), Ne(20), Ne(21), Ne(22), Ne(23), Ne(24), Ne(25),
Ne(26), Ne(27), Ne(28), Ne(29), Ne(30), Ne(31), Ne(32), Ne(33),
Ne(34), Ne(35), Ne(36), Ne(37), Ne(38), Ne(39), Ne(40), Ne(41),
Ne(42), Ne(43), Ne(44), Ne(45), Ne(46), Ne(47), Ne(48), Ne(49),
Ne(50)));
}
// Tests that AllOf(m1, ..., mn) describes itself properly.
TEST(AllOfTest, CanDescribeSelf) {
Matcher<int> m;
m = AllOf(Le(2), Ge(1));
EXPECT_EQ("(is <= 2) and (is >= 1)", Describe(m));
m = AllOf(Gt(0), Ne(1), Ne(2));
std::string expected_descr1 =
"(is > 0) and (isn't equal to 1) and (isn't equal to 2)";
EXPECT_EQ(expected_descr1, Describe(m));
m = AllOf(Gt(0), Ne(1), Ne(2), Ne(3));
std::string expected_descr2 =
"(is > 0) and (isn't equal to 1) and (isn't equal to 2) and (isn't equal "
"to 3)";
EXPECT_EQ(expected_descr2, Describe(m));
m = AllOf(Ge(0), Lt(10), Ne(3), Ne(5), Ne(7));
std::string expected_descr3 =
"(is >= 0) and (is < 10) and (isn't equal to 3) and (isn't equal to 5) "
"and (isn't equal to 7)";
EXPECT_EQ(expected_descr3, Describe(m));
}
// Tests that AllOf(m1, ..., mn) describes its negation properly.
TEST(AllOfTest, CanDescribeNegation) {
Matcher<int> m;
m = AllOf(Le(2), Ge(1));
std::string expected_descr4 = "(isn't <= 2) or (isn't >= 1)";
EXPECT_EQ(expected_descr4, DescribeNegation(m));
m = AllOf(Gt(0), Ne(1), Ne(2));
std::string expected_descr5 =
"(isn't > 0) or (is equal to 1) or (is equal to 2)";
EXPECT_EQ(expected_descr5, DescribeNegation(m));
m = AllOf(Gt(0), Ne(1), Ne(2), Ne(3));
std::string expected_descr6 =
"(isn't > 0) or (is equal to 1) or (is equal to 2) or (is equal to 3)";
EXPECT_EQ(expected_descr6, DescribeNegation(m));
m = AllOf(Ge(0), Lt(10), Ne(3), Ne(5), Ne(7));
std::string expected_desr7 =
"(isn't >= 0) or (isn't < 10) or (is equal to 3) or (is equal to 5) or "
"(is equal to 7)";
EXPECT_EQ(expected_desr7, DescribeNegation(m));
m = AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5), Ne(6), Ne(7), Ne(8), Ne(9),
Ne(10), Ne(11));
AllOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
EXPECT_THAT(Describe(m), EndsWith("and (isn't equal to 11)"));
AllOfMatches(11, m);
}
// Tests that monomorphic matchers are safely cast by the AllOf matcher.
TEST(AllOfTest, AllOfMatcherSafelyCastsMonomorphicMatchers) {
// greater_than_5 and less_than_10 are monomorphic matchers.
Matcher<int> greater_than_5 = Gt(5);
Matcher<int> less_than_10 = Lt(10);
Matcher<const int&> m = AllOf(greater_than_5, less_than_10);
Matcher<int&> m2 = AllOf(greater_than_5, less_than_10);
Matcher<int&> m3 = AllOf(greater_than_5, m2);
// Tests that BothOf works when composing itself.
Matcher<const int&> m4 = AllOf(greater_than_5, less_than_10, less_than_10);
Matcher<int&> m5 = AllOf(greater_than_5, less_than_10, less_than_10);
}
TEST_P(AllOfTestP, ExplainsResult) {
Matcher<int> m;
// Successful match. Both matchers need to explain. The second
// matcher doesn't give an explanation, so the matcher description is used.
m = AllOf(GreaterThan(10), Lt(30));
EXPECT_EQ("which is 15 more than 10, and is < 30", Explain(m, 25));
// Successful match. Both matchers need to explain.
m = AllOf(GreaterThan(10), GreaterThan(20));
EXPECT_EQ("which is 20 more than 10, and which is 10 more than 20",
Explain(m, 30));
// Successful match. All matchers need to explain. The second
// matcher doesn't given an explanation.
m = AllOf(GreaterThan(10), Lt(30), GreaterThan(20));
EXPECT_EQ(
"which is 15 more than 10, and is < 30, and which is 5 more than 20",
Explain(m, 25));
// Successful match. All matchers need to explain.
m = AllOf(GreaterThan(10), GreaterThan(20), GreaterThan(30));
EXPECT_EQ(
"which is 30 more than 10, and which is 20 more than 20, "
"and which is 10 more than 30",
Explain(m, 40));
// Failed match. The first matcher, which failed, needs to
// explain.
m = AllOf(GreaterThan(10), GreaterThan(20));
EXPECT_EQ("which is 5 less than 10", Explain(m, 5));
// Failed match. The second matcher, which failed, needs to
// explain. Since it doesn't given an explanation, the matcher text is
// printed.
m = AllOf(GreaterThan(10), Lt(30));
EXPECT_EQ("which doesn't match (is < 30)", Explain(m, 40));
// Failed match. The second matcher, which failed, needs to
// explain.
m = AllOf(GreaterThan(10), GreaterThan(20));
EXPECT_EQ("which is 5 less than 20", Explain(m, 15));
}
// Helper to allow easy testing of AnyOf matchers with num parameters.
static void AnyOfMatches(int num, const Matcher<int>& m) {
SCOPED_TRACE(Describe(m));
EXPECT_FALSE(m.Matches(0));
for (int i = 1; i <= num; ++i) {
EXPECT_TRUE(m.Matches(i));
}
EXPECT_FALSE(m.Matches(num + 1));
}
static void AnyOfStringMatches(int num, const Matcher<std::string>& m) {
SCOPED_TRACE(Describe(m));
EXPECT_FALSE(m.Matches(std::to_string(0)));
for (int i = 1; i <= num; ++i) {
EXPECT_TRUE(m.Matches(std::to_string(i)));
}
EXPECT_FALSE(m.Matches(std::to_string(num + 1)));
}
INSTANTIATE_GTEST_MATCHER_TEST_P(AnyOfTest);
// Tests that AnyOf(m1, ..., mn) matches any value that matches at
// least one of the given matchers.
TEST(AnyOfTest, MatchesWhenAnyMatches) {
Matcher<int> m;
m = AnyOf(Le(1), Ge(3));
EXPECT_TRUE(m.Matches(1));
EXPECT_TRUE(m.Matches(4));
EXPECT_FALSE(m.Matches(2));
m = AnyOf(Lt(0), Eq(1), Eq(2));
EXPECT_TRUE(m.Matches(-1));
EXPECT_TRUE(m.Matches(1));
EXPECT_TRUE(m.Matches(2));
EXPECT_FALSE(m.Matches(0));
m = AnyOf(Lt(0), Eq(1), Eq(2), Eq(3));
EXPECT_TRUE(m.Matches(-1));
EXPECT_TRUE(m.Matches(1));
EXPECT_TRUE(m.Matches(2));
EXPECT_TRUE(m.Matches(3));
EXPECT_FALSE(m.Matches(0));
m = AnyOf(Le(0), Gt(10), 3, 5, 7);
EXPECT_TRUE(m.Matches(0));
EXPECT_TRUE(m.Matches(11));
EXPECT_TRUE(m.Matches(3));
EXPECT_FALSE(m.Matches(2));
// The following tests for varying number of sub-matchers. Due to the way
// the sub-matchers are handled it is enough to test every sub-matcher once
// with sub-matchers using the same matcher type. Varying matcher types are
// checked for above.
AnyOfMatches(2, AnyOf(1, 2));
AnyOfMatches(3, AnyOf(1, 2, 3));
AnyOfMatches(4, AnyOf(1, 2, 3, 4));
AnyOfMatches(5, AnyOf(1, 2, 3, 4, 5));
AnyOfMatches(6, AnyOf(1, 2, 3, 4, 5, 6));
AnyOfMatches(7, AnyOf(1, 2, 3, 4, 5, 6, 7));
AnyOfMatches(8, AnyOf(1, 2, 3, 4, 5, 6, 7, 8));
AnyOfMatches(9, AnyOf(1, 2, 3, 4, 5, 6, 7, 8, 9));
AnyOfMatches(10, AnyOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
}
// Tests the variadic version of the AnyOfMatcher.
TEST(AnyOfTest, VariadicMatchesWhenAnyMatches) {
// Also make sure AnyOf is defined in the right namespace and does not depend
// on ADL.
Matcher<int> m = ::testing::AnyOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
EXPECT_THAT(Describe(m), EndsWith("or (is equal to 11)"));
AnyOfMatches(11, m);
AnyOfMatches(50, AnyOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
45, 46, 47, 48, 49, 50));
AnyOfStringMatches(
50, AnyOf("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12",
"13", "14", "15", "16", "17", "18", "19", "20", "21", "22",
"23", "24", "25", "26", "27", "28", "29", "30", "31", "32",
"33", "34", "35", "36", "37", "38", "39", "40", "41", "42",
"43", "44", "45", "46", "47", "48", "49", "50"));
}
TEST(ConditionalTest, MatchesFirstIfCondition) {
Matcher<std::string> eq_red = Eq("red");
Matcher<std::string> ne_red = Ne("red");
Matcher<std::string> m = Conditional(true, eq_red, ne_red);
EXPECT_TRUE(m.Matches("red"));
EXPECT_FALSE(m.Matches("green"));
StringMatchResultListener listener;
StringMatchResultListener expected;
EXPECT_FALSE(m.MatchAndExplain("green", &listener));
EXPECT_FALSE(eq_red.MatchAndExplain("green", &expected));
EXPECT_THAT(listener.str(), Eq(expected.str()));
}
TEST(ConditionalTest, MatchesSecondIfCondition) {
Matcher<std::string> eq_red = Eq("red");
Matcher<std::string> ne_red = Ne("red");
Matcher<std::string> m = Conditional(false, eq_red, ne_red);
EXPECT_FALSE(m.Matches("red"));
EXPECT_TRUE(m.Matches("green"));
StringMatchResultListener listener;
StringMatchResultListener expected;
EXPECT_FALSE(m.MatchAndExplain("red", &listener));
EXPECT_FALSE(ne_red.MatchAndExplain("red", &expected));
EXPECT_THAT(listener.str(), Eq(expected.str()));
}
// Tests that AnyOf(m1, ..., mn) describes itself properly.
TEST(AnyOfTest, CanDescribeSelf) {
Matcher<int> m;
m = AnyOf(Le(1), Ge(3));
EXPECT_EQ("(is <= 1) or (is >= 3)", Describe(m));
m = AnyOf(Lt(0), Eq(1), Eq(2));
EXPECT_EQ("(is < 0) or (is equal to 1) or (is equal to 2)", Describe(m));
m = AnyOf(Lt(0), Eq(1), Eq(2), Eq(3));
EXPECT_EQ("(is < 0) or (is equal to 1) or (is equal to 2) or (is equal to 3)",
Describe(m));
m = AnyOf(Le(0), Gt(10), 3, 5, 7);
EXPECT_EQ(
"(is <= 0) or (is > 10) or (is equal to 3) or (is equal to 5) or (is "
"equal to 7)",
Describe(m));
}
// Tests that AnyOf(m1, ..., mn) describes its negation properly.
TEST(AnyOfTest, CanDescribeNegation) {
Matcher<int> m;
m = AnyOf(Le(1), Ge(3));
EXPECT_EQ("(isn't <= 1) and (isn't >= 3)", DescribeNegation(m));
m = AnyOf(Lt(0), Eq(1), Eq(2));
EXPECT_EQ("(isn't < 0) and (isn't equal to 1) and (isn't equal to 2)",
DescribeNegation(m));
m = AnyOf(Lt(0), Eq(1), Eq(2), Eq(3));
EXPECT_EQ(
"(isn't < 0) and (isn't equal to 1) and (isn't equal to 2) and (isn't "
"equal to 3)",
DescribeNegation(m));
m = AnyOf(Le(0), Gt(10), 3, 5, 7);
EXPECT_EQ(
"(isn't <= 0) and (isn't > 10) and (isn't equal to 3) and (isn't equal "
"to 5) and (isn't equal to 7)",
DescribeNegation(m));
}
// Tests that monomorphic matchers are safely cast by the AnyOf matcher.
TEST(AnyOfTest, AnyOfMatcherSafelyCastsMonomorphicMatchers) {
// greater_than_5 and less_than_10 are monomorphic matchers.
Matcher<int> greater_than_5 = Gt(5);
Matcher<int> less_than_10 = Lt(10);
Matcher<const int&> m = AnyOf(greater_than_5, less_than_10);
Matcher<int&> m2 = AnyOf(greater_than_5, less_than_10);
Matcher<int&> m3 = AnyOf(greater_than_5, m2);
// Tests that EitherOf works when composing itself.
Matcher<const int&> m4 = AnyOf(greater_than_5, less_than_10, less_than_10);
Matcher<int&> m5 = AnyOf(greater_than_5, less_than_10, less_than_10);
}
TEST_P(AnyOfTestP, ExplainsResult) {
Matcher<int> m;
// Failed match. The second matcher have no explanation (description is used).
m = AnyOf(GreaterThan(10), Lt(0));
EXPECT_EQ("which is 5 less than 10, and isn't < 0", Explain(m, 5));
// Failed match. Both matchers have explanations.
m = AnyOf(GreaterThan(10), GreaterThan(20));
EXPECT_EQ("which is 5 less than 10, and which is 15 less than 20",
Explain(m, 5));
// Failed match. The middle matcher have no explanation.
m = AnyOf(GreaterThan(10), Gt(20), GreaterThan(30));
EXPECT_EQ(
"which is 5 less than 10, and isn't > 20, and which is 25 less than 30",
Explain(m, 5));
// Failed match. All three matchers have explanations.
m = AnyOf(GreaterThan(10), GreaterThan(20), GreaterThan(30));
EXPECT_EQ(
"which is 5 less than 10, and which is 15 less than 20, "
"and which is 25 less than 30",
Explain(m, 5));
// Successful match. The first macher succeeded and has explanation.
m = AnyOf(GreaterThan(10), GreaterThan(20));
EXPECT_EQ("which is 5 more than 10", Explain(m, 15));
// Successful match. The second matcher succeeded and has explanation.
m = AnyOf(GreaterThan(30), GreaterThan(20));
EXPECT_EQ("which is 5 more than 20", Explain(m, 25));
// Successful match. The first matcher succeeded and has no explanation.
m = AnyOf(Gt(10), Lt(20));
EXPECT_EQ("which matches (is > 10)", Explain(m, 15));
// Successful match. The second matcher succeeded and has no explanation.
m = AnyOf(Gt(30), Gt(20));
EXPECT_EQ("which matches (is > 20)", Explain(m, 25));
}
// The following predicate function and predicate functor are for
// testing the Truly(predicate) matcher.
// Returns non-zero if the input is positive. Note that the return
// type of this function is not bool. It's OK as Truly() accepts any
// unary function or functor whose return type can be implicitly
// converted to bool.
int IsPositive(double x) { return x > 0 ? 1 : 0; }
// This functor returns true if the input is greater than the given
// number.
class IsGreaterThan {
public:
explicit IsGreaterThan(int threshold) : threshold_(threshold) {}
bool operator()(int n) const { return n > threshold_; }
private:
int threshold_;
};
// For testing Truly().
const int foo = 0;
// This predicate returns true if and only if the argument references foo and
// has a zero value.
bool ReferencesFooAndIsZero(const int& n) { return (&n == &foo) && (n == 0); }
// Tests that Truly(predicate) matches what satisfies the given
// predicate.
TEST(TrulyTest, MatchesWhatSatisfiesThePredicate) {
Matcher<double> m = Truly(IsPositive);
EXPECT_TRUE(m.Matches(2.0));
EXPECT_FALSE(m.Matches(-1.5));
}
// Tests that Truly(predicate_functor) works too.
TEST(TrulyTest, CanBeUsedWithFunctor) {
Matcher<int> m = Truly(IsGreaterThan(5));
EXPECT_TRUE(m.Matches(6));
EXPECT_FALSE(m.Matches(4));
}
// A class that can be implicitly converted to bool.
class ConvertibleToBool {
public:
explicit ConvertibleToBool(int number) : number_(number) {}
operator bool() const { return number_ != 0; }
private:
int number_;
};
ConvertibleToBool IsNotZero(int number) { return ConvertibleToBool(number); }
// Tests that the predicate used in Truly() may return a class that's
// implicitly convertible to bool, even when the class has no
// operator!().
TEST(TrulyTest, PredicateCanReturnAClassConvertibleToBool) {
Matcher<int> m = Truly(IsNotZero);
EXPECT_TRUE(m.Matches(1));
EXPECT_FALSE(m.Matches(0));
}
// Tests that Truly(predicate) can describe itself properly.
TEST(TrulyTest, CanDescribeSelf) {
Matcher<double> m = Truly(IsPositive);
EXPECT_EQ("satisfies the given predicate", Describe(m));
}
// Tests that Truly(predicate) works when the matcher takes its
// argument by reference.
TEST(TrulyTest, WorksForByRefArguments) {
Matcher<const int&> m = Truly(ReferencesFooAndIsZero);
EXPECT_TRUE(m.Matches(foo));
int n = 0;
EXPECT_FALSE(m.Matches(n));
}
// Tests that Truly(predicate) provides a helpful reason when it fails.
TEST(TrulyTest, ExplainsFailures) {
StringMatchResultListener listener;
EXPECT_FALSE(ExplainMatchResult(Truly(IsPositive), -1, &listener));
EXPECT_EQ(listener.str(), "didn't satisfy the given predicate");
}
// Tests that Matches(m) is a predicate satisfied by whatever that
// matches matcher m.
TEST(MatchesTest, IsSatisfiedByWhatMatchesTheMatcher) {
EXPECT_TRUE(Matches(Ge(0))(1));
EXPECT_FALSE(Matches(Eq('a'))('b'));
}
// Tests that Matches(m) works when the matcher takes its argument by
// reference.
TEST(MatchesTest, WorksOnByRefArguments) {
int m = 0, n = 0;
EXPECT_TRUE(Matches(AllOf(Ref(n), Eq(0)))(n));
EXPECT_FALSE(Matches(Ref(m))(n));
}
// Tests that a Matcher on non-reference type can be used in
// Matches().
TEST(MatchesTest, WorksWithMatcherOnNonRefType) {
Matcher<int> eq5 = Eq(5);
EXPECT_TRUE(Matches(eq5)(5));
EXPECT_FALSE(Matches(eq5)(2));
}
// Tests Value(value, matcher). Since Value() is a simple wrapper for
// Matches(), which has been tested already, we don't spend a lot of
// effort on testing Value().
TEST(ValueTest, WorksWithPolymorphicMatcher) {
EXPECT_TRUE(Value("hi", StartsWith("h")));
EXPECT_FALSE(Value(5, Gt(10)));
}
TEST(ValueTest, WorksWithMonomorphicMatcher) {
const Matcher<int> is_zero = Eq(0);
EXPECT_TRUE(Value(0, is_zero));
EXPECT_FALSE(Value('a', is_zero));
int n = 0;
const Matcher<const int&> ref_n = Ref(n);
EXPECT_TRUE(Value(n, ref_n));
EXPECT_FALSE(Value(1, ref_n));
}
TEST(AllArgsTest, WorksForTuple) {
EXPECT_THAT(std::make_tuple(1, 2L), AllArgs(Lt()));
EXPECT_THAT(std::make_tuple(2L, 1), Not(AllArgs(Lt())));
}
TEST(AllArgsTest, WorksForNonTuple) {
EXPECT_THAT(42, AllArgs(Gt(0)));
EXPECT_THAT('a', Not(AllArgs(Eq('b'))));
}
class AllArgsHelper {
public:
AllArgsHelper() = default;
MOCK_METHOD2(Helper, int(char x, int y));
private:
AllArgsHelper(const AllArgsHelper&) = delete;
AllArgsHelper& operator=(const AllArgsHelper&) = delete;
};
TEST(AllArgsTest, WorksInWithClause) {
AllArgsHelper helper;
ON_CALL(helper, Helper(_, _)).With(AllArgs(Lt())).WillByDefault(Return(1));
EXPECT_CALL(helper, Helper(_, _));
EXPECT_CALL(helper, Helper(_, _)).With(AllArgs(Gt())).WillOnce(Return(2));
EXPECT_EQ(1, helper.Helper('\1', 2));
EXPECT_EQ(2, helper.Helper('a', 1));
}
class OptionalMatchersHelper {
public:
OptionalMatchersHelper() = default;
MOCK_METHOD0(NoArgs, int());
MOCK_METHOD1(OneArg, int(int y));
MOCK_METHOD2(TwoArgs, int(char x, int y));
MOCK_METHOD1(Overloaded, int(char x));
MOCK_METHOD2(Overloaded, int(char x, int y));
private:
OptionalMatchersHelper(const OptionalMatchersHelper&) = delete;
OptionalMatchersHelper& operator=(const OptionalMatchersHelper&) = delete;
};
TEST(AllArgsTest, WorksWithoutMatchers) {
OptionalMatchersHelper helper;
ON_CALL(helper, NoArgs).WillByDefault(Return(10));
ON_CALL(helper, OneArg).WillByDefault(Return(20));
ON_CALL(helper, TwoArgs).WillByDefault(Return(30));
EXPECT_EQ(10, helper.NoArgs());
EXPECT_EQ(20, helper.OneArg(1));
EXPECT_EQ(30, helper.TwoArgs('\1', 2));
EXPECT_CALL(helper, NoArgs).Times(1);
EXPECT_CALL(helper, OneArg).WillOnce(Return(100));
EXPECT_CALL(helper, OneArg(17)).WillOnce(Return(200));
EXPECT_CALL(helper, TwoArgs).Times(0);
EXPECT_EQ(10, helper.NoArgs());
EXPECT_EQ(100, helper.OneArg(1));
EXPECT_EQ(200, helper.OneArg(17));
}
// Tests floating-point matchers.
template <typename RawType>
class FloatingPointTest : public testing::Test {
protected:
typedef testing::internal::FloatingPoint<RawType> Floating;
typedef typename Floating::Bits Bits;
FloatingPointTest()
: max_ulps_(Floating::kMaxUlps),
zero_bits_(Floating(0).bits()),
one_bits_(Floating(1).bits()),
infinity_bits_(Floating(Floating::Infinity()).bits()),
close_to_positive_zero_(
Floating::ReinterpretBits(zero_bits_ + max_ulps_ / 2)),
close_to_negative_zero_(
-Floating::ReinterpretBits(zero_bits_ + max_ulps_ - max_ulps_ / 2)),
further_from_negative_zero_(-Floating::ReinterpretBits(
zero_bits_ + max_ulps_ + 1 - max_ulps_ / 2)),
close_to_one_(Floating::ReinterpretBits(one_bits_ + max_ulps_)),
further_from_one_(Floating::ReinterpretBits(one_bits_ + max_ulps_ + 1)),
infinity_(Floating::Infinity()),
close_to_infinity_(
Floating::ReinterpretBits(infinity_bits_ - max_ulps_)),
further_from_infinity_(
Floating::ReinterpretBits(infinity_bits_ - max_ulps_ - 1)),
max_(std::numeric_limits<RawType>::max()),
nan1_(Floating::ReinterpretBits(Floating::kExponentBitMask | 1)),
nan2_(Floating::ReinterpretBits(Floating::kExponentBitMask | 200)) {}
void TestSize() { EXPECT_EQ(sizeof(RawType), sizeof(Bits)); }
// A battery of tests for FloatingEqMatcher::Matches.
// matcher_maker is a pointer to a function which creates a FloatingEqMatcher.
void TestMatches(
testing::internal::FloatingEqMatcher<RawType> (*matcher_maker)(RawType)) {
Matcher<RawType> m1 = matcher_maker(0.0);
EXPECT_TRUE(m1.Matches(-0.0));
EXPECT_TRUE(m1.Matches(close_to_positive_zero_));
EXPECT_TRUE(m1.Matches(close_to_negative_zero_));
EXPECT_FALSE(m1.Matches(1.0));
Matcher<RawType> m2 = matcher_maker(close_to_positive_zero_);
EXPECT_FALSE(m2.Matches(further_from_negative_zero_));
Matcher<RawType> m3 = matcher_maker(1.0);
EXPECT_TRUE(m3.Matches(close_to_one_));
EXPECT_FALSE(m3.Matches(further_from_one_));
// Test commutativity: matcher_maker(0.0).Matches(1.0) was tested above.
EXPECT_FALSE(m3.Matches(0.0));
Matcher<RawType> m4 = matcher_maker(-infinity_);
EXPECT_TRUE(m4.Matches(-close_to_infinity_));
Matcher<RawType> m5 = matcher_maker(infinity_);
EXPECT_TRUE(m5.Matches(close_to_infinity_));
// This is interesting as the representations of infinity_ and nan1_
// are only 1 DLP apart.
EXPECT_FALSE(m5.Matches(nan1_));
// matcher_maker can produce a Matcher<const RawType&>, which is needed in
// some cases.
Matcher<const RawType&> m6 = matcher_maker(0.0);
EXPECT_TRUE(m6.Matches(-0.0));
EXPECT_TRUE(m6.Matches(close_to_positive_zero_));
EXPECT_FALSE(m6.Matches(1.0));
// matcher_maker can produce a Matcher<RawType&>, which is needed in some
// cases.
Matcher<RawType&> m7 = matcher_maker(0.0);
RawType x = 0.0;
EXPECT_TRUE(m7.Matches(x));
x = 0.01f;
EXPECT_FALSE(m7.Matches(x));
}
// Pre-calculated numbers to be used by the tests.
const Bits max_ulps_;
const Bits zero_bits_; // The bits that represent 0.0.
const Bits one_bits_; // The bits that represent 1.0.
const Bits infinity_bits_; // The bits that represent +infinity.
// Some numbers close to 0.0.
const RawType close_to_positive_zero_;
const RawType close_to_negative_zero_;
const RawType further_from_negative_zero_;
// Some numbers close to 1.0.
const RawType close_to_one_;
const RawType further_from_one_;
// Some numbers close to +infinity.
const RawType infinity_;
const RawType close_to_infinity_;
const RawType further_from_infinity_;
// Maximum representable value that's not infinity.
const RawType max_;
// Some NaNs.
const RawType nan1_;
const RawType nan2_;
};
// Tests floating-point matchers with fixed epsilons.
template <typename RawType>
class FloatingPointNearTest : public FloatingPointTest<RawType> {
protected:
typedef FloatingPointTest<RawType> ParentType;
// A battery of tests for FloatingEqMatcher::Matches with a fixed epsilon.
// matcher_maker is a pointer to a function which creates a FloatingEqMatcher.
void TestNearMatches(testing::internal::FloatingEqMatcher<RawType> (
*matcher_maker)(RawType, RawType)) {
Matcher<RawType> m1 = matcher_maker(0.0, 0.0);
EXPECT_TRUE(m1.Matches(0.0));
EXPECT_TRUE(m1.Matches(-0.0));
EXPECT_FALSE(m1.Matches(ParentType::close_to_positive_zero_));
EXPECT_FALSE(m1.Matches(ParentType::close_to_negative_zero_));
EXPECT_FALSE(m1.Matches(1.0));
Matcher<RawType> m2 = matcher_maker(0.0, 1.0);
EXPECT_TRUE(m2.Matches(0.0));
EXPECT_TRUE(m2.Matches(-0.0));
EXPECT_TRUE(m2.Matches(1.0));
EXPECT_TRUE(m2.Matches(-1.0));
EXPECT_FALSE(m2.Matches(ParentType::close_to_one_));
EXPECT_FALSE(m2.Matches(-ParentType::close_to_one_));
// Check that inf matches inf, regardless of the of the specified max
// absolute error.
Matcher<RawType> m3 = matcher_maker(ParentType::infinity_, 0.0);
EXPECT_TRUE(m3.Matches(ParentType::infinity_));
EXPECT_FALSE(m3.Matches(ParentType::close_to_infinity_));
EXPECT_FALSE(m3.Matches(-ParentType::infinity_));
Matcher<RawType> m4 = matcher_maker(-ParentType::infinity_, 0.0);
EXPECT_TRUE(m4.Matches(-ParentType::infinity_));
EXPECT_FALSE(m4.Matches(-ParentType::close_to_infinity_));
EXPECT_FALSE(m4.Matches(ParentType::infinity_));
// Test various overflow scenarios.
Matcher<RawType> m5 = matcher_maker(ParentType::max_, ParentType::max_);
EXPECT_TRUE(m5.Matches(ParentType::max_));
EXPECT_FALSE(m5.Matches(-ParentType::max_));
Matcher<RawType> m6 = matcher_maker(-ParentType::max_, ParentType::max_);
EXPECT_FALSE(m6.Matches(ParentType::max_));
EXPECT_TRUE(m6.Matches(-ParentType::max_));
Matcher<RawType> m7 = matcher_maker(ParentType::max_, 0);
EXPECT_TRUE(m7.Matches(ParentType::max_));
EXPECT_FALSE(m7.Matches(-ParentType::max_));
Matcher<RawType> m8 = matcher_maker(-ParentType::max_, 0);
EXPECT_FALSE(m8.Matches(ParentType::max_));
EXPECT_TRUE(m8.Matches(-ParentType::max_));
// The difference between max() and -max() normally overflows to infinity,
// but it should still match if the max_abs_error is also infinity.
Matcher<RawType> m9 =
matcher_maker(ParentType::max_, ParentType::infinity_);
EXPECT_TRUE(m8.Matches(-ParentType::max_));
// matcher_maker can produce a Matcher<const RawType&>, which is needed in
// some cases.
Matcher<const RawType&> m10 = matcher_maker(0.0, 1.0);
EXPECT_TRUE(m10.Matches(-0.0));
EXPECT_TRUE(m10.Matches(ParentType::close_to_positive_zero_));
EXPECT_FALSE(m10.Matches(ParentType::close_to_one_));
// matcher_maker can produce a Matcher<RawType&>, which is needed in some
// cases.
Matcher<RawType&> m11 = matcher_maker(0.0, 1.0);
RawType x = 0.0;
EXPECT_TRUE(m11.Matches(x));
x = 1.0f;
EXPECT_TRUE(m11.Matches(x));
x = -1.0f;
EXPECT_TRUE(m11.Matches(x));
x = 1.1f;
EXPECT_FALSE(m11.Matches(x));
x = -1.1f;
EXPECT_FALSE(m11.Matches(x));
}
};
// Instantiate FloatingPointTest for testing floats.
typedef FloatingPointTest<float> FloatTest;
TEST_F(FloatTest, FloatEqApproximatelyMatchesFloats) { TestMatches(&FloatEq); }
TEST_F(FloatTest, NanSensitiveFloatEqApproximatelyMatchesFloats) {
TestMatches(&NanSensitiveFloatEq);
}
TEST_F(FloatTest, FloatEqCannotMatchNaN) {
// FloatEq never matches NaN.
Matcher<float> m = FloatEq(nan1_);
EXPECT_FALSE(m.Matches(nan1_));
EXPECT_FALSE(m.Matches(nan2_));
EXPECT_FALSE(m.Matches(1.0));
}
TEST_F(FloatTest, NanSensitiveFloatEqCanMatchNaN) {
// NanSensitiveFloatEq will match NaN.
Matcher<float> m = NanSensitiveFloatEq(nan1_);
EXPECT_TRUE(m.Matches(nan1_));
EXPECT_TRUE(m.Matches(nan2_));
EXPECT_FALSE(m.Matches(1.0));
}
TEST_F(FloatTest, FloatEqCanDescribeSelf) {
Matcher<float> m1 = FloatEq(2.0f);
EXPECT_EQ("is approximately 2", Describe(m1));
EXPECT_EQ("isn't approximately 2", DescribeNegation(m1));
Matcher<float> m2 = FloatEq(0.5f);
EXPECT_EQ("is approximately 0.5", Describe(m2));
EXPECT_EQ("isn't approximately 0.5", DescribeNegation(m2));
Matcher<float> m3 = FloatEq(nan1_);
EXPECT_EQ("never matches", Describe(m3));
EXPECT_EQ("is anything", DescribeNegation(m3));
}
TEST_F(FloatTest, NanSensitiveFloatEqCanDescribeSelf) {
Matcher<float> m1 = NanSensitiveFloatEq(2.0f);
EXPECT_EQ("is approximately 2", Describe(m1));
EXPECT_EQ("isn't approximately 2", DescribeNegation(m1));
Matcher<float> m2 = NanSensitiveFloatEq(0.5f);
EXPECT_EQ("is approximately 0.5", Describe(m2));
EXPECT_EQ("isn't approximately 0.5", DescribeNegation(m2));
Matcher<float> m3 = NanSensitiveFloatEq(nan1_);
EXPECT_EQ("is NaN", Describe(m3));
EXPECT_EQ("isn't NaN", DescribeNegation(m3));
}
// Instantiate FloatingPointTest for testing floats with a user-specified
// max absolute error.
typedef FloatingPointNearTest<float> FloatNearTest;
TEST_F(FloatNearTest, FloatNearMatches) { TestNearMatches(&FloatNear); }
TEST_F(FloatNearTest, NanSensitiveFloatNearApproximatelyMatchesFloats) {
TestNearMatches(&NanSensitiveFloatNear);
}
TEST_F(FloatNearTest, FloatNearCanDescribeSelf) {
Matcher<float> m1 = FloatNear(2.0f, 0.5f);
EXPECT_EQ("is approximately 2 (absolute error <= 0.5)", Describe(m1));
EXPECT_EQ("isn't approximately 2 (absolute error > 0.5)",
DescribeNegation(m1));
Matcher<float> m2 = FloatNear(0.5f, 0.5f);
EXPECT_EQ("is approximately 0.5 (absolute error <= 0.5)", Describe(m2));
EXPECT_EQ("isn't approximately 0.5 (absolute error > 0.5)",
DescribeNegation(m2));
Matcher<float> m3 = FloatNear(nan1_, 0.0);
EXPECT_EQ("never matches", Describe(m3));
EXPECT_EQ("is anything", DescribeNegation(m3));
}
TEST_F(FloatNearTest, NanSensitiveFloatNearCanDescribeSelf) {
Matcher<float> m1 = NanSensitiveFloatNear(2.0f, 0.5f);
EXPECT_EQ("is approximately 2 (absolute error <= 0.5)", Describe(m1));
EXPECT_EQ("isn't approximately 2 (absolute error > 0.5)",
DescribeNegation(m1));
Matcher<float> m2 = NanSensitiveFloatNear(0.5f, 0.5f);
EXPECT_EQ("is approximately 0.5 (absolute error <= 0.5)", Describe(m2));
EXPECT_EQ("isn't approximately 0.5 (absolute error > 0.5)",
DescribeNegation(m2));
Matcher<float> m3 = NanSensitiveFloatNear(nan1_, 0.1f);
EXPECT_EQ("is NaN", Describe(m3));
EXPECT_EQ("isn't NaN", DescribeNegation(m3));
}
TEST_F(FloatNearTest, FloatNearCannotMatchNaN) {
// FloatNear never matches NaN.
Matcher<float> m = FloatNear(ParentType::nan1_, 0.1f);
EXPECT_FALSE(m.Matches(nan1_));
EXPECT_FALSE(m.Matches(nan2_));
EXPECT_FALSE(m.Matches(1.0));
}
TEST_F(FloatNearTest, NanSensitiveFloatNearCanMatchNaN) {
// NanSensitiveFloatNear will match NaN.
Matcher<float> m = NanSensitiveFloatNear(nan1_, 0.1f);
EXPECT_TRUE(m.Matches(nan1_));
EXPECT_TRUE(m.Matches(nan2_));
EXPECT_FALSE(m.Matches(1.0));
}
// Instantiate FloatingPointTest for testing doubles.
typedef FloatingPointTest<double> DoubleTest;
TEST_F(DoubleTest, DoubleEqApproximatelyMatchesDoubles) {
TestMatches(&DoubleEq);
}
TEST_F(DoubleTest, NanSensitiveDoubleEqApproximatelyMatchesDoubles) {
TestMatches(&NanSensitiveDoubleEq);
}
TEST_F(DoubleTest, DoubleEqCannotMatchNaN) {
// DoubleEq never matches NaN.
Matcher<double> m = DoubleEq(nan1_);
EXPECT_FALSE(m.Matches(nan1_));
EXPECT_FALSE(m.Matches(nan2_));
EXPECT_FALSE(m.Matches(1.0));
}
TEST_F(DoubleTest, NanSensitiveDoubleEqCanMatchNaN) {
// NanSensitiveDoubleEq will match NaN.
Matcher<double> m = NanSensitiveDoubleEq(nan1_);
EXPECT_TRUE(m.Matches(nan1_));
EXPECT_TRUE(m.Matches(nan2_));
EXPECT_FALSE(m.Matches(1.0));
}
TEST_F(DoubleTest, DoubleEqCanDescribeSelf) {
Matcher<double> m1 = DoubleEq(2.0);
EXPECT_EQ("is approximately 2", Describe(m1));
EXPECT_EQ("isn't approximately 2", DescribeNegation(m1));
Matcher<double> m2 = DoubleEq(0.5);
EXPECT_EQ("is approximately 0.5", Describe(m2));
EXPECT_EQ("isn't approximately 0.5", DescribeNegation(m2));
Matcher<double> m3 = DoubleEq(nan1_);
EXPECT_EQ("never matches", Describe(m3));
EXPECT_EQ("is anything", DescribeNegation(m3));
}
TEST_F(DoubleTest, NanSensitiveDoubleEqCanDescribeSelf) {
Matcher<double> m1 = NanSensitiveDoubleEq(2.0);
EXPECT_EQ("is approximately 2", Describe(m1));
EXPECT_EQ("isn't approximately 2", DescribeNegation(m1));
Matcher<double> m2 = NanSensitiveDoubleEq(0.5);
EXPECT_EQ("is approximately 0.5", Describe(m2));
EXPECT_EQ("isn't approximately 0.5", DescribeNegation(m2));
Matcher<double> m3 = NanSensitiveDoubleEq(nan1_);
EXPECT_EQ("is NaN", Describe(m3));
EXPECT_EQ("isn't NaN", DescribeNegation(m3));
}
// Instantiate FloatingPointTest for testing floats with a user-specified
// max absolute error.
typedef FloatingPointNearTest<double> DoubleNearTest;
TEST_F(DoubleNearTest, DoubleNearMatches) { TestNearMatches(&DoubleNear); }
TEST_F(DoubleNearTest, NanSensitiveDoubleNearApproximatelyMatchesDoubles) {
TestNearMatches(&NanSensitiveDoubleNear);
}
TEST_F(DoubleNearTest, DoubleNearCanDescribeSelf) {
Matcher<double> m1 = DoubleNear(2.0, 0.5);
EXPECT_EQ("is approximately 2 (absolute error <= 0.5)", Describe(m1));
EXPECT_EQ("isn't approximately 2 (absolute error > 0.5)",
DescribeNegation(m1));
Matcher<double> m2 = DoubleNear(0.5, 0.5);
EXPECT_EQ("is approximately 0.5 (absolute error <= 0.5)", Describe(m2));
EXPECT_EQ("isn't approximately 0.5 (absolute error > 0.5)",
DescribeNegation(m2));
Matcher<double> m3 = DoubleNear(nan1_, 0.0);
EXPECT_EQ("never matches", Describe(m3));
EXPECT_EQ("is anything", DescribeNegation(m3));
}
TEST_F(DoubleNearTest, ExplainsResultWhenMatchFails) {
EXPECT_EQ("", Explain(DoubleNear(2.0, 0.1), 2.05));
EXPECT_EQ("which is 0.2 from 2", Explain(DoubleNear(2.0, 0.1), 2.2));
EXPECT_EQ("which is -0.3 from 2", Explain(DoubleNear(2.0, 0.1), 1.7));
const std::string explanation =
Explain(DoubleNear(2.1, 1e-10), 2.1 + 1.2e-10);
// Different C++ implementations may print floating-point numbers
// slightly differently.
EXPECT_TRUE(explanation == "which is 1.2e-10 from 2.1" || // GCC
explanation == "which is 1.2e-010 from 2.1") // MSVC
<< " where explanation is \"" << explanation << "\".";
}
TEST_F(DoubleNearTest, NanSensitiveDoubleNearCanDescribeSelf) {
Matcher<double> m1 = NanSensitiveDoubleNear(2.0, 0.5);
EXPECT_EQ("is approximately 2 (absolute error <= 0.5)", Describe(m1));
EXPECT_EQ("isn't approximately 2 (absolute error > 0.5)",
DescribeNegation(m1));
Matcher<double> m2 = NanSensitiveDoubleNear(0.5, 0.5);
EXPECT_EQ("is approximately 0.5 (absolute error <= 0.5)", Describe(m2));
EXPECT_EQ("isn't approximately 0.5 (absolute error > 0.5)",
DescribeNegation(m2));
Matcher<double> m3 = NanSensitiveDoubleNear(nan1_, 0.1);
EXPECT_EQ("is NaN", Describe(m3));
EXPECT_EQ("isn't NaN", DescribeNegation(m3));
}
TEST_F(DoubleNearTest, DoubleNearCannotMatchNaN) {
// DoubleNear never matches NaN.
Matcher<double> m = DoubleNear(ParentType::nan1_, 0.1);
EXPECT_FALSE(m.Matches(nan1_));
EXPECT_FALSE(m.Matches(nan2_));
EXPECT_FALSE(m.Matches(1.0));
}
TEST_F(DoubleNearTest, NanSensitiveDoubleNearCanMatchNaN) {
// NanSensitiveDoubleNear will match NaN.
Matcher<double> m = NanSensitiveDoubleNear(nan1_, 0.1);
EXPECT_TRUE(m.Matches(nan1_));
EXPECT_TRUE(m.Matches(nan2_));
EXPECT_FALSE(m.Matches(1.0));
}
TEST(NotTest, WorksOnMoveOnlyType) {
std::unique_ptr<int> p(new int(3));
EXPECT_THAT(p, Pointee(Eq(3)));
EXPECT_THAT(p, Not(Pointee(Eq(2))));
}
TEST(AllOfTest, HugeMatcher) {
// Verify that using AllOf with many arguments doesn't cause
// the compiler to exceed template instantiation depth limit.
EXPECT_THAT(0, testing::AllOf(_, _, _, _, _, _, _, _, _,
testing::AllOf(_, _, _, _, _, _, _, _, _, _)));
}
TEST(AnyOfTest, HugeMatcher) {
// Verify that using AnyOf with many arguments doesn't cause
// the compiler to exceed template instantiation depth limit.
EXPECT_THAT(0, testing::AnyOf(_, _, _, _, _, _, _, _, _,
testing::AnyOf(_, _, _, _, _, _, _, _, _, _)));
}
namespace adl_test {
// Verifies that the implementation of ::testing::AllOf and ::testing::AnyOf
// don't issue unqualified recursive calls. If they do, the argument dependent
// name lookup will cause AllOf/AnyOf in the 'adl_test' namespace to be found
// as a candidate and the compilation will break due to an ambiguous overload.
// The matcher must be in the same namespace as AllOf/AnyOf to make argument
// dependent lookup find those.
MATCHER(M, "") {
(void)arg;
return true;
}
template <typename T1, typename T2>
bool AllOf(const T1& /*t1*/, const T2& /*t2*/) {
return true;
}
TEST(AllOfTest, DoesNotCallAllOfUnqualified) {
EXPECT_THAT(42,
testing::AllOf(M(), M(), M(), M(), M(), M(), M(), M(), M(), M()));
}
template <typename T1, typename T2>
bool AnyOf(const T1&, const T2&) {
return true;
}
TEST(AnyOfTest, DoesNotCallAnyOfUnqualified) {
EXPECT_THAT(42,
testing::AnyOf(M(), M(), M(), M(), M(), M(), M(), M(), M(), M()));
}
} // namespace adl_test
TEST(AllOfTest, WorksOnMoveOnlyType) {
std::unique_ptr<int> p(new int(3));
EXPECT_THAT(p, AllOf(Pointee(Eq(3)), Pointee(Gt(0)), Pointee(Lt(5))));
EXPECT_THAT(p, Not(AllOf(Pointee(Eq(3)), Pointee(Gt(0)), Pointee(Lt(3)))));
}
TEST(AnyOfTest, WorksOnMoveOnlyType) {
std::unique_ptr<int> p(new int(3));
EXPECT_THAT(p, AnyOf(Pointee(Eq(5)), Pointee(Lt(0)), Pointee(Lt(5))));
EXPECT_THAT(p, Not(AnyOf(Pointee(Eq(5)), Pointee(Lt(0)), Pointee(Gt(5)))));
}
} // namespace
} // namespace gmock_matchers_test
} // namespace testing
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4244 4100
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