Update googletest to 1.18.0 and SIMDe to 0.8.2.
Googletest 1.18 asks for CMake 3.13 or newer, so configuring the tests no longer warns that CMake compatibility below 3.10 is deprecated. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
e4e666f459
commit
3f10e05176
912 changed files with 224964 additions and 11502 deletions
|
|
@ -5,7 +5,7 @@
|
|||
# CMake build script for Google Mock.
|
||||
#
|
||||
# To run the tests for Google Mock itself on Linux, use 'make test' or
|
||||
# ctest. You can select which tests to run using 'ctest -R regex'.
|
||||
# ctest. You can select which tests to run using 'ctest -R regex'.
|
||||
# For more options, run 'ctest --help'.
|
||||
|
||||
option(gmock_build_tests "Build all of Google Mock's own tests." OFF)
|
||||
|
|
@ -36,8 +36,7 @@ endif()
|
|||
# as ${gmock_SOURCE_DIR} and to the root binary directory as
|
||||
# ${gmock_BINARY_DIR}.
|
||||
# Language "C" is required for find_package(Threads).
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
cmake_policy(SET CMP0048 NEW)
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(gmock VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)
|
||||
|
||||
if (COMMAND set_up_hermetic_build)
|
||||
|
|
@ -45,7 +44,7 @@ if (COMMAND set_up_hermetic_build)
|
|||
endif()
|
||||
|
||||
# Instructs CMake to process Google Test's CMakeLists.txt and add its
|
||||
# targets to the current scope. We are placing Google Test's binary
|
||||
# targets to the current scope. We are placing Google Test's binary
|
||||
# directory in a subdirectory of our own as VC compilation may break
|
||||
# if they are the same (the default).
|
||||
add_subdirectory("${gtest_dir}" "${gmock_BINARY_DIR}/${gtest_dir}")
|
||||
|
|
@ -61,25 +60,26 @@ else()
|
|||
endif()
|
||||
|
||||
# Although Google Test's CMakeLists.txt calls this function, the
|
||||
# changes there don't affect the current scope. Therefore we have to
|
||||
# changes there don't affect the current scope. Therefore we have to
|
||||
# call it again here.
|
||||
config_compiler_and_linker() # from ${gtest_dir}/cmake/internal_utils.cmake
|
||||
config_compiler_and_linker() # from ${gtest_dir}/cmake/internal_utils.cmake
|
||||
|
||||
# Adds Google Mock's and Google Test's header directories to the search path.
|
||||
# Get Google Test's include dirs from the target, gtest_SOURCE_DIR is broken
|
||||
# when using fetch-content with the name "GTest".
|
||||
get_target_property(gtest_include_dirs gtest INCLUDE_DIRECTORIES)
|
||||
set(gmock_build_include_dirs
|
||||
"${gmock_SOURCE_DIR}/include"
|
||||
"${gmock_SOURCE_DIR}"
|
||||
"${gtest_SOURCE_DIR}/include"
|
||||
# This directory is needed to build directly from Google Test sources.
|
||||
"${gtest_SOURCE_DIR}")
|
||||
"${gtest_include_dirs}")
|
||||
include_directories(${gmock_build_include_dirs})
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Defines the gmock & gmock_main libraries. User tests should link
|
||||
# Defines the gmock & gmock_main libraries. User tests should link
|
||||
# with one of them.
|
||||
|
||||
# Google Mock libraries. We build them using more strict warnings than what
|
||||
# Google Mock libraries. We build them using more strict warnings than what
|
||||
# are used for other targets, to ensure that Google Mock can be compiled by
|
||||
# a user aggressive about warnings.
|
||||
if (MSVC)
|
||||
|
|
@ -101,22 +101,18 @@ else()
|
|||
target_link_libraries(gmock_main PUBLIC gmock)
|
||||
set_target_properties(gmock_main PROPERTIES VERSION ${GOOGLETEST_VERSION})
|
||||
endif()
|
||||
# If the CMake version supports it, attach header directory information
|
||||
# to the targets for when we are part of a parent build (ie being pulled
|
||||
# in via add_subdirectory() rather than being a standalone build).
|
||||
if (DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11")
|
||||
string(REPLACE ";" "$<SEMICOLON>" dirs "${gmock_build_include_dirs}")
|
||||
target_include_directories(gmock SYSTEM INTERFACE
|
||||
"$<BUILD_INTERFACE:${dirs}>"
|
||||
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
|
||||
target_include_directories(gmock_main SYSTEM INTERFACE
|
||||
"$<BUILD_INTERFACE:${dirs}>"
|
||||
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
|
||||
endif()
|
||||
|
||||
string(REPLACE ";" "$<SEMICOLON>" dirs "${gmock_build_include_dirs}")
|
||||
target_include_directories(gmock SYSTEM INTERFACE
|
||||
"$<BUILD_INTERFACE:${dirs}>"
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
|
||||
target_include_directories(gmock_main SYSTEM INTERFACE
|
||||
"$<BUILD_INTERFACE:${dirs}>"
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Install rules
|
||||
# Install rules.
|
||||
install_project(gmock gmock_main)
|
||||
|
||||
########################################################################
|
||||
|
|
@ -126,8 +122,8 @@ install_project(gmock gmock_main)
|
|||
# You can skip this section if you aren't interested in testing
|
||||
# Google Mock itself.
|
||||
#
|
||||
# The tests are not built by default. To build them, set the
|
||||
# gmock_build_tests option to ON. You can do it by running ccmake
|
||||
# The tests are not built by default. To build them, set the
|
||||
# gmock_build_tests option to ON. You can do it by running ccmake
|
||||
# or specifying the -Dgmock_build_tests=ON flag when running cmake.
|
||||
|
||||
if (gmock_build_tests)
|
||||
|
|
@ -136,11 +132,7 @@ if (gmock_build_tests)
|
|||
enable_testing()
|
||||
|
||||
if (MINGW OR CYGWIN)
|
||||
if (CMAKE_VERSION VERSION_LESS "2.8.12")
|
||||
add_compile_options("-Wa,-mbig-obj")
|
||||
else()
|
||||
add_definitions("-Wa,-mbig-obj")
|
||||
endif()
|
||||
add_compile_options("-Wa,-mbig-obj")
|
||||
endif()
|
||||
|
||||
############################################################
|
||||
|
|
@ -196,7 +188,7 @@ if (gmock_build_tests)
|
|||
cxx_shared_library(shared_gmock_main "${cxx_default}"
|
||||
"${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc)
|
||||
|
||||
# Tests that a binary can be built with Google Mock as a shared library. On
|
||||
# Tests that a binary can be built with Google Mock as a shared library. On
|
||||
# some system configurations, it may not possible to run the binary without
|
||||
# knowing more details about the system configurations. We do not try to run
|
||||
# this binary. To get a more robust shared library coverage, configure with
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ derive better designs of your system and write better tests.
|
|||
It is inspired by:
|
||||
|
||||
* [jMock](http://www.jmock.org/)
|
||||
* [EasyMock](http://www.easymock.org/)
|
||||
* [Hamcrest](http://code.google.com/p/hamcrest/)
|
||||
* [EasyMock](https://easymock.org/)
|
||||
* [Hamcrest](https://code.google.com/p/hamcrest/)
|
||||
|
||||
It is designed with C++'s specifics in mind.
|
||||
|
||||
|
|
@ -36,5 +36,5 @@ Details and examples can be found here:
|
|||
* [gMock Cheat Sheet](https://google.github.io/googletest/gmock_cheat_sheet.html)
|
||||
|
||||
GoogleMock is a part of
|
||||
[GoogleTest C++ testing framework](http://github.com/google/googletest/) and a
|
||||
[GoogleTest C++ testing framework](https://github.com/google/googletest/) and a
|
||||
subject to the same requirements.
|
||||
|
|
|
|||
|
|
@ -135,6 +135,7 @@
|
|||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <exception>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
|
@ -175,9 +176,15 @@ struct BuiltInDefaultValueGetter<T, false> {
|
|||
static T Get() {
|
||||
Assert(false, __FILE__, __LINE__,
|
||||
"Default action undefined for the function return type.");
|
||||
return internal::Invalid<T>();
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
__builtin_unreachable();
|
||||
#elif defined(_MSC_VER)
|
||||
__assume(0);
|
||||
#else
|
||||
return Invalid<T>();
|
||||
// The above statement will never be reached, but is required in
|
||||
// order for this function to compile.
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -189,7 +196,7 @@ struct BuiltInDefaultValueGetter<T, false> {
|
|||
// other type T, the built-in default T value is undefined, and the
|
||||
// function will abort the process.
|
||||
template <typename T>
|
||||
class BuiltInDefaultValue {
|
||||
class [[nodiscard]] BuiltInDefaultValue {
|
||||
public:
|
||||
// This function returns true if and only if type T has a built-in default
|
||||
// value.
|
||||
|
|
@ -204,7 +211,7 @@ class BuiltInDefaultValue {
|
|||
// This partial specialization says that we use the same built-in
|
||||
// default value for T and const T.
|
||||
template <typename T>
|
||||
class BuiltInDefaultValue<const T> {
|
||||
class [[nodiscard]] BuiltInDefaultValue<const T> {
|
||||
public:
|
||||
static bool Exists() { return BuiltInDefaultValue<T>::Exists(); }
|
||||
static T Get() { return BuiltInDefaultValue<T>::Get(); }
|
||||
|
|
@ -213,7 +220,7 @@ class BuiltInDefaultValue<const T> {
|
|||
// This partial specialization defines the default values for pointer
|
||||
// types.
|
||||
template <typename T>
|
||||
class BuiltInDefaultValue<T*> {
|
||||
class [[nodiscard]] BuiltInDefaultValue<T*> {
|
||||
public:
|
||||
static bool Exists() { return true; }
|
||||
static T* Get() { return nullptr; }
|
||||
|
|
@ -376,7 +383,7 @@ typename std::add_const<T>::type& as_const(T& t) {
|
|||
|
||||
// Specialized for function types below.
|
||||
template <typename F>
|
||||
class OnceAction;
|
||||
class [[nodiscard]] OnceAction;
|
||||
|
||||
// An action that can only be used once.
|
||||
//
|
||||
|
|
@ -414,27 +421,26 @@ class OnceAction;
|
|||
// A less-contrived example would be an action that returns an arbitrary type,
|
||||
// whose &&-qualified call operator is capable of dealing with move-only types.
|
||||
template <typename Result, typename... Args>
|
||||
class OnceAction<Result(Args...)> final {
|
||||
class [[nodiscard]] OnceAction<Result(Args...)> final {
|
||||
private:
|
||||
// True iff we can use the given callable type (or lvalue reference) directly
|
||||
// via StdFunctionAdaptor.
|
||||
template <typename Callable>
|
||||
using IsDirectlyCompatible = internal::conjunction<
|
||||
// It must be possible to capture the callable in StdFunctionAdaptor.
|
||||
std::is_constructible<typename std::decay<Callable>::type, Callable>,
|
||||
// The callable must be compatible with our signature.
|
||||
internal::is_callable_r<Result, typename std::decay<Callable>::type,
|
||||
Args...>>;
|
||||
internal::is_callable_r<Result, std::decay_t<Callable>, Args...>,
|
||||
// It must be possible to capture the callable in StdFunctionAdaptor.
|
||||
std::is_constructible<std::decay_t<Callable>, Callable>>;
|
||||
|
||||
// True iff we can use the given callable type via StdFunctionAdaptor once we
|
||||
// ignore incoming arguments.
|
||||
template <typename Callable>
|
||||
using IsCompatibleAfterIgnoringArguments = internal::conjunction<
|
||||
// It must be possible to capture the callable in a lambda.
|
||||
std::is_constructible<typename std::decay<Callable>::type, Callable>,
|
||||
// The callable must be invocable with zero arguments, returning something
|
||||
// convertible to Result.
|
||||
internal::is_callable_r<Result, typename std::decay<Callable>::type>>;
|
||||
internal::is_callable_r<Result, std::decay_t<Callable>>,
|
||||
// It must be possible to capture the callable in a lambda.
|
||||
std::is_constructible<std::decay_t<Callable>, Callable>>;
|
||||
|
||||
public:
|
||||
// Construct from a callable that is directly compatible with our mocked
|
||||
|
|
@ -567,7 +573,7 @@ class OnceAction<Result(Args...)> final {
|
|||
// // Sets the default value for type T to be foo.
|
||||
// DefaultValue<T>::Set(foo);
|
||||
template <typename T>
|
||||
class DefaultValue {
|
||||
class [[nodiscard]] DefaultValue {
|
||||
public:
|
||||
// Sets the default value for type T; requires T to be
|
||||
// copy-constructable and have a public destructor.
|
||||
|
|
@ -611,7 +617,7 @@ class DefaultValue {
|
|||
private:
|
||||
class ValueProducer {
|
||||
public:
|
||||
virtual ~ValueProducer() {}
|
||||
virtual ~ValueProducer() = default;
|
||||
virtual T Produce() = 0;
|
||||
};
|
||||
|
||||
|
|
@ -644,7 +650,7 @@ class DefaultValue {
|
|||
// This partial specialization allows a user to set default values for
|
||||
// reference types.
|
||||
template <typename T>
|
||||
class DefaultValue<T&> {
|
||||
class [[nodiscard]] DefaultValue<T&> {
|
||||
public:
|
||||
// Sets the default value for type T&.
|
||||
static void Set(T& x) { // NOLINT
|
||||
|
|
@ -678,7 +684,7 @@ class DefaultValue<T&> {
|
|||
// This specialization allows DefaultValue<void>::Get() to
|
||||
// compile.
|
||||
template <>
|
||||
class DefaultValue<void> {
|
||||
class [[nodiscard]] DefaultValue<void> {
|
||||
public:
|
||||
static bool Exists() { return true; }
|
||||
static void Get() {}
|
||||
|
|
@ -694,13 +700,13 @@ T* DefaultValue<T&>::address_ = nullptr;
|
|||
|
||||
// Implement this interface to define an action for function type F.
|
||||
template <typename F>
|
||||
class ActionInterface {
|
||||
class [[nodiscard]] ActionInterface {
|
||||
public:
|
||||
typedef typename internal::Function<F>::Result Result;
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
ActionInterface() {}
|
||||
virtual ~ActionInterface() {}
|
||||
ActionInterface() = default;
|
||||
virtual ~ActionInterface() = default;
|
||||
|
||||
// Performs the action. This method is not const, as in general an
|
||||
// action can have side effects and be stateful. For example, a
|
||||
|
|
@ -714,7 +720,7 @@ class ActionInterface {
|
|||
};
|
||||
|
||||
template <typename F>
|
||||
class Action;
|
||||
class [[nodiscard]] Action;
|
||||
|
||||
// An Action<R(Args...)> is a copyable and IMMUTABLE (except by assignment)
|
||||
// object that represents an action to be taken when a mock function of type
|
||||
|
|
@ -723,7 +729,7 @@ class Action;
|
|||
// can view an object implementing ActionInterface<F> as a concrete action
|
||||
// (including its current state), and an Action<F> object as a handle to it.
|
||||
template <typename R, typename... Args>
|
||||
class Action<R(Args...)> {
|
||||
class [[nodiscard]] Action<R(Args...)> {
|
||||
private:
|
||||
using F = R(Args...);
|
||||
|
||||
|
|
@ -749,7 +755,7 @@ class Action<R(Args...)> {
|
|||
|
||||
// Constructs a null Action. Needed for storing Action objects in
|
||||
// STL containers.
|
||||
Action() {}
|
||||
Action() = default;
|
||||
|
||||
// Construct an Action from a specified callable.
|
||||
// This cannot take std::function directly, because then Action would not be
|
||||
|
|
@ -828,6 +834,10 @@ class Action<R(Args...)> {
|
|||
Result operator()(const InArgs&...) const {
|
||||
return function_impl();
|
||||
}
|
||||
template <typename... InArgs>
|
||||
Result operator()(const InArgs&...) {
|
||||
return function_impl();
|
||||
}
|
||||
|
||||
FunctionImpl function_impl;
|
||||
};
|
||||
|
|
@ -858,7 +868,7 @@ class Action<R(Args...)> {
|
|||
// the definition of Return(void) and SetArgumentPointee<N>(value) for
|
||||
// complete examples.
|
||||
template <typename Impl>
|
||||
class PolymorphicAction {
|
||||
class [[nodiscard]] PolymorphicAction {
|
||||
public:
|
||||
explicit PolymorphicAction(const Impl& impl) : impl_(impl) {}
|
||||
|
||||
|
|
@ -918,7 +928,7 @@ struct ByMoveWrapper {
|
|||
|
||||
// The general implementation of Return(R). Specializations follow below.
|
||||
template <typename R>
|
||||
class ReturnAction final {
|
||||
class [[nodiscard]] ReturnAction final {
|
||||
public:
|
||||
explicit ReturnAction(R value) : value_(std::move(value)) {}
|
||||
|
||||
|
|
@ -1084,7 +1094,7 @@ class ReturnAction final {
|
|||
// the const call operator, checking at runtime that it isn't called more than
|
||||
// once, since the user has declared their intent to do so by using ByMove.
|
||||
template <typename T>
|
||||
class ReturnAction<ByMoveWrapper<T>> final {
|
||||
class [[nodiscard]] ReturnAction<ByMoveWrapper<T>> final {
|
||||
public:
|
||||
explicit ReturnAction(ByMoveWrapper<T> wrapper)
|
||||
: state_(new State(std::move(wrapper.payload))) {}
|
||||
|
|
@ -1111,7 +1121,7 @@ class ReturnAction<ByMoveWrapper<T>> final {
|
|||
};
|
||||
|
||||
// Implements the ReturnNull() action.
|
||||
class ReturnNullAction {
|
||||
class [[nodiscard]] ReturnNullAction {
|
||||
public:
|
||||
// Allows ReturnNull() to be used in any pointer-returning function. In C++11
|
||||
// this is enforced by returning nullptr, and in non-C++11 by asserting a
|
||||
|
|
@ -1123,7 +1133,7 @@ class ReturnNullAction {
|
|||
};
|
||||
|
||||
// Implements the Return() action.
|
||||
class ReturnVoidAction {
|
||||
class [[nodiscard]] ReturnVoidAction {
|
||||
public:
|
||||
// Allows Return() to be used in any void-returning function.
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
|
|
@ -1136,7 +1146,7 @@ class ReturnVoidAction {
|
|||
// in any function that returns a reference to the type of x,
|
||||
// regardless of the argument types.
|
||||
template <typename T>
|
||||
class ReturnRefAction {
|
||||
class [[nodiscard]] ReturnRefAction {
|
||||
public:
|
||||
// Constructs a ReturnRefAction object from the reference to be returned.
|
||||
explicit ReturnRefAction(T& ref) : ref_(ref) {} // NOLINT
|
||||
|
|
@ -1177,7 +1187,7 @@ class ReturnRefAction {
|
|||
// used in any function that returns a reference to the type of x,
|
||||
// regardless of the argument types.
|
||||
template <typename T>
|
||||
class ReturnRefOfCopyAction {
|
||||
class [[nodiscard]] ReturnRefOfCopyAction {
|
||||
public:
|
||||
// Constructs a ReturnRefOfCopyAction object from the reference to
|
||||
// be returned.
|
||||
|
|
@ -1218,7 +1228,7 @@ class ReturnRefOfCopyAction {
|
|||
// Implements the polymorphic ReturnRoundRobin(v) action, which can be
|
||||
// used in any function that returns the element_type of v.
|
||||
template <typename T>
|
||||
class ReturnRoundRobinAction {
|
||||
class [[nodiscard]] ReturnRoundRobinAction {
|
||||
public:
|
||||
explicit ReturnRoundRobinAction(std::vector<T> values) {
|
||||
GTEST_CHECK_(!values.empty())
|
||||
|
|
@ -1246,7 +1256,7 @@ class ReturnRoundRobinAction {
|
|||
};
|
||||
|
||||
// Implements the polymorphic DoDefault() action.
|
||||
class DoDefaultAction {
|
||||
class [[nodiscard]] DoDefaultAction {
|
||||
public:
|
||||
// This template type conversion operator allows DoDefault() to be
|
||||
// used in any function.
|
||||
|
|
@ -1259,7 +1269,7 @@ class DoDefaultAction {
|
|||
// Implements the Assign action to set a given pointer referent to a
|
||||
// particular value.
|
||||
template <typename T1, typename T2>
|
||||
class AssignAction {
|
||||
class [[nodiscard]] AssignAction {
|
||||
public:
|
||||
AssignAction(T1* ptr, T2 value) : ptr_(ptr), value_(value) {}
|
||||
|
||||
|
|
@ -1273,12 +1283,12 @@ class AssignAction {
|
|||
const T2 value_;
|
||||
};
|
||||
|
||||
#if !GTEST_OS_WINDOWS_MOBILE
|
||||
#ifndef GTEST_OS_WINDOWS_MOBILE
|
||||
|
||||
// Implements the SetErrnoAndReturn action to simulate return from
|
||||
// various system calls and libc functions.
|
||||
template <typename T>
|
||||
class SetErrnoAndReturnAction {
|
||||
class [[nodiscard]] SetErrnoAndReturnAction {
|
||||
public:
|
||||
SetErrnoAndReturnAction(int errno_value, T result)
|
||||
: errno_(errno_value), result_(result) {}
|
||||
|
|
@ -1320,22 +1330,6 @@ struct InvokeMethodAction {
|
|||
}
|
||||
};
|
||||
|
||||
// Implements the InvokeWithoutArgs(f) action. The template argument
|
||||
// FunctionImpl is the implementation type of f, which can be either a
|
||||
// function pointer or a functor. InvokeWithoutArgs(f) can be used as an
|
||||
// Action<F> as long as f's type is compatible with F.
|
||||
template <typename FunctionImpl>
|
||||
struct InvokeWithoutArgsAction {
|
||||
FunctionImpl function_impl;
|
||||
|
||||
// Allows InvokeWithoutArgs(f) to be used as any action whose type is
|
||||
// compatible with f.
|
||||
template <typename... Args>
|
||||
auto operator()(const Args&...) -> decltype(function_impl()) {
|
||||
return function_impl();
|
||||
}
|
||||
};
|
||||
|
||||
// Implements the InvokeWithoutArgs(object_ptr, &Class::Method) action.
|
||||
template <class Class, typename MethodPtr>
|
||||
struct InvokeMethodWithoutArgsAction {
|
||||
|
|
@ -1386,7 +1380,7 @@ class IgnoreResultAction {
|
|||
|
||||
void Perform(const ArgumentTuple& args) override {
|
||||
// Performs the action and ignores its result.
|
||||
action_.Perform(args);
|
||||
(void)action_.Perform(args);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -1444,6 +1438,30 @@ struct WithArgsAction {
|
|||
return OA{std::move(inner_action)};
|
||||
}
|
||||
|
||||
// As above, but in the case where we want to create a OnceAction from a const
|
||||
// WithArgsAction. This is fine as long as the inner action doesn't need to
|
||||
// move any of its state to create a OnceAction.
|
||||
template <
|
||||
typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
std::is_convertible<const InnerAction&,
|
||||
OnceAction<R(internal::TupleElement<
|
||||
I, std::tuple<Args...>>...)>>::value,
|
||||
int>::type = 0>
|
||||
operator OnceAction<R(Args...)>() const& { // NOLINT
|
||||
struct OA {
|
||||
OnceAction<InnerSignature<R, Args...>> inner_action;
|
||||
|
||||
R operator()(Args&&... args) && {
|
||||
return std::move(inner_action)
|
||||
.Call(std::get<I>(
|
||||
std::forward_as_tuple(std::forward<Args>(args)...))...);
|
||||
}
|
||||
};
|
||||
|
||||
return OA{inner_action};
|
||||
}
|
||||
|
||||
template <
|
||||
typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
|
|
@ -1468,11 +1486,11 @@ struct WithArgsAction {
|
|||
};
|
||||
|
||||
template <typename... Actions>
|
||||
class DoAllAction;
|
||||
class [[nodiscard]] DoAllAction;
|
||||
|
||||
// Base case: only a single action.
|
||||
template <typename FinalAction>
|
||||
class DoAllAction<FinalAction> {
|
||||
class [[nodiscard]] DoAllAction<FinalAction> {
|
||||
public:
|
||||
struct UserConstructorTag {};
|
||||
|
||||
|
|
@ -1486,6 +1504,7 @@ class DoAllAction<FinalAction> {
|
|||
// providing a call operator because even with a particular set of arguments
|
||||
// they don't have a fixed return type.
|
||||
|
||||
// We support conversion to OnceAction whenever the sub-action does.
|
||||
template <typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
std::is_convertible<FinalAction, OnceAction<R(Args...)>>::value,
|
||||
|
|
@ -1494,6 +1513,21 @@ class DoAllAction<FinalAction> {
|
|||
return std::move(final_action_);
|
||||
}
|
||||
|
||||
// We also support conversion to OnceAction whenever the sub-action supports
|
||||
// conversion to Action (since any Action can also be a OnceAction).
|
||||
template <
|
||||
typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
conjunction<
|
||||
negation<
|
||||
std::is_convertible<FinalAction, OnceAction<R(Args...)>>>,
|
||||
std::is_convertible<FinalAction, Action<R(Args...)>>>::value,
|
||||
int>::type = 0>
|
||||
operator OnceAction<R(Args...)>() && { // NOLINT
|
||||
return Action<R(Args...)>(std::move(final_action_));
|
||||
}
|
||||
|
||||
// We support conversion to Action whenever the sub-action does.
|
||||
template <
|
||||
typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
|
|
@ -1510,7 +1544,7 @@ class DoAllAction<FinalAction> {
|
|||
// Recursive case: support N actions by calling the initial action and then
|
||||
// calling through to the base class containing N-1 actions.
|
||||
template <typename InitialAction, typename... OtherActions>
|
||||
class DoAllAction<InitialAction, OtherActions...>
|
||||
class [[nodiscard]] DoAllAction<InitialAction, OtherActions...>
|
||||
: private DoAllAction<OtherActions...> {
|
||||
private:
|
||||
using Base = DoAllAction<OtherActions...>;
|
||||
|
|
@ -1573,16 +1607,16 @@ class DoAllAction<InitialAction, OtherActions...>
|
|||
: Base({}, std::forward<U>(other_actions)...),
|
||||
initial_action_(std::forward<T>(initial_action)) {}
|
||||
|
||||
template <typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
conjunction<
|
||||
// Both the initial action and the rest must support
|
||||
// conversion to OnceAction.
|
||||
std::is_convertible<
|
||||
InitialAction,
|
||||
OnceAction<void(InitialActionArgType<Args>...)>>,
|
||||
std::is_convertible<Base, OnceAction<R(Args...)>>>::value,
|
||||
int>::type = 0>
|
||||
// We support conversion to OnceAction whenever both the initial action and
|
||||
// the rest support conversion to OnceAction.
|
||||
template <
|
||||
typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
conjunction<std::is_convertible<
|
||||
InitialAction,
|
||||
OnceAction<void(InitialActionArgType<Args>...)>>,
|
||||
std::is_convertible<Base, OnceAction<R(Args...)>>>::value,
|
||||
int>::type = 0>
|
||||
operator OnceAction<R(Args...)>() && { // NOLINT
|
||||
// Return an action that first calls the initial action with arguments
|
||||
// filtered through InitialActionArgType, then forwards arguments directly
|
||||
|
|
@ -1605,12 +1639,34 @@ class DoAllAction<InitialAction, OtherActions...>
|
|||
};
|
||||
}
|
||||
|
||||
// We also support conversion to OnceAction whenever the initial action
|
||||
// supports conversion to Action (since any Action can also be a OnceAction).
|
||||
//
|
||||
// The remaining sub-actions must also be compatible, but we don't need to
|
||||
// special case them because the base class deals with them.
|
||||
template <
|
||||
typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
conjunction<
|
||||
negation<std::is_convertible<
|
||||
InitialAction,
|
||||
OnceAction<void(InitialActionArgType<Args>...)>>>,
|
||||
std::is_convertible<InitialAction,
|
||||
Action<void(InitialActionArgType<Args>...)>>,
|
||||
std::is_convertible<Base, OnceAction<R(Args...)>>>::value,
|
||||
int>::type = 0>
|
||||
operator OnceAction<R(Args...)>() && { // NOLINT
|
||||
return DoAll(
|
||||
Action<void(InitialActionArgType<Args>...)>(std::move(initial_action_)),
|
||||
std::move(static_cast<Base&>(*this)));
|
||||
}
|
||||
|
||||
// We support conversion to Action whenever both the initial action and the
|
||||
// rest support conversion to Action.
|
||||
template <
|
||||
typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
conjunction<
|
||||
// Both the initial action and the rest must support conversion to
|
||||
// Action.
|
||||
std::is_convertible<const InitialAction&,
|
||||
Action<void(InitialActionArgType<Args>...)>>,
|
||||
std::is_convertible<const Base&, Action<R(Args...)>>>::value,
|
||||
|
|
@ -1674,6 +1730,16 @@ struct SaveArgAction {
|
|||
}
|
||||
};
|
||||
|
||||
template <size_t k, typename Ptr>
|
||||
struct SaveArgByMoveAction {
|
||||
Ptr pointer;
|
||||
|
||||
template <typename... Args>
|
||||
void operator()(Args&&... args) const {
|
||||
*pointer = std::move(std::get<k>(std::tie(args...)));
|
||||
}
|
||||
};
|
||||
|
||||
template <size_t k, typename Ptr>
|
||||
struct SaveArgPointeeAction {
|
||||
Ptr pointer;
|
||||
|
|
@ -1713,11 +1779,24 @@ struct SetArrayArgumentAction {
|
|||
};
|
||||
|
||||
template <size_t k>
|
||||
struct DeleteArgAction {
|
||||
class [[nodiscard]] DeleteArgAction {
|
||||
public:
|
||||
template <typename... Args>
|
||||
void operator()(const Args&... args) const {
|
||||
delete std::get<k>(std::tie(args...));
|
||||
DoDelete(std::get<k>(std::tie(args...)));
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
static void DoDelete(T* ptr) {
|
||||
delete ptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
[[deprecated(
|
||||
"DeleteArg<N> used for a non-pointer argument, it was likely migrated "
|
||||
"to a smart pointer type. This action should be removed.")]]
|
||||
static void DoDelete(T&) {}
|
||||
};
|
||||
|
||||
template <typename Ptr>
|
||||
|
|
@ -1740,6 +1819,13 @@ struct ThrowAction {
|
|||
return [copy](Args...) -> R { throw copy; };
|
||||
}
|
||||
};
|
||||
struct RethrowAction {
|
||||
std::exception_ptr exception;
|
||||
template <typename R, typename... Args>
|
||||
operator Action<R(Args...)>() const { // NOLINT
|
||||
return [ex = exception](Args...) -> R { std::rethrow_exception(ex); };
|
||||
}
|
||||
};
|
||||
#endif // GTEST_HAS_EXCEPTIONS
|
||||
|
||||
} // namespace internal
|
||||
|
|
@ -1776,6 +1862,13 @@ struct ThrowAction {
|
|||
// EXPECT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin));
|
||||
typedef internal::IgnoredValue Unused;
|
||||
|
||||
// Deprecated single-argument DoAll.
|
||||
template <typename Action>
|
||||
GTEST_INTERNAL_DEPRECATE_AND_INLINE("Avoid using DoAll() for single actions")
|
||||
typename std::decay<Action>::type DoAll(Action&& action) {
|
||||
return std::forward<Action>(action);
|
||||
}
|
||||
|
||||
// Creates an action that does actions a1, a2, ..., sequentially in
|
||||
// each invocation. All but the last action will have a readonly view of the
|
||||
// arguments.
|
||||
|
|
@ -1926,7 +2019,7 @@ PolymorphicAction<internal::AssignAction<T1, T2>> Assign(T1* ptr, T2 val) {
|
|||
return MakePolymorphicAction(internal::AssignAction<T1, T2>(ptr, val));
|
||||
}
|
||||
|
||||
#if !GTEST_OS_WINDOWS_MOBILE
|
||||
#ifndef GTEST_OS_WINDOWS_MOBILE
|
||||
|
||||
// Creates an action that sets errno and returns the appropriate error.
|
||||
template <typename T>
|
||||
|
|
@ -1941,10 +2034,11 @@ PolymorphicAction<internal::SetErrnoAndReturnAction<T>> SetErrnoAndReturn(
|
|||
// Various overloads for Invoke().
|
||||
|
||||
// Legacy function.
|
||||
// Actions can now be implicitly constructed from callables. No need to create
|
||||
// wrapper objects.
|
||||
// This function exists for backwards compatibility.
|
||||
template <typename FunctionImpl>
|
||||
GTEST_INTERNAL_DEPRECATE_AND_INLINE(
|
||||
"Actions can now be implicitly constructed from callables. No need to "
|
||||
"create wrapper objects using Invoke().")
|
||||
typename std::decay<FunctionImpl>::type Invoke(FunctionImpl&& function_impl) {
|
||||
return std::forward<FunctionImpl>(function_impl);
|
||||
}
|
||||
|
|
@ -1959,9 +2053,11 @@ internal::InvokeMethodAction<Class, MethodPtr> Invoke(Class* obj_ptr,
|
|||
|
||||
// Creates an action that invokes 'function_impl' with no argument.
|
||||
template <typename FunctionImpl>
|
||||
internal::InvokeWithoutArgsAction<typename std::decay<FunctionImpl>::type>
|
||||
InvokeWithoutArgs(FunctionImpl function_impl) {
|
||||
return {std::move(function_impl)};
|
||||
GTEST_INTERNAL_DEPRECATE_AND_INLINE(
|
||||
"Actions can now be implicitly constructed from zero-argument callables. "
|
||||
"No need to create wrapper objects using InvokeWithoutArgs().")
|
||||
std::decay_t<FunctionImpl> InvokeWithoutArgs(FunctionImpl&& function_impl) {
|
||||
return std::forward<FunctionImpl>(function_impl);
|
||||
}
|
||||
|
||||
// Creates an action that invokes the given method on the given object
|
||||
|
|
@ -2017,6 +2113,13 @@ internal::SaveArgAction<k, Ptr> SaveArg(Ptr pointer) {
|
|||
return {pointer};
|
||||
}
|
||||
|
||||
// Action SaveArgByMove<k>(pointer) moves the k-th (0-based) argument of the
|
||||
// mock function into *pointer.
|
||||
template <size_t k, typename Ptr>
|
||||
internal::SaveArgByMoveAction<k, Ptr> SaveArgByMove(Ptr pointer) {
|
||||
return {pointer};
|
||||
}
|
||||
|
||||
// Action SaveArgPointee<k>(pointer) saves the value pointed to
|
||||
// by the k-th (0-based) argument of the mock function to *pointer.
|
||||
template <size_t k, typename Ptr>
|
||||
|
|
@ -2056,13 +2159,23 @@ internal::ReturnPointeeAction<Ptr> ReturnPointee(Ptr pointer) {
|
|||
return {pointer};
|
||||
}
|
||||
|
||||
// Action Throw(exception) can be used in a mock function of any type
|
||||
// to throw the given exception. Any copyable value can be thrown.
|
||||
#if GTEST_HAS_EXCEPTIONS
|
||||
// Action Throw(exception) can be used in a mock function of any type
|
||||
// to throw the given exception. Any copyable value can be thrown,
|
||||
// except for std::exception_ptr, which is likely a mistake if
|
||||
// thrown directly.
|
||||
template <typename T>
|
||||
internal::ThrowAction<typename std::decay<T>::type> Throw(T&& exception) {
|
||||
typename std::enable_if<
|
||||
!std::is_base_of<std::exception_ptr, typename std::decay<T>::type>::value,
|
||||
internal::ThrowAction<typename std::decay<T>::type>>::type
|
||||
Throw(T&& exception) {
|
||||
return {std::forward<T>(exception)};
|
||||
}
|
||||
// Action Rethrow(exception_ptr) can be used in a mock function of any type
|
||||
// to rethrow any exception_ptr. Note that the same object is thrown each time.
|
||||
inline internal::RethrowAction Rethrow(std::exception_ptr exception) {
|
||||
return {std::move(exception)};
|
||||
}
|
||||
#endif // GTEST_HAS_EXCEPTIONS
|
||||
|
||||
namespace internal {
|
||||
|
|
@ -2111,13 +2224,13 @@ struct ActionImpl<R(Args...), Impl> : ImplBase<Impl>::type {
|
|||
R operator()(Args&&... arg) const {
|
||||
static constexpr size_t kMaxArgs =
|
||||
sizeof...(Args) <= 10 ? sizeof...(Args) : 10;
|
||||
return Apply(MakeIndexSequence<kMaxArgs>{},
|
||||
MakeIndexSequence<10 - kMaxArgs>{},
|
||||
return Apply(std::make_index_sequence<kMaxArgs>{},
|
||||
std::make_index_sequence<10 - kMaxArgs>{},
|
||||
args_type{std::forward<Args>(arg)...});
|
||||
}
|
||||
|
||||
template <std::size_t... arg_id, std::size_t... excess_id>
|
||||
R Apply(IndexSequence<arg_id...>, IndexSequence<excess_id...>,
|
||||
R Apply(std::index_sequence<arg_id...>, std::index_sequence<excess_id...>,
|
||||
const args_type& args) const {
|
||||
// Impl need not be specific to the signature of action being implemented;
|
||||
// only the implementing function body needs to have all of the specific
|
||||
|
|
@ -2150,9 +2263,9 @@ template <typename F, typename Impl>
|
|||
}
|
||||
|
||||
#define GMOCK_INTERNAL_ARG_UNUSED(i, data, el) \
|
||||
, const arg##i##_type& arg##i GTEST_ATTRIBUTE_UNUSED_
|
||||
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \
|
||||
const args_type& args GTEST_ATTRIBUTE_UNUSED_ GMOCK_PP_REPEAT( \
|
||||
, [[maybe_unused]] const arg##i##_type& arg##i
|
||||
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \
|
||||
[[maybe_unused]] const args_type& args GMOCK_PP_REPEAT( \
|
||||
GMOCK_INTERNAL_ARG_UNUSED, , 10)
|
||||
|
||||
#define GMOCK_INTERNAL_ARG(i, data, el) , const arg##i##_type& arg##i
|
||||
|
|
@ -2217,8 +2330,8 @@ template <typename F, typename Impl>
|
|||
std::shared_ptr<const gmock_Impl> impl_; \
|
||||
}; \
|
||||
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
|
||||
inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \
|
||||
GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) GTEST_MUST_USE_RESULT_; \
|
||||
[[nodiscard]] inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \
|
||||
GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)); \
|
||||
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
|
||||
inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \
|
||||
GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) { \
|
||||
|
|
@ -2253,7 +2366,7 @@ template <typename F, typename Impl>
|
|||
return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \
|
||||
}; \
|
||||
}; \
|
||||
inline name##Action name() GTEST_MUST_USE_RESULT_; \
|
||||
[[nodiscard]] inline name##Action name(); \
|
||||
inline name##Action name() { return name##Action(); } \
|
||||
template <typename function_type, typename return_type, typename args_type, \
|
||||
GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
|
||||
|
|
|
|||
|
|
@ -63,9 +63,9 @@ namespace testing {
|
|||
// management as Cardinality objects can now be copied like plain values.
|
||||
|
||||
// The implementation of a cardinality.
|
||||
class CardinalityInterface {
|
||||
class [[nodiscard]] CardinalityInterface {
|
||||
public:
|
||||
virtual ~CardinalityInterface() {}
|
||||
virtual ~CardinalityInterface() = default;
|
||||
|
||||
// Conservative estimate on the lower/upper bound of the number of
|
||||
// calls allowed.
|
||||
|
|
@ -88,11 +88,11 @@ class CardinalityInterface {
|
|||
// object that specifies how many times a mock function is expected to
|
||||
// be called. The implementation of Cardinality is just a std::shared_ptr
|
||||
// to const CardinalityInterface. Don't inherit from Cardinality!
|
||||
class GTEST_API_ Cardinality {
|
||||
class GTEST_API_ [[nodiscard]] Cardinality {
|
||||
public:
|
||||
// Constructs a null cardinality. Needed for storing Cardinality
|
||||
// objects in STL containers.
|
||||
Cardinality() {}
|
||||
Cardinality() = default;
|
||||
|
||||
// Constructs a Cardinality from its implementation.
|
||||
explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits> // IWYU pragma: keep
|
||||
#include <utility> // IWYU pragma: keep
|
||||
|
||||
|
|
@ -69,22 +70,22 @@ constexpr bool PrefixOf(const char* a, const char* b) {
|
|||
return *a == 0 || (*a == *b && internal::PrefixOf(a + 1, b + 1));
|
||||
}
|
||||
|
||||
template <int N, int M>
|
||||
template <size_t N, size_t M>
|
||||
constexpr bool StartsWith(const char (&prefix)[N], const char (&str)[M]) {
|
||||
return N <= M && internal::PrefixOf(prefix, str);
|
||||
}
|
||||
|
||||
template <int N, int M>
|
||||
template <size_t N, size_t M>
|
||||
constexpr bool EndsWith(const char (&suffix)[N], const char (&str)[M]) {
|
||||
return N <= M && internal::PrefixOf(suffix, str + M - N);
|
||||
}
|
||||
|
||||
template <int N, int M>
|
||||
template <size_t N, size_t M>
|
||||
constexpr bool Equals(const char (&a)[N], const char (&b)[M]) {
|
||||
return N == M && internal::PrefixOf(a, b);
|
||||
}
|
||||
|
||||
template <int N>
|
||||
template <size_t N>
|
||||
constexpr bool ValidateSpec(const char (&spec)[N]) {
|
||||
return internal::Equals("const", spec) ||
|
||||
internal::Equals("override", spec) ||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -521,9 +521,8 @@
|
|||
GMOCK_INTERNAL_DECL_##value_params) \
|
||||
GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
|
||||
= default; \
|
||||
, \
|
||||
: impl_(std::make_shared<gmock_Impl>( \
|
||||
GMOCK_INTERNAL_LIST_##value_params)){}) \
|
||||
, : impl_(std::make_shared<gmock_Impl>( \
|
||||
GMOCK_INTERNAL_LIST_##value_params)){}) \
|
||||
GMOCK_ACTION_CLASS_(name, value_params)(const GMOCK_ACTION_CLASS_( \
|
||||
name, value_params) &) noexcept GMOCK_INTERNAL_DEFN_COPY_ \
|
||||
##value_params \
|
||||
|
|
@ -551,10 +550,10 @@
|
|||
}; \
|
||||
template <GMOCK_INTERNAL_DECL_##template_params \
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
||||
GMOCK_ACTION_CLASS_( \
|
||||
[[nodiscard]] GMOCK_ACTION_CLASS_( \
|
||||
name, value_params)<GMOCK_INTERNAL_LIST_##template_params \
|
||||
GMOCK_INTERNAL_LIST_TYPE_##value_params> \
|
||||
name(GMOCK_INTERNAL_DECL_##value_params) GTEST_MUST_USE_RESULT_; \
|
||||
name(GMOCK_INTERNAL_DECL_##value_params); \
|
||||
template <GMOCK_INTERNAL_DECL_##template_params \
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
||||
inline GMOCK_ACTION_CLASS_( \
|
||||
|
|
@ -592,21 +591,23 @@ namespace internal {
|
|||
// Overloads for other custom-callables are provided in the
|
||||
// internal/custom/gmock-generated-actions.h header.
|
||||
template <typename F, typename... Args>
|
||||
auto InvokeArgument(F f, Args... args) -> decltype(f(args...)) {
|
||||
return f(args...);
|
||||
auto InvokeArgument(F &&f,
|
||||
Args... args) -> decltype(std::forward<F>(f)(args...)) {
|
||||
return std::forward<F>(f)(args...);
|
||||
}
|
||||
|
||||
template <std::size_t index, typename... Params>
|
||||
struct InvokeArgumentAction {
|
||||
template <typename... Args,
|
||||
typename = typename std::enable_if<(index < sizeof...(Args))>::type>
|
||||
auto operator()(Args &&...args) const -> decltype(internal::InvokeArgument(
|
||||
std::get<index>(std::forward_as_tuple(std::forward<Args>(args)...)),
|
||||
std::declval<const Params &>()...)) {
|
||||
auto operator()(Args &&...args) const
|
||||
-> decltype(internal::InvokeArgument(
|
||||
std::get<index>(std::forward_as_tuple(std::forward<Args>(args)...)),
|
||||
std::declval<const Params &>()...)) {
|
||||
internal::FlatTuple<Args &&...> args_tuple(FlatTupleConstructTag{},
|
||||
std::forward<Args>(args)...);
|
||||
return params.Apply([&](const Params &...unpacked_params) {
|
||||
auto &&callable = args_tuple.template Get<index>();
|
||||
auto &&callable = std::move(args_tuple.template Get<index>());
|
||||
return internal::InvokeArgument(
|
||||
std::forward<decltype(callable)>(callable), unpacked_params...);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ namespace internal {
|
|||
// Implements the polymorphic IsEmpty matcher, which
|
||||
// can be used as a Matcher<T> as long as T is either a container that defines
|
||||
// empty() and size() (e.g. std::vector or std::string), or a C-style string.
|
||||
class IsEmptyMatcher {
|
||||
class [[nodiscard]] IsEmptyMatcher {
|
||||
public:
|
||||
// Matches anything that defines empty() and size().
|
||||
template <typename MatcheeContainerType>
|
||||
|
|
@ -76,9 +76,22 @@ class IsEmptyMatcher {
|
|||
|
||||
// Matches C-style strings.
|
||||
bool MatchAndExplain(const char* s, MatchResultListener* listener) const {
|
||||
if (s == nullptr) {
|
||||
return false;
|
||||
}
|
||||
return MatchAndExplain(std::string(s), listener);
|
||||
}
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
// Matches C-style wide strings.
|
||||
bool MatchAndExplain(const wchar_t* s, MatchResultListener* listener) const {
|
||||
if (s == nullptr) {
|
||||
return false;
|
||||
}
|
||||
return MatchAndExplain(std::wstring(s), listener);
|
||||
}
|
||||
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
||||
// Describes what this matcher matches.
|
||||
void DescribeTo(std::ostream* os) const { *os << "is empty"; }
|
||||
|
||||
|
|
|
|||
|
|
@ -71,11 +71,11 @@
|
|||
|
||||
namespace testing {
|
||||
template <class MockClass>
|
||||
class NiceMock;
|
||||
class [[nodiscard]] NiceMock;
|
||||
template <class MockClass>
|
||||
class NaggyMock;
|
||||
class [[nodiscard]] NaggyMock;
|
||||
template <class MockClass>
|
||||
class StrictMock;
|
||||
class [[nodiscard]] StrictMock;
|
||||
|
||||
namespace internal {
|
||||
template <typename T>
|
||||
|
|
@ -98,7 +98,7 @@ constexpr bool HasStrictnessModifier() {
|
|||
// deregistration. This guarantees that MockClass's constructor and destructor
|
||||
// run with the same level of strictness as its instance methods.
|
||||
|
||||
#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW && \
|
||||
#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MINGW) && \
|
||||
(defined(_MSC_VER) || defined(__clang__))
|
||||
// We need to mark these classes with this declspec to ensure that
|
||||
// the empty base class optimization is performed.
|
||||
|
|
@ -108,7 +108,7 @@ constexpr bool HasStrictnessModifier() {
|
|||
#endif
|
||||
|
||||
template <typename Base>
|
||||
class NiceMockImpl {
|
||||
class [[nodiscard]] NiceMockImpl {
|
||||
public:
|
||||
NiceMockImpl() {
|
||||
::testing::Mock::AllowUninterestingCalls(reinterpret_cast<uintptr_t>(this));
|
||||
|
|
@ -120,7 +120,7 @@ class NiceMockImpl {
|
|||
};
|
||||
|
||||
template <typename Base>
|
||||
class NaggyMockImpl {
|
||||
class [[nodiscard]] NaggyMockImpl {
|
||||
public:
|
||||
NaggyMockImpl() {
|
||||
::testing::Mock::WarnUninterestingCalls(reinterpret_cast<uintptr_t>(this));
|
||||
|
|
@ -132,7 +132,7 @@ class NaggyMockImpl {
|
|||
};
|
||||
|
||||
template <typename Base>
|
||||
class StrictMockImpl {
|
||||
class [[nodiscard]] StrictMockImpl {
|
||||
public:
|
||||
StrictMockImpl() {
|
||||
::testing::Mock::FailUninterestingCalls(reinterpret_cast<uintptr_t>(this));
|
||||
|
|
@ -146,7 +146,7 @@ class StrictMockImpl {
|
|||
} // namespace internal
|
||||
|
||||
template <class MockClass>
|
||||
class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
|
||||
class [[nodiscard]] GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
|
||||
: private internal::NiceMockImpl<MockClass>,
|
||||
public MockClass {
|
||||
public:
|
||||
|
|
@ -187,7 +187,7 @@ class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
|
|||
};
|
||||
|
||||
template <class MockClass>
|
||||
class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
|
||||
class [[nodiscard]] GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
|
||||
: private internal::NaggyMockImpl<MockClass>,
|
||||
public MockClass {
|
||||
static_assert(!internal::HasStrictnessModifier<MockClass>(),
|
||||
|
|
@ -229,7 +229,7 @@ class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
|
|||
};
|
||||
|
||||
template <class MockClass>
|
||||
class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock
|
||||
class [[nodiscard]] GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock
|
||||
: private internal::StrictMockImpl<MockClass>,
|
||||
public MockClass {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -204,6 +204,9 @@ class GTEST_API_ UntypedFunctionMockerBase {
|
|||
|
||||
using UntypedExpectations = std::vector<std::shared_ptr<ExpectationBase>>;
|
||||
|
||||
struct UninterestingCallCleanupHandler;
|
||||
struct FailureCleanupHandler;
|
||||
|
||||
// Returns an Expectation object that references and co-owns exp,
|
||||
// which must be an expectation on this mock function.
|
||||
Expectation GetHandleOf(ExpectationBase* exp);
|
||||
|
|
@ -563,7 +566,7 @@ class ExpectationSet {
|
|||
typedef Expectation::Set::value_type value_type;
|
||||
|
||||
// Constructs an empty set.
|
||||
ExpectationSet() {}
|
||||
ExpectationSet() = default;
|
||||
|
||||
// This single-argument ctor must not be explicit, in order to support the
|
||||
// ExpectationSet es = EXPECT_CALL(...);
|
||||
|
|
@ -865,7 +868,7 @@ class GTEST_API_ ExpectationBase {
|
|||
Clause last_clause_;
|
||||
mutable bool action_count_checked_; // Under mutex_.
|
||||
mutable Mutex mutex_; // Protects action_count_checked_.
|
||||
}; // class ExpectationBase
|
||||
}; // class ExpectationBase
|
||||
|
||||
template <typename F>
|
||||
class TypedExpectation;
|
||||
|
|
@ -1289,10 +1292,10 @@ class MockSpec {
|
|||
: function_mocker_(function_mocker), matchers_(matchers) {}
|
||||
|
||||
// Adds a new default action spec to the function mocker and returns
|
||||
// the newly created spec.
|
||||
internal::OnCallSpec<F>& InternalDefaultActionSetAt(const char* file,
|
||||
int line, const char* obj,
|
||||
const char* call) {
|
||||
// the newly created spec. .WillByDefault() must be called on the returned
|
||||
// object.
|
||||
[[nodiscard]] internal::OnCallSpec<F>& InternalDefaultActionSetAt(
|
||||
const char* file, int line, const char* obj, const char* call) {
|
||||
LogWithLocation(internal::kInfo, file, line,
|
||||
std::string("ON_CALL(") + obj + ", " + call + ") invoked");
|
||||
return function_mocker_->AddNewOnCallSpec(file, line, matchers_);
|
||||
|
|
@ -1396,6 +1399,41 @@ class Cleanup final {
|
|||
std::function<void()> f_;
|
||||
};
|
||||
|
||||
struct UntypedFunctionMockerBase::UninterestingCallCleanupHandler {
|
||||
CallReaction reaction;
|
||||
std::stringstream& ss;
|
||||
|
||||
~UninterestingCallCleanupHandler() {
|
||||
ReportUninterestingCall(reaction, ss.str());
|
||||
}
|
||||
};
|
||||
|
||||
struct UntypedFunctionMockerBase::FailureCleanupHandler {
|
||||
std::stringstream& ss;
|
||||
std::stringstream& why;
|
||||
std::stringstream& loc;
|
||||
const ExpectationBase* untyped_expectation;
|
||||
bool found;
|
||||
bool is_excessive;
|
||||
|
||||
~FailureCleanupHandler() {
|
||||
ss << "\n" << why.str();
|
||||
|
||||
if (!found) {
|
||||
// No expectation matches this call - reports a failure.
|
||||
Expect(false, nullptr, -1, ss.str());
|
||||
} else if (is_excessive) {
|
||||
// We had an upper-bound violation and the failure message is in ss.
|
||||
Expect(false, untyped_expectation->file(), untyped_expectation->line(),
|
||||
ss.str());
|
||||
} else {
|
||||
// We had an expected call and the matching expectation is
|
||||
// described in ss.
|
||||
Log(kInfo, loc.str() + ss.str(), 2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
class FunctionMocker;
|
||||
|
||||
|
|
@ -1408,7 +1446,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
|||
using ArgumentTuple = std::tuple<Args...>;
|
||||
using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;
|
||||
|
||||
FunctionMocker() {}
|
||||
FunctionMocker() = default;
|
||||
|
||||
// There is no generally useful and implementable semantics of
|
||||
// copying a mock object, so copying a mock is usually a user error.
|
||||
|
|
@ -1429,7 +1467,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
|||
// function have been satisfied. If not, it will report Google Test
|
||||
// non-fatal failures for the violations.
|
||||
~FunctionMocker() override GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
MutexLock l(g_gmock_mutex);
|
||||
VerifyAndClearExpectationsLocked();
|
||||
Mock::UnregisterLocked(this);
|
||||
ClearDefaultActionsLocked();
|
||||
|
|
@ -1492,7 +1530,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
|||
UntypedOnCallSpecs specs_to_delete;
|
||||
untyped_on_call_specs_.swap(specs_to_delete);
|
||||
|
||||
g_gmock_mutex.Unlock();
|
||||
g_gmock_mutex.unlock();
|
||||
for (UntypedOnCallSpecs::const_iterator it = specs_to_delete.begin();
|
||||
it != specs_to_delete.end(); ++it) {
|
||||
delete static_cast<const OnCallSpec<F>*>(*it);
|
||||
|
|
@ -1500,7 +1538,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
|||
|
||||
// Lock the mutex again, since the caller expects it to be locked when we
|
||||
// return.
|
||||
g_gmock_mutex.Lock();
|
||||
g_gmock_mutex.lock();
|
||||
}
|
||||
|
||||
// Returns the result of invoking this mock function with the given
|
||||
|
|
@ -1608,7 +1646,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
|||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
const ArgumentTuple& args =
|
||||
*static_cast<const ArgumentTuple*>(untyped_args);
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
MutexLock l(g_gmock_mutex);
|
||||
TypedExpectation<F>* exp = this->FindMatchingExpectationLocked(args);
|
||||
if (exp == nullptr) { // A match wasn't found.
|
||||
this->FormatUnexpectedCallMessageLocked(args, what, why);
|
||||
|
|
@ -1794,8 +1832,14 @@ R FunctionMocker<R(Args...)>::InvokeWith(ArgumentTuple&& args)
|
|||
//
|
||||
// We use RAII to do the latter in case R is void or a non-moveable type. In
|
||||
// either case we can't assign it to a local variable.
|
||||
const Cleanup report_uninteresting_call(
|
||||
[&] { ReportUninterestingCall(reaction, ss.str()); });
|
||||
//
|
||||
// Note that std::bind() is essential here.
|
||||
// We *don't* use any local callback types (like lambdas).
|
||||
// Doing so slows down compilation dramatically because the *constructor* of
|
||||
// std::function<T> is re-instantiated with different template
|
||||
// parameters each time.
|
||||
const UninterestingCallCleanupHandler report_uninteresting_call = {reaction,
|
||||
ss};
|
||||
|
||||
return PerformActionAndPrintResult(nullptr, std::move(args), ss.str(), ss);
|
||||
}
|
||||
|
|
@ -1839,22 +1883,13 @@ R FunctionMocker<R(Args...)>::InvokeWith(ArgumentTuple&& args)
|
|||
//
|
||||
// We use RAII to do the latter in case R is void or a non-moveable type. In
|
||||
// either case we can't assign it to a local variable.
|
||||
const Cleanup handle_failures([&] {
|
||||
ss << "\n" << why.str();
|
||||
|
||||
if (!found) {
|
||||
// No expectation matches this call - reports a failure.
|
||||
Expect(false, nullptr, -1, ss.str());
|
||||
} else if (is_excessive) {
|
||||
// We had an upper-bound violation and the failure message is in ss.
|
||||
Expect(false, untyped_expectation->file(), untyped_expectation->line(),
|
||||
ss.str());
|
||||
} else {
|
||||
// We had an expected call and the matching expectation is
|
||||
// described in ss.
|
||||
Log(kInfo, loc.str() + ss.str(), 2);
|
||||
}
|
||||
});
|
||||
//
|
||||
// Note that we *don't* use any local callback types (like lambdas) here.
|
||||
// Doing so slows down compilation dramatically because the *constructor* of
|
||||
// std::function<T> is re-instantiated with different template
|
||||
// parameters each time.
|
||||
const FailureCleanupHandler handle_failures = {
|
||||
ss, why, loc, untyped_expectation, found, is_excessive};
|
||||
|
||||
return PerformActionAndPrintResult(untyped_action, std::move(args), ss.str(),
|
||||
ss);
|
||||
|
|
@ -1922,6 +1957,11 @@ struct SignatureOf<R(Args...)> {
|
|||
using type = R(Args...);
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct SignatureOf<R(Args...) const> {
|
||||
using type = R(Args...);
|
||||
};
|
||||
|
||||
template <template <typename> class C, typename F>
|
||||
struct SignatureOf<C<F>,
|
||||
typename std::enable_if<std::is_function<F>::value>::type>
|
||||
|
|
@ -2097,9 +2137,9 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
|||
// second argument is an internal type derived from the method signature. The
|
||||
// failure to disambiguate two overloads of this method in the ON_CALL statement
|
||||
// is how we block callers from setting expectations on overloaded methods.
|
||||
#define GMOCK_ON_CALL_IMPL_(mock_expr, Setter, call) \
|
||||
((mock_expr).gmock_##call)(::testing::internal::GetWithoutMatchers(), \
|
||||
nullptr) \
|
||||
#define GMOCK_ON_CALL_IMPL_(mock_expr, Setter, call) \
|
||||
((mock_expr).gmock_##call)(::testing::internal::WithoutMatchers::Get(), \
|
||||
nullptr) \
|
||||
.Setter(__FILE__, __LINE__, #mock_expr, #call)
|
||||
|
||||
#define ON_CALL(obj, call) \
|
||||
|
|
|
|||
|
|
@ -53,13 +53,14 @@
|
|||
//
|
||||
// where all clauses are optional and WillOnce() can be repeated.
|
||||
|
||||
#include "gmock/gmock-actions.h"
|
||||
#include "gmock/gmock-cardinalities.h"
|
||||
#include "gmock/gmock-function-mocker.h"
|
||||
#include "gmock/gmock-matchers.h"
|
||||
#include "gmock/gmock-more-actions.h"
|
||||
#include "gmock/gmock-more-matchers.h"
|
||||
#include "gmock/gmock-nice-strict.h"
|
||||
#include "gmock/gmock-actions.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-cardinalities.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-function-mocker.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-matchers.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-more-actions.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-more-matchers.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-nice-strict.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-spec-builders.h" // IWYU pragma: export
|
||||
#include "gmock/internal/gmock-internal-utils.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -41,9 +41,11 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <iterator>
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
|
|
@ -192,11 +194,11 @@ using LosslessArithmeticConvertibleImpl = std::integral_constant<
|
|||
// 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)) ||
|
||||
!(std::is_signed_v<From> && !std::is_signed_v<To>)) ||
|
||||
// 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)))
|
||||
(std::is_signed_v<From> == std::is_signed_v<To>)))
|
||||
) ? true
|
||||
// Floating point conversions are lossless if and only if `To` is at least
|
||||
// as wide as `From`.
|
||||
|
|
@ -219,12 +221,12 @@ using LosslessArithmeticConvertible =
|
|||
|
||||
// This interface knows how to report a Google Mock failure (either
|
||||
// non-fatal or fatal).
|
||||
class FailureReporterInterface {
|
||||
class [[nodiscard]] FailureReporterInterface {
|
||||
public:
|
||||
// The type of a failure (either non-fatal or fatal).
|
||||
enum FailureType { kNonfatal, kFatal };
|
||||
|
||||
virtual ~FailureReporterInterface() {}
|
||||
virtual ~FailureReporterInterface() = default;
|
||||
|
||||
// Reports a failure that occurred at the given source file location.
|
||||
virtual void ReportFailure(FailureType type, const char* file, int line,
|
||||
|
|
@ -295,14 +297,13 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message,
|
|||
//
|
||||
// ON_CALL(mock, Method({}, nullptr))...
|
||||
//
|
||||
class WithoutMatchers {
|
||||
class [[nodiscard]] WithoutMatchers {
|
||||
private:
|
||||
WithoutMatchers() {}
|
||||
friend GTEST_API_ WithoutMatchers GetWithoutMatchers();
|
||||
};
|
||||
WithoutMatchers() = default;
|
||||
|
||||
// Internal use only: access the singleton instance of WithoutMatchers.
|
||||
GTEST_API_ WithoutMatchers GetWithoutMatchers();
|
||||
public:
|
||||
GTEST_API_ static WithoutMatchers Get();
|
||||
};
|
||||
|
||||
// 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
|
||||
|
|
@ -311,7 +312,8 @@ GTEST_API_ WithoutMatchers GetWithoutMatchers();
|
|||
// crashes).
|
||||
template <typename T>
|
||||
inline T Invalid() {
|
||||
Assert(false, "", -1, "Internal error: attempt to return invalid value");
|
||||
Assert(/*condition=*/false, /*file=*/"", /*line=*/-1,
|
||||
"Internal error: attempt to return invalid value");
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
__builtin_unreachable();
|
||||
#elif defined(_MSC_VER)
|
||||
|
|
@ -321,6 +323,24 @@ inline T Invalid() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void GetValueType(const void*);
|
||||
|
||||
template <class T>
|
||||
typename std::iterator_traits<
|
||||
decltype(std::begin(std::declval<T&>()))>::value_type
|
||||
GetValueType(T*);
|
||||
|
||||
template <class T, class = void>
|
||||
struct RangeTraits {
|
||||
typedef decltype(internal::GetValueType(
|
||||
static_cast<std::remove_reference_t<T>*>(nullptr))) value_type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct RangeTraits<T, std::conditional_t<true, void, typename T::value_type>> {
|
||||
typedef typename T::value_type value_type;
|
||||
};
|
||||
|
||||
// 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
|
||||
|
|
@ -338,13 +358,13 @@ inline T Invalid() {
|
|||
// This generic version is used when RawContainer itself is already an
|
||||
// STL-style container.
|
||||
template <class RawContainer>
|
||||
class StlContainerView {
|
||||
class [[nodiscard]] StlContainerView {
|
||||
public:
|
||||
typedef RawContainer type;
|
||||
typedef const type& const_reference;
|
||||
|
||||
static const_reference ConstReference(const RawContainer& container) {
|
||||
static_assert(!std::is_const<RawContainer>::value,
|
||||
static_assert(!std::is_const_v<RawContainer>,
|
||||
"RawContainer type must not be const");
|
||||
return container;
|
||||
}
|
||||
|
|
@ -353,7 +373,7 @@ class StlContainerView {
|
|||
|
||||
// This specialization is used when RawContainer is a native array type.
|
||||
template <typename Element, size_t N>
|
||||
class StlContainerView<Element[N]> {
|
||||
class [[nodiscard]] StlContainerView<Element[N]> {
|
||||
public:
|
||||
typedef typename std::remove_const<Element>::type RawElement;
|
||||
typedef internal::NativeArray<RawElement> type;
|
||||
|
|
@ -365,7 +385,7 @@ class StlContainerView<Element[N]> {
|
|||
typedef const type const_reference;
|
||||
|
||||
static const_reference ConstReference(const Element (&array)[N]) {
|
||||
static_assert(std::is_same<Element, RawElement>::value,
|
||||
static_assert(std::is_same_v<Element, RawElement>,
|
||||
"Element type must not be const");
|
||||
return type(array, N, RelationToSourceReference());
|
||||
}
|
||||
|
|
@ -377,7 +397,7 @@ class StlContainerView<Element[N]> {
|
|||
// 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> > {
|
||||
class [[nodiscard]] StlContainerView< ::std::tuple<ElementPointer, Size> > {
|
||||
public:
|
||||
typedef typename std::remove_const<
|
||||
typename std::pointer_traits<ElementPointer>::element_type>::type
|
||||
|
|
@ -419,7 +439,7 @@ struct RemoveConstFromKey<std::pair<const K, V> > {
|
|||
GTEST_API_ void IllegalDoDefault(const char* file, int line);
|
||||
|
||||
template <typename F, typename Tuple, size_t... Idx>
|
||||
auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<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))...);
|
||||
|
|
@ -429,11 +449,11 @@ auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>)
|
|||
template <typename F, typename Tuple>
|
||||
auto Apply(F&& f, Tuple&& args) -> decltype(ApplyImpl(
|
||||
std::forward<F>(f), std::forward<Tuple>(args),
|
||||
MakeIndexSequence<std::tuple_size<
|
||||
typename std::remove_reference<Tuple>::type>::value>())) {
|
||||
std::make_index_sequence<
|
||||
std::tuple_size_v<std::remove_reference_t<Tuple>>>())) {
|
||||
return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
|
||||
MakeIndexSequence<std::tuple_size<
|
||||
typename std::remove_reference<Tuple>::type>::value>());
|
||||
std::make_index_sequence<
|
||||
std::tuple_size_v<std::remove_reference_t<Tuple>>>());
|
||||
}
|
||||
|
||||
// Template struct Function<F>, where F must be a function type, contains
|
||||
|
|
@ -464,15 +484,12 @@ struct Function<R(Args...)> {
|
|||
using MakeResultIgnoredValue = IgnoredValue(Args...);
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
constexpr size_t Function<R(Args...)>::ArgumentCount;
|
||||
|
||||
// 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;
|
||||
using TupleElement = std::tuple_element_t<I, T>;
|
||||
|
||||
bool Base64Unescape(const std::string& encoded, std::string* decoded);
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
|
||||
|
|
@ -56,7 +57,7 @@
|
|||
#include "gmock/internal/custom/gmock-port.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
|
||||
#include "absl/flags/declare.h"
|
||||
#include "absl/flags/flag.h"
|
||||
#endif
|
||||
|
|
@ -73,7 +74,7 @@
|
|||
#define GMOCK_FLAG(name) FLAGS_gmock_##name
|
||||
|
||||
// Pick a command line flags implementation.
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
|
||||
|
||||
// Macros for defining flags.
|
||||
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||
|
|
@ -85,17 +86,17 @@
|
|||
|
||||
// Macros for declaring flags.
|
||||
#define GMOCK_DECLARE_bool_(name) \
|
||||
ABSL_DECLARE_FLAG(bool, GMOCK_FLAG_NAME_(name))
|
||||
GTEST_API_ ABSL_DECLARE_FLAG(bool, GMOCK_FLAG_NAME_(name))
|
||||
#define GMOCK_DECLARE_int32_(name) \
|
||||
ABSL_DECLARE_FLAG(int32_t, GMOCK_FLAG_NAME_(name))
|
||||
GTEST_API_ ABSL_DECLARE_FLAG(int32_t, GMOCK_FLAG_NAME_(name))
|
||||
#define GMOCK_DECLARE_string_(name) \
|
||||
ABSL_DECLARE_FLAG(std::string, GMOCK_FLAG_NAME_(name))
|
||||
GTEST_API_ 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 // GTEST_HAS_ABSL
|
||||
#else // defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
|
||||
|
||||
// Macros for defining flags.
|
||||
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||
|
|
@ -134,6 +135,6 @@
|
|||
#define GMOCK_FLAG_GET(name) ::testing::GMOCK_FLAG(name)
|
||||
#define GMOCK_FLAG_SET(name, value) (void)(::testing::GMOCK_FLAG(name) = value)
|
||||
|
||||
#endif // GTEST_HAS_ABSL
|
||||
#endif // defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||
|
|
|
|||
|
|
@ -25,16 +25,18 @@
|
|||
// 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))
|
||||
// Requires: the number of arguments after expansion is at most 31.
|
||||
#define GMOCK_PP_NARG(...) \
|
||||
GMOCK_PP_INTERNAL_32ND((__VA_ARGS__, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, \
|
||||
21, 20, 19, 18, 17, 16, 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 0. Requires no more than 31 unprotected commas.
|
||||
#define GMOCK_PP_HAS_COMMA(...) \
|
||||
GMOCK_PP_INTERNAL_32ND((__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
|
||||
1, 1, 1, 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))
|
||||
|
|
@ -51,7 +53,7 @@
|
|||
// 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.
|
||||
// Requires: * the number of arguments after expansion is at most 31.
|
||||
// * If the argument is a macro, it must be able to be called with one
|
||||
// argument.
|
||||
//
|
||||
|
|
@ -104,7 +106,7 @@
|
|||
// GMOCK_PP_NARG0(x, y) => 2
|
||||
// GMOCK_PP_NARG0(PAIR) => 2
|
||||
//
|
||||
// Requires: * the number of arguments after expansion is at most 15.
|
||||
// Requires: * the number of arguments after expansion is at most 31.
|
||||
// * If the argument is a macro, it must be able to be called with one
|
||||
// argument.
|
||||
#define GMOCK_PP_NARG0(...) \
|
||||
|
|
@ -127,7 +129,7 @@
|
|||
// 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.
|
||||
// * |_Tuple| expansion has no more than 31 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)
|
||||
|
|
@ -135,20 +137,21 @@
|
|||
// 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
|
||||
// * |_K| literal between 0 and 31
|
||||
#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.
|
||||
// Increments the argument, requires the argument to be between 0 and 31.
|
||||
#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.
|
||||
// Returns comma if _i != 0. Requires _i to be between 0 and 31.
|
||||
#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_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
|
||||
|
|
@ -164,12 +167,13 @@
|
|||
// 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_32ND( \
|
||||
_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, ...) \
|
||||
_32
|
||||
#define GMOCK_PP_INTERNAL_32ND(_Args) \
|
||||
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_32ND _Args)
|
||||
#define GMOCK_PP_INTERNAL_INTERNAL_HEAD(_1, ...) _1
|
||||
#define GMOCK_PP_INTERNAL_HEAD(_Args) \
|
||||
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_HEAD _Args)
|
||||
|
|
@ -198,6 +202,22 @@
|
|||
#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_INC_16 17
|
||||
#define GMOCK_PP_INTERNAL_INC_17 18
|
||||
#define GMOCK_PP_INTERNAL_INC_18 19
|
||||
#define GMOCK_PP_INTERNAL_INC_19 20
|
||||
#define GMOCK_PP_INTERNAL_INC_20 21
|
||||
#define GMOCK_PP_INTERNAL_INC_21 22
|
||||
#define GMOCK_PP_INTERNAL_INC_22 23
|
||||
#define GMOCK_PP_INTERNAL_INC_23 24
|
||||
#define GMOCK_PP_INTERNAL_INC_24 25
|
||||
#define GMOCK_PP_INTERNAL_INC_25 26
|
||||
#define GMOCK_PP_INTERNAL_INC_26 27
|
||||
#define GMOCK_PP_INTERNAL_INC_27 28
|
||||
#define GMOCK_PP_INTERNAL_INC_28 29
|
||||
#define GMOCK_PP_INTERNAL_INC_29 30
|
||||
#define GMOCK_PP_INTERNAL_INC_30 31
|
||||
#define GMOCK_PP_INTERNAL_INC_31 32
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_0
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_1 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_2 ,
|
||||
|
|
@ -214,6 +234,22 @@
|
|||
#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_COMMA_IF_16 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_17 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_18 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_19 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_20 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_21 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_22 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_23 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_24 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_25 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_26 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_27 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_28 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_29 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_30 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_31 ,
|
||||
#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)
|
||||
|
|
@ -275,5 +311,69 @@
|
|||
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))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_16(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_15(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_17(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_16(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_18(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_17(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_19(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_18(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_20(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_19(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_21(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_20(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_22(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_21(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_23(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_22(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_24(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_23(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_25(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_24(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_26(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_25(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_27(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_26(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_28(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_27(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_29(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_28(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_30(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_29(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_31(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_30(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_
|
||||
|
|
|
|||
|
|
@ -53,12 +53,12 @@ class BetweenCardinalityImpl : public CardinalityInterface {
|
|||
: 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 << ".";
|
||||
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 << ".";
|
||||
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
|
||||
|
|
|
|||
|
|
@ -41,8 +41,10 @@
|
|||
#include <cctype>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
|
|
@ -87,7 +89,7 @@ GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name) {
|
|||
(!IsDigit(prev_char) && IsDigit(*p));
|
||||
|
||||
if (IsAlNum(*p)) {
|
||||
if (starts_new_word && result != "") result += ' ';
|
||||
if (starts_new_word && !result.empty()) result += ' ';
|
||||
result += ToLower(*p);
|
||||
}
|
||||
}
|
||||
|
|
@ -154,7 +156,7 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message,
|
|||
if (!LogIsVisible(severity)) return;
|
||||
|
||||
// Ensures that logs from different threads don't interleave.
|
||||
MutexLock l(&g_log_mutex);
|
||||
MutexLock l(g_log_mutex);
|
||||
|
||||
if (severity == kWarning) {
|
||||
// Prints a GMOCK WARNING marker to make the warnings easily searchable.
|
||||
|
|
@ -186,7 +188,7 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message,
|
|||
std::cout << ::std::flush;
|
||||
}
|
||||
|
||||
GTEST_API_ WithoutMatchers GetWithoutMatchers() { return WithoutMatchers(); }
|
||||
GTEST_API_ WithoutMatchers WithoutMatchers::Get() { return WithoutMatchers(); }
|
||||
|
||||
GTEST_API_ void IllegalDoDefault(const char* file, int line) {
|
||||
internal::Assert(
|
||||
|
|
@ -210,14 +212,14 @@ constexpr char UnBase64Impl(char c, const char* const base64, char carry) {
|
|||
}
|
||||
|
||||
template <size_t... I>
|
||||
constexpr std::array<char, 256> UnBase64Impl(IndexSequence<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(MakeIndexSequence<256>{}, base64);
|
||||
return UnBase64Impl(std::make_index_sequence<256>{}, base64);
|
||||
}
|
||||
|
||||
static constexpr char kBase64[] =
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ 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.size() >= 1) {
|
||||
if (!param_values.empty()) {
|
||||
result += " " + JoinAsKeyValueTuple(param_names, param_values);
|
||||
}
|
||||
return negation ? "not (" + result + ")" : result;
|
||||
|
|
@ -120,7 +120,7 @@ GTEST_API_ std::string FormatMatcherDescription(
|
|||
// [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,
|
||||
// 'http://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm'
|
||||
// 'https://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm'
|
||||
class MaxBipartiteMatchState {
|
||||
public:
|
||||
explicit MaxBipartiteMatchState(const MatchMatrix& graph)
|
||||
|
|
@ -236,9 +236,8 @@ static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs,
|
|||
os << "{";
|
||||
const char* sep = "";
|
||||
for (Iter it = pairs.begin(); it != pairs.end(); ++it) {
|
||||
os << sep << "\n ("
|
||||
<< "element #" << it->first << ", "
|
||||
<< "matcher #" << it->second << ")";
|
||||
os << sep << "\n (" << "element #" << it->first << ", " << "matcher #"
|
||||
<< it->second << ")";
|
||||
sep = ",";
|
||||
}
|
||||
os << "\n}";
|
||||
|
|
@ -374,20 +373,20 @@ bool UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix(
|
|||
return true;
|
||||
}
|
||||
|
||||
if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
|
||||
if (matrix.LhsSize() != matrix.RhsSize()) {
|
||||
// The element count doesn't match. If the container is empty,
|
||||
// there's no need to explain anything as Google Mock already
|
||||
// prints the empty container. Otherwise we just need to show
|
||||
// how many elements there actually are.
|
||||
if (matrix.LhsSize() != 0 && listener->IsInterested()) {
|
||||
*listener << "which has " << Elements(matrix.LhsSize());
|
||||
}
|
||||
return false;
|
||||
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 = true;
|
||||
bool result = !is_exact_match_with_size_discrepency;
|
||||
::std::vector<char> element_matched(matrix.LhsSize(), 0);
|
||||
::std::vector<char> matcher_matched(matrix.RhsSize(), 0);
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
|
@ -48,10 +49,10 @@
|
|||
#include "gtest/gtest.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC
|
||||
#if defined(GTEST_OS_CYGWIN) || defined(GTEST_OS_LINUX) || defined(GTEST_OS_MAC)
|
||||
#include <unistd.h> // NOLINT
|
||||
#endif
|
||||
#if GTEST_OS_QURT
|
||||
#ifdef GTEST_OS_QURT
|
||||
#include <qurt_event.h>
|
||||
#endif
|
||||
|
||||
|
|
@ -95,7 +96,7 @@ ExpectationBase::ExpectationBase(const char* a_file, int a_line,
|
|||
action_count_checked_(false) {}
|
||||
|
||||
// Destructs an ExpectationBase object.
|
||||
ExpectationBase::~ExpectationBase() {}
|
||||
ExpectationBase::~ExpectationBase() = default;
|
||||
|
||||
// Explicitly specifies the cardinality of this expectation. Used by
|
||||
// the subclasses to implement the .Times() clause.
|
||||
|
|
@ -211,7 +212,7 @@ void ExpectationBase::CheckActionCountIfNotDone() const
|
|||
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||
bool should_check = false;
|
||||
{
|
||||
MutexLock l(&mutex_);
|
||||
MutexLock l(mutex_);
|
||||
if (!action_count_checked_) {
|
||||
action_count_checked_ = true;
|
||||
should_check = true;
|
||||
|
|
@ -292,7 +293,7 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg) {
|
|||
Log(kWarning,
|
||||
msg +
|
||||
"\nNOTE: You can safely ignore the above warning unless this "
|
||||
"call should not happen. Do not suppress it by blindly adding "
|
||||
"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/"
|
||||
|
|
@ -308,7 +309,7 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg) {
|
|||
UntypedFunctionMockerBase::UntypedFunctionMockerBase()
|
||||
: mock_obj_(nullptr), name_("") {}
|
||||
|
||||
UntypedFunctionMockerBase::~UntypedFunctionMockerBase() {}
|
||||
UntypedFunctionMockerBase::~UntypedFunctionMockerBase() = default;
|
||||
|
||||
// Sets the mock object this mock method belongs to, and registers
|
||||
// this information in the global mock registry. Will be called
|
||||
|
|
@ -317,7 +318,7 @@ UntypedFunctionMockerBase::~UntypedFunctionMockerBase() {}
|
|||
void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
{
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
MutexLock l(g_gmock_mutex);
|
||||
mock_obj_ = mock_obj;
|
||||
}
|
||||
Mock::Register(mock_obj, this);
|
||||
|
|
@ -331,7 +332,7 @@ void UntypedFunctionMockerBase::SetOwnerAndName(const void* mock_obj,
|
|||
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);
|
||||
MutexLock l(g_gmock_mutex);
|
||||
mock_obj_ = mock_obj;
|
||||
name_ = name;
|
||||
}
|
||||
|
|
@ -344,7 +345,7 @@ const void* UntypedFunctionMockerBase::MockObject() const
|
|||
{
|
||||
// We protect mock_obj_ under g_gmock_mutex in case this mock
|
||||
// function is called from two threads concurrently.
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
MutexLock l(g_gmock_mutex);
|
||||
Assert(mock_obj_ != nullptr, __FILE__, __LINE__,
|
||||
"MockObject() must not be called before RegisterOwner() or "
|
||||
"SetOwnerAndName() has been called.");
|
||||
|
|
@ -361,7 +362,7 @@ const char* UntypedFunctionMockerBase::Name() const
|
|||
{
|
||||
// We protect name_ under g_gmock_mutex in case this mock
|
||||
// function is called from two threads concurrently.
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
MutexLock l(g_gmock_mutex);
|
||||
Assert(name_ != nullptr, __FILE__, __LINE__,
|
||||
"Name() must not be called before SetOwnerAndName() has "
|
||||
"been called.");
|
||||
|
|
@ -435,9 +436,9 @@ bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()
|
|||
UntypedExpectations expectations_to_delete;
|
||||
untyped_expectations_.swap(expectations_to_delete);
|
||||
|
||||
g_gmock_mutex.Unlock();
|
||||
g_gmock_mutex.unlock();
|
||||
expectations_to_delete.clear();
|
||||
g_gmock_mutex.Lock();
|
||||
g_gmock_mutex.lock();
|
||||
|
||||
return expectations_met;
|
||||
}
|
||||
|
|
@ -489,6 +490,7 @@ class MockObjectRegistry {
|
|||
// 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();
|
||||
|
|
@ -503,7 +505,7 @@ class MockObjectRegistry {
|
|||
std::cout << internal::FormatFileLocation(state.first_used_file,
|
||||
state.first_used_line);
|
||||
std::cout << " ERROR: this mock object";
|
||||
if (state.first_used_test != "") {
|
||||
if (!state.first_used_test.empty()) {
|
||||
std::cout << " (used in test " << state.first_used_test_suite << "."
|
||||
<< state.first_used_test << ")";
|
||||
}
|
||||
|
|
@ -526,10 +528,10 @@ class MockObjectRegistry {
|
|||
// RUN_ALL_TESTS() has already returned when this destructor is
|
||||
// called. Therefore we cannot use the normal Google Test
|
||||
// failure reporting mechanism.
|
||||
#if GTEST_OS_QURT
|
||||
#ifdef GTEST_OS_QURT
|
||||
qurt_exception_raise_fatal();
|
||||
#else
|
||||
_exit(1); // We cannot call exit() as it is not reentrant and
|
||||
_Exit(1); // We cannot call exit() as it is not reentrant and
|
||||
// may already have been called.
|
||||
#endif
|
||||
}
|
||||
|
|
@ -557,7 +559,7 @@ UninterestingCallReactionMap() {
|
|||
void SetReactionOnUninterestingCalls(uintptr_t mock_obj,
|
||||
internal::CallReaction reaction)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
internal::MutexLock l(internal::g_gmock_mutex);
|
||||
UninterestingCallReactionMap()[mock_obj] = reaction;
|
||||
}
|
||||
|
||||
|
|
@ -588,7 +590,7 @@ void Mock::FailUninterestingCalls(uintptr_t mock_obj)
|
|||
// 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);
|
||||
internal::MutexLock l(internal::g_gmock_mutex);
|
||||
UninterestingCallReactionMap().erase(static_cast<uintptr_t>(mock_obj));
|
||||
}
|
||||
|
||||
|
|
@ -596,7 +598,7 @@ void Mock::UnregisterCallReaction(uintptr_t mock_obj)
|
|||
// 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);
|
||||
internal::MutexLock l(internal::g_gmock_mutex);
|
||||
return (UninterestingCallReactionMap().count(
|
||||
reinterpret_cast<uintptr_t>(mock_obj)) == 0)
|
||||
? internal::intToCallReaction(
|
||||
|
|
@ -609,7 +611,7 @@ internal::CallReaction Mock::GetReactionOnUninterestingCalls(
|
|||
// objects.
|
||||
void Mock::AllowLeak(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
internal::MutexLock l(internal::g_gmock_mutex);
|
||||
g_mock_object_registry.states()[mock_obj].leakable = true;
|
||||
}
|
||||
|
||||
|
|
@ -618,7 +620,7 @@ void Mock::AllowLeak(const void* mock_obj)
|
|||
// 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);
|
||||
internal::MutexLock l(internal::g_gmock_mutex);
|
||||
return VerifyAndClearExpectationsLocked(mock_obj);
|
||||
}
|
||||
|
||||
|
|
@ -627,7 +629,7 @@ bool Mock::VerifyAndClearExpectations(void* mock_obj)
|
|||
// verification was successful.
|
||||
bool Mock::VerifyAndClear(void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
internal::MutexLock l(internal::g_gmock_mutex);
|
||||
ClearDefaultActionsLocked(mock_obj);
|
||||
return VerifyAndClearExpectationsLocked(mock_obj);
|
||||
}
|
||||
|
|
@ -677,7 +679,7 @@ bool Mock::IsStrict(void* mock_obj)
|
|||
void Mock::Register(const void* mock_obj,
|
||||
internal::UntypedFunctionMockerBase* mocker)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
internal::MutexLock l(internal::g_gmock_mutex);
|
||||
g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker);
|
||||
}
|
||||
|
||||
|
|
@ -687,7 +689,7 @@ void Mock::Register(const void* mock_obj,
|
|||
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);
|
||||
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;
|
||||
|
|
@ -745,13 +747,13 @@ void Mock::ClearDefaultActionsLocked(void* mock_obj)
|
|||
// needed by VerifyAndClearExpectationsLocked().
|
||||
}
|
||||
|
||||
Expectation::Expectation() {}
|
||||
Expectation::Expectation() = default;
|
||||
|
||||
Expectation::Expectation(
|
||||
const std::shared_ptr<internal::ExpectationBase>& an_expectation_base)
|
||||
: expectation_base_(an_expectation_base) {}
|
||||
|
||||
Expectation::~Expectation() {}
|
||||
Expectation::~Expectation() = default;
|
||||
|
||||
// Adds an expectation to a sequence.
|
||||
void Sequence::AddExpectation(const Expectation& expectation) const {
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
|
||||
GMOCK_DEFINE_bool_(catch_leaked_mocks, true,
|
||||
|
|
|
|||
|
|
@ -32,8 +32,9 @@
|
|||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#if GTEST_OS_ESP8266 || GTEST_OS_ESP32
|
||||
#if GTEST_OS_ESP8266
|
||||
#if defined(GTEST_OS_ESP8266) || defined(GTEST_OS_ESP32) || \
|
||||
(defined(GTEST_OS_NRF52) && defined(ARDUINO))
|
||||
#ifdef GTEST_OS_ESP8266
|
||||
extern "C" {
|
||||
#endif
|
||||
void setup() {
|
||||
|
|
@ -43,7 +44,7 @@ void setup() {
|
|||
testing::InitGoogleMock();
|
||||
}
|
||||
void loop() { RUN_ALL_TESTS(); }
|
||||
#if GTEST_OS_ESP8266
|
||||
#ifdef GTEST_OS_ESP8266
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -55,7 +56,7 @@ void loop() { RUN_ALL_TESTS(); }
|
|||
// 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
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
#ifdef GTEST_OS_WINDOWS_MOBILE
|
||||
#include <tchar.h> // NOLINT
|
||||
|
||||
GTEST_API_ int _tmain(int argc, TCHAR** argv) {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#
|
||||
# Bazel Build for Google C++ Testing Framework(Google Test)-googlemock
|
||||
|
||||
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test")
|
||||
load("@rules_python//python:defs.bzl", "py_library", "py_test")
|
||||
|
||||
licenses(["notice"])
|
||||
|
|
|
|||
|
|
@ -37,14 +37,18 @@
|
|||
#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.
|
||||
|
|
@ -62,30 +66,30 @@ 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_v<std::false_type, internal::negation<std::true_type>>,
|
||||
"");
|
||||
|
||||
static_assert(std::is_base_of<std::true_type,
|
||||
internal::negation<std::false_type>>::value,
|
||||
"");
|
||||
static_assert(
|
||||
std::is_base_of_v<std::true_type, internal::negation<std::false_type>>,
|
||||
"");
|
||||
|
||||
// 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_v<std::true_type,
|
||||
internal::negation<std::integral_constant<int, 0>>>,
|
||||
"");
|
||||
|
||||
static_assert(std::is_base_of<
|
||||
std::false_type,
|
||||
internal::negation<std::integral_constant<int, 1>>>::value,
|
||||
"");
|
||||
static_assert(
|
||||
std::is_base_of_v<std::false_type,
|
||||
internal::negation<std::integral_constant<int, 1>>>,
|
||||
"");
|
||||
|
||||
static_assert(std::is_base_of<
|
||||
std::false_type,
|
||||
internal::negation<std::integral_constant<int, -1>>>::value,
|
||||
"");
|
||||
static_assert(
|
||||
std::is_base_of_v<std::false_type,
|
||||
internal::negation<std::integral_constant<int, -1>>>,
|
||||
"");
|
||||
}
|
||||
|
||||
// Weird false/true types that aren't actually bool constants (but should still
|
||||
|
|
@ -104,79 +108,76 @@ 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,
|
||||
"");
|
||||
static_assert(std::is_base_of_v<std::true_type, internal::conjunction<>>, "");
|
||||
|
||||
// One predicate: inherits from that predicate, regardless of value.
|
||||
static_assert(
|
||||
std::is_base_of<MyFalse<0>, internal::conjunction<MyFalse<0>>>::value,
|
||||
"");
|
||||
std::is_base_of_v<MyFalse<0>, internal::conjunction<MyFalse<0>>>, "");
|
||||
|
||||
static_assert(
|
||||
std::is_base_of<MyTrue<0>, internal::conjunction<MyTrue<0>>>::value, "");
|
||||
static_assert(std::is_base_of_v<MyTrue<0>, internal::conjunction<MyTrue<0>>>,
|
||||
"");
|
||||
|
||||
// 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,
|
||||
std::is_base_of_v<
|
||||
MyFalse<1>, internal::conjunction<MyTrue<0>, MyFalse<1>, MyTrue<2>>>,
|
||||
"");
|
||||
|
||||
static_assert(
|
||||
std::is_base_of<MyFalse<1>, internal::conjunction<MyTrue<0>, MyFalse<1>,
|
||||
MyFalse<2>>>::value,
|
||||
std::is_base_of_v<
|
||||
MyFalse<1>, internal::conjunction<MyTrue<0>, MyFalse<1>, MyFalse<2>>>,
|
||||
"");
|
||||
|
||||
// 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,
|
||||
std::is_base_of_v<MyFalse<1>,
|
||||
internal::conjunction<MyTrue<0>, MyFalse<1>, Empty>>,
|
||||
"");
|
||||
|
||||
// All predicates true: inherits from the last.
|
||||
static_assert(
|
||||
std::is_base_of<MyTrue<2>, internal::conjunction<MyTrue<0>, MyTrue<1>,
|
||||
MyTrue<2>>>::value,
|
||||
std::is_base_of_v<MyTrue<2>,
|
||||
internal::conjunction<MyTrue<0>, MyTrue<1>, MyTrue<2>>>,
|
||||
"");
|
||||
}
|
||||
|
||||
TEST(TypeTraits, Disjunction) {
|
||||
// Base case: always false.
|
||||
static_assert(
|
||||
std::is_base_of<std::false_type, internal::disjunction<>>::value, "");
|
||||
static_assert(std::is_base_of_v<std::false_type, internal::disjunction<>>,
|
||||
"");
|
||||
|
||||
// One predicate: inherits from that predicate, regardless of value.
|
||||
static_assert(
|
||||
std::is_base_of<MyFalse<0>, internal::disjunction<MyFalse<0>>>::value,
|
||||
"");
|
||||
std::is_base_of_v<MyFalse<0>, internal::disjunction<MyFalse<0>>>, "");
|
||||
|
||||
static_assert(
|
||||
std::is_base_of<MyTrue<0>, internal::disjunction<MyTrue<0>>>::value, "");
|
||||
static_assert(std::is_base_of_v<MyTrue<0>, internal::disjunction<MyTrue<0>>>,
|
||||
"");
|
||||
|
||||
// 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,
|
||||
std::is_base_of_v<
|
||||
MyTrue<1>, internal::disjunction<MyFalse<0>, MyTrue<1>, MyFalse<2>>>,
|
||||
"");
|
||||
|
||||
static_assert(
|
||||
std::is_base_of<MyTrue<1>, internal::disjunction<MyFalse<0>, MyTrue<1>,
|
||||
MyTrue<2>>>::value,
|
||||
std::is_base_of_v<
|
||||
MyTrue<1>, internal::disjunction<MyFalse<0>, MyTrue<1>, MyTrue<2>>>,
|
||||
"");
|
||||
|
||||
// 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,
|
||||
std::is_base_of_v<MyTrue<1>,
|
||||
internal::disjunction<MyFalse<0>, MyTrue<1>, Empty>>,
|
||||
"");
|
||||
|
||||
// All predicates false: inherits from the last.
|
||||
static_assert(
|
||||
std::is_base_of<MyFalse<2>, internal::disjunction<MyFalse<0>, MyFalse<1>,
|
||||
MyFalse<2>>>::value,
|
||||
std::is_base_of_v<MyFalse<2>, internal::disjunction<
|
||||
MyFalse<0>, MyFalse<1>, MyFalse<2>>>,
|
||||
"");
|
||||
}
|
||||
|
||||
|
|
@ -184,7 +185,7 @@ TEST(TypeTraits, IsInvocableRV) {
|
|||
struct C {
|
||||
int operator()() const { return 0; }
|
||||
void operator()(int) & {}
|
||||
std::string operator()(int) && { return ""; };
|
||||
std::string operator()(int) && { return ""; }
|
||||
};
|
||||
|
||||
// The first overload is callable for const and non-const rvalues and lvalues.
|
||||
|
|
@ -218,7 +219,8 @@ TEST(TypeTraits, IsInvocableRV) {
|
|||
// 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.
|
||||
#if defined(__cplusplus) && __cplusplus >= 201703L
|
||||
// TODO(b/396121064) - Fix this test under MSVC
|
||||
#ifndef _MSC_VER
|
||||
{
|
||||
struct NonMoveable {
|
||||
NonMoveable() = default;
|
||||
|
|
@ -239,7 +241,7 @@ TEST(TypeTraits, IsInvocableRV) {
|
|||
static_assert(!internal::is_callable_r<int, Callable>::value);
|
||||
static_assert(!internal::is_callable_r<NonMoveable, Callable, int>::value);
|
||||
}
|
||||
#endif // C++17 and above
|
||||
#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.
|
||||
|
|
@ -436,15 +438,15 @@ TEST(DefaultValueDeathTest, GetReturnsBuiltInDefaultValueWhenUnset) {
|
|||
|
||||
EXPECT_EQ(0, DefaultValue<int>::Get());
|
||||
|
||||
EXPECT_DEATH_IF_SUPPORTED({ DefaultValue<MyNonDefaultConstructible>::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::unique_ptr<int>(new int(42)); });
|
||||
[] { 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);
|
||||
|
|
@ -500,8 +502,8 @@ TEST(DefaultValueOfReferenceDeathTest, GetReturnsBuiltInDefaultValueWhenUnset) {
|
|||
EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible&>::IsSet());
|
||||
|
||||
EXPECT_DEATH_IF_SUPPORTED({ DefaultValue<int&>::Get(); }, "");
|
||||
EXPECT_DEATH_IF_SUPPORTED({ DefaultValue<MyNonDefaultConstructible>::Get(); },
|
||||
"");
|
||||
EXPECT_DEATH_IF_SUPPORTED(
|
||||
{ DefaultValue<MyNonDefaultConstructible>::Get(); }, "");
|
||||
}
|
||||
|
||||
// Tests that ActionInterface can be implemented by defining the
|
||||
|
|
@ -742,8 +744,8 @@ 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, "");
|
||||
static_assert(std::is_convertible_v<const R&, U>, "");
|
||||
static_assert(!std::is_convertible_v<R, U>, "");
|
||||
|
||||
MockFunction<U()> mock;
|
||||
EXPECT_CALL(mock, Call).WillOnce(Return(17)).WillRepeatedly(Return(19));
|
||||
|
|
@ -766,11 +768,11 @@ TEST(ReturnTest, ConversionRequiresMutableLvalueReference) {
|
|||
S(std::string&) {} // NOLINT
|
||||
};
|
||||
|
||||
static_assert(std::is_convertible<std::string&, S>::value, "");
|
||||
static_assert(std::is_convertible_v<std::string&, S>, "");
|
||||
#ifndef _MSC_VER
|
||||
static_assert(!std::is_convertible<std::string&&, S>::value, "");
|
||||
static_assert(!std::is_convertible_v<std::string&&, S>, "");
|
||||
#endif
|
||||
static_assert(!std::is_convertible<const std::string&, S>::value, "");
|
||||
static_assert(!std::is_convertible_v<const std::string&, S>, "");
|
||||
|
||||
// It shouldn't be possible to use the result of Return(std::string) in a
|
||||
// context where an S is needed.
|
||||
|
|
@ -779,9 +781,9 @@ TEST(ReturnTest, ConversionRequiresMutableLvalueReference) {
|
|||
// 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, "");
|
||||
static_assert(!std::is_convertible_v<RA, Action<S()>>, "");
|
||||
#ifndef _MSC_VER
|
||||
static_assert(!std::is_convertible<RA, OnceAction<S()>>::value, "");
|
||||
static_assert(!std::is_convertible_v<RA, OnceAction<S()>>, "");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -798,8 +800,8 @@ TEST(ReturnTest, MoveOnlyResultType) {
|
|||
|
||||
// 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,
|
||||
static_assert(!std::is_convertible_v<decltype(Return(std::unique_ptr<int>())),
|
||||
Action<std::unique_ptr<int>()>>,
|
||||
"");
|
||||
}
|
||||
|
||||
|
|
@ -982,7 +984,7 @@ TEST(ReturnRoundRobinTest, WorksForVector) {
|
|||
|
||||
class MockClass {
|
||||
public:
|
||||
MockClass() {}
|
||||
MockClass() = default;
|
||||
|
||||
MOCK_METHOD1(IntFunc, int(bool flag)); // NOLINT
|
||||
MOCK_METHOD0(Foo, MyNonDefaultConstructible());
|
||||
|
|
@ -1025,8 +1027,7 @@ void VoidFunc(bool /* flag */) {}
|
|||
|
||||
TEST(DoDefaultDeathTest, DiesIfUsedInCompositeAction) {
|
||||
MockClass mock;
|
||||
EXPECT_CALL(mock, IntFunc(_))
|
||||
.WillRepeatedly(DoAll(Invoke(VoidFunc), DoDefault()));
|
||||
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
|
||||
|
|
@ -1221,37 +1222,41 @@ class Foo {
|
|||
|
||||
// Tests InvokeWithoutArgs(function).
|
||||
TEST(InvokeWithoutArgsTest, Function) {
|
||||
GTEST_DISABLE_DEPRECATED_PUSH_()
|
||||
// As an action that takes one argument.
|
||||
Action<int(int)> a = InvokeWithoutArgs(Nullary); // NOLINT
|
||||
Action<int(int)> a = 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
|
||||
Action<int(int, double)> a2 = 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
|
||||
Action<void(int)> a3 = VoidNullary; // NOLINT
|
||||
g_done = false;
|
||||
a3.Perform(std::make_tuple(1));
|
||||
EXPECT_TRUE(g_done);
|
||||
GTEST_DISABLE_DEPRECATED_POP_()
|
||||
}
|
||||
|
||||
// Tests InvokeWithoutArgs(functor).
|
||||
TEST(InvokeWithoutArgsTest, Functor) {
|
||||
GTEST_DISABLE_DEPRECATED_PUSH_()
|
||||
// As an action that takes no argument.
|
||||
Action<int()> a = InvokeWithoutArgs(NullaryFunctor()); // NOLINT
|
||||
Action<int()> a = 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());
|
||||
NullaryFunctor();
|
||||
EXPECT_EQ(2, a2.Perform(std::make_tuple(3, 3.5, 'a')));
|
||||
|
||||
// As an action that returns void.
|
||||
Action<void()> a3 = InvokeWithoutArgs(VoidNullaryFunctor());
|
||||
Action<void()> a3 = VoidNullaryFunctor();
|
||||
g_done = false;
|
||||
a3.Perform(std::make_tuple());
|
||||
EXPECT_TRUE(g_done);
|
||||
GTEST_DISABLE_DEPRECATED_POP_()
|
||||
}
|
||||
|
||||
// Tests InvokeWithoutArgs(obj_ptr, method).
|
||||
|
|
@ -1277,7 +1282,7 @@ int ReturnOne() {
|
|||
|
||||
TEST(IgnoreResultTest, MonomorphicAction) {
|
||||
g_done = false;
|
||||
Action<void()> a = IgnoreResult(Invoke(ReturnOne));
|
||||
Action<void()> a = IgnoreResult(&ReturnOne);
|
||||
a.Perform(std::make_tuple());
|
||||
EXPECT_TRUE(g_done);
|
||||
}
|
||||
|
|
@ -1292,7 +1297,7 @@ MyNonDefaultConstructible ReturnMyNonDefaultConstructible(double /* x */) {
|
|||
TEST(IgnoreResultTest, ActionReturningClass) {
|
||||
g_done = false;
|
||||
Action<void(int)> a =
|
||||
IgnoreResult(Invoke(ReturnMyNonDefaultConstructible)); // NOLINT
|
||||
IgnoreResult(&ReturnMyNonDefaultConstructible); // NOLINT
|
||||
a.Perform(std::make_tuple(2));
|
||||
EXPECT_TRUE(g_done);
|
||||
}
|
||||
|
|
@ -1306,7 +1311,7 @@ TEST(AssignTest, Int) {
|
|||
|
||||
TEST(AssignTest, String) {
|
||||
::std::string x;
|
||||
Action<void(void)> a = Assign(&x, "Hello, world");
|
||||
Action<void()> a = Assign(&x, "Hello, world");
|
||||
a.Perform(std::make_tuple());
|
||||
EXPECT_EQ("Hello, world", x);
|
||||
}
|
||||
|
|
@ -1472,9 +1477,50 @@ TEST(DoAll, SupportsTypeErasedActions) {
|
|||
}
|
||||
}
|
||||
|
||||
// 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>(Invoke(Unary)); // NOLINT
|
||||
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)));
|
||||
}
|
||||
|
|
@ -1482,7 +1528,7 @@ TEST(WithArgsTest, OneArg) {
|
|||
// 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>(Invoke(Binary));
|
||||
WithArgs<0, 2>(Binary);
|
||||
const char s[] = "Hello";
|
||||
EXPECT_EQ(s + 2, a.Perform(std::make_tuple(CharPtr(s), 0.5, Short(2))));
|
||||
}
|
||||
|
|
@ -1498,7 +1544,7 @@ struct ConcatAll {
|
|||
// 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>(Invoke(ConcatAll{}));
|
||||
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"))));
|
||||
|
|
@ -1523,21 +1569,21 @@ TEST(WithArgsTest, NonInvokeAction) {
|
|||
// 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>(Invoke(Ternary));
|
||||
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>(Invoke(SumOf4));
|
||||
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>(Invoke(Binary));
|
||||
WithArgs<1, 0>(Binary);
|
||||
const char s[] = "Hello";
|
||||
EXPECT_EQ(s + 2, a.Perform(std::make_tuple(Short(2), CharPtr(s))));
|
||||
}
|
||||
|
|
@ -1545,14 +1591,14 @@ TEST(WithArgsTest, ReversedArgumentOrder) {
|
|||
// 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>(Invoke(Ternary));
|
||||
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>(Invoke(VoidBinary));
|
||||
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);
|
||||
|
|
@ -1592,7 +1638,23 @@ TEST(WithArgsTest, RefQualifiedInnerAction) {
|
|||
EXPECT_EQ(19, mock.AsStdFunction()(0, 17));
|
||||
}
|
||||
|
||||
#if !GTEST_OS_WINDOWS_MOBILE
|
||||
// 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:
|
||||
|
|
@ -1601,14 +1663,14 @@ class SetErrnoAndReturnTest : public testing::Test {
|
|||
};
|
||||
|
||||
TEST_F(SetErrnoAndReturnTest, Int) {
|
||||
Action<int(void)> a = SetErrnoAndReturn(ENOTTY, -5);
|
||||
Action<int()> 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);
|
||||
Action<int*()> a = SetErrnoAndReturn(ENOTTY, &x);
|
||||
EXPECT_EQ(&x, a.Perform(std::make_tuple()));
|
||||
EXPECT_EQ(ENOTTY, errno);
|
||||
}
|
||||
|
|
@ -1751,9 +1813,7 @@ TEST(ReturnNewTest, ConstructorThatTakes10Arguments) {
|
|||
delete c;
|
||||
}
|
||||
|
||||
std::unique_ptr<int> UniquePtrSource() {
|
||||
return std::unique_ptr<int>(new int(19));
|
||||
}
|
||||
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;
|
||||
|
|
@ -1763,7 +1823,7 @@ std::vector<std::unique_ptr<int>> VectorUniquePtrSource() {
|
|||
|
||||
TEST(MockMethodTest, CanReturnMoveOnlyValue_Return) {
|
||||
MockClass mock;
|
||||
std::unique_ptr<int> i(new int(19));
|
||||
std::unique_ptr<int> i = std::make_unique<int>(19);
|
||||
EXPECT_CALL(mock, MakeUnique()).WillOnce(Return(ByMove(std::move(i))));
|
||||
EXPECT_CALL(mock, MakeVectorUnique())
|
||||
.WillOnce(Return(ByMove(VectorUniquePtrSource())));
|
||||
|
|
@ -1786,7 +1846,7 @@ TEST(MockMethodTest, CanReturnMoveOnlyValue_Return) {
|
|||
TEST(MockMethodTest, CanReturnMoveOnlyValue_DoAllReturn) {
|
||||
testing::MockFunction<void()> mock_function;
|
||||
MockClass mock;
|
||||
std::unique_ptr<int> i(new int(19));
|
||||
std::unique_ptr<int> i = std::make_unique<int>(19);
|
||||
EXPECT_CALL(mock_function, Call());
|
||||
EXPECT_CALL(mock, MakeUnique())
|
||||
.WillOnce(DoAll(InvokeWithoutArgs(&mock_function,
|
||||
|
|
@ -1802,12 +1862,11 @@ TEST(MockMethodTest, CanReturnMoveOnlyValue_Invoke) {
|
|||
|
||||
// Check default value
|
||||
DefaultValue<std::unique_ptr<int>>::SetFactory(
|
||||
[] { return std::unique_ptr<int>(new int(42)); });
|
||||
[] { return std::make_unique<int>(42); });
|
||||
EXPECT_EQ(42, *mock.MakeUnique());
|
||||
|
||||
EXPECT_CALL(mock, MakeUnique()).WillRepeatedly(Invoke(UniquePtrSource));
|
||||
EXPECT_CALL(mock, MakeVectorUnique())
|
||||
.WillRepeatedly(Invoke(VectorUniquePtrSource));
|
||||
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();
|
||||
|
|
@ -1822,14 +1881,14 @@ TEST(MockMethodTest, CanReturnMoveOnlyValue_Invoke) {
|
|||
|
||||
TEST(MockMethodTest, CanTakeMoveOnlyValue) {
|
||||
MockClass mock;
|
||||
auto make = [](int i) { return std::unique_ptr<int>(new int(i)); };
|
||||
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(Invoke([](std::unique_ptr<int> j) {}),
|
||||
// .WillRepeatedly(DoAll([](std::unique_ptr<int> j) {})),
|
||||
// Return(1)));
|
||||
EXPECT_CALL(mock, TakeUnique(testing::Pointee(7)))
|
||||
.WillOnce(Return(-7))
|
||||
|
|
@ -2053,9 +2112,7 @@ struct Double {
|
|||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<int> UniqueInt(int i) {
|
||||
return std::unique_ptr<int>(new int(i));
|
||||
}
|
||||
std::unique_ptr<int> UniqueInt(int i) { return std::make_unique<int>(i); }
|
||||
|
||||
TEST(FunctorActionTest, ActionFromFunction) {
|
||||
Action<int(int, int&, int*)> a = &Add;
|
||||
|
|
@ -2114,7 +2171,7 @@ TEST(FunctorActionTest, TypeConversion) {
|
|||
EXPECT_EQ(7, d.Perform(std::make_tuple(1)));
|
||||
|
||||
// Ensure creation of an empty action succeeds.
|
||||
Action<void(int)>(nullptr);
|
||||
(void)Action<void(int)>(nullptr);
|
||||
}
|
||||
|
||||
TEST(FunctorActionTest, UnusedArguments) {
|
||||
|
|
@ -2140,7 +2197,7 @@ TEST(MoveOnlyArgumentsTest, ReturningActions) {
|
|||
EXPECT_EQ(x, 3);
|
||||
}
|
||||
|
||||
ACTION(ReturnArity) { return std::tuple_size<args_type>::value; }
|
||||
ACTION(ReturnArity) { return std::tuple_size_v<args_type>; }
|
||||
|
||||
TEST(ActionMacro, LargeArity) {
|
||||
EXPECT_EQ(
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@
|
|||
//
|
||||
// This file tests the built-in cardinalities.
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest-spi.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
|
@ -50,7 +52,7 @@ using testing::MakeCardinality;
|
|||
|
||||
class MockFoo {
|
||||
public:
|
||||
MockFoo() {}
|
||||
MockFoo() = default;
|
||||
MOCK_METHOD0(Bar, int()); // NOLINT
|
||||
|
||||
private:
|
||||
|
|
@ -131,7 +133,7 @@ TEST(AnyNumberTest, HasCorrectBounds) {
|
|||
TEST(AtLeastTest, OnNegativeNumber) {
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
{ // NOLINT
|
||||
AtLeast(-1);
|
||||
(void)AtLeast(-1);
|
||||
},
|
||||
"The invocation lower bound must be >= 0");
|
||||
}
|
||||
|
|
@ -184,7 +186,7 @@ TEST(AtLeastTest, HasCorrectBounds) {
|
|||
TEST(AtMostTest, OnNegativeNumber) {
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
{ // NOLINT
|
||||
AtMost(-1);
|
||||
(void)AtMost(-1);
|
||||
},
|
||||
"The invocation upper bound must be >= 0");
|
||||
}
|
||||
|
|
@ -237,7 +239,7 @@ TEST(AtMostTest, HasCorrectBounds) {
|
|||
TEST(BetweenTest, OnNegativeStart) {
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
{ // NOLINT
|
||||
Between(-1, 2);
|
||||
(void)Between(-1, 2);
|
||||
},
|
||||
"The invocation lower bound must be >= 0, but is actually -1");
|
||||
}
|
||||
|
|
@ -245,7 +247,7 @@ TEST(BetweenTest, OnNegativeStart) {
|
|||
TEST(BetweenTest, OnNegativeEnd) {
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
{ // NOLINT
|
||||
Between(1, -2);
|
||||
(void)Between(1, -2);
|
||||
},
|
||||
"The invocation upper bound must be >= 0, but is actually -2");
|
||||
}
|
||||
|
|
@ -253,7 +255,7 @@ TEST(BetweenTest, OnNegativeEnd) {
|
|||
TEST(BetweenTest, OnStartBiggerThanEnd) {
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
{ // NOLINT
|
||||
Between(2, 1);
|
||||
(void)Between(2, 1);
|
||||
},
|
||||
"The invocation upper bound (1) must be >= "
|
||||
"the invocation lower bound (2)");
|
||||
|
|
@ -338,7 +340,7 @@ TEST(BetweenTest, HasCorrectBounds) {
|
|||
TEST(ExactlyTest, OnNegativeNumber) {
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
{ // NOLINT
|
||||
Exactly(-1);
|
||||
(void)Exactly(-1);
|
||||
},
|
||||
"The invocation lower bound must be >= 0");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,14 @@
|
|||
// Silence C4503 (decorated name length exceeded) for MSVC.
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4503)
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
// This file intentionally tests many ways of writing Mock classes, including
|
||||
// with and without the override keyword.
|
||||
#pragma clang diagnostic ignored "-Winconsistent-missing-override"
|
||||
#endif
|
||||
|
||||
#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.
|
||||
|
|
@ -70,7 +77,7 @@ using testing::TypedEq;
|
|||
template <typename T>
|
||||
class TemplatedCopyable {
|
||||
public:
|
||||
TemplatedCopyable() {}
|
||||
TemplatedCopyable() = default;
|
||||
|
||||
template <typename U>
|
||||
TemplatedCopyable(const U& other) {} // NOLINT
|
||||
|
|
@ -78,7 +85,7 @@ class TemplatedCopyable {
|
|||
|
||||
class FooInterface {
|
||||
public:
|
||||
virtual ~FooInterface() {}
|
||||
virtual ~FooInterface() = default;
|
||||
|
||||
virtual void VoidReturning(int x) = 0;
|
||||
|
||||
|
|
@ -91,7 +98,7 @@ class FooInterface {
|
|||
|
||||
virtual bool TakesNonConstReference(int& n) = 0; // NOLINT
|
||||
virtual std::string TakesConstReference(const int& n) = 0;
|
||||
virtual bool TakesConst(const int x) = 0;
|
||||
virtual bool TakesConst(int x) = 0;
|
||||
|
||||
virtual int OverloadedOnArgumentNumber() = 0;
|
||||
virtual int OverloadedOnArgumentNumber(int n) = 0;
|
||||
|
|
@ -120,7 +127,7 @@ class FooInterface {
|
|||
virtual int RefQualifiedOverloaded() & = 0;
|
||||
virtual int RefQualifiedOverloaded() && = 0;
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
STDMETHOD_(int, CTNullary)() = 0;
|
||||
STDMETHOD_(bool, CTUnary)(int x) = 0;
|
||||
STDMETHOD_(int, CTDecimal)
|
||||
|
|
@ -137,7 +144,7 @@ class FooInterface {
|
|||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4373)
|
||||
class MockFoo : public FooInterface {
|
||||
public:
|
||||
MockFoo() {}
|
||||
MockFoo() = default;
|
||||
|
||||
// Makes sure that a mock function parameter can be named.
|
||||
MOCK_METHOD(void, VoidReturning, (int n)); // NOLINT
|
||||
|
|
@ -178,7 +185,7 @@ class MockFoo : public FooInterface {
|
|||
MOCK_METHOD(int (*)(bool), ReturnsFunctionPointer1, (int), ());
|
||||
MOCK_METHOD(fn_ptr, ReturnsFunctionPointer2, (int), ());
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
MOCK_METHOD(int, CTNullary, (), (Calltype(STDMETHODCALLTYPE)));
|
||||
MOCK_METHOD(bool, CTUnary, (int), (Calltype(STDMETHODCALLTYPE)));
|
||||
MOCK_METHOD(int, CTDecimal,
|
||||
|
|
@ -208,7 +215,7 @@ class MockFoo : public FooInterface {
|
|||
|
||||
class LegacyMockFoo : public FooInterface {
|
||||
public:
|
||||
LegacyMockFoo() {}
|
||||
LegacyMockFoo() = default;
|
||||
|
||||
// Makes sure that a mock function parameter can be named.
|
||||
MOCK_METHOD1(VoidReturning, void(int n)); // NOLINT
|
||||
|
|
@ -248,7 +255,7 @@ class LegacyMockFoo : public FooInterface {
|
|||
MOCK_METHOD1(ReturnsFunctionPointer1, int (*(int))(bool));
|
||||
MOCK_METHOD1(ReturnsFunctionPointer2, fn_ptr(int));
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
#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,
|
||||
|
|
@ -325,8 +332,8 @@ TYPED_TEST(FunctionMockerTest, MocksBinaryFunction) {
|
|||
|
||||
// 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, NULL, "hi"))
|
||||
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"));
|
||||
|
|
@ -404,7 +411,7 @@ TYPED_TEST(FunctionMockerTest, MocksTypeWithTemplatedCopyCtor) {
|
|||
EXPECT_TRUE(this->foo_->TypeWithTemplatedCopyCtor(TemplatedCopyable<int>()));
|
||||
}
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
// Tests mocking a nullary function with calltype.
|
||||
TYPED_TEST(FunctionMockerTest, MocksNullaryFunctionWithCallType) {
|
||||
EXPECT_CALL(this->mock_foo_, CTNullary())
|
||||
|
|
@ -451,6 +458,87 @@ TYPED_TEST(FunctionMockerTest, MocksReturnTypeWithCommaAndCallType) {
|
|||
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
// Compilability test, to ensure macros expand to all the arguments they're
|
||||
// supposed to.
|
||||
class MockManyArgs {
|
||||
using T = int;
|
||||
|
||||
public:
|
||||
MockManyArgs() = default;
|
||||
|
||||
MOCK_METHOD(void, F, (), ());
|
||||
MOCK_METHOD(void, F, (T), ());
|
||||
MOCK_METHOD(void, F, (T, T), ());
|
||||
MOCK_METHOD(void, F, (T, T, T), ());
|
||||
MOCK_METHOD(void, F, (T, T, T, T), ());
|
||||
MOCK_METHOD(void, F, (T, T, T, T, T), ());
|
||||
MOCK_METHOD(void, F, (T, T, T, T, T, T), ());
|
||||
MOCK_METHOD(void, F, (T, T, T, T, T, T, T), ());
|
||||
MOCK_METHOD(void, F, (T, T, T, T, T, T, T, T), ());
|
||||
MOCK_METHOD(void, F, (T, T, T, T, T, T, T, T, T), ());
|
||||
MOCK_METHOD(void, F, (T, T, T, T, T, T, T, T, T, T), ());
|
||||
MOCK_METHOD(void, F, (T, T, T, T, T, T, T, T, T, T, T), ());
|
||||
MOCK_METHOD(void, F, (T, T, T, T, T, T, T, T, T, T, T, T), ());
|
||||
MOCK_METHOD(void, F, (T, T, T, T, T, T, T, T, T, T, T, T, T), ());
|
||||
MOCK_METHOD(void, F, (T, T, T, T, T, T, T, T, T, T, T, T, T, T), ());
|
||||
MOCK_METHOD(void, F, (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T), ());
|
||||
MOCK_METHOD(void, F, (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T), ());
|
||||
MOCK_METHOD(void, F, (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T), ());
|
||||
MOCK_METHOD(void, F, (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T),
|
||||
());
|
||||
MOCK_METHOD(void, F,
|
||||
(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T), ());
|
||||
MOCK_METHOD(void, F,
|
||||
(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T), ());
|
||||
MOCK_METHOD(void, F,
|
||||
(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T),
|
||||
());
|
||||
MOCK_METHOD(void, F,
|
||||
(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,
|
||||
T),
|
||||
());
|
||||
MOCK_METHOD(void, F,
|
||||
(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,
|
||||
T),
|
||||
());
|
||||
MOCK_METHOD(void, F,
|
||||
(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,
|
||||
T, T),
|
||||
());
|
||||
MOCK_METHOD(void, F,
|
||||
(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,
|
||||
T, T, T),
|
||||
());
|
||||
MOCK_METHOD(void, F,
|
||||
(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,
|
||||
T, T, T, T),
|
||||
());
|
||||
MOCK_METHOD(void, F,
|
||||
(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,
|
||||
T, T, T, T, T),
|
||||
());
|
||||
MOCK_METHOD(void, F,
|
||||
(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,
|
||||
T, T, T, T, T, T),
|
||||
());
|
||||
MOCK_METHOD(void, F,
|
||||
(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,
|
||||
T, T, T, T, T, T, T),
|
||||
());
|
||||
MOCK_METHOD(void, F,
|
||||
(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,
|
||||
T, T, T, T, T, T, T, T),
|
||||
());
|
||||
MOCK_METHOD(void, F,
|
||||
(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,
|
||||
T, T, T, T, T, T, T, T, T),
|
||||
());
|
||||
|
||||
private:
|
||||
MockManyArgs(const MockManyArgs&) = delete;
|
||||
MockManyArgs& operator=(const MockManyArgs&) = delete;
|
||||
};
|
||||
|
||||
TEST(FunctionMockerTest, RefQualified) {
|
||||
MockFoo mock_foo;
|
||||
|
||||
|
|
@ -487,7 +575,7 @@ TEST(FunctionMockerTest, RefQualified) {
|
|||
|
||||
class MockB {
|
||||
public:
|
||||
MockB() {}
|
||||
MockB() = default;
|
||||
|
||||
MOCK_METHOD(void, DoB, ());
|
||||
|
||||
|
|
@ -498,7 +586,7 @@ class MockB {
|
|||
|
||||
class LegacyMockB {
|
||||
public:
|
||||
LegacyMockB() {}
|
||||
LegacyMockB() = default;
|
||||
|
||||
MOCK_METHOD0(DoB, void());
|
||||
|
||||
|
|
@ -534,7 +622,7 @@ TYPED_TEST(ExpectCallTest, UnmentionedFunctionCanBeCalledAnyNumberOfTimes) {
|
|||
template <typename T>
|
||||
class StackInterface {
|
||||
public:
|
||||
virtual ~StackInterface() {}
|
||||
virtual ~StackInterface() = default;
|
||||
|
||||
// Template parameter appears in function parameter.
|
||||
virtual void Push(const T& value) = 0;
|
||||
|
|
@ -547,7 +635,7 @@ class StackInterface {
|
|||
template <typename T>
|
||||
class MockStack : public StackInterface<T> {
|
||||
public:
|
||||
MockStack() {}
|
||||
MockStack() = default;
|
||||
|
||||
MOCK_METHOD(void, Push, (const T& elem), ());
|
||||
MOCK_METHOD(void, Pop, (), (final));
|
||||
|
|
@ -566,7 +654,7 @@ class MockStack : public StackInterface<T> {
|
|||
template <typename T>
|
||||
class LegacyMockStack : public StackInterface<T> {
|
||||
public:
|
||||
LegacyMockStack() {}
|
||||
LegacyMockStack() = default;
|
||||
|
||||
MOCK_METHOD1_T(Push, void(const T& elem));
|
||||
MOCK_METHOD0_T(Pop, void());
|
||||
|
|
@ -620,7 +708,7 @@ TYPED_TEST(TemplateMockTest, MethodWithCommaInReturnTypeWorks) {
|
|||
EXPECT_EQ(a_map, mock.ReturnTypeWithComma(1));
|
||||
}
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
// Tests mocking template interfaces with calltype.
|
||||
|
||||
template <typename T>
|
||||
|
|
@ -711,7 +799,7 @@ TYPED_TEST(TemplateMockTestWithCallType, Works) {
|
|||
|
||||
class MockOverloadedOnArgNumber {
|
||||
public:
|
||||
MockOverloadedOnArgNumber() {}
|
||||
MockOverloadedOnArgNumber() = default;
|
||||
|
||||
MY_MOCK_METHODS1_;
|
||||
|
||||
|
|
@ -723,7 +811,7 @@ class MockOverloadedOnArgNumber {
|
|||
|
||||
class LegacyMockOverloadedOnArgNumber {
|
||||
public:
|
||||
LegacyMockOverloadedOnArgNumber() {}
|
||||
LegacyMockOverloadedOnArgNumber() = default;
|
||||
|
||||
LEGACY_MY_MOCK_METHODS1_;
|
||||
|
||||
|
|
@ -758,7 +846,7 @@ TYPED_TEST(OverloadedMockMethodTest, CanOverloadOnArgNumberInMacroBody) {
|
|||
|
||||
class MockOverloadedOnConstness {
|
||||
public:
|
||||
MockOverloadedOnConstness() {}
|
||||
MockOverloadedOnConstness() = default;
|
||||
|
||||
MY_MOCK_METHODS2_;
|
||||
|
||||
|
|
@ -849,11 +937,20 @@ namespace {
|
|||
template <typename Expected, typename F>
|
||||
static constexpr bool IsMockFunctionTemplateArgumentDeducedTo(
|
||||
const internal::MockFunction<F>&) {
|
||||
return std::is_same<F, Expected>::value;
|
||||
return std::is_same_v<F, Expected>;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Like std::add_const, but for function types.
|
||||
template <typename F>
|
||||
struct AddConstToFunction;
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct AddConstToFunction<R(Args...)> {
|
||||
using type = R(Args...) const;
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
class MockMethodMockFunctionSignatureTest : public Test {};
|
||||
|
||||
|
|
@ -865,25 +962,69 @@ TYPED_TEST_SUITE(MockMethodMockFunctionSignatureTest,
|
|||
|
||||
TYPED_TEST(MockMethodMockFunctionSignatureTest,
|
||||
IsMockFunctionTemplateArgumentDeducedForRawSignature) {
|
||||
using Argument = TypeParam;
|
||||
MockFunction<Argument> foo;
|
||||
EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<TypeParam>(foo));
|
||||
// Non-const
|
||||
{
|
||||
using Argument = TypeParam;
|
||||
MockFunction<Argument> foo;
|
||||
EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<TypeParam>(foo));
|
||||
}
|
||||
|
||||
// Const
|
||||
{
|
||||
using Argument = typename AddConstToFunction<TypeParam>::type;
|
||||
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));
|
||||
// Non-const
|
||||
{
|
||||
using Argument = std::function<TypeParam>;
|
||||
MockFunction<Argument> foo;
|
||||
EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<TypeParam>(foo));
|
||||
}
|
||||
|
||||
// As of 2026-05 MSVC doesn't know how to deal with this, providing pages of
|
||||
// inscrutable errors about std::_Get_function_impl. But this is fine, since
|
||||
// std::function<R(Args...) const> doesn't apply the const qualifier correctly
|
||||
// anyway.
|
||||
#if !defined(_MSC_VER)
|
||||
|
||||
// Const
|
||||
{
|
||||
using Argument =
|
||||
std::function<typename AddConstToFunction<TypeParam>::type>;
|
||||
|
||||
MockFunction<Argument> foo;
|
||||
EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<TypeParam>(foo));
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
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));
|
||||
// Non-const
|
||||
{
|
||||
using ForRawSignature = decltype(&MockFunction<TypeParam>::Call);
|
||||
using ForStdFunction =
|
||||
decltype(&MockFunction<std::function<TypeParam>>::Call);
|
||||
EXPECT_TRUE((std::is_same<ForRawSignature, ForStdFunction>::value));
|
||||
}
|
||||
|
||||
// Const
|
||||
{
|
||||
using ConstTypeParam = typename AddConstToFunction<TypeParam>::type;
|
||||
using ForRawSignature = decltype(&MockFunction<ConstTypeParam>::Call);
|
||||
|
||||
using ForStdFunction =
|
||||
decltype(&MockFunction<std::function<ConstTypeParam>>::Call);
|
||||
|
||||
EXPECT_TRUE((std::is_same<ForRawSignature, ForStdFunction>::value));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
|
|
@ -56,7 +57,7 @@
|
|||
#include "src/gtest-internal-inl.h"
|
||||
#undef GTEST_IMPLEMENTATION_
|
||||
|
||||
#if GTEST_OS_CYGWIN
|
||||
#ifdef GTEST_OS_CYGWIN
|
||||
#include <sys/types.h> // For ssize_t. NOLINT
|
||||
#endif
|
||||
|
||||
|
|
@ -167,7 +168,7 @@ TEST(KindOfTest, Integer) {
|
|||
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 GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN
|
||||
#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
|
||||
|
|
@ -544,7 +545,7 @@ TEST(ExpectCallTest, DoesNotLogWhenVerbosityIsError) {
|
|||
|
||||
void OnCallLogger() {
|
||||
DummyMock mock;
|
||||
ON_CALL(mock, TestMethod());
|
||||
(void)ON_CALL(mock, TestMethod());
|
||||
}
|
||||
|
||||
// Verifies that ON_CALL logs if the --gmock_verbose flag is set to "info".
|
||||
|
|
@ -567,7 +568,7 @@ TEST(OnCallTest, DoesNotLogWhenVerbosityIsError) {
|
|||
|
||||
void OnCallAnyArgumentLogger() {
|
||||
DummyMock mock;
|
||||
ON_CALL(mock, TestMethodArg(_));
|
||||
(void)ON_CALL(mock, TestMethodArg(_));
|
||||
}
|
||||
|
||||
// Verifies that ON_CALL prints provided _ argument.
|
||||
|
|
|
|||
|
|
@ -31,9 +31,15 @@
|
|||
//
|
||||
// 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
|
||||
|
|
@ -393,6 +399,188 @@ TEST(NanSensitiveDoubleNearTest, CanDescribeSelfWithNaNs) {
|
|||
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;
|
||||
|
|
@ -532,7 +720,6 @@ TEST(AllOfTest, CanDescribeNegation) {
|
|||
|
||||
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);
|
||||
}
|
||||
|
|
@ -556,10 +743,9 @@ TEST_P(AllOfTestP, ExplainsResult) {
|
|||
Matcher<int> m;
|
||||
|
||||
// Successful match. Both matchers need to explain. The second
|
||||
// matcher doesn't give an explanation, so only the first matcher's
|
||||
// explanation is printed.
|
||||
// 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", Explain(m, 25));
|
||||
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));
|
||||
|
|
@ -569,8 +755,9 @@ TEST_P(AllOfTestP, ExplainsResult) {
|
|||
// 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 which is 5 more than 20",
|
||||
Explain(m, 25));
|
||||
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));
|
||||
|
|
@ -582,13 +769,14 @@ TEST_P(AllOfTestP, ExplainsResult) {
|
|||
// 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));
|
||||
EXPECT_EQ("which is 5 less than 10, and which is 15 less than 20",
|
||||
Explain(m, 5));
|
||||
|
||||
// Failed match. The second matcher, which failed, needs to
|
||||
// explain. Since it doesn't given an explanation, nothing is
|
||||
// explain. Since it doesn't given an explanation, the matcher text is
|
||||
// printed.
|
||||
m = AllOf(GreaterThan(10), Lt(30));
|
||||
EXPECT_EQ("", Explain(m, 40));
|
||||
EXPECT_EQ("which doesn't match (is < 30)", Explain(m, 40));
|
||||
|
||||
// Failed match. The second matcher, which failed, needs to
|
||||
// explain.
|
||||
|
|
@ -771,45 +959,43 @@ TEST(AnyOfTest, AnyOfMatcherSafelyCastsMonomorphicMatchers) {
|
|||
TEST_P(AnyOfTestP, ExplainsResult) {
|
||||
Matcher<int> m;
|
||||
|
||||
// Failed match. Both matchers need to explain. The second
|
||||
// matcher doesn't give an explanation, so only the first matcher's
|
||||
// explanation is printed.
|
||||
// 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", Explain(m, 5));
|
||||
EXPECT_EQ("which is 5 less than 10, and isn't < 0", Explain(m, 5));
|
||||
|
||||
// Failed match. Both matchers need to explain.
|
||||
// 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. All matchers need to explain. The second
|
||||
// matcher doesn't given an explanation.
|
||||
// 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 which is 25 less than 30",
|
||||
Explain(m, 5));
|
||||
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 matchers need to explain.
|
||||
// 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 matcher, which succeeded, needs to
|
||||
// explain.
|
||||
// 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, which succeeded, needs to
|
||||
// explain. Since it doesn't given an explanation, nothing is
|
||||
// printed.
|
||||
m = AnyOf(GreaterThan(10), Lt(30));
|
||||
EXPECT_EQ("", Explain(m, 0));
|
||||
|
||||
// Successful match. The second matcher, which succeeded, needs to
|
||||
// explain.
|
||||
// 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
|
||||
|
|
@ -952,7 +1138,7 @@ TEST(AllArgsTest, WorksForNonTuple) {
|
|||
|
||||
class AllArgsHelper {
|
||||
public:
|
||||
AllArgsHelper() {}
|
||||
AllArgsHelper() = default;
|
||||
|
||||
MOCK_METHOD2(Helper, int(char x, int y));
|
||||
|
||||
|
|
@ -973,7 +1159,7 @@ TEST(AllArgsTest, WorksInWithClause) {
|
|||
|
||||
class OptionalMatchersHelper {
|
||||
public:
|
||||
OptionalMatchersHelper() {}
|
||||
OptionalMatchersHelper() = default;
|
||||
|
||||
MOCK_METHOD0(NoArgs, int());
|
||||
|
||||
|
|
@ -1439,7 +1625,7 @@ TEST_F(DoubleNearTest, NanSensitiveDoubleNearCanMatchNaN) {
|
|||
}
|
||||
|
||||
TEST(NotTest, WorksOnMoveOnlyType) {
|
||||
std::unique_ptr<int> p(new int(3));
|
||||
std::unique_ptr<int> p = std::make_unique<int>(3);
|
||||
EXPECT_THAT(p, Pointee(Eq(3)));
|
||||
EXPECT_THAT(p, Not(Pointee(Eq(2))));
|
||||
}
|
||||
|
|
@ -1495,13 +1681,13 @@ TEST(AnyOfTest, DoesNotCallAnyOfUnqualified) {
|
|||
} // namespace adl_test
|
||||
|
||||
TEST(AllOfTest, WorksOnMoveOnlyType) {
|
||||
std::unique_ptr<int> p(new int(3));
|
||||
std::unique_ptr<int> p = std::make_unique<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));
|
||||
std::unique_ptr<int> p = std::make_unique<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)))));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,15 +31,22 @@
|
|||
//
|
||||
// This file tests some commonly used argument matchers.
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#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 {
|
||||
|
|
@ -230,7 +237,6 @@ TEST(StringMatcherTest, CanBeImplicitlyConstructedFromString) {
|
|||
EXPECT_FALSE(m2.Matches("hello"));
|
||||
}
|
||||
|
||||
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
// Tests that a C-string literal can be implicitly converted to a
|
||||
// Matcher<StringView> or Matcher<const StringView&>.
|
||||
TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) {
|
||||
|
|
@ -266,7 +272,6 @@ TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromStringView) {
|
|||
EXPECT_TRUE(m2.Matches("cats"));
|
||||
EXPECT_FALSE(m2.Matches("dogs"));
|
||||
}
|
||||
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
|
||||
// Tests that a std::reference_wrapper<std::string> object can be implicitly
|
||||
// converted to a Matcher<std::string> or Matcher<const std::string&> via Eq().
|
||||
|
|
@ -406,9 +411,27 @@ class IntValue {
|
|||
int value_;
|
||||
};
|
||||
|
||||
// For testing casting matchers between compatible types. This is similar to
|
||||
// IntValue, but takes a non-const reference to the value, showing MatcherCast
|
||||
// works with such types (and doesn't, for example, use a const ref internally).
|
||||
class MutableIntView {
|
||||
public:
|
||||
// An int& can be statically (although not implicitly) cast to a
|
||||
// MutableIntView.
|
||||
explicit MutableIntView(int& a_value) : value_(a_value) {}
|
||||
|
||||
int& value() const { return value_; }
|
||||
|
||||
private:
|
||||
int& value_;
|
||||
};
|
||||
|
||||
// For testing casting matchers between compatible types.
|
||||
bool IsPositiveIntValue(const IntValue& foo) { return foo.value() > 0; }
|
||||
|
||||
// For testing casting matchers between compatible types.
|
||||
bool IsPositiveMutableIntView(MutableIntView foo) { return foo.value() > 0; }
|
||||
|
||||
// Tests that MatcherCast<T>(m) works when m is a Matcher<U> where T
|
||||
// can be statically converted to U.
|
||||
TEST(MatcherCastTest, FromCompatibleType) {
|
||||
|
|
@ -424,14 +447,34 @@ TEST(MatcherCastTest, FromCompatibleType) {
|
|||
// predicate.
|
||||
EXPECT_TRUE(m4.Matches(1));
|
||||
EXPECT_FALSE(m4.Matches(0));
|
||||
|
||||
Matcher<MutableIntView> m5 = Truly(IsPositiveMutableIntView);
|
||||
Matcher<int> m6 = MatcherCast<int>(m5);
|
||||
// In the following, the arguments 1 and 0 are statically converted to
|
||||
// MutableIntView objects, and then tested by the IsPositiveMutableIntView()
|
||||
// predicate.
|
||||
EXPECT_TRUE(m6.Matches(1));
|
||||
EXPECT_FALSE(m6.Matches(0));
|
||||
}
|
||||
|
||||
// Tests that MatcherCast<T>(m) works when m is a Matcher<const T&>.
|
||||
TEST(MatcherCastTest, FromConstReferenceToNonReference) {
|
||||
Matcher<const int&> m1 = Eq(0);
|
||||
int n = 0;
|
||||
Matcher<const int&> m1 = Ref(n);
|
||||
Matcher<int> m2 = MatcherCast<int>(m1);
|
||||
EXPECT_TRUE(m2.Matches(0));
|
||||
EXPECT_FALSE(m2.Matches(1));
|
||||
int n1 = 0;
|
||||
EXPECT_TRUE(m2.Matches(n));
|
||||
EXPECT_FALSE(m2.Matches(n1));
|
||||
}
|
||||
|
||||
// Tests that MatcherCast<T&>(m) works when m is a Matcher<const T&>.
|
||||
TEST(MatcherCastTest, FromConstReferenceToReference) {
|
||||
int n = 0;
|
||||
Matcher<const int&> m1 = Ref(n);
|
||||
Matcher<int&> m2 = MatcherCast<int&>(m1);
|
||||
int n1 = 0;
|
||||
EXPECT_TRUE(m2.Matches(n));
|
||||
EXPECT_FALSE(m2.Matches(n1));
|
||||
}
|
||||
|
||||
// Tests that MatcherCast<T>(m) works when m is a Matcher<T&>.
|
||||
|
|
@ -440,6 +483,12 @@ TEST(MatcherCastTest, FromReferenceToNonReference) {
|
|||
Matcher<int> m2 = MatcherCast<int>(m1);
|
||||
EXPECT_TRUE(m2.Matches(0));
|
||||
EXPECT_FALSE(m2.Matches(1));
|
||||
|
||||
// Of course, reference identity isn't preserved since a copy is required.
|
||||
int n = 0;
|
||||
Matcher<int&> m3 = Ref(n);
|
||||
Matcher<int> m4 = MatcherCast<int>(m3);
|
||||
EXPECT_FALSE(m4.Matches(n));
|
||||
}
|
||||
|
||||
// Tests that MatcherCast<const T&>(m) works when m is a Matcher<T>.
|
||||
|
|
@ -572,21 +621,48 @@ struct IntReferenceWrapper {
|
|||
const int* value;
|
||||
};
|
||||
|
||||
// Compared the contained values
|
||||
bool operator==(const IntReferenceWrapper& a, const IntReferenceWrapper& b) {
|
||||
return a.value == b.value;
|
||||
return *a.value == *b.value;
|
||||
}
|
||||
|
||||
TEST(MatcherCastTest, ValueIsNotCopied) {
|
||||
int n = 42;
|
||||
Matcher<IntReferenceWrapper> m = MatcherCast<IntReferenceWrapper>(n);
|
||||
// Verify that the matcher holds a reference to n, not to its temporary copy.
|
||||
EXPECT_TRUE(m.Matches(n));
|
||||
TEST(MatcherCastTest, ValueIsCopied) {
|
||||
{
|
||||
// When an IntReferenceWrapper is passed.
|
||||
int n = 42;
|
||||
Matcher<IntReferenceWrapper> m =
|
||||
MatcherCast<IntReferenceWrapper>(IntReferenceWrapper(n));
|
||||
{
|
||||
int value = 42;
|
||||
EXPECT_TRUE(m.Matches(value));
|
||||
value = 10;
|
||||
EXPECT_FALSE(m.Matches(value));
|
||||
// This changes the stored reference.
|
||||
n = 10;
|
||||
EXPECT_TRUE(m.Matches(value));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// When an int is passed.
|
||||
int n = 42;
|
||||
Matcher<IntReferenceWrapper> m = MatcherCast<IntReferenceWrapper>(n);
|
||||
{
|
||||
int value = 42;
|
||||
EXPECT_TRUE(m.Matches(value));
|
||||
value = 10;
|
||||
EXPECT_FALSE(m.Matches(value));
|
||||
// This does not change the stored int.
|
||||
n = 10;
|
||||
EXPECT_FALSE(m.Matches(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Base {
|
||||
public:
|
||||
virtual ~Base() {}
|
||||
Base() {}
|
||||
virtual ~Base() = default;
|
||||
Base() = default;
|
||||
|
||||
private:
|
||||
Base(const Base&) = delete;
|
||||
|
|
@ -644,6 +720,16 @@ TEST(SafeMatcherCastTest, FromBaseClass) {
|
|||
EXPECT_FALSE(m4.Matches(d2));
|
||||
}
|
||||
|
||||
// Tests that SafeMatcherCast<T>(m) works when m is a Matcher<const T&>.
|
||||
TEST(SafeMatcherCastTest, FromConstReferenceToNonReference) {
|
||||
int n = 0;
|
||||
Matcher<const int&> m1 = Ref(n);
|
||||
Matcher<int> m2 = SafeMatcherCast<int>(m1);
|
||||
int n1 = 0;
|
||||
EXPECT_TRUE(m2.Matches(n));
|
||||
EXPECT_FALSE(m2.Matches(n1));
|
||||
}
|
||||
|
||||
// Tests that SafeMatcherCast<T&>(m) works when m is a Matcher<const T&>.
|
||||
TEST(SafeMatcherCastTest, FromConstReferenceToReference) {
|
||||
int n = 0;
|
||||
|
|
@ -711,6 +797,7 @@ TEST(ExpectThat, TakesLiterals) {
|
|||
EXPECT_THAT(1, 1);
|
||||
EXPECT_THAT(1.0, 1.0);
|
||||
EXPECT_THAT(std::string(), "");
|
||||
EXPECT_THAT(std::shared_ptr<int>(), nullptr);
|
||||
}
|
||||
|
||||
TEST(ExpectThat, TakesFunctions) {
|
||||
|
|
@ -1004,8 +1091,20 @@ TEST(IsEmptyTest, MatchesCString) {
|
|||
const char b[] = "x";
|
||||
EXPECT_TRUE(m.Matches(a));
|
||||
EXPECT_FALSE(m.Matches(b));
|
||||
EXPECT_FALSE(m.Matches(nullptr));
|
||||
}
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
TEST(IsEmptyTest, MatchesCWideString) {
|
||||
const Matcher<const wchar_t*> m = IsEmpty();
|
||||
const wchar_t a[] = L"";
|
||||
const wchar_t b[] = L"x";
|
||||
EXPECT_TRUE(m.Matches(a));
|
||||
EXPECT_FALSE(m.Matches(b));
|
||||
EXPECT_FALSE(m.Matches(nullptr));
|
||||
}
|
||||
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
||||
// Tests that IsNull() matches any NULL pointer of any type.
|
||||
TEST(IsNullTest, MatchesNullPointer) {
|
||||
Matcher<int*> m1 = IsNull();
|
||||
|
|
@ -1039,6 +1138,16 @@ TEST(IsNullTest, CanDescribeSelf) {
|
|||
EXPECT_EQ("isn't NULL", DescribeNegation(m));
|
||||
}
|
||||
|
||||
struct SmartPtrHelper {
|
||||
MOCK_METHOD(void, Call, (std::shared_ptr<int>));
|
||||
};
|
||||
|
||||
TEST(IsNullTest, WorksWithSmartPtr) {
|
||||
SmartPtrHelper helper;
|
||||
EXPECT_CALL(helper, Call(nullptr));
|
||||
helper.Call(nullptr);
|
||||
}
|
||||
|
||||
// Tests that NotNull() matches any non-NULL pointer of any type.
|
||||
TEST(NotNullTest, MatchesNonNullPointer) {
|
||||
Matcher<int*> m1 = NotNull();
|
||||
|
|
@ -1144,22 +1253,26 @@ TEST(RefTest, ExplainsResult) {
|
|||
// Tests string comparison matchers.
|
||||
|
||||
template <typename T = std::string>
|
||||
std::string FromStringLike(internal::StringLike<T> str) {
|
||||
return std::string(str);
|
||||
internal::StringType<T> ToString(T str) {
|
||||
return internal::StringType<T>(str);
|
||||
}
|
||||
|
||||
TEST(StringLike, TestConversions) {
|
||||
EXPECT_EQ("foo", FromStringLike("foo"));
|
||||
EXPECT_EQ("foo", FromStringLike(std::string("foo")));
|
||||
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
EXPECT_EQ("foo", FromStringLike(internal::StringView("foo")));
|
||||
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
TEST(StringType, TestConversions) {
|
||||
EXPECT_EQ("foo", ToString("foo"));
|
||||
EXPECT_EQ("foo", ToString(std::string("foo")));
|
||||
EXPECT_EQ("foo", ToString(internal::StringView("foo")));
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
EXPECT_EQ(L"foo", ToString(L"foo"));
|
||||
EXPECT_EQ(L"foo", ToString(std::wstring(L"foo")));
|
||||
EXPECT_EQ(L"foo", ToString(std::wstring_view(L"foo")));
|
||||
#endif
|
||||
|
||||
// Non deducible types.
|
||||
EXPECT_EQ("", FromStringLike({}));
|
||||
EXPECT_EQ("foo", FromStringLike({'f', 'o', 'o'}));
|
||||
EXPECT_EQ("", ToString({}));
|
||||
EXPECT_EQ("foo", ToString({'f', 'o', 'o'}));
|
||||
const char buf[] = "foo";
|
||||
EXPECT_EQ("foo", FromStringLike({buf, buf + 3}));
|
||||
EXPECT_EQ("foo", ToString({buf, buf + 3}));
|
||||
}
|
||||
|
||||
TEST(StrEqTest, MatchesEqualString) {
|
||||
|
|
@ -1172,7 +1285,6 @@ TEST(StrEqTest, MatchesEqualString) {
|
|||
EXPECT_TRUE(m2.Matches("Hello"));
|
||||
EXPECT_FALSE(m2.Matches("Hi"));
|
||||
|
||||
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
Matcher<const internal::StringView&> m3 =
|
||||
StrEq(internal::StringView("Hello"));
|
||||
EXPECT_TRUE(m3.Matches(internal::StringView("Hello")));
|
||||
|
|
@ -1183,7 +1295,6 @@ TEST(StrEqTest, MatchesEqualString) {
|
|||
EXPECT_TRUE(m_empty.Matches(internal::StringView("")));
|
||||
EXPECT_TRUE(m_empty.Matches(internal::StringView()));
|
||||
EXPECT_FALSE(m_empty.Matches(internal::StringView("hello")));
|
||||
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
}
|
||||
|
||||
TEST(StrEqTest, CanDescribeSelf) {
|
||||
|
|
@ -1210,12 +1321,10 @@ TEST(StrNeTest, MatchesUnequalString) {
|
|||
EXPECT_TRUE(m2.Matches("hello"));
|
||||
EXPECT_FALSE(m2.Matches("Hello"));
|
||||
|
||||
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
Matcher<const internal::StringView> m3 = StrNe(internal::StringView("Hello"));
|
||||
EXPECT_TRUE(m3.Matches(internal::StringView("")));
|
||||
EXPECT_TRUE(m3.Matches(internal::StringView()));
|
||||
EXPECT_FALSE(m3.Matches(internal::StringView("Hello")));
|
||||
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
}
|
||||
|
||||
TEST(StrNeTest, CanDescribeSelf) {
|
||||
|
|
@ -1234,14 +1343,12 @@ TEST(StrCaseEqTest, MatchesEqualStringIgnoringCase) {
|
|||
EXPECT_TRUE(m2.Matches("hello"));
|
||||
EXPECT_FALSE(m2.Matches("Hi"));
|
||||
|
||||
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
Matcher<const internal::StringView&> m3 =
|
||||
StrCaseEq(internal::StringView("Hello"));
|
||||
EXPECT_TRUE(m3.Matches(internal::StringView("Hello")));
|
||||
EXPECT_TRUE(m3.Matches(internal::StringView("hello")));
|
||||
EXPECT_FALSE(m3.Matches(internal::StringView("Hi")));
|
||||
EXPECT_FALSE(m3.Matches(internal::StringView()));
|
||||
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
}
|
||||
|
||||
TEST(StrCaseEqTest, MatchesEqualStringWith0IgnoringCase) {
|
||||
|
|
@ -1285,14 +1392,12 @@ TEST(StrCaseNeTest, MatchesUnequalStringIgnoringCase) {
|
|||
EXPECT_TRUE(m2.Matches(""));
|
||||
EXPECT_FALSE(m2.Matches("Hello"));
|
||||
|
||||
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
Matcher<const internal::StringView> m3 =
|
||||
StrCaseNe(internal::StringView("Hello"));
|
||||
EXPECT_TRUE(m3.Matches(internal::StringView("Hi")));
|
||||
EXPECT_TRUE(m3.Matches(internal::StringView()));
|
||||
EXPECT_FALSE(m3.Matches(internal::StringView("Hello")));
|
||||
EXPECT_FALSE(m3.Matches(internal::StringView("hello")));
|
||||
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
}
|
||||
|
||||
TEST(StrCaseNeTest, CanDescribeSelf) {
|
||||
|
|
@ -1333,7 +1438,6 @@ TEST(HasSubstrTest, WorksForCStrings) {
|
|||
EXPECT_FALSE(m_empty.Matches(nullptr));
|
||||
}
|
||||
|
||||
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
// Tests that HasSubstr() works for matching StringView-typed values.
|
||||
TEST(HasSubstrTest, WorksForStringViewClasses) {
|
||||
const Matcher<internal::StringView> m1 =
|
||||
|
|
@ -1352,7 +1456,6 @@ TEST(HasSubstrTest, WorksForStringViewClasses) {
|
|||
EXPECT_TRUE(m3.Matches(internal::StringView("")));
|
||||
EXPECT_TRUE(m3.Matches(internal::StringView()));
|
||||
}
|
||||
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
|
||||
// Tests that HasSubstr(s) describes itself properly.
|
||||
TEST(HasSubstrTest, CanDescribeSelf) {
|
||||
|
|
@ -1542,7 +1645,7 @@ TEST(PairTest, MatchesCorrectly) {
|
|||
|
||||
TEST(PairTest, WorksWithMoveOnly) {
|
||||
pair<std::unique_ptr<int>, std::unique_ptr<int>> p;
|
||||
p.second.reset(new int(7));
|
||||
p.second = std::make_unique<int>(7);
|
||||
EXPECT_THAT(p, Pair(Eq(nullptr), Ne(nullptr)));
|
||||
}
|
||||
|
||||
|
|
@ -1751,13 +1854,11 @@ TEST(StartsWithTest, MatchesStringWithGivenPrefix) {
|
|||
EXPECT_FALSE(m2.Matches("H"));
|
||||
EXPECT_FALSE(m2.Matches(" Hi"));
|
||||
|
||||
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
const Matcher<internal::StringView> m_empty =
|
||||
StartsWith(internal::StringView(""));
|
||||
EXPECT_TRUE(m_empty.Matches(internal::StringView()));
|
||||
EXPECT_TRUE(m_empty.Matches(internal::StringView("")));
|
||||
EXPECT_TRUE(m_empty.Matches(internal::StringView("not empty")));
|
||||
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
}
|
||||
|
||||
TEST(StartsWithTest, CanDescribeSelf) {
|
||||
|
|
@ -1765,6 +1866,11 @@ TEST(StartsWithTest, CanDescribeSelf) {
|
|||
EXPECT_EQ("starts with \"Hi\"", Describe(m));
|
||||
}
|
||||
|
||||
TEST(StartsWithTest, WorksWithStringMatcherOnStringViewMatchee) {
|
||||
EXPECT_THAT(internal::StringView("talk to me goose"),
|
||||
StartsWith(std::string("talk")));
|
||||
}
|
||||
|
||||
// Tests EndsWith(s).
|
||||
|
||||
TEST(EndsWithTest, MatchesStringWithGivenSuffix) {
|
||||
|
|
@ -1780,14 +1886,12 @@ TEST(EndsWithTest, MatchesStringWithGivenSuffix) {
|
|||
EXPECT_FALSE(m2.Matches("i"));
|
||||
EXPECT_FALSE(m2.Matches("Hi "));
|
||||
|
||||
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
const Matcher<const internal::StringView&> m4 =
|
||||
EndsWith(internal::StringView(""));
|
||||
EXPECT_TRUE(m4.Matches("Hi"));
|
||||
EXPECT_TRUE(m4.Matches(""));
|
||||
EXPECT_TRUE(m4.Matches(internal::StringView()));
|
||||
EXPECT_TRUE(m4.Matches(internal::StringView("")));
|
||||
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
}
|
||||
|
||||
TEST(EndsWithTest, CanDescribeSelf) {
|
||||
|
|
@ -1810,14 +1914,12 @@ TEST(WhenBase64UnescapedTest, MatchesUnescapedBase64Strings) {
|
|||
EXPECT_TRUE(m2.Matches("aGVsbG8gd29ybGQh")); // hello world!
|
||||
EXPECT_TRUE(m2.Matches("+/-_IQ")); // \xfb\xff\xbf!
|
||||
|
||||
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
const Matcher<const internal::StringView&> m3 =
|
||||
WhenBase64Unescaped(EndsWith("!"));
|
||||
EXPECT_FALSE(m3.Matches("invalid base64"));
|
||||
EXPECT_FALSE(m3.Matches("aGVsbG8gd29ybGQ=")); // hello world
|
||||
EXPECT_TRUE(m3.Matches("aGVsbG8gd29ybGQh")); // hello world!
|
||||
EXPECT_TRUE(m3.Matches("+/-_IQ")); // \xfb\xff\xbf!
|
||||
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
}
|
||||
|
||||
TEST(WhenBase64UnescapedTest, CanDescribeSelf) {
|
||||
|
|
@ -1838,7 +1940,6 @@ TEST(MatchesRegexTest, MatchesStringMatchingGivenRegex) {
|
|||
EXPECT_FALSE(m2.Matches("az1"));
|
||||
EXPECT_FALSE(m2.Matches("1az"));
|
||||
|
||||
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
const Matcher<const internal::StringView&> m3 = MatchesRegex("a.*z");
|
||||
EXPECT_TRUE(m3.Matches(internal::StringView("az")));
|
||||
EXPECT_TRUE(m3.Matches(internal::StringView("abcz")));
|
||||
|
|
@ -1848,7 +1949,6 @@ TEST(MatchesRegexTest, MatchesStringMatchingGivenRegex) {
|
|||
MatchesRegex(internal::StringView(""));
|
||||
EXPECT_TRUE(m4.Matches(internal::StringView("")));
|
||||
EXPECT_TRUE(m4.Matches(internal::StringView()));
|
||||
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
}
|
||||
|
||||
TEST(MatchesRegexTest, CanDescribeSelf) {
|
||||
|
|
@ -1858,10 +1958,8 @@ TEST(MatchesRegexTest, CanDescribeSelf) {
|
|||
Matcher<const char*> m2 = MatchesRegex(new RE("a.*"));
|
||||
EXPECT_EQ("matches regular expression \"a.*\"", Describe(m2));
|
||||
|
||||
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
Matcher<const internal::StringView> m3 = MatchesRegex(new RE("0.*"));
|
||||
EXPECT_EQ("matches regular expression \"0.*\"", Describe(m3));
|
||||
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
}
|
||||
|
||||
// Tests ContainsRegex().
|
||||
|
|
@ -1877,7 +1975,6 @@ TEST(ContainsRegexTest, MatchesStringContainingGivenRegex) {
|
|||
EXPECT_TRUE(m2.Matches("az1"));
|
||||
EXPECT_FALSE(m2.Matches("1a"));
|
||||
|
||||
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
const Matcher<const internal::StringView&> m3 = ContainsRegex(new RE("a.*z"));
|
||||
EXPECT_TRUE(m3.Matches(internal::StringView("azbz")));
|
||||
EXPECT_TRUE(m3.Matches(internal::StringView("az1")));
|
||||
|
|
@ -1887,7 +1984,6 @@ TEST(ContainsRegexTest, MatchesStringContainingGivenRegex) {
|
|||
ContainsRegex(internal::StringView(""));
|
||||
EXPECT_TRUE(m4.Matches(internal::StringView("")));
|
||||
EXPECT_TRUE(m4.Matches(internal::StringView()));
|
||||
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
}
|
||||
|
||||
TEST(ContainsRegexTest, CanDescribeSelf) {
|
||||
|
|
@ -1897,10 +1993,8 @@ TEST(ContainsRegexTest, CanDescribeSelf) {
|
|||
Matcher<const char*> m2 = ContainsRegex(new RE("a.*"));
|
||||
EXPECT_EQ("contains regular expression \"a.*\"", Describe(m2));
|
||||
|
||||
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
Matcher<const internal::StringView> m3 = ContainsRegex(new RE("0.*"));
|
||||
EXPECT_EQ("contains regular expression \"0.*\"", Describe(m3));
|
||||
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
}
|
||||
|
||||
// Tests for wide strings.
|
||||
|
|
@ -2293,22 +2387,19 @@ PolymorphicMatcher<DivisibleByImpl> DivisibleBy(int n) {
|
|||
return MakePolymorphicMatcher(DivisibleByImpl(n));
|
||||
}
|
||||
|
||||
// Tests that when AllOf() fails, only the first failing matcher is
|
||||
// asked to explain why.
|
||||
// Tests that when AllOf() fails, all failing matchers are asked to explain why.
|
||||
TEST(ExplainMatchResultTest, AllOf_False_False) {
|
||||
const Matcher<int> m = AllOf(DivisibleBy(4), DivisibleBy(3));
|
||||
EXPECT_EQ("which is 1 modulo 4", Explain(m, 5));
|
||||
EXPECT_EQ("which is 1 modulo 4, and which is 2 modulo 3", Explain(m, 5));
|
||||
}
|
||||
|
||||
// Tests that when AllOf() fails, only the first failing matcher is
|
||||
// asked to explain why.
|
||||
// Tests that when AllOf() fails, all failing matchers are asked to explain why.
|
||||
TEST(ExplainMatchResultTest, AllOf_False_True) {
|
||||
const Matcher<int> m = AllOf(DivisibleBy(4), DivisibleBy(3));
|
||||
EXPECT_EQ("which is 2 modulo 4", Explain(m, 6));
|
||||
}
|
||||
|
||||
// Tests that when AllOf() fails, only the first failing matcher is
|
||||
// asked to explain why.
|
||||
// Tests that when AllOf() fails, all failing matchers are asked to explain why.
|
||||
TEST(ExplainMatchResultTest, AllOf_True_False) {
|
||||
const Matcher<int> m = AllOf(Ge(1), DivisibleBy(3));
|
||||
EXPECT_EQ("which is 2 modulo 3", Explain(m, 5));
|
||||
|
|
@ -2321,9 +2412,79 @@ TEST(ExplainMatchResultTest, AllOf_True_True) {
|
|||
EXPECT_EQ("which is 0 modulo 2, and which is 0 modulo 3", Explain(m, 6));
|
||||
}
|
||||
|
||||
// Tests that when AllOf() succeeds, but matchers have no explanation,
|
||||
// the matcher description is used.
|
||||
TEST(ExplainMatchResultTest, AllOf_True_True_2) {
|
||||
const Matcher<int> m = AllOf(Ge(2), Le(3));
|
||||
EXPECT_EQ("", Explain(m, 2));
|
||||
EXPECT_EQ("is >= 2, and is <= 3", Explain(m, 2));
|
||||
}
|
||||
|
||||
// A matcher that records whether the listener was interested.
|
||||
template <typename T>
|
||||
class CountingMatcher : public MatcherInterface<T> {
|
||||
public:
|
||||
explicit CountingMatcher(const Matcher<T>& base_matcher,
|
||||
std::vector<bool>* listener_interested)
|
||||
: base_matcher_(base_matcher),
|
||||
listener_interested_(listener_interested) {}
|
||||
|
||||
bool MatchAndExplain(T x, MatchResultListener* listener) const override {
|
||||
listener_interested_->push_back(listener->IsInterested());
|
||||
return base_matcher_.MatchAndExplain(x, listener);
|
||||
}
|
||||
|
||||
void DescribeTo(ostream* os) const override { base_matcher_.DescribeTo(os); }
|
||||
|
||||
private:
|
||||
Matcher<T> base_matcher_;
|
||||
std::vector<bool>* listener_interested_;
|
||||
};
|
||||
|
||||
TEST(AllOfTest, DoesNotFormatChildMatchersWhenNotInterested) {
|
||||
std::vector<bool> listener_interested;
|
||||
Matcher<int> matcher =
|
||||
MakeMatcher(new CountingMatcher<int>(Eq(1), &listener_interested));
|
||||
EXPECT_TRUE(matcher.Matches(1));
|
||||
EXPECT_THAT(listener_interested, ElementsAre(false));
|
||||
listener_interested.clear();
|
||||
Matcher<int> all_of_matcher = AllOf(matcher, matcher);
|
||||
EXPECT_TRUE(all_of_matcher.Matches(1));
|
||||
EXPECT_THAT(listener_interested, ElementsAre(false, false));
|
||||
listener_interested.clear();
|
||||
EXPECT_FALSE(all_of_matcher.Matches(0));
|
||||
EXPECT_THAT(listener_interested, ElementsAre(false));
|
||||
}
|
||||
|
||||
TEST(AnyOfTest, DoesNotFormatChildMatchersWhenNotInterested) {
|
||||
std::vector<bool> listener_interested;
|
||||
Matcher<int> matcher =
|
||||
MakeMatcher(new CountingMatcher<int>(Eq(1), &listener_interested));
|
||||
EXPECT_TRUE(matcher.Matches(1));
|
||||
EXPECT_THAT(listener_interested, ElementsAre(false));
|
||||
listener_interested.clear();
|
||||
Matcher<int> any_of_matcher = AnyOf(matcher, matcher);
|
||||
EXPECT_TRUE(any_of_matcher.Matches(1));
|
||||
EXPECT_THAT(listener_interested, ElementsAre(false));
|
||||
listener_interested.clear();
|
||||
EXPECT_FALSE(any_of_matcher.Matches(0));
|
||||
EXPECT_THAT(listener_interested, ElementsAre(false, false));
|
||||
}
|
||||
|
||||
TEST(OptionalTest, DoesNotFormatChildMatcherWhenNotInterested) {
|
||||
std::vector<bool> listener_interested;
|
||||
Matcher<int> matcher =
|
||||
MakeMatcher(new CountingMatcher<int>(Eq(1), &listener_interested));
|
||||
EXPECT_TRUE(matcher.Matches(1));
|
||||
EXPECT_THAT(listener_interested, ElementsAre(false));
|
||||
listener_interested.clear();
|
||||
Matcher<std::optional<int>> optional_matcher = Optional(matcher);
|
||||
EXPECT_FALSE(optional_matcher.Matches(std::nullopt));
|
||||
EXPECT_THAT(listener_interested, ElementsAre());
|
||||
EXPECT_TRUE(optional_matcher.Matches(1));
|
||||
EXPECT_THAT(listener_interested, ElementsAre(false));
|
||||
listener_interested.clear();
|
||||
EXPECT_FALSE(matcher.Matches(0));
|
||||
EXPECT_THAT(listener_interested, ElementsAre(false));
|
||||
}
|
||||
|
||||
INSTANTIATE_GTEST_MATCHER_TEST_P(ExplainmatcherResultTest);
|
||||
|
|
|
|||
|
|
@ -31,14 +31,27 @@
|
|||
//
|
||||
// This file tests some commonly used argument matchers.
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <deque>
|
||||
#include <forward_list>
|
||||
#include <iterator>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#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)
|
||||
|
||||
#include "test/gmock-matchers_test.h"
|
||||
|
||||
namespace testing {
|
||||
namespace gmock_matchers_test {
|
||||
namespace {
|
||||
|
|
@ -204,7 +217,7 @@ TEST(PointeeTest, ReferenceToNonConstRawPointer) {
|
|||
TEST(PointeeTest, SmartPointer) {
|
||||
const Matcher<std::unique_ptr<int>> m = Pointee(Ge(0));
|
||||
|
||||
std::unique_ptr<int> n(new int(1));
|
||||
std::unique_ptr<int> n = std::make_unique<int>(1);
|
||||
EXPECT_TRUE(m.Matches(n));
|
||||
}
|
||||
|
||||
|
|
@ -241,7 +254,7 @@ TEST(PointerTest, RawPointerToConst) {
|
|||
}
|
||||
|
||||
TEST(PointerTest, SmartPointer) {
|
||||
std::unique_ptr<int> n(new int(10));
|
||||
std::unique_ptr<int> n = std::make_unique<int>(10);
|
||||
int* raw_n = n.get();
|
||||
const Matcher<std::unique_ptr<int>> m = Pointer(Eq(raw_n));
|
||||
|
||||
|
|
@ -1034,8 +1047,8 @@ TEST(ResultOfTest, WorksForCompatibleMatcherTypes) {
|
|||
// a NULL function pointer.
|
||||
TEST(ResultOfDeathTest, DiesOnNullFunctionPointers) {
|
||||
EXPECT_DEATH_IF_SUPPORTED(
|
||||
ResultOf(static_cast<std::string (*)(int dummy)>(nullptr),
|
||||
Eq(std::string("foo"))),
|
||||
(void)ResultOf(static_cast<std::string (*)(int dummy)>(nullptr),
|
||||
Eq(std::string("foo"))),
|
||||
"NULL function pointer is passed into ResultOf\\(\\)\\.");
|
||||
}
|
||||
|
||||
|
|
@ -1192,13 +1205,16 @@ TEST(SizeIsTest, ExplainsResult) {
|
|||
vector<int> container;
|
||||
EXPECT_EQ("whose size 0 doesn't match", Explain(m1, container));
|
||||
EXPECT_EQ("whose size 0 matches", Explain(m2, container));
|
||||
EXPECT_EQ("whose size 0 matches", Explain(m3, container));
|
||||
EXPECT_EQ("whose size 0 matches, which matches (is equal to 0)",
|
||||
Explain(m3, container));
|
||||
EXPECT_EQ("whose size 0 doesn't match", Explain(m4, container));
|
||||
container.push_back(0);
|
||||
container.push_back(0);
|
||||
EXPECT_EQ("whose size 2 matches", Explain(m1, container));
|
||||
EXPECT_EQ("whose size 2 doesn't match", Explain(m2, container));
|
||||
EXPECT_EQ("whose size 2 doesn't match", Explain(m3, container));
|
||||
EXPECT_EQ(
|
||||
"whose size 2 doesn't match, isn't equal to 0, and isn't equal to 3",
|
||||
Explain(m3, container));
|
||||
EXPECT_EQ("whose size 2 matches", Explain(m4, container));
|
||||
}
|
||||
|
||||
|
|
@ -1256,10 +1272,11 @@ TEST(WhenSortedByTest, CanDescribeSelf) {
|
|||
|
||||
TEST(WhenSortedByTest, ExplainsMatchResult) {
|
||||
const int a[] = {2, 1};
|
||||
EXPECT_EQ("which is { 1, 2 } when sorted, whose element #0 doesn't match",
|
||||
Explain(WhenSortedBy(less<int>(), ElementsAre(2, 3)), a));
|
||||
EXPECT_EQ("which is { 1, 2 } when sorted",
|
||||
Explain(WhenSortedBy(less<int>(), ElementsAre(1, 2)), a));
|
||||
EXPECT_EQ(
|
||||
Explain(WhenSortedBy(less<int>(), ElementsAre(2, 3)), a),
|
||||
"which is { 1, 2 } when sorted, whose element #0 (1) isn't equal to 2");
|
||||
EXPECT_EQ(Explain(WhenSortedBy(less<int>(), ElementsAre(1, 2)), a),
|
||||
"which is { 1, 2 } when sorted");
|
||||
}
|
||||
|
||||
// WhenSorted() is a simple wrapper on WhenSortedBy(). Hence we don't
|
||||
|
|
@ -1463,8 +1480,10 @@ TEST_P(BeginEndDistanceIsTestP, ExplainsResult) {
|
|||
Explain(m1, container));
|
||||
EXPECT_EQ("whose distance between begin() and end() 0 matches",
|
||||
Explain(m2, container));
|
||||
EXPECT_EQ("whose distance between begin() and end() 0 matches",
|
||||
Explain(m3, container));
|
||||
EXPECT_EQ(
|
||||
"whose distance between begin() and end() 0 matches, which matches (is "
|
||||
"equal to 0)",
|
||||
Explain(m3, container));
|
||||
EXPECT_EQ(
|
||||
"whose distance between begin() and end() 0 doesn't match, which is 1 "
|
||||
"less than 1",
|
||||
|
|
@ -1475,8 +1494,10 @@ TEST_P(BeginEndDistanceIsTestP, ExplainsResult) {
|
|||
Explain(m1, container));
|
||||
EXPECT_EQ("whose distance between begin() and end() 2 doesn't match",
|
||||
Explain(m2, container));
|
||||
EXPECT_EQ("whose distance between begin() and end() 2 doesn't match",
|
||||
Explain(m3, container));
|
||||
EXPECT_EQ(
|
||||
"whose distance between begin() and end() 2 doesn't match, isn't equal "
|
||||
"to 0, and isn't equal to 3",
|
||||
Explain(m3, container));
|
||||
EXPECT_EQ(
|
||||
"whose distance between begin() and end() 2 matches, which is 1 more "
|
||||
"than 1",
|
||||
|
|
@ -1756,6 +1777,295 @@ TEST(IsSubsetOfTest, WorksWithMoveOnly) {
|
|||
helper.Call(MakeUniquePtrs({2}));
|
||||
}
|
||||
|
||||
// A container whose iterator returns a temporary. This can iterate over the
|
||||
// characters in a string.
|
||||
class CharString {
|
||||
public:
|
||||
using value_type = char;
|
||||
|
||||
class const_iterator {
|
||||
public:
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
using value_type = char;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = const char*;
|
||||
using reference = const char&;
|
||||
|
||||
// Create an iterator that points to the given character.
|
||||
explicit const_iterator(const char* ptr) : ptr_(ptr) {}
|
||||
|
||||
// Returns the current character. IMPORTANT: this must return a temporary,
|
||||
// not a reference, to test that ElementsAre() works with containers whose
|
||||
// iterators return temporaries.
|
||||
char operator*() const { return *ptr_; }
|
||||
|
||||
// Advances to the next character.
|
||||
const_iterator& operator++() {
|
||||
++ptr_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Compares two iterators.
|
||||
bool operator==(const const_iterator& other) const {
|
||||
return ptr_ == other.ptr_;
|
||||
}
|
||||
bool operator!=(const const_iterator& other) const {
|
||||
return ptr_ != other.ptr_;
|
||||
}
|
||||
|
||||
private:
|
||||
const char* ptr_ = nullptr;
|
||||
};
|
||||
|
||||
// Creates a CharString that contains the given string.
|
||||
explicit CharString(const std::string& s) : s_(s) {}
|
||||
|
||||
// Returns an iterator pointing to the first character in the string.
|
||||
const_iterator begin() const { return const_iterator(s_.c_str()); }
|
||||
|
||||
// Returns an iterator pointing past the last character in the string.
|
||||
const_iterator end() const { return const_iterator(s_.c_str() + s_.size()); }
|
||||
|
||||
private:
|
||||
std::string s_;
|
||||
};
|
||||
|
||||
// Tests using ElementsAre() with a container whose iterator returns a
|
||||
// temporary.
|
||||
TEST(ElementsAreTest, WorksWithContainerThatReturnsTempInIterator) {
|
||||
CharString s("abc");
|
||||
EXPECT_THAT(s, ElementsAre('a', 'b', 'c'));
|
||||
EXPECT_THAT(s, Not(ElementsAre('a', 'b', 'd')));
|
||||
}
|
||||
|
||||
// Tests using ElementsAreArray() with a container whose iterator returns a
|
||||
// temporary.
|
||||
TEST(ElementsAreArrayTest, WorksWithContainerThatReturnsTempInIterator) {
|
||||
CharString s("abc");
|
||||
EXPECT_THAT(s, ElementsAreArray({'a', 'b', 'c'}));
|
||||
EXPECT_THAT(s, Not(ElementsAreArray({'a', 'b', 'd'})));
|
||||
}
|
||||
|
||||
// A container whose iterator returns a temporary and is not copy-assignable.
|
||||
// This simulates the behavior of the proxy object returned by absl::StrSplit().
|
||||
class CharString2 {
|
||||
public:
|
||||
using value_type = char;
|
||||
|
||||
class const_iterator {
|
||||
public:
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
using value_type = char;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = const char*;
|
||||
using reference = const char&;
|
||||
|
||||
// Make const_iterator copy-constructible but not copy-assignable,
|
||||
// simulating the behavior of the proxy object returned by absl::StrSplit().
|
||||
const_iterator(const const_iterator&) = default;
|
||||
const_iterator& operator=(const const_iterator&) = delete;
|
||||
|
||||
// Create an iterator that points to the given character.
|
||||
explicit const_iterator(const char* ptr) : ptr_(ptr) {}
|
||||
|
||||
// Returns the current character. IMPORTANT: this must return a temporary,
|
||||
// not a reference, to test that ElementsAre() works with containers whose
|
||||
// iterators return temporaries.
|
||||
char operator*() const { return *ptr_; }
|
||||
|
||||
// Advances to the next character.
|
||||
const_iterator& operator++() {
|
||||
++ptr_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Compares two iterators.
|
||||
bool operator==(const const_iterator& other) const {
|
||||
return ptr_ == other.ptr_;
|
||||
}
|
||||
bool operator!=(const const_iterator& other) const {
|
||||
return ptr_ != other.ptr_;
|
||||
}
|
||||
|
||||
private:
|
||||
const char* ptr_ = nullptr;
|
||||
};
|
||||
|
||||
// Creates a CharString that contains the given string.
|
||||
explicit CharString2(const std::string& s) : s_(s) {}
|
||||
|
||||
// Returns an iterator pointing to the first character in the string.
|
||||
const_iterator begin() const { return const_iterator(s_.c_str()); }
|
||||
|
||||
// Returns an iterator pointing past the last character in the string.
|
||||
const_iterator end() const { return const_iterator(s_.c_str() + s_.size()); }
|
||||
|
||||
private:
|
||||
std::string s_;
|
||||
};
|
||||
|
||||
// Tests using ElementsAre() with a container whose iterator returns a
|
||||
// temporary and is not copy-assignable.
|
||||
TEST(ElementsAreTest, WorksWithContainerThatReturnsTempInUnassignableIterator) {
|
||||
CharString2 s("abc");
|
||||
EXPECT_THAT(s, ElementsAre('a', 'b', 'c'));
|
||||
EXPECT_THAT(s, Not(ElementsAre('a', 'b', 'd')));
|
||||
}
|
||||
|
||||
// Tests using ElementsAreArray() with a container whose iterator returns a
|
||||
// temporary and is not copy-assignable.
|
||||
TEST(ElementsAreArrayTest,
|
||||
WorksWithContainerThatReturnsTempInUnassignableIterator) {
|
||||
CharString2 s("abc");
|
||||
EXPECT_THAT(s, ElementsAreArray({'a', 'b', 'c'}));
|
||||
EXPECT_THAT(s, Not(ElementsAreArray({'a', 'b', 'd'})));
|
||||
}
|
||||
|
||||
// A container whose iterator returns a temporary and is neither
|
||||
// copy-constructible nor copy-assignable.
|
||||
class CharString3 {
|
||||
public:
|
||||
using value_type = char;
|
||||
|
||||
class const_iterator {
|
||||
public:
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
using value_type = char;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = const char*;
|
||||
using reference = const char&;
|
||||
|
||||
// Make const_iterator neither copy-constructible nor copy-assignable.
|
||||
const_iterator(const const_iterator&) = delete;
|
||||
const_iterator& operator=(const const_iterator&) = delete;
|
||||
|
||||
// Create an iterator that points to the given character.
|
||||
explicit const_iterator(const char* ptr) : ptr_(ptr) {}
|
||||
|
||||
// Returns the current character. IMPORTANT: this must return a temporary,
|
||||
// not a reference, to test that ElementsAre() works with containers whose
|
||||
// iterators return temporaries.
|
||||
char operator*() const { return *ptr_; }
|
||||
|
||||
// Advances to the next character.
|
||||
const_iterator& operator++() {
|
||||
++ptr_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Compares two iterators.
|
||||
bool operator==(const const_iterator& other) const {
|
||||
return ptr_ == other.ptr_;
|
||||
}
|
||||
bool operator!=(const const_iterator& other) const {
|
||||
return ptr_ != other.ptr_;
|
||||
}
|
||||
|
||||
private:
|
||||
const char* ptr_ = nullptr;
|
||||
};
|
||||
|
||||
// Creates a CharString that contains the given string.
|
||||
explicit CharString3(const std::string& s) : s_(s) {}
|
||||
|
||||
// Returns an iterator pointing to the first character in the string.
|
||||
const_iterator begin() const { return const_iterator(s_.c_str()); }
|
||||
|
||||
// Returns an iterator pointing past the last character in the string.
|
||||
const_iterator end() const { return const_iterator(s_.c_str() + s_.size()); }
|
||||
|
||||
private:
|
||||
std::string s_;
|
||||
};
|
||||
|
||||
// Tests using ElementsAre() with a container whose iterator returns a
|
||||
// temporary and is neither copy-constructible nor copy-assignable.
|
||||
TEST(ElementsAreTest, WorksWithContainerThatReturnsTempInUncopyableIterator) {
|
||||
CharString3 s("abc");
|
||||
EXPECT_THAT(s, ElementsAre('a', 'b', 'c'));
|
||||
EXPECT_THAT(s, Not(ElementsAre('a', 'b', 'd')));
|
||||
}
|
||||
|
||||
// Tests using ElementsAreArray() with a container whose iterator returns a
|
||||
// temporary and is neither copy-constructible nor copy-assignable.
|
||||
TEST(ElementsAreArrayTest,
|
||||
WorksWithContainerThatReturnsTempInUncopyableIterator) {
|
||||
CharString3 s("abc");
|
||||
EXPECT_THAT(s, ElementsAreArray({'a', 'b', 'c'}));
|
||||
EXPECT_THAT(s, Not(ElementsAreArray({'a', 'b', 'd'})));
|
||||
}
|
||||
|
||||
// A container whose iterator returns a temporary, is neither
|
||||
// copy-constructible nor copy-assignable, and has no member types.
|
||||
class CharString4 {
|
||||
public:
|
||||
using value_type = char;
|
||||
|
||||
class const_iterator {
|
||||
public:
|
||||
// Do not define difference_type, etc.
|
||||
|
||||
// Make const_iterator neither copy-constructible nor copy-assignable.
|
||||
const_iterator(const const_iterator&) = delete;
|
||||
const_iterator& operator=(const const_iterator&) = delete;
|
||||
|
||||
// Create an iterator that points to the given character.
|
||||
explicit const_iterator(const char* ptr) : ptr_(ptr) {}
|
||||
|
||||
// Returns the current character. IMPORTANT: this must return a temporary,
|
||||
// not a reference, to test that ElementsAre() works with containers whose
|
||||
// iterators return temporaries.
|
||||
char operator*() const { return *ptr_; }
|
||||
|
||||
// Advances to the next character.
|
||||
const_iterator& operator++() {
|
||||
++ptr_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Compares two iterators.
|
||||
bool operator==(const const_iterator& other) const {
|
||||
return ptr_ == other.ptr_;
|
||||
}
|
||||
bool operator!=(const const_iterator& other) const {
|
||||
return ptr_ != other.ptr_;
|
||||
}
|
||||
|
||||
private:
|
||||
const char* ptr_ = nullptr;
|
||||
};
|
||||
|
||||
// Creates a CharString that contains the given string.
|
||||
explicit CharString4(const std::string& s) : s_(s) {}
|
||||
|
||||
// Returns an iterator pointing to the first character in the string.
|
||||
const_iterator begin() const { return const_iterator(s_.c_str()); }
|
||||
|
||||
// Returns an iterator pointing past the last character in the string.
|
||||
const_iterator end() const { return const_iterator(s_.c_str() + s_.size()); }
|
||||
|
||||
private:
|
||||
std::string s_;
|
||||
};
|
||||
|
||||
// Tests using ElementsAre() with a container whose iterator returns a
|
||||
// temporary, is neither copy-constructible nor copy-assignable, and has no
|
||||
// member types.
|
||||
TEST(ElementsAreTest, WorksWithContainerWithIteratorWithNoMemberTypes) {
|
||||
CharString4 s("abc");
|
||||
EXPECT_THAT(s, ElementsAre('a', 'b', 'c'));
|
||||
EXPECT_THAT(s, Not(ElementsAre('a', 'b', 'd')));
|
||||
}
|
||||
|
||||
// Tests using ElementsAreArray() with a container whose iterator returns a
|
||||
// temporary, is neither copy-constructible nor copy-assignable, and has no
|
||||
// member types.
|
||||
TEST(ElementsAreArrayTest, WorksWithContainerWithIteratorWithNoMemberTypes) {
|
||||
CharString4 s("abc");
|
||||
EXPECT_THAT(s, ElementsAreArray({'a', 'b', 'c'}));
|
||||
EXPECT_THAT(s, Not(ElementsAreArray({'a', 'b', 'd'})));
|
||||
}
|
||||
|
||||
// Tests using ElementsAre() and ElementsAreArray() with stream-like
|
||||
// "containers".
|
||||
|
||||
|
|
@ -1824,8 +2134,8 @@ TEST(UnorderedElementsAreArrayTest, SucceedsWhenExpected) {
|
|||
}
|
||||
|
||||
TEST(UnorderedElementsAreArrayTest, VectorBool) {
|
||||
const bool a[] = {0, 1, 0, 1, 1};
|
||||
const bool b[] = {1, 0, 1, 1, 0};
|
||||
const bool a[] = {false, true, false, true, true};
|
||||
const bool b[] = {true, false, true, true, false};
|
||||
std::vector<bool> expected(std::begin(a), std::end(a));
|
||||
std::vector<bool> actual(std::begin(b), std::end(b));
|
||||
StringMatchResultListener listener;
|
||||
|
|
@ -2002,7 +2312,14 @@ TEST_F(UnorderedElementsAreTest, FailMessageCountWrong) {
|
|||
StringMatchResultListener listener;
|
||||
EXPECT_FALSE(ExplainMatchResult(UnorderedElementsAre(1, 2, 3), v, &listener))
|
||||
<< listener.str();
|
||||
EXPECT_THAT(listener.str(), Eq("which has 1 element"));
|
||||
EXPECT_THAT(listener.str(),
|
||||
Eq("which has 1 element\n"
|
||||
"where the following matchers don't match any elements:\n"
|
||||
"matcher #0: is equal to 1,\n"
|
||||
"matcher #1: is equal to 2,\n"
|
||||
"matcher #2: is equal to 3\n"
|
||||
"and where the following elements don't match any matchers:\n"
|
||||
"element #0: 4"));
|
||||
}
|
||||
|
||||
TEST_F(UnorderedElementsAreTest, FailMessageCountWrongZero) {
|
||||
|
|
@ -2010,7 +2327,11 @@ TEST_F(UnorderedElementsAreTest, FailMessageCountWrongZero) {
|
|||
StringMatchResultListener listener;
|
||||
EXPECT_FALSE(ExplainMatchResult(UnorderedElementsAre(1, 2, 3), v, &listener))
|
||||
<< listener.str();
|
||||
EXPECT_THAT(listener.str(), Eq(""));
|
||||
EXPECT_THAT(listener.str(),
|
||||
Eq("where the following matchers don't match any elements:\n"
|
||||
"matcher #0: is equal to 1,\n"
|
||||
"matcher #1: is equal to 2,\n"
|
||||
"matcher #2: is equal to 3"));
|
||||
}
|
||||
|
||||
TEST_F(UnorderedElementsAreTest, FailMessageUnmatchedMatchers) {
|
||||
|
|
@ -2125,7 +2446,7 @@ TEST_P(EachTestP, ExplainsMatchResultCorrectly) {
|
|||
Matcher<set<int>> m = Each(2);
|
||||
EXPECT_EQ("", Explain(m, a));
|
||||
|
||||
Matcher<const int(&)[1]> n = Each(1); // NOLINT
|
||||
Matcher<const int (&)[1]> n = Each(1); // NOLINT
|
||||
|
||||
const int b[1] = {1};
|
||||
EXPECT_EQ("", Explain(n, b));
|
||||
|
|
@ -2260,7 +2581,7 @@ TEST(PointwiseTest, MakesCopyOfRhs) {
|
|||
rhs.push_back(4);
|
||||
|
||||
int lhs[] = {1, 2};
|
||||
const Matcher<const int(&)[2]> m = Pointwise(IsHalfOf(), rhs);
|
||||
const Matcher<const int (&)[2]> m = Pointwise(IsHalfOf(), rhs);
|
||||
EXPECT_THAT(lhs, m);
|
||||
|
||||
// Changing rhs now shouldn't affect m, which made a copy of rhs.
|
||||
|
|
@ -2388,7 +2709,7 @@ TEST(UnorderedPointwiseTest, MakesCopyOfRhs) {
|
|||
rhs.push_back(4);
|
||||
|
||||
int lhs[] = {2, 1};
|
||||
const Matcher<const int(&)[2]> m = UnorderedPointwise(IsHalfOf(), rhs);
|
||||
const Matcher<const int (&)[2]> m = UnorderedPointwise(IsHalfOf(), rhs);
|
||||
EXPECT_THAT(lhs, m);
|
||||
|
||||
// Changing rhs now shouldn't affect m, which made a copy of rhs.
|
||||
|
|
@ -2426,7 +2747,7 @@ TEST(UnorderedPointwiseTest, RejectsWrongSize) {
|
|||
const double lhs[2] = {1, 2};
|
||||
const int rhs[1] = {0};
|
||||
EXPECT_THAT(lhs, Not(UnorderedPointwise(Gt(), rhs)));
|
||||
EXPECT_EQ("which has 2 elements",
|
||||
EXPECT_EQ("which has 2 elements\n",
|
||||
Explain(UnorderedPointwise(Gt(), rhs), lhs));
|
||||
|
||||
const int rhs2[3] = {0, 1, 2};
|
||||
|
|
@ -2475,7 +2796,7 @@ TEST(UnorderedPointwiseTest, WorksWithMoveOnly) {
|
|||
}
|
||||
|
||||
TEST(PointeeTest, WorksOnMoveOnlyType) {
|
||||
std::unique_ptr<int> p(new int(3));
|
||||
std::unique_ptr<int> p = std::make_unique<int>(3);
|
||||
EXPECT_THAT(p, Pointee(Eq(3)));
|
||||
EXPECT_THAT(p, Not(Pointee(Eq(2))));
|
||||
}
|
||||
|
|
@ -2639,11 +2960,11 @@ TEST_P(ElementsAreTestP, CanExplainMismatchRightSize) {
|
|||
vector<int> v;
|
||||
v.push_back(2);
|
||||
v.push_back(1);
|
||||
EXPECT_EQ("whose element #0 doesn't match", Explain(m, v));
|
||||
EXPECT_EQ(Explain(m, v), "whose element #0 (2) isn't equal to 1");
|
||||
|
||||
v[0] = 1;
|
||||
EXPECT_EQ("whose element #1 doesn't match, which is 4 less than 5",
|
||||
Explain(m, v));
|
||||
EXPECT_EQ(Explain(m, v),
|
||||
"whose element #1 (1) is <= 5, which is 4 less than 5");
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, MatchesOneElementVector) {
|
||||
|
|
@ -2776,7 +3097,7 @@ TEST(ElementsAreTest, WorksWithNativeArrayPassedByReference) {
|
|||
|
||||
class NativeArrayPassedAsPointerAndSize {
|
||||
public:
|
||||
NativeArrayPassedAsPointerAndSize() {}
|
||||
NativeArrayPassedAsPointerAndSize() = default;
|
||||
|
||||
MOCK_METHOD(void, Helper, (int* array, int size));
|
||||
|
||||
|
|
@ -3043,7 +3364,7 @@ TEST(ContainsTest, SetDoesNotMatchWhenElementIsNotInContainer) {
|
|||
|
||||
TEST_P(ContainsTestP, ExplainsMatchResultCorrectly) {
|
||||
const int a[2] = {1, 2};
|
||||
Matcher<const int(&)[2]> m = Contains(2);
|
||||
Matcher<const int (&)[2]> m = Contains(2);
|
||||
EXPECT_EQ("whose element #1 matches", Explain(m, a));
|
||||
|
||||
m = Contains(3);
|
||||
|
|
@ -3118,6 +3439,78 @@ TEST(ContainsTest, WorksForTwoDimensionalNativeArray) {
|
|||
EXPECT_THAT(a, Contains(Not(Contains(5))));
|
||||
}
|
||||
|
||||
// Tests ContainsSubsequence().
|
||||
|
||||
TEST(ContainsSubsequenceTest, WorksForNativeArray) {
|
||||
const int a[] = {1, 2, 3, 4, 5};
|
||||
EXPECT_THAT(a, ContainsSubsequence(1, 3, 4));
|
||||
EXPECT_THAT(a, Not(ContainsSubsequence(1, 3, 2)));
|
||||
}
|
||||
|
||||
TEST(ContainsSubsequenceTest, AcceptsMatcher) {
|
||||
const int a[] = {1, 2, 3, 4, 5};
|
||||
EXPECT_THAT(a, ContainsSubsequence(Eq(1), Gt(3), Gt(4)));
|
||||
EXPECT_THAT(a, Not(ContainsSubsequence(1, Gt(3), Lt(3))));
|
||||
}
|
||||
|
||||
TEST(ContainsSubsequenceTest, WorksForTwoDimensionalNativeArray) {
|
||||
int a[][3] = {{1, 2, 3}, {7, 8, 9}, {4, 5, 6}};
|
||||
EXPECT_THAT(a, ContainsSubsequence(ElementsAre(1, 2, 3), Contains(4)));
|
||||
EXPECT_THAT(a,
|
||||
Not(ContainsSubsequence(Contains(1), Contains(8), Contains(9))));
|
||||
}
|
||||
|
||||
TEST(ContainsSubsequenceTest, WorksForVector) {
|
||||
const vector<int> a = {1, 2, 3, 4, 5};
|
||||
EXPECT_THAT(a, ContainsSubsequence(1, 3, 4));
|
||||
EXPECT_THAT(a, Not(ContainsSubsequence(1, 3, 2)));
|
||||
}
|
||||
|
||||
TEST(ContainsSubsequenceTest, WorksForEmptySmallSizedSubsequences) {
|
||||
const int a[] = {1, 2, 3, 4, 5};
|
||||
EXPECT_THAT(a, ContainsSubsequence());
|
||||
EXPECT_THAT(a, ContainsSubsequence(Gt(4)));
|
||||
EXPECT_THAT(a, Not(ContainsSubsequence(Gt(6))));
|
||||
EXPECT_THAT(a, ContainsSubsequence(Lt(2), Gt(3)));
|
||||
EXPECT_THAT(a, Not(ContainsSubsequence(Lt(2), Lt(2))));
|
||||
}
|
||||
|
||||
TEST(ContainsSubsequenceTest, DescribesItselfCorrectly) {
|
||||
Matcher<const int (&)[5]> m = ContainsSubsequence(1, 3, 4);
|
||||
EXPECT_EQ(
|
||||
"contains in order a subsequence of elements that matches: is equal to "
|
||||
"1, then is equal to 3, then is equal to 4",
|
||||
Describe(m));
|
||||
m = ContainsSubsequence(Eq(1), Gt(3), Gt(4));
|
||||
EXPECT_EQ(
|
||||
"contains in order a subsequence of elements that matches: is equal to "
|
||||
"1, then is > 3, then is > 4",
|
||||
Describe(m));
|
||||
|
||||
m = Not(ContainsSubsequence(1, 3, 4));
|
||||
EXPECT_EQ(
|
||||
"does not contain in order a subsequence of elements that matches is "
|
||||
"equal to 1, then is equal to 3, then is equal to 4",
|
||||
Describe(m));
|
||||
}
|
||||
|
||||
TEST(ContainsSubsequenceTest, ExplainsMismatchCorrectlyForSingleMatcher) {
|
||||
const int a[] = {1, 2, 3, 4, 5};
|
||||
Matcher<const int (&)[5]> m = ContainsSubsequence(Eq(6));
|
||||
EXPECT_EQ(Explain(m, a),
|
||||
"could not find a match for matcher #0 (is equal to 6)");
|
||||
}
|
||||
|
||||
TEST(ContainsSubsequenceTest, ExplainsMismatchCorrectlyForMultipleMatchers) {
|
||||
const int a[] = {1, 2, 3, 4, 5};
|
||||
Matcher<const int (&)[5]> m = ContainsSubsequence(Eq(2), Gt(4), Gt(4));
|
||||
EXPECT_EQ(
|
||||
Explain(m, a),
|
||||
"found match for matcher #0 with element at position #1, found match for "
|
||||
"matcher #1 with element at position #4, but could not find a match for "
|
||||
"matcher #2 (is > 4) after the last match at position #4");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace gmock_matchers_test
|
||||
} // namespace testing
|
||||
|
|
|
|||
|
|
@ -31,14 +31,23 @@
|
|||
//
|
||||
// This file tests some commonly used argument matchers.
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#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)
|
||||
|
||||
#include "test/gmock-matchers_test.h"
|
||||
|
||||
namespace testing {
|
||||
namespace gmock_matchers_test {
|
||||
namespace {
|
||||
|
|
@ -70,7 +79,7 @@ TEST(AddressTest, Const) {
|
|||
}
|
||||
|
||||
TEST(AddressTest, MatcherDoesntCopy) {
|
||||
std::unique_ptr<int> n(new int(1));
|
||||
std::unique_ptr<int> n = std::make_unique<int>(1);
|
||||
const Matcher<std::unique_ptr<int>> m = Address(Eq(&n));
|
||||
|
||||
EXPECT_TRUE(m.Matches(n));
|
||||
|
|
@ -193,14 +202,14 @@ TEST(IsTrueTest, IsTrueIsFalse) {
|
|||
EXPECT_THAT(nullptr, Not(IsTrue()));
|
||||
EXPECT_THAT(nullptr, IsFalse());
|
||||
std::unique_ptr<int> null_unique;
|
||||
std::unique_ptr<int> nonnull_unique(new int(0));
|
||||
std::unique_ptr<int> nonnull_unique = std::make_unique<int>(0);
|
||||
EXPECT_THAT(null_unique, Not(IsTrue()));
|
||||
EXPECT_THAT(null_unique, IsFalse());
|
||||
EXPECT_THAT(nonnull_unique, IsTrue());
|
||||
EXPECT_THAT(nonnull_unique, Not(IsFalse()));
|
||||
}
|
||||
|
||||
#if GTEST_HAS_TYPED_TEST
|
||||
#ifdef GTEST_HAS_TYPED_TEST
|
||||
// Tests ContainerEq with different container types, and
|
||||
// different element types.
|
||||
|
||||
|
|
@ -666,6 +675,8 @@ TEST_P(MatcherTupleTestP, ExplainsMatchFailure) {
|
|||
// explanation.
|
||||
}
|
||||
|
||||
#if GTEST_HAS_TYPED_TEST
|
||||
|
||||
// Sample optional type implementation with minimal requirements for use with
|
||||
// Optional matcher.
|
||||
template <typename T>
|
||||
|
|
@ -683,38 +694,94 @@ class SampleOptional {
|
|||
bool has_value_;
|
||||
};
|
||||
|
||||
TEST(OptionalTest, DescribesSelf) {
|
||||
const Matcher<SampleOptional<int>> m = Optional(Eq(1));
|
||||
// Sample optional type implementation with alternative minimal requirements for
|
||||
// use with Optional matcher. In particular, while it doesn't have a bool
|
||||
// conversion operator, it does have a has_value() method.
|
||||
template <typename T>
|
||||
class SampleOptionalWithoutBoolConversion {
|
||||
public:
|
||||
using value_type = T;
|
||||
explicit SampleOptionalWithoutBoolConversion(T value)
|
||||
: value_(std::move(value)), has_value_(true) {}
|
||||
SampleOptionalWithoutBoolConversion() : value_(), has_value_(false) {}
|
||||
bool has_value() const { return has_value_; }
|
||||
const T& operator*() const { return value_; }
|
||||
|
||||
private:
|
||||
T value_;
|
||||
bool has_value_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class OptionalTest : public testing::Test {};
|
||||
|
||||
using OptionalTestTypes =
|
||||
testing::Types<SampleOptional<int>,
|
||||
SampleOptionalWithoutBoolConversion<int>>;
|
||||
|
||||
TYPED_TEST_SUITE(OptionalTest, OptionalTestTypes);
|
||||
|
||||
TYPED_TEST(OptionalTest, DescribesSelf) {
|
||||
const Matcher<TypeParam> m = Optional(Eq(1));
|
||||
EXPECT_EQ("value is equal to 1", Describe(m));
|
||||
}
|
||||
|
||||
TEST(OptionalTest, ExplainsSelf) {
|
||||
const Matcher<SampleOptional<int>> m = Optional(Eq(1));
|
||||
EXPECT_EQ("whose value 1 matches", Explain(m, SampleOptional<int>(1)));
|
||||
EXPECT_EQ("whose value 2 doesn't match", Explain(m, SampleOptional<int>(2)));
|
||||
TYPED_TEST(OptionalTest, ExplainsSelf) {
|
||||
const Matcher<TypeParam> m = Optional(Eq(1));
|
||||
EXPECT_EQ("whose value 1 matches", Explain(m, TypeParam(1)));
|
||||
EXPECT_EQ("whose value 2 doesn't match", Explain(m, TypeParam(2)));
|
||||
}
|
||||
|
||||
TEST(OptionalTest, MatchesNonEmptyOptional) {
|
||||
const Matcher<SampleOptional<int>> m1 = Optional(1);
|
||||
const Matcher<SampleOptional<int>> m2 = Optional(Eq(2));
|
||||
const Matcher<SampleOptional<int>> m3 = Optional(Lt(3));
|
||||
SampleOptional<int> opt(1);
|
||||
TYPED_TEST(OptionalTest, MatchesNonEmptyOptional) {
|
||||
const Matcher<TypeParam> m1 = Optional(1);
|
||||
const Matcher<TypeParam> m2 = Optional(Eq(2));
|
||||
const Matcher<TypeParam> m3 = Optional(Lt(3));
|
||||
TypeParam opt(1);
|
||||
EXPECT_TRUE(m1.Matches(opt));
|
||||
EXPECT_FALSE(m2.Matches(opt));
|
||||
EXPECT_TRUE(m3.Matches(opt));
|
||||
}
|
||||
|
||||
TEST(OptionalTest, DoesNotMatchNullopt) {
|
||||
const Matcher<SampleOptional<int>> m = Optional(1);
|
||||
SampleOptional<int> empty;
|
||||
TYPED_TEST(OptionalTest, DoesNotMatchNullopt) {
|
||||
const Matcher<TypeParam> m = Optional(1);
|
||||
TypeParam empty;
|
||||
EXPECT_FALSE(m.Matches(empty));
|
||||
}
|
||||
|
||||
TEST(OptionalTest, WorksWithMoveOnly) {
|
||||
Matcher<SampleOptional<std::unique_ptr<int>>> m = Optional(Eq(nullptr));
|
||||
EXPECT_TRUE(m.Matches(SampleOptional<std::unique_ptr<int>>(nullptr)));
|
||||
TYPED_TEST(OptionalTest, ComposesWithMonomorphicMatchersTakingReferences) {
|
||||
const Matcher<const int&> eq1 = Eq(1);
|
||||
const Matcher<const int&> eq2 = Eq(2);
|
||||
TypeParam opt(1);
|
||||
EXPECT_THAT(opt, Optional(eq1));
|
||||
EXPECT_THAT(opt, Optional(Not(eq2)));
|
||||
EXPECT_THAT(opt, Optional(AllOf(eq1, Not(eq2))));
|
||||
}
|
||||
|
||||
TYPED_TEST(OptionalTest, ComposesWithMonomorphicMatchersRequiringConversion) {
|
||||
const Matcher<int64_t> eq1 = Eq(1);
|
||||
const Matcher<int64_t> eq2 = Eq(2);
|
||||
TypeParam opt(1);
|
||||
EXPECT_THAT(opt, Optional(eq1));
|
||||
EXPECT_THAT(opt, Optional(Not(eq2)));
|
||||
EXPECT_THAT(opt, Optional(AllOf(eq1, Not(eq2))));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class MoveOnlyOptionalTest : public testing::Test {};
|
||||
|
||||
using MoveOnlyOptionalTestTypes =
|
||||
testing::Types<SampleOptional<std::unique_ptr<int>>,
|
||||
SampleOptionalWithoutBoolConversion<std::unique_ptr<int>>>;
|
||||
|
||||
TYPED_TEST_SUITE(MoveOnlyOptionalTest, MoveOnlyOptionalTestTypes);
|
||||
|
||||
TYPED_TEST(MoveOnlyOptionalTest, WorksWithMoveOnly) {
|
||||
Matcher<TypeParam> m = Optional(Eq(nullptr));
|
||||
EXPECT_TRUE(m.Matches(TypeParam(nullptr)));
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_TYPED_TEST
|
||||
|
||||
class SampleVariantIntString {
|
||||
public:
|
||||
SampleVariantIntString(int i) : i_(i), has_int_(true) {}
|
||||
|
|
@ -722,7 +789,7 @@ class SampleVariantIntString {
|
|||
|
||||
template <typename T>
|
||||
friend bool holds_alternative(const SampleVariantIntString& value) {
|
||||
return value.has_int_ == std::is_same<T, int>::value;
|
||||
return value.has_int_ == std::is_same_v<T, int>;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
|
@ -1568,10 +1635,10 @@ TEST_P(AnyOfArrayTestP, ExplainsMatchResultCorrectly) {
|
|||
const Matcher<int> m1 = AnyOfArray(v1);
|
||||
const Matcher<int> m2 = AnyOfArray(v2);
|
||||
EXPECT_EQ("", Explain(m0, 0));
|
||||
EXPECT_EQ("", Explain(m1, 1));
|
||||
EXPECT_EQ("", Explain(m1, 2));
|
||||
EXPECT_EQ("", Explain(m2, 3));
|
||||
EXPECT_EQ("", Explain(m2, 4));
|
||||
EXPECT_EQ("which matches (is equal to 1)", Explain(m1, 1));
|
||||
EXPECT_EQ("isn't equal to 1", Explain(m1, 2));
|
||||
EXPECT_EQ("which matches (is equal to 3)", Explain(m2, 3));
|
||||
EXPECT_EQ("isn't equal to 2, and isn't equal to 3", Explain(m2, 4));
|
||||
EXPECT_EQ("()", Describe(m0));
|
||||
EXPECT_EQ("(is equal to 1)", Describe(m1));
|
||||
EXPECT_EQ("(is equal to 2) or (is equal to 3)", Describe(m2));
|
||||
|
|
@ -1598,7 +1665,7 @@ MATCHER(IsNotNull, "") { return arg != nullptr; }
|
|||
// Verifies that a matcher defined using MATCHER() can work on
|
||||
// move-only types.
|
||||
TEST(MatcherMacroTest, WorksOnMoveOnlyType) {
|
||||
std::unique_ptr<int> p(new int(3));
|
||||
std::unique_ptr<int> p = std::make_unique<int>(3);
|
||||
EXPECT_THAT(p, IsNotNull());
|
||||
EXPECT_THAT(std::unique_ptr<int>(), Not(IsNotNull()));
|
||||
}
|
||||
|
|
@ -1608,7 +1675,7 @@ MATCHER_P(UniquePointee, pointee, "") { return *arg == pointee; }
|
|||
// Verifies that a matcher defined using MATCHER_P*() can work on
|
||||
// move-only types.
|
||||
TEST(MatcherPMacroTest, WorksOnMoveOnlyType) {
|
||||
std::unique_ptr<int> p(new int(3));
|
||||
std::unique_ptr<int> p = std::make_unique<int>(3);
|
||||
EXPECT_THAT(p, UniquePointee(3));
|
||||
EXPECT_THAT(p, Not(UniquePointee(2)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,8 +123,7 @@ struct GtestGreaterThanMatcher {
|
|||
};
|
||||
|
||||
template <typename T>
|
||||
GtestGreaterThanMatcher<typename std::decay<T>::type> GtestGreaterThan(
|
||||
T&& rhs) {
|
||||
GtestGreaterThanMatcher<std::decay_t<T>> GtestGreaterThan(T&& rhs) {
|
||||
return {rhs};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,10 +33,14 @@
|
|||
|
||||
#include "gmock/gmock-more-actions.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest-spi.h"
|
||||
|
|
@ -55,6 +59,7 @@ using testing::Invoke;
|
|||
using testing::ReturnArg;
|
||||
using testing::ReturnPointee;
|
||||
using testing::SaveArg;
|
||||
using testing::SaveArgByMove;
|
||||
using testing::SaveArgPointee;
|
||||
using testing::SetArgReferee;
|
||||
using testing::Unused;
|
||||
|
|
@ -81,6 +86,16 @@ struct UnaryFunctor {
|
|||
int operator()(bool x) { return x ? 1 : -1; }
|
||||
};
|
||||
|
||||
struct UnaryMoveOnlyFunctor : UnaryFunctor {
|
||||
UnaryMoveOnlyFunctor() = default;
|
||||
UnaryMoveOnlyFunctor(const UnaryMoveOnlyFunctor&) = delete;
|
||||
UnaryMoveOnlyFunctor(UnaryMoveOnlyFunctor&&) = default;
|
||||
};
|
||||
|
||||
struct OneShotUnaryFunctor {
|
||||
int operator()(bool x) && { return x ? 1 : -1; }
|
||||
};
|
||||
|
||||
const char* Binary(const char* input, short n) { return input + n; } // NOLINT
|
||||
|
||||
int Ternary(int x, char y, short z) { return x + y + z; } // NOLINT
|
||||
|
|
@ -187,45 +202,45 @@ class Foo {
|
|||
|
||||
// Tests using Invoke() with a nullary function.
|
||||
TEST(InvokeTest, Nullary) {
|
||||
Action<int()> a = Invoke(Nullary); // NOLINT
|
||||
Action<int()> a = &Nullary;
|
||||
EXPECT_EQ(1, a.Perform(std::make_tuple()));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a unary function.
|
||||
TEST(InvokeTest, Unary) {
|
||||
Action<bool(int)> a = Invoke(Unary); // NOLINT
|
||||
Action<bool(int)> a = &Unary;
|
||||
EXPECT_FALSE(a.Perform(std::make_tuple(1)));
|
||||
EXPECT_TRUE(a.Perform(std::make_tuple(-1)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a binary function.
|
||||
TEST(InvokeTest, Binary) {
|
||||
Action<const char*(const char*, short)> a = Invoke(Binary); // NOLINT
|
||||
Action<const char*(const char*, short)> a = &Binary; // NOLINT
|
||||
const char* p = "Hello";
|
||||
EXPECT_EQ(p + 2, a.Perform(std::make_tuple(p, Short(2))));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a ternary function.
|
||||
TEST(InvokeTest, Ternary) {
|
||||
Action<int(int, char, short)> a = Invoke(Ternary); // NOLINT
|
||||
Action<int(int, char, short)> a = &Ternary; // NOLINT
|
||||
EXPECT_EQ(6, a.Perform(std::make_tuple(1, '\2', Short(3))));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 4-argument function.
|
||||
TEST(InvokeTest, FunctionThatTakes4Arguments) {
|
||||
Action<int(int, int, int, int)> a = Invoke(SumOf4); // NOLINT
|
||||
Action<int(int, int, int, int)> a = &SumOf4;
|
||||
EXPECT_EQ(1234, a.Perform(std::make_tuple(1000, 200, 30, 4)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 5-argument function.
|
||||
TEST(InvokeTest, FunctionThatTakes5Arguments) {
|
||||
Action<int(int, int, int, int, int)> a = Invoke(SumOf5); // NOLINT
|
||||
Action<int(int, int, int, int, int)> a = &SumOf5;
|
||||
EXPECT_EQ(12345, a.Perform(std::make_tuple(10000, 2000, 300, 40, 5)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 6-argument function.
|
||||
TEST(InvokeTest, FunctionThatTakes6Arguments) {
|
||||
Action<int(int, int, int, int, int, int)> a = Invoke(SumOf6); // NOLINT
|
||||
Action<int(int, int, int, int, int, int)> a = &SumOf6;
|
||||
EXPECT_EQ(123456,
|
||||
a.Perform(std::make_tuple(100000, 20000, 3000, 400, 50, 6)));
|
||||
}
|
||||
|
|
@ -238,7 +253,7 @@ inline const char* CharPtr(const char* s) { return s; }
|
|||
TEST(InvokeTest, FunctionThatTakes7Arguments) {
|
||||
Action<std::string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*)>
|
||||
a = Invoke(Concat7);
|
||||
a = &Concat7;
|
||||
EXPECT_EQ("1234567",
|
||||
a.Perform(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
||||
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
||||
|
|
@ -249,7 +264,7 @@ TEST(InvokeTest, FunctionThatTakes7Arguments) {
|
|||
TEST(InvokeTest, FunctionThatTakes8Arguments) {
|
||||
Action<std::string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*, const char*)>
|
||||
a = Invoke(Concat8);
|
||||
a = &Concat8;
|
||||
EXPECT_EQ("12345678",
|
||||
a.Perform(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
||||
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
||||
|
|
@ -261,7 +276,7 @@ TEST(InvokeTest, FunctionThatTakes9Arguments) {
|
|||
Action<std::string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*, const char*,
|
||||
const char*)>
|
||||
a = Invoke(Concat9);
|
||||
a = &Concat9;
|
||||
EXPECT_EQ("123456789", a.Perform(std::make_tuple(
|
||||
CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
||||
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
||||
|
|
@ -273,7 +288,7 @@ TEST(InvokeTest, FunctionThatTakes10Arguments) {
|
|||
Action<std::string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*, const char*,
|
||||
const char*, const char*)>
|
||||
a = Invoke(Concat10);
|
||||
a = &Concat10;
|
||||
EXPECT_EQ("1234567890",
|
||||
a.Perform(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
|
||||
CharPtr("4"), CharPtr("5"), CharPtr("6"),
|
||||
|
|
@ -283,12 +298,12 @@ TEST(InvokeTest, FunctionThatTakes10Arguments) {
|
|||
|
||||
// Tests using Invoke() with functions with parameters declared as Unused.
|
||||
TEST(InvokeTest, FunctionWithUnusedParameters) {
|
||||
Action<int(int, int, double, const std::string&)> a1 = Invoke(SumOfFirst2);
|
||||
Action<int(int, int, double, const std::string&)> a1 = &SumOfFirst2;
|
||||
std::tuple<int, int, double, std::string> dummy =
|
||||
std::make_tuple(10, 2, 5.6, std::string("hi"));
|
||||
EXPECT_EQ(12, a1.Perform(dummy));
|
||||
|
||||
Action<int(int, int, bool, int*)> a2 = Invoke(SumOfFirst2);
|
||||
Action<int(int, int, bool, int*)> a2 = &SumOfFirst2;
|
||||
EXPECT_EQ(
|
||||
23, a2.Perform(std::make_tuple(20, 3, true, static_cast<int*>(nullptr))));
|
||||
}
|
||||
|
|
@ -305,13 +320,13 @@ TEST(InvokeTest, MethodWithUnusedParameters) {
|
|||
|
||||
// Tests using Invoke() with a functor.
|
||||
TEST(InvokeTest, Functor) {
|
||||
Action<long(long, int)> a = Invoke(plus<long>()); // NOLINT
|
||||
Action<long(long, int)> a = plus<long>(); // NOLINT
|
||||
EXPECT_EQ(3L, a.Perform(std::make_tuple(1, 2)));
|
||||
}
|
||||
|
||||
// Tests using Invoke(f) as an action of a compatible type.
|
||||
TEST(InvokeTest, FunctionWithCompatibleType) {
|
||||
Action<long(int, short, char, bool)> a = Invoke(SumOf4); // NOLINT
|
||||
Action<long(int, short, char, bool)> a = &SumOf4; // NOLINT
|
||||
EXPECT_EQ(4321, a.Perform(std::make_tuple(4000, Short(300), Char(20), true)));
|
||||
}
|
||||
|
||||
|
|
@ -432,13 +447,13 @@ TEST(InvokeMethodTest, MethodWithCompatibleType) {
|
|||
|
||||
// Tests using WithoutArgs with an action that takes no argument.
|
||||
TEST(WithoutArgsTest, NoArg) {
|
||||
Action<int(int n)> a = WithoutArgs(Invoke(Nullary)); // NOLINT
|
||||
Action<int(int n)> a = WithoutArgs(&Nullary); // NOLINT
|
||||
EXPECT_EQ(1, a.Perform(std::make_tuple(2)));
|
||||
}
|
||||
|
||||
// Tests using WithArg with an action that takes 1 argument.
|
||||
TEST(WithArgTest, OneArg) {
|
||||
Action<bool(double x, int n)> b = WithArg<1>(Invoke(Unary)); // NOLINT
|
||||
Action<bool(double x, int n)> b = WithArg<1>(&Unary); // NOLINT
|
||||
EXPECT_TRUE(b.Perform(std::make_tuple(1.5, -1)));
|
||||
EXPECT_FALSE(b.Perform(std::make_tuple(1.5, 1)));
|
||||
}
|
||||
|
|
@ -478,6 +493,34 @@ TEST(SaveArgActionTest, WorksForCompatibleType) {
|
|||
EXPECT_EQ('a', result);
|
||||
}
|
||||
|
||||
struct MoveOnly {
|
||||
explicit MoveOnly(int v) : i(v) {}
|
||||
MoveOnly(MoveOnly&& o) {
|
||||
i = o.i;
|
||||
o.i = -1;
|
||||
}
|
||||
MoveOnly& operator=(MoveOnly&& o) {
|
||||
i = o.i;
|
||||
o.i = -1;
|
||||
return *this;
|
||||
}
|
||||
int i;
|
||||
};
|
||||
|
||||
TEST(SaveArgByMoveActionTest, WorksForSameType) {
|
||||
MoveOnly result{0};
|
||||
const Action<void(MoveOnly v)> a1 = SaveArgByMove<0>(&result);
|
||||
a1.Perform(std::make_tuple(MoveOnly{5}));
|
||||
EXPECT_EQ(5, result.i);
|
||||
}
|
||||
|
||||
TEST(SaveArgByMoveActionTest, WorksForCompatibleType) {
|
||||
MoveOnly result{0};
|
||||
const Action<void(bool, MoveOnly)> a1 = SaveArgByMove<1>(&result);
|
||||
a1.Perform(std::make_tuple(true, MoveOnly{7}));
|
||||
EXPECT_EQ(7, result.i);
|
||||
}
|
||||
|
||||
TEST(SaveArgPointeeActionTest, WorksForSameType) {
|
||||
int result = 0;
|
||||
const int value = 5;
|
||||
|
|
@ -571,13 +614,13 @@ TEST(ThrowActionTest, ThrowsGivenExceptionInNullaryFunction) {
|
|||
|
||||
class Object {
|
||||
public:
|
||||
virtual ~Object() {}
|
||||
virtual ~Object() = default;
|
||||
virtual void Func() {}
|
||||
};
|
||||
|
||||
class MockObject : public Object {
|
||||
public:
|
||||
~MockObject() override {}
|
||||
~MockObject() override = default;
|
||||
MOCK_METHOD(void, Func, (), (override));
|
||||
};
|
||||
|
||||
|
|
@ -673,7 +716,7 @@ TEST(SetArrayArgumentTest, SetsTheNthArrayWithIteratorArgument) {
|
|||
Action<MyFunction> a = SetArrayArgument<1>(letters.begin(), letters.end());
|
||||
|
||||
std::string s;
|
||||
a.Perform(std::make_tuple(true, back_inserter(s)));
|
||||
a.Perform(std::make_tuple(true, std::back_inserter(s)));
|
||||
EXPECT_EQ(letters, s);
|
||||
}
|
||||
|
||||
|
|
@ -694,12 +737,24 @@ TEST(InvokeArgumentTest, Function0) {
|
|||
EXPECT_EQ(1, a.Perform(std::make_tuple(2, &Nullary)));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a unary function.
|
||||
// Tests using InvokeArgument with a unary functor.
|
||||
TEST(InvokeArgumentTest, Functor1) {
|
||||
Action<int(UnaryFunctor)> a = InvokeArgument<0>(true); // NOLINT
|
||||
EXPECT_EQ(1, a.Perform(std::make_tuple(UnaryFunctor())));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a unary move-only functor.
|
||||
TEST(InvokeArgumentTest, Functor1MoveOnly) {
|
||||
Action<int(UnaryMoveOnlyFunctor)> a = InvokeArgument<0>(true); // NOLINT
|
||||
EXPECT_EQ(1, a.Perform(std::make_tuple(UnaryMoveOnlyFunctor())));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a one-shot unary functor.
|
||||
TEST(InvokeArgumentTest, OneShotFunctor1) {
|
||||
Action<int(OneShotUnaryFunctor)> a = InvokeArgument<0>(true); // NOLINT
|
||||
EXPECT_EQ(1, a.Perform(std::make_tuple(OneShotUnaryFunctor())));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a 5-ary function.
|
||||
TEST(InvokeArgumentTest, Function5) {
|
||||
Action<int(int (*)(int, int, int, int, int))> a = // NOLINT
|
||||
|
|
@ -730,34 +785,34 @@ TEST(InvokeArgumentTest, Functor6) {
|
|||
|
||||
// Tests using InvokeArgument with a 7-ary function.
|
||||
TEST(InvokeArgumentTest, Function7) {
|
||||
Action<std::string(std::string(*)(const char*, const char*, const char*,
|
||||
const char*, const char*, const char*,
|
||||
const char*))>
|
||||
Action<std::string(std::string (*)(const char*, const char*, const char*,
|
||||
const char*, const char*, const char*,
|
||||
const char*))>
|
||||
a = InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7");
|
||||
EXPECT_EQ("1234567", a.Perform(std::make_tuple(&Concat7)));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a 8-ary function.
|
||||
TEST(InvokeArgumentTest, Function8) {
|
||||
Action<std::string(std::string(*)(const char*, const char*, const char*,
|
||||
const char*, const char*, const char*,
|
||||
const char*, const char*))>
|
||||
Action<std::string(std::string (*)(const char*, const char*, const char*,
|
||||
const char*, const char*, const char*,
|
||||
const char*, const char*))>
|
||||
a = InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8");
|
||||
EXPECT_EQ("12345678", a.Perform(std::make_tuple(&Concat8)));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a 9-ary function.
|
||||
TEST(InvokeArgumentTest, Function9) {
|
||||
Action<std::string(std::string(*)(const char*, const char*, const char*,
|
||||
const char*, const char*, const char*,
|
||||
const char*, const char*, const char*))>
|
||||
Action<std::string(std::string (*)(const char*, const char*, const char*,
|
||||
const char*, const char*, const char*,
|
||||
const char*, const char*, const char*))>
|
||||
a = InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9");
|
||||
EXPECT_EQ("123456789", a.Perform(std::make_tuple(&Concat9)));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a 10-ary function.
|
||||
TEST(InvokeArgumentTest, Function10) {
|
||||
Action<std::string(std::string(*)(
|
||||
Action<std::string(std::string (*)(
|
||||
const char*, const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*, const char*, const char*))>
|
||||
a = InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9", "0");
|
||||
|
|
@ -802,6 +857,22 @@ TEST(InvokeArgumentTest, ByExplicitConstReferenceFunction) {
|
|||
EXPECT_FALSE(a.Perform(std::make_tuple(&ReferencesGlobalDouble)));
|
||||
}
|
||||
|
||||
TEST(InvokeArgumentTest, MoveOnlyType) {
|
||||
struct Marker {};
|
||||
struct {
|
||||
// Method takes a unique_ptr (to a type we don't care about), and an
|
||||
// invocable type.
|
||||
MOCK_METHOD(bool, MockMethod,
|
||||
(std::unique_ptr<Marker>, std::function<int()>), ());
|
||||
} mock;
|
||||
|
||||
ON_CALL(mock, MockMethod(_, _)).WillByDefault(InvokeArgument<1>());
|
||||
|
||||
// This compiles, but is a little opaque as a workaround:
|
||||
ON_CALL(mock, MockMethod(_, _))
|
||||
.WillByDefault(WithArg<1>(InvokeArgument<0>()));
|
||||
}
|
||||
|
||||
// Tests DoAll(a1, a2).
|
||||
TEST(DoAllTest, TwoActions) {
|
||||
int n = 0;
|
||||
|
|
@ -955,9 +1026,8 @@ TEST(DoAllTest, NoArgs) {
|
|||
|
||||
TEST(DoAllTest, MoveOnlyArgs) {
|
||||
bool ran_first = false;
|
||||
Action<int(std::unique_ptr<int>)> a =
|
||||
DoAll(InvokeWithoutArgs([&] { ran_first = true; }),
|
||||
[](std::unique_ptr<int> p) { return *p; });
|
||||
Action<int(std::unique_ptr<int>)> a = DoAll(
|
||||
[&] { ran_first = true; }, [](std::unique_ptr<int> p) { return *p; });
|
||||
EXPECT_EQ(7, a.Perform(std::make_tuple(std::unique_ptr<int>(new int(7)))));
|
||||
EXPECT_TRUE(ran_first);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
// clash with ::testing::Mock.
|
||||
class Mock {
|
||||
public:
|
||||
Mock() {}
|
||||
Mock() = default;
|
||||
|
||||
MOCK_METHOD0(DoThis, void());
|
||||
|
||||
|
|
@ -78,7 +78,7 @@ class CallsMockMethodInDestructor {
|
|||
|
||||
class Foo {
|
||||
public:
|
||||
virtual ~Foo() {}
|
||||
virtual ~Foo() = default;
|
||||
|
||||
virtual void DoThis() = 0;
|
||||
virtual int DoThat(bool flag) = 0;
|
||||
|
|
@ -86,7 +86,7 @@ class Foo {
|
|||
|
||||
class MockFoo : public Foo {
|
||||
public:
|
||||
MockFoo() {}
|
||||
MockFoo() = default;
|
||||
void Delete() { delete this; }
|
||||
|
||||
MOCK_METHOD0(DoThis, void());
|
||||
|
|
@ -109,7 +109,7 @@ class MockBar {
|
|||
(a10 ? 'T' : 'F');
|
||||
}
|
||||
|
||||
virtual ~MockBar() {}
|
||||
virtual ~MockBar() = default;
|
||||
|
||||
const std::string& str() const { return str_; }
|
||||
|
||||
|
|
|
|||
|
|
@ -11,8 +11,10 @@ namespace internal {
|
|||
namespace gmockpp {
|
||||
|
||||
static_assert(GMOCK_PP_CAT(1, 4) == 14, "");
|
||||
static_assert(GMOCK_PP_INTERNAL_INTERNAL_16TH(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
|
||||
12, 13, 14, 15, 16, 17, 18) == 16,
|
||||
static_assert(GMOCK_PP_INTERNAL_INTERNAL_32ND(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) == 32,
|
||||
"");
|
||||
static_assert(GMOCK_PP_NARG() == 1, "");
|
||||
static_assert(GMOCK_PP_NARG(x) == 1, "");
|
||||
|
|
@ -70,7 +72,7 @@ static_assert(GMOCK_PP_INTERNAL_VAR_TEST(x, y) == 2, "");
|
|||
static_assert(GMOCK_PP_INTERNAL_VAR_TEST(silly) == 1, "");
|
||||
static_assert(GMOCK_PP_INTERNAL_VAR_TEST(x, y, z) == 3, "");
|
||||
|
||||
// TODO(iserna): The following asserts fail in --config=lexan.
|
||||
// TODO(iserna): The following asserts fail in --config=windows.
|
||||
#define GMOCK_PP_INTERNAL_IS_EMPTY_TEST_1
|
||||
static_assert(GMOCK_PP_IS_EMPTY(GMOCK_PP_INTERNAL_IS_EMPTY_TEST_1), "");
|
||||
static_assert(GMOCK_PP_IS_EMPTY(), "");
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ class NonDefaultConstructible {
|
|||
|
||||
class MockA {
|
||||
public:
|
||||
MockA() {}
|
||||
MockA() = default;
|
||||
|
||||
MOCK_METHOD1(DoA, void(int n));
|
||||
MOCK_METHOD1(ReturnResult, Result(int n));
|
||||
|
|
@ -113,7 +113,7 @@ class MockA {
|
|||
|
||||
class MockB {
|
||||
public:
|
||||
MockB() {}
|
||||
MockB() = default;
|
||||
|
||||
MOCK_CONST_METHOD0(DoB, int()); // NOLINT
|
||||
MOCK_METHOD1(DoB, int(int n)); // NOLINT
|
||||
|
|
@ -125,7 +125,7 @@ class MockB {
|
|||
|
||||
class ReferenceHoldingMock {
|
||||
public:
|
||||
ReferenceHoldingMock() {}
|
||||
ReferenceHoldingMock() = default;
|
||||
|
||||
MOCK_METHOD1(AcceptReference, void(std::shared_ptr<MockA>*));
|
||||
|
||||
|
|
@ -143,12 +143,12 @@ class ReferenceHoldingMock {
|
|||
|
||||
class CC {
|
||||
public:
|
||||
virtual ~CC() {}
|
||||
virtual ~CC() = default;
|
||||
virtual int Method() = 0;
|
||||
};
|
||||
class MockCC : public CC {
|
||||
public:
|
||||
MockCC() {}
|
||||
MockCC() = default;
|
||||
|
||||
MOCK_METHOD0(Method, int());
|
||||
|
||||
|
|
@ -160,7 +160,7 @@ class MockCC : public CC {
|
|||
// Tests that a method with expanded name compiles.
|
||||
TEST(OnCallSyntaxTest, CompilesWithMethodNameExpandedFromMacro) {
|
||||
MockCC cc;
|
||||
ON_CALL(cc, Method());
|
||||
(void)ON_CALL(cc, Method());
|
||||
}
|
||||
|
||||
// Tests that the method with expanded name not only compiles but runs
|
||||
|
|
@ -193,7 +193,7 @@ TEST(OnCallSyntaxTest, EvaluatesFirstArgumentOnce) {
|
|||
MockA a;
|
||||
MockA* pa = &a;
|
||||
|
||||
ON_CALL(*pa++, DoA(_));
|
||||
(void)ON_CALL(*pa++, DoA(_));
|
||||
EXPECT_EQ(&a + 1, pa);
|
||||
}
|
||||
|
||||
|
|
@ -201,7 +201,7 @@ TEST(OnCallSyntaxTest, EvaluatesSecondArgumentOnce) {
|
|||
MockA a;
|
||||
int n = 0;
|
||||
|
||||
ON_CALL(a, DoA(n++));
|
||||
(void)ON_CALL(a, DoA(n++));
|
||||
EXPECT_EQ(1, n);
|
||||
}
|
||||
|
||||
|
|
@ -232,7 +232,7 @@ TEST(OnCallSyntaxTest, WillByDefaultIsMandatory) {
|
|||
|
||||
EXPECT_DEATH_IF_SUPPORTED(
|
||||
{
|
||||
ON_CALL(a, DoA(5));
|
||||
(void)ON_CALL(a, DoA(5));
|
||||
a.DoA(5);
|
||||
},
|
||||
"");
|
||||
|
|
@ -804,39 +804,39 @@ TEST(ExpectCallTest, InfersCardinality1WhenThereIsWillRepeatedly) {
|
|||
"to be called at least once");
|
||||
}
|
||||
|
||||
#if defined(__cplusplus) && __cplusplus >= 201703L
|
||||
|
||||
// TODO(b/396121064) - Fix this test under MSVC
|
||||
#ifndef _MSC_VER
|
||||
// It should be possible to return a non-moveable type from a mock action in
|
||||
// C++17 and above, where it's guaranteed that such a type can be initialized
|
||||
// from a prvalue returned from a function.
|
||||
TEST(ExpectCallTest, NonMoveableType) {
|
||||
// Define a non-moveable result type.
|
||||
struct Result {
|
||||
explicit Result(int x_in) : x(x_in) {}
|
||||
Result(Result&&) = delete;
|
||||
struct NonMoveableStruct {
|
||||
explicit NonMoveableStruct(int x_in) : x(x_in) {}
|
||||
NonMoveableStruct(NonMoveableStruct&&) = delete;
|
||||
|
||||
int x;
|
||||
};
|
||||
|
||||
static_assert(!std::is_move_constructible_v<Result>);
|
||||
static_assert(!std::is_copy_constructible_v<Result>);
|
||||
static_assert(!std::is_move_constructible_v<NonMoveableStruct>);
|
||||
static_assert(!std::is_copy_constructible_v<NonMoveableStruct>);
|
||||
|
||||
static_assert(!std::is_move_assignable_v<Result>);
|
||||
static_assert(!std::is_copy_assignable_v<Result>);
|
||||
static_assert(!std::is_move_assignable_v<NonMoveableStruct>);
|
||||
static_assert(!std::is_copy_assignable_v<NonMoveableStruct>);
|
||||
|
||||
// We should be able to use a callable that returns that result as both a
|
||||
// OnceAction and an Action, whether the callable ignores arguments or not.
|
||||
const auto return_17 = [] { return Result(17); };
|
||||
const auto return_17 = [] { return NonMoveableStruct(17); };
|
||||
|
||||
static_cast<void>(OnceAction<Result()>{return_17});
|
||||
static_cast<void>(Action<Result()>{return_17});
|
||||
static_cast<void>(OnceAction<NonMoveableStruct()>{return_17});
|
||||
static_cast<void>(Action<NonMoveableStruct()>{return_17});
|
||||
|
||||
static_cast<void>(OnceAction<Result(int)>{return_17});
|
||||
static_cast<void>(Action<Result(int)>{return_17});
|
||||
static_cast<void>(OnceAction<NonMoveableStruct(int)>{return_17});
|
||||
static_cast<void>(Action<NonMoveableStruct(int)>{return_17});
|
||||
|
||||
// It should be possible to return the result end to end through an
|
||||
// EXPECT_CALL statement, with both WillOnce and WillRepeatedly.
|
||||
MockFunction<Result()> mock;
|
||||
MockFunction<NonMoveableStruct()> mock;
|
||||
EXPECT_CALL(mock, Call) //
|
||||
.WillOnce(return_17) //
|
||||
.WillRepeatedly(return_17);
|
||||
|
|
@ -846,7 +846,7 @@ TEST(ExpectCallTest, NonMoveableType) {
|
|||
EXPECT_EQ(17, mock.AsStdFunction()().x);
|
||||
}
|
||||
|
||||
#endif // C++17 and above
|
||||
#endif // _MSC_VER
|
||||
|
||||
// Tests that the n-th action is taken for the n-th matching
|
||||
// invocation.
|
||||
|
|
@ -905,7 +905,7 @@ TEST(ExpectCallTest, TakesDefaultActionWhenWillListIsExhausted) {
|
|||
" - returning default value."));
|
||||
}
|
||||
|
||||
TEST(FunctionMockerMessageTest, ReportsExpectCallLocationForExhausedActions) {
|
||||
TEST(FunctionMockerMessageTest, ReportsExpectCallLocationForExhaustedActions) {
|
||||
MockB b;
|
||||
std::string expect_call_location = FormatFileLocation(__FILE__, __LINE__ + 1);
|
||||
EXPECT_CALL(b, DoB()).Times(AnyNumber()).WillOnce(Return(1));
|
||||
|
|
@ -1088,7 +1088,7 @@ TEST(UnexpectedCallTest, UnsatisfiedPrerequisites) {
|
|||
|
||||
// Verifies that the failure message contains the two unsatisfied
|
||||
// pre-requisites but not the satisfied one.
|
||||
#if GTEST_USES_POSIX_RE
|
||||
#ifdef GTEST_USES_POSIX_RE
|
||||
EXPECT_THAT(r.message(),
|
||||
ContainsRegex(
|
||||
// POSIX RE doesn't understand the (?s) prefix, but has no
|
||||
|
|
@ -1881,7 +1881,7 @@ struct Unprintable {
|
|||
|
||||
class MockC {
|
||||
public:
|
||||
MockC() {}
|
||||
MockC() = default;
|
||||
|
||||
MOCK_METHOD6(VoidMethod, void(bool cond, int n, std::string s, void* p,
|
||||
const Printable& x, Unprintable y));
|
||||
|
|
@ -2045,7 +2045,7 @@ class GMockVerboseFlagTest : public VerboseFlagPreservingFixture {
|
|||
NaggyMock<MockA> a;
|
||||
const std::string note =
|
||||
"NOTE: You can safely ignore the above warning unless this "
|
||||
"call should not happen. Do not suppress it by blindly adding "
|
||||
"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/"
|
||||
|
|
@ -2121,7 +2121,7 @@ void PrintTo(PrintMeNot /* dummy */, ::std::ostream* /* os */) {
|
|||
|
||||
class LogTestHelper {
|
||||
public:
|
||||
LogTestHelper() {}
|
||||
LogTestHelper() = default;
|
||||
|
||||
MOCK_METHOD1(Foo, PrintMeNot(PrintMeNot));
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
// Tests Google Mock's functionality that depends on exceptions.
|
||||
|
||||
#include <exception>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -40,13 +40,13 @@ using ::testing::Return;
|
|||
|
||||
class FooInterface {
|
||||
public:
|
||||
virtual ~FooInterface() {}
|
||||
virtual ~FooInterface() = default;
|
||||
virtual void DoThis() = 0;
|
||||
};
|
||||
|
||||
class MockFoo : public FooInterface {
|
||||
public:
|
||||
MockFoo() {}
|
||||
MockFoo() = default;
|
||||
|
||||
MOCK_METHOD0(DoThis, void());
|
||||
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@
|
|||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
#if !GTEST_OS_WINDOWS_MOBILE
|
||||
#ifndef GTEST_OS_WINDOWS_MOBILE
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
|
|
@ -181,11 +181,12 @@ using testing::WithArg;
|
|||
using testing::WithArgs;
|
||||
using testing::WithoutArgs;
|
||||
|
||||
#if !GTEST_OS_WINDOWS_MOBILE
|
||||
#ifndef GTEST_OS_WINDOWS_MOBILE
|
||||
using testing::SetErrnoAndReturn;
|
||||
#endif
|
||||
|
||||
#if GTEST_HAS_EXCEPTIONS
|
||||
using testing::Rethrow;
|
||||
using testing::Throw;
|
||||
#endif
|
||||
|
||||
|
|
@ -194,7 +195,7 @@ using testing::MatchesRegex;
|
|||
|
||||
class Interface {
|
||||
public:
|
||||
virtual ~Interface() {}
|
||||
virtual ~Interface() = default;
|
||||
virtual void VoidFromString(char* str) = 0;
|
||||
virtual char* StringFromString(char* str) = 0;
|
||||
virtual int IntFromString(char* str) = 0;
|
||||
|
|
@ -208,7 +209,7 @@ class Interface {
|
|||
|
||||
class Mock : public Interface {
|
||||
public:
|
||||
Mock() {}
|
||||
Mock() = default;
|
||||
|
||||
MOCK_METHOD1(VoidFromString, void(char* str));
|
||||
MOCK_METHOD1(StringFromString, char*(char* str));
|
||||
|
|
@ -306,7 +307,7 @@ TEST(LinkTest, TestSetArrayArgument) {
|
|||
mock.VoidFromString(&ch);
|
||||
}
|
||||
|
||||
#if !GTEST_OS_WINDOWS_MOBILE
|
||||
#ifndef GTEST_OS_WINDOWS_MOBILE
|
||||
|
||||
// Tests the linkage of the SetErrnoAndReturn action.
|
||||
TEST(LinkTest, TestSetErrnoAndReturn) {
|
||||
|
|
@ -326,7 +327,7 @@ TEST(LinkTest, TestInvoke) {
|
|||
InvokeHelper test_invoke_helper;
|
||||
|
||||
EXPECT_CALL(mock, VoidFromString(_))
|
||||
.WillOnce(Invoke(&InvokeHelper::StaticVoidFromString))
|
||||
.WillOnce(&InvokeHelper::StaticVoidFromString)
|
||||
.WillOnce(Invoke(&test_invoke_helper, &InvokeHelper::VoidFromString));
|
||||
mock.VoidFromString(nullptr);
|
||||
mock.VoidFromString(nullptr);
|
||||
|
|
@ -337,10 +338,12 @@ TEST(LinkTest, TestInvokeWithoutArgs) {
|
|||
Mock mock;
|
||||
InvokeHelper test_invoke_helper;
|
||||
|
||||
GTEST_DISABLE_DEPRECATED_PUSH_()
|
||||
EXPECT_CALL(mock, VoidFromString(_))
|
||||
.WillOnce(InvokeWithoutArgs(&InvokeHelper::StaticVoidFromVoid))
|
||||
.WillOnce(&InvokeHelper::StaticVoidFromVoid)
|
||||
.WillOnce(
|
||||
InvokeWithoutArgs(&test_invoke_helper, &InvokeHelper::VoidFromVoid));
|
||||
GTEST_DISABLE_DEPRECATED_POP_()
|
||||
mock.VoidFromString(nullptr);
|
||||
mock.VoidFromString(nullptr);
|
||||
}
|
||||
|
|
@ -359,7 +362,7 @@ TEST(LinkTest, TestWithArg) {
|
|||
Mock mock;
|
||||
|
||||
EXPECT_CALL(mock, VoidFromString(_))
|
||||
.WillOnce(WithArg<0>(Invoke(&InvokeHelper::StaticVoidFromString)));
|
||||
.WillOnce(WithArg<0>(&InvokeHelper::StaticVoidFromString));
|
||||
mock.VoidFromString(nullptr);
|
||||
}
|
||||
|
||||
|
|
@ -368,7 +371,7 @@ TEST(LinkTest, TestWithArgs) {
|
|||
Mock mock;
|
||||
|
||||
EXPECT_CALL(mock, VoidFromString(_))
|
||||
.WillOnce(WithArgs<0>(Invoke(&InvokeHelper::StaticVoidFromString)));
|
||||
.WillOnce(WithArgs<0>(&InvokeHelper::StaticVoidFromString));
|
||||
mock.VoidFromString(nullptr);
|
||||
}
|
||||
|
||||
|
|
@ -416,6 +419,14 @@ TEST(LinkTest, TestThrow) {
|
|||
EXPECT_CALL(mock, VoidFromString(_)).WillOnce(Throw(42));
|
||||
EXPECT_THROW(mock.VoidFromString(nullptr), int);
|
||||
}
|
||||
// Tests the linkage of the Rethrow action.
|
||||
TEST(LinkTest, TestRethrow) {
|
||||
Mock mock;
|
||||
|
||||
EXPECT_CALL(mock, VoidFromString(_))
|
||||
.WillOnce(Rethrow(std::make_exception_ptr(42)));
|
||||
EXPECT_THROW(mock.VoidFromString(nullptr), int);
|
||||
}
|
||||
#endif // GTEST_HAS_EXCEPTIONS
|
||||
|
||||
// The ACTION*() macros trigger warning C4100 (unreferenced formal
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
|
@ -53,7 +52,7 @@ using testing::Value;
|
|||
|
||||
class MockFoo {
|
||||
public:
|
||||
MockFoo() {}
|
||||
MockFoo() = default;
|
||||
|
||||
MOCK_METHOD3(Bar, char(const std::string& s, int i, double x));
|
||||
MOCK_METHOD2(Bar2, bool(int x, int y));
|
||||
|
|
@ -255,16 +254,12 @@ TEST_F(GMockOutputTest, CatchesLeakedMocks) {
|
|||
}
|
||||
|
||||
MATCHER_P2(IsPair, first, second, "") {
|
||||
return Value(std::get<0>(arg), first) && Value(std::get<1>(arg), second);
|
||||
return Value(arg.first, first) && Value(arg.second, second);
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, PrintsMatcher) {
|
||||
const testing::Matcher<int> m1 = Ge(48);
|
||||
// Explicitly using std::tuple instead of std::pair due to differences between
|
||||
// MSVC and other compilers. std::pair is printed as
|
||||
// "struct std::pair<int,bool>" when using MSVC vs "std::pair<int,bool>" with
|
||||
// other compilers.
|
||||
EXPECT_THAT((std::tuple<int, bool>(42, true)), IsPair(m1, true));
|
||||
EXPECT_THAT((std::pair<int, bool>(42, true)), IsPair(m1, true));
|
||||
}
|
||||
|
||||
void TestCatchesLeakedMocksInAdHocTests() {
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ FILE:#: EXPECT_CALL(foo_, Bar2(0, _))...
|
|||
Actual: 1
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.UnexpectedCall
|
||||
[ RUN ] GMockOutputTest.UnexpectedCallToVoidFunction
|
||||
unknown file: Failure
|
||||
|
|
@ -53,6 +54,7 @@ FILE:#: EXPECT_CALL(foo_, Bar3(0, _))...
|
|||
Actual: 1
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.UnexpectedCallToVoidFunction
|
||||
[ RUN ] GMockOutputTest.ExcessiveCall
|
||||
FILE:#: Failure
|
||||
|
|
@ -61,6 +63,7 @@ Mock function called more times than expected - returning default value.
|
|||
Returns: false
|
||||
Expected: to be called once
|
||||
Actual: called twice - over-saturated and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.ExcessiveCall
|
||||
[ RUN ] GMockOutputTest.ExcessiveCallToVoidFunction
|
||||
FILE:#: Failure
|
||||
|
|
@ -68,6 +71,7 @@ Mock function called more times than expected - returning directly.
|
|||
Function call: Bar3(0, 1)
|
||||
Expected: to be called once
|
||||
Actual: called twice - over-saturated and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.ExcessiveCallToVoidFunction
|
||||
[ RUN ] GMockOutputTest.UninterestingCall
|
||||
|
||||
|
|
@ -75,14 +79,14 @@ GMOCK WARNING:
|
|||
Uninteresting mock function call - returning default value.
|
||||
Function call: Bar2(0, 1)
|
||||
Returns: false
|
||||
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly 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.
|
||||
NOTE: 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.
|
||||
[ OK ] GMockOutputTest.UninterestingCall
|
||||
[ RUN ] GMockOutputTest.UninterestingCallToVoidFunction
|
||||
|
||||
GMOCK WARNING:
|
||||
Uninteresting mock function call - returning directly.
|
||||
Function call: Bar3(0, 1)
|
||||
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly 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.
|
||||
NOTE: 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.
|
||||
[ OK ] GMockOutputTest.UninterestingCallToVoidFunction
|
||||
[ RUN ] GMockOutputTest.RetiredExpectation
|
||||
unknown file: Failure
|
||||
|
|
@ -104,6 +108,7 @@ FILE:#: tried expectation #1: EXPECT_CALL(foo_, Bar2(0, 0))...
|
|||
Actual: 1
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.RetiredExpectation
|
||||
[ RUN ] GMockOutputTest.UnsatisfiedPrerequisite
|
||||
unknown file: Failure
|
||||
|
|
@ -125,6 +130,7 @@ FILE:#: pre-requisite #0
|
|||
(end of pre-requisites)
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.UnsatisfiedPrerequisite
|
||||
[ RUN ] GMockOutputTest.UnsatisfiedPrerequisites
|
||||
unknown file: Failure
|
||||
|
|
@ -147,6 +153,7 @@ FILE:#: pre-requisite #1
|
|||
(end of pre-requisites)
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.UnsatisfiedPrerequisites
|
||||
[ RUN ] GMockOutputTest.UnsatisfiedWith
|
||||
FILE:#: Failure
|
||||
|
|
@ -154,16 +161,19 @@ Actual function call count doesn't match EXPECT_CALL(foo_, Bar2(_, _))...
|
|||
Expected args: are a pair where the first >= the second
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.UnsatisfiedWith
|
||||
[ RUN ] GMockOutputTest.UnsatisfiedExpectation
|
||||
FILE:#: Failure
|
||||
Actual function call count doesn't match EXPECT_CALL(foo_, Bar2(0, _))...
|
||||
Expected: to be called twice
|
||||
Actual: called once - unsatisfied and active
|
||||
|
||||
FILE:#: Failure
|
||||
Actual function call count doesn't match EXPECT_CALL(foo_, Bar(_, _, _))...
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.UnsatisfiedExpectation
|
||||
[ RUN ] GMockOutputTest.MismatchArguments
|
||||
unknown file: Failure
|
||||
|
|
@ -180,6 +190,7 @@ FILE:#: EXPECT_CALL(foo_, Bar(Ref(s), _, Ge(0)))...
|
|||
Actual: -0.1
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.MismatchArguments
|
||||
[ RUN ] GMockOutputTest.MismatchWith
|
||||
unknown file: Failure
|
||||
|
|
@ -194,6 +205,7 @@ FILE:#: EXPECT_CALL(foo_, Bar2(Ge(2), Ge(1)))...
|
|||
Actual: don't match
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.MismatchWith
|
||||
[ RUN ] GMockOutputTest.MismatchArgumentsAndWith
|
||||
unknown file: Failure
|
||||
|
|
@ -210,6 +222,7 @@ FILE:#: EXPECT_CALL(foo_, Bar2(Ge(2), Ge(1)))...
|
|||
Actual: don't match
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.MismatchArgumentsAndWith
|
||||
[ RUN ] GMockOutputTest.UnexpectedCallWithDefaultAction
|
||||
unknown file: Failure
|
||||
|
|
@ -227,6 +240,7 @@ FILE:#: EXPECT_CALL(foo_, Bar2(2, 2))...
|
|||
Actual: 0
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
|
||||
unknown file: Failure
|
||||
|
||||
Unexpected mock function call - taking default action specified at:
|
||||
|
|
@ -242,6 +256,7 @@ FILE:#: EXPECT_CALL(foo_, Bar2(2, 2))...
|
|||
Actual: 0
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.UnexpectedCallWithDefaultAction
|
||||
[ RUN ] GMockOutputTest.ExcessiveCallWithDefaultAction
|
||||
FILE:#: Failure
|
||||
|
|
@ -251,6 +266,7 @@ FILE:#:
|
|||
Returns: true
|
||||
Expected: to be called once
|
||||
Actual: called twice - over-saturated and active
|
||||
|
||||
FILE:#: Failure
|
||||
Mock function called more times than expected - taking default action specified at:
|
||||
FILE:#:
|
||||
|
|
@ -258,6 +274,7 @@ FILE:#:
|
|||
Returns: false
|
||||
Expected: to be called once
|
||||
Actual: called twice - over-saturated and active
|
||||
|
||||
[ FAILED ] GMockOutputTest.ExcessiveCallWithDefaultAction
|
||||
[ RUN ] GMockOutputTest.UninterestingCallWithDefaultAction
|
||||
|
||||
|
|
@ -266,14 +283,14 @@ Uninteresting mock function call - taking default action specified at:
|
|||
FILE:#:
|
||||
Function call: Bar2(2, 2)
|
||||
Returns: true
|
||||
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly 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.
|
||||
NOTE: 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.
|
||||
|
||||
GMOCK WARNING:
|
||||
Uninteresting mock function call - taking default action specified at:
|
||||
FILE:#:
|
||||
Function call: Bar2(1, 1)
|
||||
Returns: false
|
||||
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly 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.
|
||||
NOTE: 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.
|
||||
[ OK ] GMockOutputTest.UninterestingCallWithDefaultAction
|
||||
[ RUN ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction
|
||||
|
||||
|
|
@ -290,9 +307,10 @@ Stack trace:
|
|||
[ OK ] GMockOutputTest.CatchesLeakedMocks
|
||||
[ RUN ] GMockOutputTest.PrintsMatcher
|
||||
FILE:#: Failure
|
||||
Value of: (std::tuple<int, bool>(42, true))
|
||||
Value of: (std::pair<int, bool>(42, true))
|
||||
Expected: is pair (first: is >= 48, second: true)
|
||||
Actual: (42, true)
|
||||
Actual: (42, true) (of type std::pair<int,bool>)
|
||||
|
||||
[ FAILED ] GMockOutputTest.PrintsMatcher
|
||||
[ FAILED ] GMockOutputTest.UnexpectedCall
|
||||
[ FAILED ] GMockOutputTest.UnexpectedCallToVoidFunction
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@
|
|||
// Tests that Google Mock constructs can be used in a large number of
|
||||
// threads concurrently.
|
||||
|
||||
#include <iterator>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
|
|
@ -188,7 +190,7 @@ TEST(StressTest, CanUseGMockWithThreads) {
|
|||
&TestPartiallyOrderedExpectationsWithThreads,
|
||||
};
|
||||
|
||||
const int kRoutines = sizeof(test_routines) / sizeof(test_routines[0]);
|
||||
const int kRoutines = std::size(test_routines);
|
||||
const int kCopiesOfEachRoutine = kMaxTestThreads / kRoutines;
|
||||
const int kTestThreads = kCopiesOfEachRoutine * kRoutines;
|
||||
ThreadWithParam<Dummy>* threads[kTestThreads] = {};
|
||||
|
|
|
|||
|
|
@ -174,6 +174,6 @@ TEST(WideInitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
|
|||
// Makes sure Google Mock flags can be accessed in code.
|
||||
TEST(FlagTest, IsAccessibleInCode) {
|
||||
bool dummy =
|
||||
GMOCK_FLAG_GET(catch_leaked_mocks) && GMOCK_FLAG_GET(verbose) == "";
|
||||
GMOCK_FLAG_GET(catch_leaked_mocks) && GMOCK_FLAG_GET(verbose).empty();
|
||||
(void)dummy; // Avoids the "unused local variable" warning.
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue