summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorofats <ofats@google.com>2021-01-20 12:14:44 -0500
committerCJ Johnson <johnsoncj@google.com>2021-01-26 15:43:04 -0500
commit59dea67b815a046122d77113d5c6df1df66076bb (patch)
tree5f9968473d8bba82aa3a75829767aeb1e4ad7548
parent997c36c1881105bd7ce482a1ec93759badf64ce6 (diff)
downloadgoogletest-git-59dea67b815a046122d77113d5c6df1df66076bb.tar.gz
Googletest export
Remove scripts for code generating together with related files. PiperOrigin-RevId: 352805926
-rw-r--r--CONTRIBUTING.md12
-rw-r--r--docs/pump_manual.md190
-rw-r--r--googlemock/CMakeLists.txt1
-rw-r--r--googlemock/include/gmock/gmock-generated-actions.h.pump390
-rw-r--r--googlemock/include/gmock/gmock-more-actions.h (renamed from googlemock/include/gmock/gmock-generated-actions.h)10
-rw-r--r--googlemock/include/gmock/gmock.h2
-rwxr-xr-xgooglemock/scripts/pump.py856
-rw-r--r--googlemock/test/gmock-generated-actions_nc.cc170
-rw-r--r--googlemock/test/gmock-generated-actions_test.cc1036
-rw-r--r--googlemock/test/gmock-more-actions_test.cc916
-rw-r--r--googlemock/test/gmock_all_test.cc1
-rwxr-xr-xgooglemock/test/gmock_generated_actions_nc_test.py137
-rwxr-xr-xgooglemock/test/pump_test.py182
13 files changed, 873 insertions, 3030 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 2f653c82..da45e445 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -128,15 +128,3 @@ To run the tests, do
make test
All tests should pass.
-
-### Regenerating Source Files
-
-Some of Google Test's source files are generated from templates (not in the C++
-sense) using a script. For example, the file
-*googlemock/include/gmock/gmock-generated-actions.h.pump* is used to generate
-*gmock-generated-actions.h* in the same directory.
-
-You don't need to worry about regenerating the source files unless you need to
-modify them. You would then modify the corresponding `.pump` files and run the
-'[pump.py](googlemock/scripts/pump.py)' generator script. See the
-[Pump Manual](googlemock/docs/pump_manual.md).
diff --git a/docs/pump_manual.md b/docs/pump_manual.md
deleted file mode 100644
index bef498d3..00000000
--- a/docs/pump_manual.md
+++ /dev/null
@@ -1,190 +0,0 @@
-<b>P</b>ump is <b>U</b>seful for <b>M</b>eta <b>P</b>rogramming.
-
-[TOC]
-
-# The Problem
-
-Template and macro libraries often need to define many classes, functions, or
-macros that vary only (or almost only) in the number of arguments they take.
-It's a lot of repetitive, mechanical, and error-prone work.
-
-Our experience is that it's tedious to write custom scripts, which tend to
-reflect the structure of the generated code poorly and are often hard to read
-and edit. For example, a small change needed in the generated code may require
-some non-intuitive, non-trivial changes in the script. This is especially
-painful when experimenting with the code.
-
-This script may be useful for generating meta code, for example a series of
-macros of FOO1, FOO2, etc. Nevertheless, please make it your last resort
-technique by favouring C++ template metaprogramming or variadic macros.
-
-# Our Solution
-
-Pump (for Pump is Useful for Meta Programming, Pretty Useful for Meta
-Programming, or Practical Utility for Meta Programming, whichever you prefer) is
-a simple meta-programming tool for C++. The idea is that a programmer writes a
-`foo.pump` file which contains C++ code plus meta code that manipulates the C++
-code. The meta code can handle iterations over a range, nested iterations, local
-meta variable definitions, simple arithmetic, and conditional expressions. You
-can view it as a small Domain-Specific Language. The meta language is designed
-to be non-intrusive (s.t. it won't confuse Emacs' C++ mode, for example) and
-concise, making Pump code intuitive and easy to maintain.
-
-## Highlights
-
-* The implementation is in a single Python script and thus ultra portable: no
- build or installation is needed and it works cross platforms.
-* Pump tries to be smart with respect to
- [Google's style guide](https://github.com/google/styleguide): it breaks long
- lines (easy to have when they are generated) at acceptable places to fit
- within 80 columns and indent the continuation lines correctly.
-* The format is human-readable and more concise than XML.
-* The format works relatively well with Emacs' C++ mode.
-
-## Examples
-
-The following Pump code (where meta keywords start with `$`, `[[` and `]]` are
-meta brackets, and `$$` starts a meta comment that ends with the line):
-
-```
-$var n = 3 $$ Defines a meta variable n.
-$range i 0..n $$ Declares the range of meta iterator i (inclusive).
-$for i [[
- $$ Meta loop.
-// Foo$i does blah for $i-ary predicates.
-$range j 1..i
-template <size_t N $for j [[, typename A$j]]>
-class Foo$i {
-$if i == 0 [[
- blah a;
-]] $elif i <= 2 [[
- blah b;
-]] $else [[
- blah c;
-]]
-};
-
-]]
-```
-
-will be translated by the Pump compiler to:
-
-```cpp
-// Foo0 does blah for 0-ary predicates.
-template <size_t N>
-class Foo0 {
- blah a;
-};
-
-// Foo1 does blah for 1-ary predicates.
-template <size_t N, typename A1>
-class Foo1 {
- blah b;
-};
-
-// Foo2 does blah for 2-ary predicates.
-template <size_t N, typename A1, typename A2>
-class Foo2 {
- blah b;
-};
-
-// Foo3 does blah for 3-ary predicates.
-template <size_t N, typename A1, typename A2, typename A3>
-class Foo3 {
- blah c;
-};
-```
-
-In another example,
-
-```
-$range i 1..n
-Func($for i + [[a$i]]);
-$$ The text between i and [[ is the separator between iterations.
-```
-
-will generate one of the following lines (without the comments), depending on
-the value of `n`:
-
-```cpp
-Func(); // If n is 0.
-Func(a1); // If n is 1.
-Func(a1 + a2); // If n is 2.
-Func(a1 + a2 + a3); // If n is 3.
-// And so on...
-```
-
-## Constructs
-
-We support the following meta programming constructs:
-
-| `$var id = exp` | Defines a named constant value. `$id` is |
-: : valid until the end of the current meta :
-: : lexical block. :
-| :------------------------------- | :--------------------------------------- |
-| `$range id exp..exp` | Sets the range of an iteration variable, |
-: : which can be reused in multiple loops :
-: : later. :
-| `$for id sep [[ code ]]` | Iteration. The range of `id` must have |
-: : been defined earlier. `$id` is valid in :
-: : `code`. :
-| `$($)` | Generates a single `$` character. |
-| `$id` | Value of the named constant or iteration |
-: : variable. :
-| `$(exp)` | Value of the expression. |
-| `$if exp [[ code ]] else_branch` | Conditional. |
-| `[[ code ]]` | Meta lexical block. |
-| `cpp_code` | Raw C++ code. |
-| `$$ comment` | Meta comment. |
-
-**Note:** To give the user some freedom in formatting the Pump source code, Pump
-ignores a new-line character if it's right after `$for foo` or next to `[[` or
-`]]`. Without this rule you'll often be forced to write very long lines to get
-the desired output. Therefore sometimes you may need to insert an extra new-line
-in such places for a new-line to show up in your output.
-
-## Grammar
-
-```ebnf
-code ::= atomic_code*
-atomic_code ::= $var id = exp
- | $var id = [[ code ]]
- | $range id exp..exp
- | $for id sep [[ code ]]
- | $($)
- | $id
- | $(exp)
- | $if exp [[ code ]] else_branch
- | [[ code ]]
- | cpp_code
-sep ::= cpp_code | empty_string
-else_branch ::= $else [[ code ]]
- | $elif exp [[ code ]] else_branch
- | empty_string
-exp ::= simple_expression_in_Python_syntax
-```
-
-## Code
-
-You can find the source code of Pump in
-[googlemock/scripts/pump.py](../googlemock/scripts/pump.py). It is still very
-unpolished and lacks automated tests, although it has been successfully used
-many times. If you find a chance to use it in your project, please let us know
-what you think! We also welcome help on improving Pump.
-
-## Real Examples
-
-You can find real-world applications of Pump in
-[Google Test](https://github.com/google/googletest/tree/master/googletest) and
-[Google Mock](https://github.com/google/googletest/tree/master/googlemock). The
-source file `foo.h.pump` generates `foo.h`.
-
-## Tips
-
-* If a meta variable is followed by a letter or digit, you can separate them
- using `[[]]`, which inserts an empty string. For example `Foo$j[[]]Helper`
- generate `Foo1Helper` when `j` is 1.
-* To avoid extra-long Pump source lines, you can break a line anywhere you
- want by inserting `[[]]` followed by a new line. Since any new-line
- character next to `[[` or `]]` is ignored, the generated code won't contain
- this new line.
diff --git a/googlemock/CMakeLists.txt b/googlemock/CMakeLists.txt
index 3d6699a8..e7df8ec5 100644
--- a/googlemock/CMakeLists.txt
+++ b/googlemock/CMakeLists.txt
@@ -153,7 +153,6 @@ if (gmock_build_tests)
cxx_test(gmock-cardinalities_test gmock_main)
cxx_test(gmock_ex_test gmock_main)
cxx_test(gmock-function-mocker_test gmock_main)
- cxx_test(gmock-generated-actions_test gmock_main)
cxx_test(gmock-internal-utils_test gmock_main)
cxx_test(gmock-matchers_test gmock_main)
cxx_test(gmock-more-actions_test gmock_main)
diff --git a/googlemock/include/gmock/gmock-generated-actions.h.pump b/googlemock/include/gmock/gmock-generated-actions.h.pump
deleted file mode 100644
index 7ede66e1..00000000
--- a/googlemock/include/gmock/gmock-generated-actions.h.pump
+++ /dev/null
@@ -1,390 +0,0 @@
-$$ -*- mode: c++; -*-
-$$ This is a Pump source file. Please use Pump to convert it to
-$$ gmock-generated-actions.h.
-$$
-$var n = 10 $$ The maximum arity we support.
-$$}} This meta comment fixes auto-indentation in editors.
-// Copyright 2007, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-// Google Mock - a framework for writing C++ mock classes.
-//
-// This file implements some commonly used variadic actions.
-
-// GOOGLETEST_CM0002 DO NOT DELETE
-
-#ifndef THIRD_PARTY_GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
-#define THIRD_PARTY_GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
-
-#include <memory>
-#include <utility>
-
-#include "gmock/gmock-actions.h"
-#include "gmock/internal/gmock-port.h"
-
-// Include any custom callback actions added by the local installation.
-#include "gmock/internal/custom/gmock-generated-actions.h"
-
-$range i 0..n
-$range k 0..n-1
-
-// Sometimes you want to give an action explicit template parameters
-// that cannot be inferred from its value parameters. ACTION() and
-// ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that
-// and can be viewed as an extension to ACTION() and ACTION_P*().
-//
-// The syntax:
-//
-// ACTION_TEMPLATE(ActionName,
-// HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m),
-// AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; }
-//
-// defines an action template that takes m explicit template
-// parameters and n value parameters. name_i is the name of the i-th
-// template parameter, and kind_i specifies whether it's a typename,
-// an integral constant, or a template. p_i is the name of the i-th
-// value parameter.
-//
-// Example:
-//
-// // DuplicateArg<k, T>(output) converts the k-th argument of the mock
-// // function to type T and copies it to *output.
-// ACTION_TEMPLATE(DuplicateArg,
-// HAS_2_TEMPLATE_PARAMS(int, k, typename, T),
-// AND_1_VALUE_PARAMS(output)) {
-// *output = T(::std::get<k>(args));
-// }
-// ...
-// int n;
-// EXPECT_CALL(mock, Foo(_, _))
-// .WillOnce(DuplicateArg<1, unsigned char>(&n));
-//
-// To create an instance of an action template, write:
-//
-// ActionName<t1, ..., t_m>(v1, ..., v_n)
-//
-// where the ts are the template arguments and the vs are the value
-// arguments. The value argument types are inferred by the compiler.
-// If you want to explicitly specify the value argument types, you can
-// provide additional template arguments:
-//
-// ActionName<t1, ..., t_m, u1, ..., u_k>(v1, ..., v_n)
-//
-// where u_i is the desired type of v_i.
-//
-// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the
-// number of value parameters, but not on the number of template
-// parameters. Without the restriction, the meaning of the following
-// is unclear:
-//
-// OverloadedAction<int, bool>(x);
-//
-// Are we using a single-template-parameter action where 'bool' refers
-// to the type of x, or are we using a two-template-parameter action
-// where the compiler is asked to infer the type of x?
-//
-// Implementation notes:
-//
-// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and
-// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for
-// implementing ACTION_TEMPLATE. The main trick we use is to create
-// new macro invocations when expanding a macro. For example, we have
-//
-// #define ACTION_TEMPLATE(name, template_params, value_params)
-// ... GMOCK_INTERNAL_DECL_##template_params ...
-//
-// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...)
-// to expand to
-//
-// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ...
-//
-// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the
-// preprocessor will continue to expand it to
-//
-// ... typename T ...
-//
-// This technique conforms to the C++ standard and is portable. It
-// allows us to implement action templates using O(N) code, where N is
-// the maximum number of template/value parameters supported. Without
-// using it, we'd have to devote O(N^2) amount of code to implement all
-// combinations of m and n.
-
-// Declares the template parameters.
-
-$range j 1..n
-$for j [[
-$range m 0..j-1
-#define GMOCK_INTERNAL_DECL_HAS_$j[[]]
-_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[kind$m name$m]]
-
-
-]]
-
-// Lists the template parameters.
-
-$for j [[
-$range m 0..j-1
-#define GMOCK_INTERNAL_LIST_HAS_$j[[]]
-_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[name$m]]
-
-
-]]
-
-// Declares the types of value parameters.
-
-$for i [[
-$range j 0..i-1
-#define GMOCK_INTERNAL_DECL_TYPE_AND_$i[[]]
-_VALUE_PARAMS($for j, [[p$j]]) $for j [[, typename p$j##_type]]
-
-
-]]
-
-// Initializes the value parameters.
-
-$for i [[
-$range j 0..i-1
-#define GMOCK_INTERNAL_INIT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])\
- ($for j, [[p$j##_type gmock_p$j]])$if i>0 [[ : ]]$for j, [[p$j(::std::move(gmock_p$j))]]
-
-
-]]
-
-// Defines the copy constructor
-
-$for i [[
-#define GMOCK_INTERNAL_DEFN_COPY_AND_$i[[]]_VALUE_PARAMS$if i == 0[[() \
- noexcept {} // Avoid https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82134
-]] $else [[(...) = default;]]
-
-
-]]
-
-// Declares the fields for storing the value parameters.
-
-$for i [[
-$range j 0..i-1
-#define GMOCK_INTERNAL_DEFN_AND_$i[[]]
-_VALUE_PARAMS($for j, [[p$j]]) $for j [[p$j##_type p$j; ]]
-
-
-]]
-
-// Lists the value parameters.
-
-$for i [[
-$range j 0..i-1
-#define GMOCK_INTERNAL_LIST_AND_$i[[]]
-_VALUE_PARAMS($for j, [[p$j]]) $for j, [[p$j]]
-
-
-]]
-
-// Lists the value parameter types.
-
-$for i [[
-$range j 0..i-1
-#define GMOCK_INTERNAL_LIST_TYPE_AND_$i[[]]
-_VALUE_PARAMS($for j, [[p$j]]) $for j [[, p$j##_type]]
-
-
-]]
-
-// Declares the value parameters.
-
-$for i [[
-$range j 0..i-1
-#define GMOCK_INTERNAL_DECL_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]]
-$for j, [[p$j##_type p$j]]
-
-
-]]
-
-// The suffix of the class template implementing the action template.
-$for i [[
-
-
-$range j 0..i-1
-#define GMOCK_INTERNAL_COUNT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]]
-$if i==1 [[P]] $elif i>=2 [[P$i]]
-]]
-
-
-// The name of the class template implementing the action template.
-#define GMOCK_ACTION_CLASS_(name, value_params)\
- GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params)
-
-$range k 0..n-1
-
-#define ACTION_TEMPLATE(name, template_params, value_params) \
- template <GMOCK_INTERNAL_DECL_##template_params \
- GMOCK_INTERNAL_DECL_TYPE_##value_params> \
- class GMOCK_ACTION_CLASS_(name, value_params) { \
- public: \
- explicit GMOCK_ACTION_CLASS_(name, value_params)( \
- 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)) { }) \
- GMOCK_ACTION_CLASS_(name, value_params)( \
- const GMOCK_ACTION_CLASS_(name, value_params)&) \
- GMOCK_INTERNAL_DEFN_COPY_##value_params \
- GMOCK_ACTION_CLASS_(name, value_params)( \
- GMOCK_ACTION_CLASS_(name, value_params)&&) \
- GMOCK_INTERNAL_DEFN_COPY_##value_params \
- template <typename F> \
- operator ::testing::Action<F>() const { \
- return GMOCK_PP_IF( \
- GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
- (::testing::internal::MakeAction<F, gmock_Impl>()), \
- (::testing::internal::MakeAction<F>(impl_))); \
- } \
- private: \
- class gmock_Impl { \
- public: \
- explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {} \
- template <typename function_type, typename return_type, \
- typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
- return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \
- GMOCK_INTERNAL_DEFN_##value_params \
- }; \
- GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
- , std::shared_ptr<const gmock_Impl> impl_;) \
- }; \
- template <GMOCK_INTERNAL_DECL_##template_params \
- GMOCK_INTERNAL_DECL_TYPE_##value_params> \
- 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_; \
- template <GMOCK_INTERNAL_DECL_##template_params \
- GMOCK_INTERNAL_DECL_TYPE_##value_params> \
- inline GMOCK_ACTION_CLASS_(name, value_params)< \
- GMOCK_INTERNAL_LIST_##template_params \
- GMOCK_INTERNAL_LIST_TYPE_##value_params> name( \
- GMOCK_INTERNAL_DECL_##value_params) { \
- return GMOCK_ACTION_CLASS_(name, value_params)< \
- GMOCK_INTERNAL_LIST_##template_params \
- GMOCK_INTERNAL_LIST_TYPE_##value_params>( \
- GMOCK_INTERNAL_LIST_##value_params); \
- } \
- template <GMOCK_INTERNAL_DECL_##template_params \
- GMOCK_INTERNAL_DECL_TYPE_##value_params> \
- template <typename function_type, typename return_type, typename args_type, \
- GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
- return_type GMOCK_ACTION_CLASS_(name, value_params)< \
- GMOCK_INTERNAL_LIST_##template_params \
- GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl::gmock_PerformImpl( \
- GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
-
-namespace testing {
-
-// The ACTION*() macros trigger warning C4100 (unreferenced formal
-// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
-// the macro definition, as the warnings are generated when the macro
-// is expanded and macro expansion cannot contain #pragma. Therefore
-// we suppress them here.
-#ifdef _MSC_VER
-# pragma warning(push)
-# pragma warning(disable:4100)
-#endif
-
-namespace internal {
-
-// internal::InvokeArgument - a helper for InvokeArgument action.
-// The basic overloads are provided here for generic functors.
-// 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...);
-}
-
-template <std::size_t index, typename... Params>
-struct InvokeArgumentAction {
- template <typename... Args>
- 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(std::forward<Args>(args)...);
- return params.Apply([&](const Params&... unpacked_params) {
- auto&& callable = args_tuple.template Get<index>();
- return internal::InvokeArgument(
- std::forward<decltype(callable)>(callable), unpacked_params...);
- });
- }
-
- internal::FlatTuple<Params...> params;
-};
-
-} // namespace internal
-
-// The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th
-// (0-based) argument, which must be a k-ary callable, of the mock
-// function, with arguments a1, a2, ..., a_k.
-//
-// Notes:
-//
-// 1. The arguments are passed by value by default. If you need to
-// pass an argument by reference, wrap it inside std::ref(). For
-// example,
-//
-// InvokeArgument<1>(5, string("Hello"), std::ref(foo))
-//
-// passes 5 and string("Hello") by value, and passes foo by
-// reference.
-//
-// 2. If the callable takes an argument by reference but std::ref() is
-// not used, it will receive the reference to a copy of the value,
-// instead of the original value. For example, when the 0-th
-// argument of the mock function takes a const string&, the action
-//
-// InvokeArgument<0>(string("Hello"))
-//
-// makes a copy of the temporary string("Hello") object and passes a
-// reference of the copy, instead of the original temporary object,
-// to the callable. This makes it easy for a user to define an
-// InvokeArgument action from temporary values and have it performed
-// later.
-template <std::size_t index, typename... Params>
-internal::InvokeArgumentAction<index, typename std::decay<Params>::type...>
-InvokeArgument(Params&&... params) {
- return {internal::FlatTuple<typename std::decay<Params>::type...>(
- std::forward<Params>(params)...)};
-}
-
-#ifdef _MSC_VER
-# pragma warning(pop)
-#endif
-
-} // namespace testing
-
-#endif // THIRD_PARTY_GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
diff --git a/googlemock/include/gmock/gmock-generated-actions.h b/googlemock/include/gmock/gmock-more-actions.h
index 62909ea0..5d00ec35 100644
--- a/googlemock/include/gmock/gmock-generated-actions.h
+++ b/googlemock/include/gmock/gmock-more-actions.h
@@ -1,7 +1,3 @@
-// This file was GENERATED by command:
-// pump.py gmock-generated-actions.h.pump
-// DO NOT EDIT BY HAND!!!
-
// Copyright 2007, Google Inc.
// All rights reserved.
//
@@ -38,8 +34,8 @@
// GOOGLETEST_CM0002 DO NOT DELETE
-#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
-#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
+#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
+#define GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
#include <memory>
#include <utility>
@@ -574,4 +570,4 @@ InvokeArgument(Params&&... params) {
} // namespace testing
-#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
+#endif // GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
diff --git a/googlemock/include/gmock/gmock.h b/googlemock/include/gmock/gmock.h
index 8a4aceae..7f6f78e5 100644
--- a/googlemock/include/gmock/gmock.h
+++ b/googlemock/include/gmock/gmock.h
@@ -59,8 +59,8 @@
#include "gmock/gmock-actions.h"
#include "gmock/gmock-cardinalities.h"
#include "gmock/gmock-function-mocker.h"
-#include "gmock/gmock-generated-actions.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/internal/gmock-internal-utils.h"
diff --git a/googlemock/scripts/pump.py b/googlemock/scripts/pump.py
deleted file mode 100755
index 5523a19d..00000000
--- a/googlemock/scripts/pump.py
+++ /dev/null
@@ -1,856 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2008, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-"""pump v0.2.0 - Pretty Useful for Meta Programming.
-
-A tool for preprocessor meta programming. Useful for generating
-repetitive boilerplate code. Especially useful for writing C++
-classes, functions, macros, and templates that need to work with
-various number of arguments.
-
-USAGE:
- pump.py SOURCE_FILE
-
-EXAMPLES:
- pump.py foo.cc.pump
- Converts foo.cc.pump to foo.cc.
-
-GRAMMAR:
- CODE ::= ATOMIC_CODE*
- ATOMIC_CODE ::= $var ID = EXPRESSION
- | $var ID = [[ CODE ]]
- | $range ID EXPRESSION..EXPRESSION
- | $for ID SEPARATOR [[ CODE ]]
- | $($)
- | $ID
- | $(EXPRESSION)
- | $if EXPRESSION [[ CODE ]] ELSE_BRANCH
- | [[ CODE ]]
- | RAW_CODE
- SEPARATOR ::= RAW_CODE | EMPTY
- ELSE_BRANCH ::= $else [[ CODE ]]
- | $elif EXPRESSION [[ CODE ]] ELSE_BRANCH
- | EMPTY
- EXPRESSION has Python syntax.
-"""
-
-from __future__ import print_function
-
-import io
-import os
-import re
-import sys
-
-
-TOKEN_TABLE = [
- (re.compile(r'\$var\s+'), '$var'),
- (re.compile(r'\$elif\s+'), '$elif'),
- (re.compile(r'\$else\s+'), '$else'),
- (re.compile(r'\$for\s+'), '$for'),
- (re.compile(r'\$if\s+'), '$if'),
- (re.compile(r'\$range\s+'), '$range'),
- (re.compile(r'\$[_A-Za-z]\w*'), '$id'),
- (re.compile(r'\$\(\$\)'), '$($)'),
- (re.compile(r'\$'), '$'),
- (re.compile(r'\[\[\n?'), '[['),
- (re.compile(r'\]\]\n?'), ']]'),
- ]
-
-
-class Cursor:
- """Represents a position (line and column) in a text file."""
-
- def __init__(self, line=-1, column=-1):
- self.line = line
- self.column = column
-
- def __eq__(self, rhs):
- return self.line == rhs.line and self.column == rhs.column
-
- def __ne__(self, rhs):
- return not self == rhs
-
- def __lt__(self, rhs):
- return self.line < rhs.line or (
- self.line == rhs.line and self.column < rhs.column)
-
- def __le__(self, rhs):
- return self < rhs or self == rhs
-
- def __gt__(self, rhs):
- return rhs < self
-
- def __ge__(self, rhs):
- return rhs <= self
-
- def __str__(self):
- if self == Eof():
- return 'EOF'
- else:
- return '%s(%s)' % (self.line + 1, self.column)
-
- def __add__(self, offset):
- return Cursor(self.line, self.column + offset)
-
- def __sub__(self, offset):
- return Cursor(self.line, self.column - offset)
-
- def Clone(self):
- """Returns a copy of self."""
-
- return Cursor(self.line, self.column)
-
-
-# Special cursor to indicate the end-of-file.
-def Eof():
- """Returns the special cursor to denote the end-of-file."""
- return Cursor(-1, -1)
-
-
-class Token:
- """Represents a token in a Pump source file."""
-
- def __init__(self, start=None, end=None, value=None, token_type=None):
- if start is None:
- self.start = Eof()
- else:
- self.start = start
- if end is None:
- self.end = Eof()
- else:
- self.end = end
- self.value = value
- self.token_type = token_type
-
- def __str__(self):
- return 'Token @%s: \'%s\' type=%s' % (
- self.start, self.value, self.token_type)
-
- def Clone(self):
- """Returns a copy of self."""
-
- return Token(self.start.Clone(), self.end.Clone(), self.value,
- self.token_type)
-
-
-def StartsWith(lines, pos, string):
- """Returns True iff the given position in lines starts with 'string'."""
-
- return lines[pos.line][pos.column:].startswith(string)
-
-
-def FindFirstInLine(line, token_table):
- best_match_start = -1
- for (regex, token_type) in token_table:
- m = regex.search(line)
- if m:
- # We found regex in lines
- if best_match_start < 0 or m.start() < best_match_start:
- best_match_start = m.start()
- best_match_length = m.end() - m.start()
- best_match_token_type = token_type
-
- if best_match_start < 0:
- return None
-
- return (best_match_start, best_match_length, best_match_token_type)
-
-
-def FindFirst(lines, token_table, cursor):
- """Finds the first occurrence of any string in strings in lines."""
-
- start = cursor.Clone()
- cur_line_number = cursor.line
- for line in lines[start.line:]:
- if cur_line_number == start.line:
- line = line[start.column:]
- m = FindFirstInLine(line, token_table)
- if m:
- # We found a regex in line.
- (start_column, length, token_type) = m
- if cur_line_number == start.line:
- start_column += start.column
- found_start = Cursor(cur_line_number, start_column)
- found_end = found_start + length
- return MakeToken(lines, found_start, found_end, token_type)
- cur_line_number += 1
- # We failed to find str in lines
- return None
-
-
-def SubString(lines, start, end):
- """Returns a substring in lines."""
-
- if end == Eof():
- end = Cursor(len(lines) - 1, len(lines[-1]))
-
- if start >= end:
- return ''
-
- if start.line == end.line:
- return lines[start.line][start.column:end.column]
-
- result_lines = ([lines[start.line][start.column:]] +
- lines[start.line + 1:end.line] +
- [lines[end.line][:end.column]])
- return ''.join(result_lines)
-
-
-def StripMetaComments(str):
- """Strip meta comments from each line in the given string."""
-
- # First, completely remove lines containing nothing but a meta
- # comment, including the trailing \n.
- str = re.sub(r'^\s*\$\$.*\n', '', str)
-
- # Then, remove meta comments from contentful lines.
- return re.sub(r'\s*\$\$.*', '', str)
-
-
-def MakeToken(lines, start, end, token_type):
- """Creates a new instance of Token."""
-
- return Token(start, end, SubString(lines, start, end), token_type)
-
-
-def ParseToken(lines, pos, regex, token_type):
- line = lines[pos.line][pos.column:]
- m = regex.search(line)
- if m and not m.start():
- return MakeToken(lines, pos, pos + m.end(), token_type)
- else:
- print('ERROR: %s expected at %s.' % (token_type, pos))
- sys.exit(1)
-
-
-ID_REGEX = re.compile(r'[_A-Za-z]\w*')
-EQ_REGEX = re.compile(r'=')
-REST_OF_LINE_REGEX = re.compile(r'.*?(?=$|\$\$)')
-OPTIONAL_WHITE_SPACES_REGEX = re.compile(r'\s*')
-WHITE_SPACE_REGEX = re.compile(r'\s')
-DOT_DOT_REGEX = re.compile(r'\.\.')
-
-
-def Skip(lines, pos, regex):
- line = lines[pos.line][pos.column:]
- m = re.search(regex, line)
- if m and not m.start():
- return pos + m.end()
- else:
- return pos
-
-
-def SkipUntil(lines, pos, regex, token_type):
- line = lines[pos.line][pos.column:]
- m = re.search(regex, line)
- if m:
- return pos + m.start()
- else:
- print ('ERROR: %s expected on line %s after column %s.' %
- (token_type, pos.line + 1, pos.column))
- sys.exit(1)
-
-
-def ParseExpTokenInParens(lines, pos):
- def ParseInParens(pos):
- pos = Skip(lines, pos, OPTIONAL_WHITE_SPACES_REGEX)
- pos = Skip(lines, pos, r'\(')
- pos = Parse(pos)
- pos = Skip(lines, pos, r'\)')
- return pos
-
- def Parse(pos):
- pos = SkipUntil(lines, pos, r'\(|\)', ')')
- if SubString(lines, pos, pos + 1) == '(':
- pos = Parse(pos + 1)
- pos = Skip(lines, pos, r'\)')
- return Parse(pos)
- else:
- return pos
-
- start = pos.Clone()
- pos = ParseInParens(pos)
- return MakeToken(lines, start, pos, 'exp')
-
-
-def RStripNewLineFromToken(token):
- if token.value.endswith('\n'):
- return Token(token.start, token.end, token.value[:-1], token.token_type)
- else:
- return token
-
-
-def TokenizeLines(lines, pos):
- while True:
- found = FindFirst(lines, TOKEN_TABLE, pos)
- if not found:
- yield MakeToken(lines, pos, Eof(), 'code')
- return
-
- if found.start == pos:
- prev_token = None
- prev_token_rstripped = None
- else:
- prev_token = MakeToken(lines, pos, found.start, 'code')
- prev_token_rstripped = RStripNewLineFromToken(prev_token)
-
- if found.token_type == '$var':
- if prev_token_rstripped:
- yield prev_token_rstripped
- yield found
- id_token = ParseToken(lines, found.end, ID_REGEX, 'id')
- yield id_token
- pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX)
-
- eq_token = ParseToken(lines, pos, EQ_REGEX, '=')
- yield eq_token
- pos = Skip(lines, eq_token.end, r'\s*')
-
- if SubString(lines, pos, pos + 2) != '[[':
- exp_token = ParseToken(lines, pos, REST_OF_LINE_REGEX, 'exp')
- yield exp_token
- pos = Cursor(exp_token.end.line + 1, 0)
- elif found.token_type == '$for':
- if prev_token_rstripped:
- yield prev_token_rstripped
- yield found
- id_token = ParseToken(lines, found.end, ID_REGEX, 'id')
- yield id_token
- pos = Skip(lines, id_token.end, WHITE_SPACE_REGEX)
- elif found.token_type == '$range':
- if prev_token_rstripped:
- yield prev_token_rstripped
- yield found
- id_token = ParseToken(lines, found.end, ID_REGEX, 'id')
- yield id_token
- pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX)
-
- dots_pos = SkipUntil(lines, pos, DOT_DOT_REGEX, '..')
- yield MakeToken(lines, pos, dots_pos, 'exp')
- yield MakeToken(lines, dots_pos, dots_pos + 2, '..')
- pos = dots_pos + 2
- new_pos = Cursor(pos.line + 1, 0)
- yield MakeToken(lines, pos, new_pos, 'exp')
- pos = new_pos
- elif found.token_type == '$':
- if prev_token:
- yield prev_token
- yield found
- exp_token = ParseExpTokenInParens(lines, found.end)
- yield exp_token
- pos = exp_token.end
- elif (found.token_type == ']]' or found.token_type == '$if' or
- found.token_type == '$elif' or found.token_type == '$else'):
- if prev_token_rstripped:
- yield prev_token_rstripped
- yield found
- pos = found.end
- else:
- if prev_token:
- yield prev_token
- yield found
- pos = found.end
-
-
-def Tokenize(s):
- """A generator that yields the tokens in the given string."""
- if s != '':
- lines = s.splitlines(True)
- for token in TokenizeLines(lines, Cursor(0, 0)):
- yield token
-
-
-class CodeNode:
- def __init__(self, atomic_code_list=None):
- self.atomic_code = atomic_code_list
-
-
-class VarNode:
- def __init__(self, identifier=None, atomic_code=None):
- self.identifier = identifier
- self.atomic_code = atomic_code
-
-
-class RangeNode:
- def __init__(self, identifier=None, exp1=None, exp2=None):
- self.identifier = identifier
- self.exp1 = exp1
- self.exp2 = exp2
-
-
-class ForNode:
- def __init__(self, identifier=None, sep=None, code=None):
- self.identifier = identifier
- self.sep = sep
- self.code = code
-
-
-class ElseNode:
- def __init__(self, else_branch=None):
- self.else_branch = else_branch
-
-
-class IfNode:
- def __init__(self, exp=None, then_branch=None, else_branch=None):
- self.exp = exp
- self.then_branch = then_branch
- self.else_branch = else_branch
-
-
-class RawCodeNode:
- def __init__(self, token=None):
- self.raw_code = token
-
-
-class LiteralDollarNode:
- def __init__(self, token):
- self.token = token
-
-
-class ExpNode:
- def __init__(self, token, python_exp):
- self.token = token
- self.python_exp = python_exp
-
-
-def PopFront(a_list):
- head = a_list[0]
- a_list[:1] = []
- return head
-
-
-def PushFront(a_list, elem):
- a_list[:0] = [elem]
-
-
-def PopToken(a_list, token_type=None):
- token = PopFront(a_list)
- if token_type is not None and token.token_type != token_type:
- print('ERROR: %s expected at %s' % (token_type, token.start))
- print('ERROR: %s found instead' % (token,))
- sys.exit(1)
-
- return token
-
-
-def PeekToken(a_list):
- if not a_list:
- return None
-
- return a_list[0]
-
-
-def ParseExpNode(token):
- python_exp = re.sub(r'([_A-Za-z]\w*)', r'self.GetValue("\1")', token.value)
- return ExpNode(token, python_exp)
-
-
-def ParseElseNode(tokens):
- def Pop(token_type=None):
- return PopToken(tokens, token_type)
-
- next = PeekToken(tokens)
- if not next:
- return None
- if next.token_type == '$else':
- Pop('$else')
- Pop('[[')
- code_node = ParseCodeNode(tokens)
- Pop(']]')
- return code_node
- elif next.token_type == '$elif':
- Pop('$elif')
- exp = Pop('code')
- Pop('[[')
- code_node = ParseCodeNode(tokens)
- Pop(']]')
- inner_else_node = ParseElseNode(tokens)
- return CodeNode([IfNode(ParseExpNode(exp), code_node, inner_else_node)])
- elif not next.value.strip():
- Pop('code')
- return ParseElseNode(tokens)
- else:
- return None
-
-
-def ParseAtomicCodeNode(tokens):
- def Pop(token_type=None):
- return PopToken(tokens, token_type)
-
- head = PopFront(tokens)
- t = head.token_type
- if t == 'code':
- return RawCodeNode(head)
- elif t == '$var':
- id_token = Pop('id')
- Pop('=')
- next = PeekToken(tokens)
- if next.token_type == 'exp':
- exp_token = Pop()
- return VarNode(id_token, ParseExpNode(exp_token))
- Pop('[[')
- code_node = ParseCodeNode(tokens)
- Pop(']]')
- return VarNode(id_token, code_node)
- elif t == '$for':
- id_token = Pop('id')
- next_token = PeekToken(tokens)
- if next_token.token_type == 'code':
- sep_token = next_token
- Pop('code')
- else:
- sep_token = None
- Pop('[[')
- code_node = ParseCodeNode(tokens)
- Pop(']]')
- return ForNode(id_token, sep_token, code_node)
- elif t == '$if':
- exp_token = Pop('code')
- Pop('[[')
- code_node = ParseCodeNode(tokens)
- Pop(']]')
- else_node = ParseElseNode(tokens)
- return IfNode(ParseExpNode(exp_token), code_node, else_node)
- elif t == '$range':
- id_token = Pop('id')
- exp1_token = Pop('exp')
- Pop('..')
- exp2_token = Pop('exp')
- return RangeNode(id_token, ParseExpNode(exp1_token),
- ParseExpNode(exp2_token))
- elif t == '$id':
- return ParseExpNode(Token(head.start + 1, head.end, head.value[1:], 'id'))
- elif t == '$($)':
- return LiteralDollarNode(head)
- elif t == '$':
- exp_token = Pop('exp')
- return ParseExpNode(exp_token)
- elif t == '[[':
- code_node = ParseCodeNode(tokens)
- Pop(']]')
- return code_node
- else:
- PushFront(tokens, head)
- return None
-
-
-def ParseCodeNode(tokens):
- atomic_code_list = []
- while True:
- if not tokens:
- break
- atomic_code_node = ParseAtomicCodeNode(tokens)
- if atomic_code_node:
- atomic_code_list.append(atomic_code_node)
- else:
- break
- return CodeNode(atomic_code_list)
-
-
-def ParseToAST(pump_src_text):
- """Convert the given Pump source text into an AST."""
- tokens = list(Tokenize(pump_src_text))
- code_node = ParseCodeNode(tokens)
- return code_node
-
-
-class Env:
- def __init__(self):
- self.variables = []
- self.ranges = []
-
- def Clone(self):
- clone = Env()
- clone.variables = self.variables[:]
- clone.ranges = self.ranges[:]
- return clone
-
- def PushVariable(self, var, value):
- # If value looks like an int, store it as an int.
- try:
- int_value = int(value)
- if ('%s' % int_value) == value:
- value = int_value
- except Exception:
- pass
- self.variables[:0] = [(var, value)]
-
- def PopVariable(self):
- self.variables[:1] = []
-
- def PushRange(self, var, lower, upper):
- self.ranges[:0] = [(var, lower, upper)]
-
- def PopRange(self):
- self.ranges[:1] = []
-
- def GetValue(self, identifier):
- for (var, value) in self.variables:
- if identifier == var:
- return value
-
- print('ERROR: meta variable %s is undefined.' % (identifier,))
- sys.exit(1)
-
- def EvalExp(self, exp):
- try:
- result = eval(exp.python_exp)
- except Exception as e: # pylint: disable=broad-except
- print('ERROR: caught exception %s: %s' % (e.__class__.__name__, e))
- print('ERROR: failed to evaluate meta expression %s at %s' %
- (exp.python_exp, exp.token.start))
- sys.exit(1)
- return result
-
- def GetRange(self, identifier):
- for (var, lower, upper) in self.ranges:
- if identifier == var:
- return (lower, upper)
-
- print('ERROR: range %s is undefined.' % (identifier,))
- sys.exit(1)
-
-
-class Output:
- def __init__(self):
- self.string = ''
-
- def GetLastLine(self):
- index = self.string.rfind('\n')
- if index < 0:
- return ''
-
- return self.string[index + 1:]
-
- def Append(self, s):
- self.string += s
-
-
-def RunAtomicCode(env, node, output):
- if isinstance(node, VarNode):
- identifier = node.identifier.value.strip()
- result = Output()
- RunAtomicCode(env.Clone(), node.atomic_code, result)
- value = result.string
- env.PushVariable(identifier, value)
- elif isinstance(node, RangeNode):
- identifier = node.identifier.value.strip()
- lower = int(env.EvalExp(node.exp1))
- upper = int(env.EvalExp(node.exp2))
- env.PushRange(identifier, lower, upper)
- elif isinstance(node, ForNode):
- identifier = node.identifier.value.strip()
- if node.sep is None:
- sep = ''
- else:
- sep = node.sep.value
- (lower, upper) = env.GetRange(identifier)
- for i in range(lower, upper + 1):
- new_env = env.Clone()
- new_env.PushVariable(identifier, i)
- RunCode(new_env, node.code, output)
- if i != upper:
- output.Append(sep)
- elif isinstance(node, RawCodeNode):
- output.Append(node.raw_code.value)
- elif isinstance(node, IfNode):
- cond = env.EvalExp(node.exp)
- if cond:
- RunCode(env.Clone(), node.then_branch, output)
- elif node.else_branch is not None:
- RunCode(env.Clone(), node.else_branch, output)
- elif isinstance(node, ExpNode):
- value = env.EvalExp(node)
- output.Append('%s' % (value,))
- elif isinstance(node, LiteralDollarNode):
- output.Append('$')
- elif isinstance(node, CodeNode):
- RunCode(env.Clone(), node, output)
- else:
- print('BAD')
- print(node)
- sys.exit(1)
-
-
-def RunCode(env, code_node, output):
- for atomic_code in code_node.atomic_code:
- RunAtomicCode(env, atomic_code, output)
-
-
-def IsSingleLineComment(cur_line):
- return '//' in cur_line
-
-
-def IsInPreprocessorDirective(prev_lines, cur_line):
- if cur_line.lstrip().startswith('#'):
- return True
- return prev_lines and prev_lines[-1].endswith('\\')
-
-
-def WrapComment(line, output):
- loc = line.find('//')
- before_comment = line[:loc].rstrip()
- if before_comment == '':
- indent = loc
- else:
- output.append(before_comment)
- indent = len(before_comment) - len(before_comment.lstrip())
- prefix = indent*' ' + '// '
- max_len = 80 - len(prefix)
- comment = line[loc + 2:].strip()
- segs = [seg for seg in re.split(r'(\w+\W*)', comment) if seg != '']
- cur_line = ''
- for seg in segs:
- if len((cur_line + seg).rstrip()) < max_len:
- cur_line += seg
- else:
- if cur_line.strip() != '':
- output.append(prefix + cur_line.rstrip())
- cur_line = seg.lstrip()
- if cur_line.strip() != '':
- output.append(prefix + cur_line.strip())
-
-
-def WrapCode(line, line_concat, output):
- indent = len(line) - len(line.lstrip())
- prefix = indent*' ' # Prefix of the current line
- max_len = 80 - indent - len(line_concat) # Maximum length of the current line
- new_prefix = prefix + 4*' ' # Prefix of a continuation line
- new_max_len = max_len - 4 # Maximum length of a continuation line
- # Prefers to wrap a line after a ',' or ';'.
- segs = [seg for seg in re.split(r'([^,;]+[,;]?)', line.strip()) if seg != '']
- cur_line = '' # The current line without leading spaces.
- for seg in segs:
- # If the line is still too long, wrap at a space.
- while cur_line == '' and len(seg.strip()) > max_len:
- seg = seg.lstrip()
- split_at = seg.rfind(' ', 0, max_len)
- output.append(prefix + seg[:split_at].strip() + line_concat)
- seg = seg[split_at + 1:]
- prefix = new_prefix
- max_len = new_max_len
-
- if len((cur_line + seg).rstrip()) < max_len:
- cur_line = (cur_line + seg).lstrip()
- else:
- output.append(prefix + cur_line.rstrip() + line_concat)
- prefix = new_prefix
- max_len = new_max_len
- cur_line = seg.lstrip()
- if cur_line.strip() != '':
- output.append(prefix + cur_line.strip())
-
-
-def WrapPreprocessorDirective(line, output):
- WrapCode(line, ' \\', output)
-
-
-def WrapPlainCode(line, output):
- WrapCode(line, '', output)
-
-
-def IsMultiLineIWYUPragma(line):
- return re.search(r'/\* IWYU pragma: ', line)
-
-
-def IsHeaderGuardIncludeOrOneLineIWYUPragma(line):
- return (re.match(r'^#(ifndef|define|endif\s*//)\s*[\w_]+\s*$', line) or
- re.match(r'^#include\s', line) or
- # Don't break IWYU pragmas, either; that causes iwyu.py problems.
- re.search(r'// IWYU pragma: ', line))
-
-
-def WrapLongLine(line, output):
- line = line.rstrip()
- if len(line) <= 80:
- output.append(line)
- elif IsSingleLineComment(line):
- if IsHeaderGuardIncludeOrOneLineIWYUPragma(line):
- # The style guide made an exception to allow long header guard lines,
- # includes and IWYU pragmas.
- output.append(line)
- else:
- WrapComment(line, output)
- elif IsInPreprocessorDirective(output, line):
- if IsHeaderGuardIncludeOrOneLineIWYUPragma(line):
- # The style guide made an exception to allow long header guard lines,
- # includes and IWYU pragmas.
- output.append(line)
- else:
- WrapPreprocessorDirective(line, output)
- elif IsMultiLineIWYUPragma(line):
- output.append(line)
- else:
- WrapPlainCode(line, output)
-
-
-def BeautifyCode(string):
- lines = string.splitlines()
- output = []
- for line in lines:
- WrapLongLine(line, output)
- output2 = [line.rstrip() for line in output]
- return '\n'.join(output2) + '\n'
-
-
-def ConvertFromPumpSource(src_text):
- """Return the text generated from the given Pump source text."""
- ast = ParseToAST(StripMetaComments(src_text))
- output = Output()
- RunCode(Env(), ast, output)
- return BeautifyCode(output.string)
-
-
-def main(argv):
- if len(argv) == 1:
- print(__doc__)
- sys.exit(1)
-
- file_path = argv[-1]
- output_str = ConvertFromPumpSource(io.open(file_path, 'r').read())
- if file_path.endswith('.pump'):
- output_file_path = file_path[:-5]
- else:
- output_file_path = '-'
- if output_file_path == '-':
- print(output_str,)
- else:
- output_file = io.open(output_file_path, 'w')
- output_file.write(u'// This file was GENERATED by command:\n')
- output_file.write(u'// %s %s\n' %
- (os.path.basename(__file__), os.path.basename(file_path)))
- output_file.write(u'// DO NOT EDIT BY HAND!!!\n\n')
- output_file.write(output_str)
- output_file.close()
-
-
-if __name__ == '__main__':
- main(sys.argv)
diff --git a/googlemock/test/gmock-generated-actions_nc.cc b/googlemock/test/gmock-generated-actions_nc.cc
deleted file mode 100644
index 59f47989..00000000
--- a/googlemock/test/gmock-generated-actions_nc.cc
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-// Google Mock - a framework for writing C++ mock classes.
-//
-// This file contains negative compilation tests for script-generated
-// Google Mock actions.
-
-#include "gmock/gmock.h"
-
-using testing::Action;
-using testing::Invoke;
-using testing::WithArgs;
-
-int Nullary() { return 0; }
-int Binary(int a, int b) { return a + b; }
-
-#if defined(TEST_NULLARY_WITH_ARGS)
-
-// Tests that WithArgs(action) doesn't compile.
-void Test() {
- Action<int(int)> a = WithArgs(Invoke(Nullary));
-}
-
-#elif defined(TEST_TOO_FEW_ARGS_FOR_WITH_ARGS)
-
-// Tests that you cannot pass too few arguments to the inner action in
-// WithArgs().
-void Test() {
- Action<int(int, int, int)> a = WithArgs<1>(Invoke(Binary));
-}
-
-#elif defined(TEST_TOO_MANY_ARGS_FOR_WITH_ARGS)
-
-// Tests that you cannot pass too many arguments to the inner action in
-// WithArgs().
-void Test() {
- Action<int(int, int, int)> a = WithArgs<1, 2, 0>(Invoke(Binary));
-}
-
-#elif defined(TEST_INCOMPATIBLE_ARG_TYPES_FOR_WITH_ARGS)
-
-// Tests that you cannot pass arguments of incompatible types to the
-// inner action in WithArgs().
-void Test() {
- Action<int(int, const char*, int)> a = WithArgs<1, 2>(Invoke(Binary));
-}
-
-#elif defined(TEST_WRONG_ARG_TYPE_IN_ACTION_MACRO)
-
-// Tests using an ACTION definition in a mock function whose argument
-// types are incompatible.
-ACTION(WrongArgType) { return 10/arg0; }
-
-void Test() {
- Action<int(const char*)> a = WrongArgType();
-}
-
-#elif defined(TEST_WRONG_RETURN_TYPE_IN_ACTION_MACRO)
-
-// Tests using an ACTION definition in a mock function whose return
-// types is incompatible.
-ACTION(WrongReturnType) { return 10; }
-
-void Test() {
- Action<const char*()> a = WrongReturnType();
-}
-
-#elif defined(TEST_EXCESSIVE_ARG_IN_ACTION_MACRO)
-
-// Tests using an ACTION definition in a mock function that doesn't
-// provide enough arguments.
-ACTION(UseExcessiveArg) { return arg0 + arg1; }
-
-void Test() {
- Action<int(int)> a = UseExcessiveArg();
-}
-
-#elif defined(TEST_ACTION_MACRO_IN_CLASS)
-
-// Tests using ACTION in a class scope.
-class Foo {
- public:
- // This won't compile as C++ doesn't allow defining a method of a
- // nested class out-of-line in the enclosing class.
- ACTION(Bar) { return arg0; }
-};
-
-#elif defined(TEST_ACTION_MACRO_IN_FUNCTION)
-
-// Tests using ACTION in a function body.
-void Test() {
- // This won't compile as C++ doesn't allow member templates in local
- // classes. We may want to revisit this when C++0x is widely
- // implemented.
- ACTION(Bar) { return arg0; }
-}
-
-#elif defined(TEST_SET_ARG_REFEREE_MUST_BE_USED_WITH_REFERENCE)
-
-// Verifies that using SetArgReferee<k>(...) where the k-th argument
-// of the mock function is not a reference generates a compiler error.
-void Test() {
- Action<void(bool, int)> a = testing::SetArgReferee<1>(5);
-}
-
-#elif defined(TEST_DELETE_ARG_MUST_BE_USED_WITH_POINTER)
-
-// Verifies that using DeleteArg<k>(...) where the k-th argument of the mock
-// function is not a pointer generates a compiler error.
-void Test() {
- Action<void(int)> a = testing::DeleteArg<0>(); // NOLINT
-}
-
-#elif defined(TEST_CANNOT_OVERLOAD_ACTION_TEMPLATE_ON_TEMPLATE_PARAM_NUMBER)
-
-// Tests that ACTION_TEMPLATE cannot be overloaded on the number of
-// template parameters alone.
-
-ACTION_TEMPLATE(OverloadedAction,
- HAS_1_TEMPLATE_PARAMS(typename, T),
- AND_1_VALUE_PARAMS(p)) {}
-
-ACTION_TEMPLATE(OverloadedAction,
- HAS_2_TEMPLATE_PARAMS(typename, T1, typename, T2),
- AND_1_VALUE_PARAMS(p)) {}
-
-#elif defined(TEST_CANNOT_OVERLOAD_ACTION_AND_ACTION_TEMPLATE_W_SAME_VALUE_PS)
-
-// Tests that ACTION_TEMPLATE and ACTION_P cannot be overloaded when
-// they have the same number of value parameters.
-
-ACTION_P(OverloadedAction, p) {}
-
-ACTION_TEMPLATE(OverloadedAction,
- HAS_1_TEMPLATE_PARAMS(typename, T),
- AND_1_VALUE_PARAMS(p)) {}
-
-#else
-
-// Sanity check - this should compile.
-
-#endif
diff --git a/googlemock/test/gmock-generated-actions_test.cc b/googlemock/test/gmock-generated-actions_test.cc
deleted file mode 100644
index 64906164..00000000
--- a/googlemock/test/gmock-generated-actions_test.cc
+++ /dev/null
@@ -1,1036 +0,0 @@
-// Copyright 2007, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-// Google Mock - a framework for writing C++ mock classes.
-//
-// This file tests the built-in actions generated by a script.
-
-#include "gmock/gmock-generated-actions.h"
-
-#include <functional>
-#include <memory>
-#include <sstream>
-#include <string>
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-
-namespace testing {
-namespace gmock_generated_actions_test {
-
-using ::std::plus;
-using ::std::string;
-using testing::_;
-using testing::Action;
-using testing::ActionInterface;
-using testing::ByRef;
-using testing::DoAll;
-using testing::Invoke;
-using testing::Return;
-using testing::SetArgPointee;
-using testing::StaticAssertTypeEq;
-using testing::Unused;
-
-// For suppressing compiler warnings on conversion possibly losing precision.
-inline short Short(short n) { return n; } // NOLINT
-inline char Char(char ch) { return ch; }
-
-// Sample functions and functors for testing various actions.
-int Nullary() { return 1; }
-
-bool g_done = false;
-
-bool ByConstRef(const std::string& s) { return s == "Hi"; }
-
-const double g_double = 0;
-bool ReferencesGlobalDouble(const double& x) { return &x == &g_double; }
-
-struct UnaryFunctor {
- int operator()(bool x) { return x ? 1 : -1; }
-};
-
-const char* Binary(const char* input, short n) { return input + n; } // NOLINT
-
-int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
-
-struct SumOf5Functor {
- int operator()(int a, int b, int c, int d, int e) {
- return a + b + c + d + e;
- }
-};
-
-std::string Concat5(const char* s1, const char* s2, const char* s3,
- const char* s4, const char* s5) {
- return std::string(s1) + s2 + s3 + s4 + s5;
-}
-
-int SumOf6(int a, int b, int c, int d, int e, int f) {
- return a + b + c + d + e + f;
-}
-
-struct SumOf6Functor {
- int operator()(int a, int b, int c, int d, int e, int f) {
- return a + b + c + d + e + f;
- }
-};
-
-std::string Concat6(const char* s1, const char* s2, const char* s3,
- const char* s4, const char* s5, const char* s6) {
- return std::string(s1) + s2 + s3 + s4 + s5 + s6;
-}
-
-std::string Concat7(const char* s1, const char* s2, const char* s3,
- const char* s4, const char* s5, const char* s6,
- const char* s7) {
- return std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7;
-}
-
-std::string Concat8(const char* s1, const char* s2, const char* s3,
- const char* s4, const char* s5, const char* s6,
- const char* s7, const char* s8) {
- return std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;
-}
-
-std::string Concat9(const char* s1, const char* s2, const char* s3,
- const char* s4, const char* s5, const char* s6,
- const char* s7, const char* s8, const char* s9) {
- return std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;
-}
-
-std::string Concat10(const char* s1, const char* s2, const char* s3,
- const char* s4, const char* s5, const char* s6,
- const char* s7, const char* s8, const char* s9,
- const char* s10) {
- return std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
-}
-
-// A helper that turns the type of a C-string literal from const
-// char[N] to const char*.
-inline const char* CharPtr(const char* s) { return s; }
-
-// Tests InvokeArgument<N>(...).
-
-// Tests using InvokeArgument with a nullary function.
-TEST(InvokeArgumentTest, Function0) {
- Action<int(int, int(*)())> a = InvokeArgument<1>(); // NOLINT
- EXPECT_EQ(1, a.Perform(std::make_tuple(2, &Nullary)));
-}
-
-// Tests using InvokeArgument with a unary function.
-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 5-ary function.
-TEST(InvokeArgumentTest, Function5) {
- Action<int(int(*)(int, int, int, int, int))> a = // NOLINT
- InvokeArgument<0>(10000, 2000, 300, 40, 5);
- EXPECT_EQ(12345, a.Perform(std::make_tuple(&SumOf5)));
-}
-
-// Tests using InvokeArgument with a 5-ary functor.
-TEST(InvokeArgumentTest, Functor5) {
- Action<int(SumOf5Functor)> a = // NOLINT
- InvokeArgument<0>(10000, 2000, 300, 40, 5);
- EXPECT_EQ(12345, a.Perform(std::make_tuple(SumOf5Functor())));
-}
-
-// Tests using InvokeArgument with a 6-ary function.
-TEST(InvokeArgumentTest, Function6) {
- Action<int(int(*)(int, int, int, int, int, int))> a = // NOLINT
- InvokeArgument<0>(100000, 20000, 3000, 400, 50, 6);
- EXPECT_EQ(123456, a.Perform(std::make_tuple(&SumOf6)));
-}
-
-// Tests using InvokeArgument with a 6-ary functor.
-TEST(InvokeArgumentTest, Functor6) {
- Action<int(SumOf6Functor)> a = // NOLINT
- InvokeArgument<0>(100000, 20000, 3000, 400, 50, 6);
- EXPECT_EQ(123456, a.Perform(std::make_tuple(SumOf6Functor())));
-}
-
-// 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*))>
- 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*))>
- 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*))>
- 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(*)(
- 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");
- EXPECT_EQ("1234567890", a.Perform(std::make_tuple(&Concat10)));
-}
-
-// Tests using InvokeArgument with a function that takes a pointer argument.
-TEST(InvokeArgumentTest, ByPointerFunction) {
- Action<const char*(const char*(*)(const char* input, short n))> a = // NOLINT
- InvokeArgument<0>(static_cast<const char*>("Hi"), Short(1));
- EXPECT_STREQ("i", a.Perform(std::make_tuple(&Binary)));
-}
-
-// Tests using InvokeArgument with a function that takes a const char*
-// by passing it a C-string literal.
-TEST(InvokeArgumentTest, FunctionWithCStringLiteral) {
- Action<const char*(const char*(*)(const char* input, short n))> a = // NOLINT
- InvokeArgument<0>("Hi", Short(1));
- EXPECT_STREQ("i", a.Perform(std::make_tuple(&Binary)));
-}
-
-// Tests using InvokeArgument with a function that takes a const reference.
-TEST(InvokeArgumentTest, ByConstReferenceFunction) {
- Action<bool(bool (*function)(const std::string& s))> a = // NOLINT
- InvokeArgument<0>(std::string("Hi"));
- // When action 'a' is constructed, it makes a copy of the temporary
- // string object passed to it, so it's OK to use 'a' later, when the
- // temporary object has already died.
- EXPECT_TRUE(a.Perform(std::make_tuple(&ByConstRef)));
-}
-
-// Tests using InvokeArgument with ByRef() and a function that takes a
-// const reference.
-TEST(InvokeArgumentTest, ByExplicitConstReferenceFunction) {
- Action<bool(bool(*)(const double& x))> a = // NOLINT
- InvokeArgument<0>(ByRef(g_double));
- // The above line calls ByRef() on a const value.
- EXPECT_TRUE(a.Perform(std::make_tuple(&ReferencesGlobalDouble)));
-
- double x = 0;
- a = InvokeArgument<0>(ByRef(x)); // This calls ByRef() on a non-const.
- EXPECT_FALSE(a.Perform(std::make_tuple(&ReferencesGlobalDouble)));
-}
-
-// Tests DoAll(a1, a2).
-TEST(DoAllTest, TwoActions) {
- int n = 0;
- Action<int(int*)> a = DoAll(SetArgPointee<0>(1), // NOLINT
- Return(2));
- EXPECT_EQ(2, a.Perform(std::make_tuple(&n)));
- EXPECT_EQ(1, n);
-}
-
-// Tests DoAll(a1, a2, a3).
-TEST(DoAllTest, ThreeActions) {
- int m = 0, n = 0;
- Action<int(int*, int*)> a = DoAll(SetArgPointee<0>(1), // NOLINT
- SetArgPointee<1>(2),
- Return(3));
- EXPECT_EQ(3, a.Perform(std::make_tuple(&m, &n)));
- EXPECT_EQ(1, m);
- EXPECT_EQ(2, n);
-}
-
-// Tests DoAll(a1, a2, a3, a4).
-TEST(DoAllTest, FourActions) {
- int m = 0, n = 0;
- char ch = '\0';
- Action<int(int*, int*, char*)> a = // NOLINT
- DoAll(SetArgPointee<0>(1),
- SetArgPointee<1>(2),
- SetArgPointee<2>('a'),
- Return(3));
- EXPECT_EQ(3, a.Perform(std::make_tuple(&m, &n, &ch)));
- EXPECT_EQ(1, m);
- EXPECT_EQ(2, n);
- EXPECT_EQ('a', ch);
-}
-
-// Tests DoAll(a1, a2, a3, a4, a5).
-TEST(DoAllTest, FiveActions) {
- int m = 0, n = 0;
- char a = '\0', b = '\0';
- Action<int(int*, int*, char*, char*)> action = // NOLINT
- DoAll(SetArgPointee<0>(1),
- SetArgPointee<1>(2),
- SetArgPointee<2>('a'),
- SetArgPointee<3>('b'),
- Return(3));
- EXPECT_EQ(3, action.Perform(std::make_tuple(&m, &n, &a, &b)));
- EXPECT_EQ(1, m);
- EXPECT_EQ(2, n);
- EXPECT_EQ('a', a);
- EXPECT_EQ('b', b);
-}
-
-// Tests DoAll(a1, a2, ..., a6).
-TEST(DoAllTest, SixActions) {
- int m = 0, n = 0;
- char a = '\0', b = '\0', c = '\0';
- Action<int(int*, int*, char*, char*, char*)> action = // NOLINT
- DoAll(SetArgPointee<0>(1),
- SetArgPointee<1>(2),
- SetArgPointee<2>('a'),
- SetArgPointee<3>('b'),
- SetArgPointee<4>('c'),
- Return(3));
- EXPECT_EQ(3, action.Perform(std::make_tuple(&m, &n, &a, &b, &c)));
- EXPECT_EQ(1, m);
- EXPECT_EQ(2, n);
- EXPECT_EQ('a', a);
- EXPECT_EQ('b', b);
- EXPECT_EQ('c', c);
-}
-
-// Tests DoAll(a1, a2, ..., a7).
-TEST(DoAllTest, SevenActions) {
- int m = 0, n = 0;
- char a = '\0', b = '\0', c = '\0', d = '\0';
- Action<int(int*, int*, char*, char*, char*, char*)> action = // NOLINT
- DoAll(SetArgPointee<0>(1),
- SetArgPointee<1>(2),
- SetArgPointee<2>('a'),
- SetArgPointee<3>('b'),
- SetArgPointee<4>('c'),
- SetArgPointee<5>('d'),
- Return(3));
- EXPECT_EQ(3, action.Perform(std::make_tuple(&m, &n, &a, &b, &c, &d)));
- EXPECT_EQ(1, m);
- EXPECT_EQ(2, n);
- EXPECT_EQ('a', a);
- EXPECT_EQ('b', b);
- EXPECT_EQ('c', c);
- EXPECT_EQ('d', d);
-}
-
-// Tests DoAll(a1, a2, ..., a8).
-TEST(DoAllTest, EightActions) {
- int m = 0, n = 0;
- char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0';
- Action<int(int*, int*, char*, char*, char*, char*, // NOLINT
- char*)> action =
- DoAll(SetArgPointee<0>(1),
- SetArgPointee<1>(2),
- SetArgPointee<2>('a'),
- SetArgPointee<3>('b'),
- SetArgPointee<4>('c'),
- SetArgPointee<5>('d'),
- SetArgPointee<6>('e'),
- Return(3));
- EXPECT_EQ(3, action.Perform(std::make_tuple(&m, &n, &a, &b, &c, &d, &e)));
- EXPECT_EQ(1, m);
- EXPECT_EQ(2, n);
- EXPECT_EQ('a', a);
- EXPECT_EQ('b', b);
- EXPECT_EQ('c', c);
- EXPECT_EQ('d', d);
- EXPECT_EQ('e', e);
-}
-
-// Tests DoAll(a1, a2, ..., a9).
-TEST(DoAllTest, NineActions) {
- int m = 0, n = 0;
- char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0', f = '\0';
- Action<int(int*, int*, char*, char*, char*, char*, // NOLINT
- char*, char*)> action =
- DoAll(SetArgPointee<0>(1),
- SetArgPointee<1>(2),
- SetArgPointee<2>('a'),
- SetArgPointee<3>('b'),
- SetArgPointee<4>('c'),
- SetArgPointee<5>('d'),
- SetArgPointee<6>('e'),
- SetArgPointee<7>('f'),
- Return(3));
- EXPECT_EQ(3, action.Perform(std::make_tuple(&m, &n, &a, &b, &c, &d, &e, &f)));
- EXPECT_EQ(1, m);
- EXPECT_EQ(2, n);
- EXPECT_EQ('a', a);
- EXPECT_EQ('b', b);
- EXPECT_EQ('c', c);
- EXPECT_EQ('d', d);
- EXPECT_EQ('e', e);
- EXPECT_EQ('f', f);
-}
-
-// Tests DoAll(a1, a2, ..., a10).
-TEST(DoAllTest, TenActions) {
- int m = 0, n = 0;
- char a = '\0', b = '\0', c = '\0', d = '\0';
- char e = '\0', f = '\0', g = '\0';
- Action<int(int*, int*, char*, char*, char*, char*, // NOLINT
- char*, char*, char*)> action =
- DoAll(SetArgPointee<0>(1),
- SetArgPointee<1>(2),
- SetArgPointee<2>('a'),
- SetArgPointee<3>('b'),
- SetArgPointee<4>('c'),
- SetArgPointee<5>('d'),
- SetArgPointee<6>('e'),
- SetArgPointee<7>('f'),
- SetArgPointee<8>('g'),
- Return(3));
- EXPECT_EQ(
- 3, action.Perform(std::make_tuple(&m, &n, &a, &b, &c, &d, &e, &f, &g)));
- EXPECT_EQ(1, m);
- EXPECT_EQ(2, n);
- EXPECT_EQ('a', a);
- EXPECT_EQ('b', b);
- EXPECT_EQ('c', c);
- EXPECT_EQ('d', d);
- EXPECT_EQ('e', e);
- EXPECT_EQ('f', f);
- EXPECT_EQ('g', g);
-}
-
-TEST(DoAllTest, NoArgs) {
- bool ran_first = false;
- Action<bool()> a =
- DoAll([&] { ran_first = true; }, [&] { return ran_first; });
- EXPECT_TRUE(a.Perform({}));
-}
-
-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; });
- EXPECT_EQ(7, a.Perform(std::make_tuple(std::unique_ptr<int>(new int(7)))));
- EXPECT_TRUE(ran_first);
-}
-
-TEST(DoAllTest, ImplicitlyConvertsActionArguments) {
- bool ran_first = false;
- // Action<void(std::vector<int>)> isn't an
- // Action<void(const std::vector<int>&) but can be converted.
- Action<void(std::vector<int>)> first = [&] { ran_first = true; };
- Action<int(std::vector<int>)> a =
- DoAll(first, [](std::vector<int> arg) { return arg.front(); });
- EXPECT_EQ(7, a.Perform(std::make_tuple(std::vector<int>{7})));
- EXPECT_TRUE(ran_first);
-}
-
-// The ACTION*() macros trigger warning C4100 (unreferenced formal
-// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
-// the macro definition, as the warnings are generated when the macro
-// is expanded and macro expansion cannot contain #pragma. Therefore
-// we suppress them here.
-// Also suppress C4503 decorated name length exceeded, name was truncated
-#ifdef _MSC_VER
-# pragma warning(push)
-# pragma warning(disable:4100)
-# pragma warning(disable:4503)
-#endif
-// Tests the ACTION*() macro family.
-
-// Tests that ACTION() can define an action that doesn't reference the
-// mock function arguments.
-ACTION(Return5) { return 5; }
-
-TEST(ActionMacroTest, WorksWhenNotReferencingArguments) {
- Action<double()> a1 = Return5();
- EXPECT_DOUBLE_EQ(5, a1.Perform(std::make_tuple()));
-
- Action<int(double, bool)> a2 = Return5();
- EXPECT_EQ(5, a2.Perform(std::make_tuple(1, true)));
-}
-
-// Tests that ACTION() can define an action that returns void.
-ACTION(IncrementArg1) { (*arg1)++; }
-
-TEST(ActionMacroTest, WorksWhenReturningVoid) {
- Action<void(int, int*)> a1 = IncrementArg1();
- int n = 0;
- a1.Perform(std::make_tuple(5, &n));
- EXPECT_EQ(1, n);
-}
-
-// Tests that the body of ACTION() can reference the type of the
-// argument.
-ACTION(IncrementArg2) {
- StaticAssertTypeEq<int*, arg2_type>();
- arg2_type temp = arg2;
- (*temp)++;
-}
-
-TEST(ActionMacroTest, CanReferenceArgumentType) {
- Action<void(int, bool, int*)> a1 = IncrementArg2();
- int n = 0;
- a1.Perform(std::make_tuple(5, false, &n));
- EXPECT_EQ(1, n);
-}
-
-// Tests that the body of ACTION() can reference the argument tuple
-// via args_type and args.
-ACTION(Sum2) {
- StaticAssertTypeEq<std::tuple<int, char, int*>, args_type>();
- args_type args_copy = args;
- return std::get<0>(args_copy) + std::get<1>(args_copy);
-}
-
-TEST(ActionMacroTest, CanReferenceArgumentTuple) {
- Action<int(int, char, int*)> a1 = Sum2();
- int dummy = 0;
- EXPECT_EQ(11, a1.Perform(std::make_tuple(5, Char(6), &dummy)));
-}
-
-// Tests that the body of ACTION() can reference the mock function
-// type.
-int Dummy(bool flag) { return flag? 1 : 0; }
-
-ACTION(InvokeDummy) {
- StaticAssertTypeEq<int(bool), function_type>();
- function_type* fp = &Dummy;
- return (*fp)(true);
-}
-
-TEST(ActionMacroTest, CanReferenceMockFunctionType) {
- Action<int(bool)> a1 = InvokeDummy();
- EXPECT_EQ(1, a1.Perform(std::make_tuple(true)));
- EXPECT_EQ(1, a1.Perform(std::make_tuple(false)));
-}
-
-// Tests that the body of ACTION() can reference the mock function's
-// return type.
-ACTION(InvokeDummy2) {
- StaticAssertTypeEq<int, return_type>();
- return_type result = Dummy(true);
- return result;
-}
-
-TEST(ActionMacroTest, CanReferenceMockFunctionReturnType) {
- Action<int(bool)> a1 = InvokeDummy2();
- EXPECT_EQ(1, a1.Perform(std::make_tuple(true)));
- EXPECT_EQ(1, a1.Perform(std::make_tuple(false)));
-}
-
-// Tests that ACTION() works for arguments passed by const reference.
-ACTION(ReturnAddrOfConstBoolReferenceArg) {
- StaticAssertTypeEq<const bool&, arg1_type>();
- return &arg1;
-}
-
-TEST(ActionMacroTest, WorksForConstReferenceArg) {
- Action<const bool*(int, const bool&)> a = ReturnAddrOfConstBoolReferenceArg();
- const bool b = false;
- EXPECT_EQ(&b, a.Perform(std::tuple<int, const bool&>(0, b)));
-}
-
-// Tests that ACTION() works for arguments passed by non-const reference.
-ACTION(ReturnAddrOfIntReferenceArg) {
- StaticAssertTypeEq<int&, arg0_type>();
- return &arg0;
-}
-
-TEST(ActionMacroTest, WorksForNonConstReferenceArg) {
- Action<int*(int&, bool, int)> a = ReturnAddrOfIntReferenceArg();
- int n = 0;
- EXPECT_EQ(&n, a.Perform(std::tuple<int&, bool, int>(n, true, 1)));
-}
-
-// Tests that ACTION() can be used in a namespace.
-namespace action_test {
-ACTION(Sum) { return arg0 + arg1; }
-} // namespace action_test
-
-TEST(ActionMacroTest, WorksInNamespace) {
- Action<int(int, int)> a1 = action_test::Sum();
- EXPECT_EQ(3, a1.Perform(std::make_tuple(1, 2)));
-}
-
-// Tests that the same ACTION definition works for mock functions with
-// different argument numbers.
-ACTION(PlusTwo) { return arg0 + 2; }
-
-TEST(ActionMacroTest, WorksForDifferentArgumentNumbers) {
- Action<int(int)> a1 = PlusTwo();
- EXPECT_EQ(4, a1.Perform(std::make_tuple(2)));
-
- Action<double(float, void*)> a2 = PlusTwo();
- int dummy;
- EXPECT_DOUBLE_EQ(6, a2.Perform(std::make_tuple(4.0f, &dummy)));
-}
-
-// Tests that ACTION_P can define a parameterized action.
-ACTION_P(Plus, n) { return arg0 + n; }
-
-TEST(ActionPMacroTest, DefinesParameterizedAction) {
- Action<int(int m, bool t)> a1 = Plus(9);
- EXPECT_EQ(10, a1.Perform(std::make_tuple(1, true)));
-}
-
-// Tests that the body of ACTION_P can reference the argument types
-// and the parameter type.
-ACTION_P(TypedPlus, n) {
- arg0_type t1 = arg0;
- n_type t2 = n;
- return t1 + t2;
-}
-
-TEST(ActionPMacroTest, CanReferenceArgumentAndParameterTypes) {
- Action<int(char m, bool t)> a1 = TypedPlus(9);
- EXPECT_EQ(10, a1.Perform(std::make_tuple(Char(1), true)));
-}
-
-// Tests that a parameterized action can be used in any mock function
-// whose type is compatible.
-TEST(ActionPMacroTest, WorksInCompatibleMockFunction) {
- Action<std::string(const std::string& s)> a1 = Plus("tail");
- const std::string re = "re";
- std::tuple<const std::string> dummy = std::make_tuple(re);
- EXPECT_EQ("retail", a1.Perform(dummy));
-}
-
-// Tests that we can use ACTION*() to define actions overloaded on the
-// number of parameters.
-
-ACTION(OverloadedAction) { return arg0 ? arg1 : "hello"; }
-
-ACTION_P(OverloadedAction, default_value) {
- return arg0 ? arg1 : default_value;
-}
-
-ACTION_P2(OverloadedAction, true_value, false_value) {
- return arg0 ? true_value : false_value;
-}
-
-TEST(ActionMacroTest, CanDefineOverloadedActions) {
- typedef Action<const char*(bool, const char*)> MyAction;
-
- const MyAction a1 = OverloadedAction();
- EXPECT_STREQ("hello", a1.Perform(std::make_tuple(false, CharPtr("world"))));
- EXPECT_STREQ("world", a1.Perform(std::make_tuple(true, CharPtr("world"))));
-
- const MyAction a2 = OverloadedAction("hi");
- EXPECT_STREQ("hi", a2.Perform(std::make_tuple(false, CharPtr("world"))));
- EXPECT_STREQ("world", a2.Perform(std::make_tuple(true, CharPtr("world"))));
-
- const MyAction a3 = OverloadedAction("hi", "you");
- EXPECT_STREQ("hi", a3.Perform(std::make_tuple(true, CharPtr("world"))));
- EXPECT_STREQ("you", a3.Perform(std::make_tuple(false, CharPtr("world"))));
-}
-
-// Tests ACTION_Pn where n >= 3.
-
-ACTION_P3(Plus, m, n, k) { return arg0 + m + n + k; }
-
-TEST(ActionPnMacroTest, WorksFor3Parameters) {
- Action<double(int m, bool t)> a1 = Plus(100, 20, 3.4);
- EXPECT_DOUBLE_EQ(3123.4, a1.Perform(std::make_tuple(3000, true)));
-
- Action<std::string(const std::string& s)> a2 = Plus("tail", "-", ">");
- const std::string re = "re";
- std::tuple<const std::string> dummy = std::make_tuple(re);
- EXPECT_EQ("retail->", a2.Perform(dummy));
-}
-
-ACTION_P4(Plus, p0, p1, p2, p3) { return arg0 + p0 + p1 + p2 + p3; }
-
-TEST(ActionPnMacroTest, WorksFor4Parameters) {
- Action<int(int)> a1 = Plus(1, 2, 3, 4);
- EXPECT_EQ(10 + 1 + 2 + 3 + 4, a1.Perform(std::make_tuple(10)));
-}
-
-ACTION_P5(Plus, p0, p1, p2, p3, p4) { return arg0 + p0 + p1 + p2 + p3 + p4; }
-
-TEST(ActionPnMacroTest, WorksFor5Parameters) {
- Action<int(int)> a1 = Plus(1, 2, 3, 4, 5);
- EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5, a1.Perform(std::make_tuple(10)));
-}
-
-ACTION_P6(Plus, p0, p1, p2, p3, p4, p5) {
- return arg0 + p0 + p1 + p2 + p3 + p4 + p5;
-}
-
-TEST(ActionPnMacroTest, WorksFor6Parameters) {
- Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6);
- EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6, a1.Perform(std::make_tuple(10)));
-}
-
-ACTION_P7(Plus, p0, p1, p2, p3, p4, p5, p6) {
- return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6;
-}
-
-TEST(ActionPnMacroTest, WorksFor7Parameters) {
- Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7);
- EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7, a1.Perform(std::make_tuple(10)));
-}
-
-ACTION_P8(Plus, p0, p1, p2, p3, p4, p5, p6, p7) {
- return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7;
-}
-
-TEST(ActionPnMacroTest, WorksFor8Parameters) {
- Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8);
- EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8,
- a1.Perform(std::make_tuple(10)));
-}
-
-ACTION_P9(Plus, p0, p1, p2, p3, p4, p5, p6, p7, p8) {
- return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8;
-}
-
-TEST(ActionPnMacroTest, WorksFor9Parameters) {
- Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8, 9);
- EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9,
- a1.Perform(std::make_tuple(10)));
-}
-
-ACTION_P10(Plus, p0, p1, p2, p3, p4, p5, p6, p7, p8, last_param) {
- arg0_type t0 = arg0;
- last_param_type t9 = last_param;
- return t0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + t9;
-}
-
-TEST(ActionPnMacroTest, WorksFor10Parameters) {
- Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
- EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10,
- a1.Perform(std::make_tuple(10)));
-}
-
-// Tests that the action body can promote the parameter types.
-
-ACTION_P2(PadArgument, prefix, suffix) {
- // The following lines promote the two parameters to desired types.
- std::string prefix_str(prefix);
- char suffix_char = static_cast<char>(suffix);
- return prefix_str + arg0 + suffix_char;
-}
-
-TEST(ActionPnMacroTest, SimpleTypePromotion) {
- Action<std::string(const char*)> no_promo =
- PadArgument(std::string("foo"), 'r');
- Action<std::string(const char*)> promo =
- PadArgument("foo", static_cast<int>('r'));
- EXPECT_EQ("foobar", no_promo.Perform(std::make_tuple(CharPtr("ba"))));
- EXPECT_EQ("foobar", promo.Perform(std::make_tuple(CharPtr("ba"))));
-}
-
-// Tests that we can partially restrict parameter types using a
-// straight-forward pattern.
-
-// Defines a generic action that doesn't restrict the types of its
-// parameters.
-ACTION_P3(ConcatImpl, a, b, c) {
- std::stringstream ss;
- ss << a << b << c;
- return ss.str();
-}
-
-// Next, we try to restrict that either the first parameter is a
-// string, or the second parameter is an int.
-
-// Defines a partially specialized wrapper that restricts the first
-// parameter to std::string.
-template <typename T1, typename T2>
-// ConcatImplActionP3 is the class template ACTION_P3 uses to
-// implement ConcatImpl. We shouldn't change the name as this
-// pattern requires the user to use it directly.
-ConcatImplActionP3<std::string, T1, T2>
-Concat(const std::string& a, T1 b, T2 c) {
- GTEST_INTENTIONAL_CONST_COND_PUSH_()
- if (true) {
- GTEST_INTENTIONAL_CONST_COND_POP_()
- // This branch verifies that ConcatImpl() can be invoked without
- // explicit template arguments.
- return ConcatImpl(a, b, c);
- } else {
- // This branch verifies that ConcatImpl() can also be invoked with
- // explicit template arguments. It doesn't really need to be
- // executed as this is a compile-time verification.
- return ConcatImpl<std::string, T1, T2>(a, b, c);
- }
-}
-
-// Defines another partially specialized wrapper that restricts the
-// second parameter to int.
-template <typename T1, typename T2>
-ConcatImplActionP3<T1, int, T2>
-Concat(T1 a, int b, T2 c) {
- return ConcatImpl(a, b, c);
-}
-
-TEST(ActionPnMacroTest, CanPartiallyRestrictParameterTypes) {
- Action<const std::string()> a1 = Concat("Hello", "1", 2);
- EXPECT_EQ("Hello12", a1.Perform(std::make_tuple()));
-
- a1 = Concat(1, 2, 3);
- EXPECT_EQ("123", a1.Perform(std::make_tuple()));
-}
-
-// Verifies the type of an ACTION*.
-
-ACTION(DoFoo) {}
-ACTION_P(DoFoo, p) {}
-ACTION_P2(DoFoo, p0, p1) {}
-
-TEST(ActionPnMacroTest, TypesAreCorrect) {
- // DoFoo() must be assignable to a DoFooAction variable.
- DoFooAction a0 = DoFoo();
-
- // DoFoo(1) must be assignable to a DoFooActionP variable.
- DoFooActionP<int> a1 = DoFoo(1);
-
- // DoFoo(p1, ..., pk) must be assignable to a DoFooActionPk
- // variable, and so on.
- DoFooActionP2<int, char> a2 = DoFoo(1, '2');
- PlusActionP3<int, int, char> a3 = Plus(1, 2, '3');
- PlusActionP4<int, int, int, char> a4 = Plus(1, 2, 3, '4');
- PlusActionP5<int, int, int, int, char> a5 = Plus(1, 2, 3, 4, '5');
- PlusActionP6<int, int, int, int, int, char> a6 = Plus(1, 2, 3, 4, 5, '6');
- PlusActionP7<int, int, int, int, int, int, char> a7 =
- Plus(1, 2, 3, 4, 5, 6, '7');
- PlusActionP8<int, int, int, int, int, int, int, char> a8 =
- Plus(1, 2, 3, 4, 5, 6, 7, '8');
- PlusActionP9<int, int, int, int, int, int, int, int, char> a9 =
- Plus(1, 2, 3, 4, 5, 6, 7, 8, '9');
- PlusActionP10<int, int, int, int, int, int, int, int, int, char> a10 =
- Plus(1, 2, 3, 4, 5, 6, 7, 8, 9, '0');
-
- // Avoid "unused variable" warnings.
- (void)a0;
- (void)a1;
- (void)a2;
- (void)a3;
- (void)a4;
- (void)a5;
- (void)a6;
- (void)a7;
- (void)a8;
- (void)a9;
- (void)a10;
-}
-
-// Tests that an ACTION_P*() action can be explicitly instantiated
-// with reference-typed parameters.
-
-ACTION_P(Plus1, x) { return x; }
-ACTION_P2(Plus2, x, y) { return x + y; }
-ACTION_P3(Plus3, x, y, z) { return x + y + z; }
-ACTION_P10(Plus10, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {
- return a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9;
-}
-
-TEST(ActionPnMacroTest, CanExplicitlyInstantiateWithReferenceTypes) {
- int x = 1, y = 2, z = 3;
- const std::tuple<> empty = std::make_tuple();
-
- Action<int()> a = Plus1<int&>(x);
- EXPECT_EQ(1, a.Perform(empty));
-
- a = Plus2<const int&, int&>(x, y);
- EXPECT_EQ(3, a.Perform(empty));
-
- a = Plus3<int&, const int&, int&>(x, y, z);
- EXPECT_EQ(6, a.Perform(empty));
-
- int n[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
- a = Plus10<const int&, int&, const int&, int&, const int&, int&, const int&,
- int&, const int&, int&>(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7],
- n[8], n[9]);
- EXPECT_EQ(55, a.Perform(empty));
-}
-
-
-class TenArgConstructorClass {
- public:
- TenArgConstructorClass(int a1, int a2, int a3, int a4, int a5,
- int a6, int a7, int a8, int a9, int a10)
- : value_(a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10) {
- }
- int value_;
-};
-
-// Tests that ACTION_TEMPLATE works when there is no value parameter.
-ACTION_TEMPLATE(CreateNew,
- HAS_1_TEMPLATE_PARAMS(typename, T),
- AND_0_VALUE_PARAMS()) {
- return new T;
-}
-
-TEST(ActionTemplateTest, WorksWithoutValueParam) {
- const Action<int*()> a = CreateNew<int>();
- int* p = a.Perform(std::make_tuple());
- delete p;
-}
-
-// Tests that ACTION_TEMPLATE works when there are value parameters.
-ACTION_TEMPLATE(CreateNew,
- HAS_1_TEMPLATE_PARAMS(typename, T),
- AND_1_VALUE_PARAMS(a0)) {
- return new T(a0);
-}
-
-TEST(ActionTemplateTest, WorksWithValueParams) {
- const Action<int*()> a = CreateNew<int>(42);
- int* p = a.Perform(std::make_tuple());
- EXPECT_EQ(42, *p);
- delete p;
-}
-
-// Tests that ACTION_TEMPLATE works for integral template parameters.
-ACTION_TEMPLATE(MyDeleteArg,
- HAS_1_TEMPLATE_PARAMS(int, k),
- AND_0_VALUE_PARAMS()) {
- delete std::get<k>(args);
-}
-
-// Resets a bool variable in the destructor.
-class BoolResetter {
- public:
- explicit BoolResetter(bool* value) : value_(value) {}
- ~BoolResetter() { *value_ = false; }
- private:
- bool* value_;
-};
-
-TEST(ActionTemplateTest, WorksForIntegralTemplateParams) {
- const Action<void(int*, BoolResetter*)> a = MyDeleteArg<1>();
- int n = 0;
- bool b = true;
- BoolResetter* resetter = new BoolResetter(&b);
- a.Perform(std::make_tuple(&n, resetter));
- EXPECT_FALSE(b); // Verifies that resetter is deleted.
-}
-
-// Tests that ACTION_TEMPLATES works for template template parameters.
-ACTION_TEMPLATE(ReturnSmartPointer,
- HAS_1_TEMPLATE_PARAMS(template <typename Pointee> class,
- Pointer),
- AND_1_VALUE_PARAMS(pointee)) {
- return Pointer<pointee_type>(new pointee_type(pointee));
-}
-
-TEST(ActionTemplateTest, WorksForTemplateTemplateParameters) {
- const Action<std::shared_ptr<int>()> a =
- ReturnSmartPointer<std::shared_ptr>(42);
- std::shared_ptr<int> p = a.Perform(std::make_tuple());
- EXPECT_EQ(42, *p);
-}
-
-// Tests that ACTION_TEMPLATE works for 10 template parameters.
-template <typename T1, typename T2, typename T3, int k4, bool k5,
- unsigned int k6, typename T7, typename T8, typename T9>
-struct GiantTemplate {
- public:
- explicit GiantTemplate(int a_value) : value(a_value) {}
- int value;
-};
-
-ACTION_TEMPLATE(ReturnGiant,
- HAS_10_TEMPLATE_PARAMS(
- typename, T1,
- typename, T2,
- typename, T3,
- int, k4,
- bool, k5,
- unsigned int, k6,
- class, T7,
- class, T8,
- class, T9,
- template <typename T> class, T10),
- AND_1_VALUE_PARAMS(value)) {
- return GiantTemplate<T10<T1>, T2, T3, k4, k5, k6, T7, T8, T9>(value);
-}
-
-TEST(ActionTemplateTest, WorksFor10TemplateParameters) {
- using Giant = GiantTemplate<std::shared_ptr<int>, bool, double, 5, true, 6,
- char, unsigned, int>;
- const Action<Giant()> a = ReturnGiant<int, bool, double, 5, true, 6, char,
- unsigned, int, std::shared_ptr>(42);
- Giant giant = a.Perform(std::make_tuple());
- EXPECT_EQ(42, giant.value);
-}
-
-// Tests that ACTION_TEMPLATE works for 10 value parameters.
-ACTION_TEMPLATE(ReturnSum,
- HAS_1_TEMPLATE_PARAMS(typename, Number),
- AND_10_VALUE_PARAMS(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10)) {
- return static_cast<Number>(v1) + v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9 + v10;
-}
-
-TEST(ActionTemplateTest, WorksFor10ValueParameters) {
- const Action<int()> a = ReturnSum<int>(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
- EXPECT_EQ(55, a.Perform(std::make_tuple()));
-}
-
-// Tests that ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded
-// on the number of value parameters.
-
-ACTION(ReturnSum) { return 0; }
-
-ACTION_P(ReturnSum, x) { return x; }
-
-ACTION_TEMPLATE(ReturnSum,
- HAS_1_TEMPLATE_PARAMS(typename, Number),
- AND_2_VALUE_PARAMS(v1, v2)) {
- return static_cast<Number>(v1) + v2;
-}
-
-ACTION_TEMPLATE(ReturnSum,
- HAS_1_TEMPLATE_PARAMS(typename, Number),
- AND_3_VALUE_PARAMS(v1, v2, v3)) {
- return static_cast<Number>(v1) + v2 + v3;
-}
-
-ACTION_TEMPLATE(ReturnSum,
- HAS_2_TEMPLATE_PARAMS(typename, Number, int, k),
- AND_4_VALUE_PARAMS(v1, v2, v3, v4)) {
- return static_cast<Number>(v1) + v2 + v3 + v4 + k;
-}
-
-TEST(ActionTemplateTest, CanBeOverloadedOnNumberOfValueParameters) {
- const Action<int()> a0 = ReturnSum();
- const Action<int()> a1 = ReturnSum(1);
- const Action<int()> a2 = ReturnSum<int>(1, 2);
- const Action<int()> a3 = ReturnSum<int>(1, 2, 3);
- const Action<int()> a4 = ReturnSum<int, 10000>(2000, 300, 40, 5);
- EXPECT_EQ(0, a0.Perform(std::make_tuple()));
- EXPECT_EQ(1, a1.Perform(std::make_tuple()));
- EXPECT_EQ(3, a2.Perform(std::make_tuple()));
- EXPECT_EQ(6, a3.Perform(std::make_tuple()));
- EXPECT_EQ(12345, a4.Perform(std::make_tuple()));
-}
-
-
-} // namespace gmock_generated_actions_test
-} // namespace testing
diff --git a/googlemock/test/gmock-more-actions_test.cc b/googlemock/test/gmock-more-actions_test.cc
index 4bcb5df6..53bb029f 100644
--- a/googlemock/test/gmock-more-actions_test.cc
+++ b/googlemock/test/gmock-more-actions_test.cc
@@ -31,12 +31,18 @@
//
// This file tests the built-in actions in gmock-actions.h.
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4577)
+#endif
+
+#include "gmock/gmock-more-actions.h"
+
#include <functional>
#include <memory>
#include <sstream>
#include <string>
-#include "gmock/gmock-actions.h"
#include "gmock/gmock.h"
#include "gtest/gtest-spi.h"
#include "gtest/gtest.h"
@@ -46,12 +52,9 @@ namespace gmock_more_actions_test {
using ::std::plus;
using ::std::string;
-using testing::_;
using testing::Action;
-using testing::ActionInterface;
using testing::DeleteArg;
using testing::Invoke;
-using testing::Return;
using testing::ReturnArg;
using testing::ReturnPointee;
using testing::SaveArg;
@@ -68,55 +71,27 @@ inline char Char(char ch) { return ch; }
// Sample functions and functors for testing Invoke() and etc.
int Nullary() { return 1; }
-class NullaryFunctor {
- public:
- int operator()() { return 2; }
-};
-
bool g_done = false;
-void VoidNullary() { g_done = true; }
-
-class VoidNullaryFunctor {
- public:
- void operator()() { g_done = true; }
-};
bool Unary(int x) { return x < 0; }
-const char* Plus1(const char* s) { return s + 1; }
-
-void VoidUnary(int /* n */) { g_done = true; }
-
bool ByConstRef(const std::string& s) { return s == "Hi"; }
const double g_double = 0;
bool ReferencesGlobalDouble(const double& x) { return &x == &g_double; }
-std::string ByNonConstRef(std::string& s) { return s += "+"; } // NOLINT
-
struct UnaryFunctor {
int operator()(bool x) { return x ? 1 : -1; }
};
const char* Binary(const char* input, short n) { return input + n; } // NOLINT
-void VoidBinary(int, char) { g_done = true; }
-
int Ternary(int x, char y, short z) { return x + y + z; } // NOLINT
-void VoidTernary(int, char, bool) { g_done = true; }
-
int SumOf4(int a, int b, int c, int d) { return a + b + c + d; }
int SumOfFirst2(int a, int b, Unused, Unused) { return a + b; }
-void VoidFunctionWithFourArguments(char, int, float, double) { g_done = true; }
-
-std::string Concat4(const char* s1, const char* s2, const char* s3,
- const char* s4) {
- return std::string(s1) + s2 + s3 + s4;
-}
-
int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
struct SumOf5Functor {
@@ -125,11 +100,6 @@ struct SumOf5Functor {
}
};
-std::string Concat5(const char* s1, const char* s2, const char* s3,
- const char* s4, const char* s5) {
- return std::string(s1) + s2 + s3 + s4 + s5;
-}
-
int SumOf6(int a, int b, int c, int d, int e, int f) {
return a + b + c + d + e + f;
}
@@ -140,11 +110,6 @@ struct SumOf6Functor {
}
};
-std::string Concat6(const char* s1, const char* s2, const char* s3,
- const char* s4, const char* s5, const char* s6) {
- return std::string(s1) + s2 + s3 + s4 + s5 + s6;
-}
-
std::string Concat7(const char* s1, const char* s2, const char* s3,
const char* s4, const char* s5, const char* s6,
const char* s7) {
@@ -636,7 +601,7 @@ TEST(ThrowActionTest, Times0) {
// Tests that SetArrayArgument<N>(first, last) sets the elements of the array
// pointed to by the N-th (0-based) argument to values in range [first, last).
TEST(SetArrayArgumentTest, SetsTheNthArray) {
- typedef void MyFunction(bool, int*, char*);
+ using MyFunction = void(bool, int*, char*);
int numbers[] = { 1, 2, 3 };
Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers + 3);
@@ -672,7 +637,7 @@ TEST(SetArrayArgumentTest, SetsTheNthArray) {
// Tests SetArrayArgument<N>(first, last) where first == last.
TEST(SetArrayArgumentTest, SetsTheNthArrayWithEmptyRange) {
- typedef void MyFunction(bool, int*);
+ using MyFunction = void(bool, int*);
int numbers[] = { 1, 2, 3 };
Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers);
@@ -688,7 +653,7 @@ TEST(SetArrayArgumentTest, SetsTheNthArrayWithEmptyRange) {
// Tests SetArrayArgument<N>(first, last) where *first is convertible
// (but not equal) to the argument type.
TEST(SetArrayArgumentTest, SetsTheNthArrayWithConvertibleType) {
- typedef void MyFunction(bool, int*);
+ using MyFunction = void(bool, int*);
char chars[] = { 97, 98, 99 };
Action<MyFunction> a = SetArrayArgument<1>(chars, chars + 3);
@@ -703,7 +668,7 @@ TEST(SetArrayArgumentTest, SetsTheNthArrayWithConvertibleType) {
// Test SetArrayArgument<N>(first, last) with iterator as argument.
TEST(SetArrayArgumentTest, SetsTheNthArrayWithIteratorArgument) {
- typedef void MyFunction(bool, std::back_insert_iterator<std::string>);
+ using MyFunction = void(bool, std::back_insert_iterator<std::string>);
std::string letters = "abc";
Action<MyFunction> a = SetArrayArgument<1>(letters.begin(), letters.end());
@@ -721,5 +686,862 @@ TEST(ReturnPointeeTest, Works) {
EXPECT_EQ(43, a.Perform(std::make_tuple()));
}
-} // namespace gmock_generated_actions_test
+// Tests InvokeArgument<N>(...).
+
+// Tests using InvokeArgument with a nullary function.
+TEST(InvokeArgumentTest, Function0) {
+ Action<int(int, int (*)())> a = InvokeArgument<1>(); // NOLINT
+ EXPECT_EQ(1, a.Perform(std::make_tuple(2, &Nullary)));
+}
+
+// Tests using InvokeArgument with a unary function.
+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 5-ary function.
+TEST(InvokeArgumentTest, Function5) {
+ Action<int(int (*)(int, int, int, int, int))> a = // NOLINT
+ InvokeArgument<0>(10000, 2000, 300, 40, 5);
+ EXPECT_EQ(12345, a.Perform(std::make_tuple(&SumOf5)));
+}
+
+// Tests using InvokeArgument with a 5-ary functor.
+TEST(InvokeArgumentTest, Functor5) {
+ Action<int(SumOf5Functor)> a = // NOLINT
+ InvokeArgument<0>(10000, 2000, 300, 40, 5);
+ EXPECT_EQ(12345, a.Perform(std::make_tuple(SumOf5Functor())));
+}
+
+// Tests using InvokeArgument with a 6-ary function.
+TEST(InvokeArgumentTest, Function6) {
+ Action<int(int (*)(int, int, int, int, int, int))> a = // NOLINT
+ InvokeArgument<0>(100000, 20000, 3000, 400, 50, 6);
+ EXPECT_EQ(123456, a.Perform(std::make_tuple(&SumOf6)));
+}
+
+// Tests using InvokeArgument with a 6-ary functor.
+TEST(InvokeArgumentTest, Functor6) {
+ Action<int(SumOf6Functor)> a = // NOLINT
+ InvokeArgument<0>(100000, 20000, 3000, 400, 50, 6);
+ EXPECT_EQ(123456, a.Perform(std::make_tuple(SumOf6Functor())));
+}
+
+// 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*))>
+ 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*))>
+ 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*))>
+ 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(*)(
+ 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");
+ EXPECT_EQ("1234567890", a.Perform(std::make_tuple(&Concat10)));
+}
+
+// Tests using InvokeArgument with a function that takes a pointer argument.
+TEST(InvokeArgumentTest, ByPointerFunction) {
+ Action<const char*(const char* (*)(const char* input, short n))> // NOLINT
+ a = InvokeArgument<0>(static_cast<const char*>("Hi"), Short(1));
+ EXPECT_STREQ("i", a.Perform(std::make_tuple(&Binary)));
+}
+
+// Tests using InvokeArgument with a function that takes a const char*
+// by passing it a C-string literal.
+TEST(InvokeArgumentTest, FunctionWithCStringLiteral) {
+ Action<const char*(const char* (*)(const char* input, short n))> // NOLINT
+ a = InvokeArgument<0>("Hi", Short(1));
+ EXPECT_STREQ("i", a.Perform(std::make_tuple(&Binary)));
+}
+
+// Tests using InvokeArgument with a function that takes a const reference.
+TEST(InvokeArgumentTest, ByConstReferenceFunction) {
+ Action<bool(bool (*function)(const std::string& s))> a = // NOLINT
+ InvokeArgument<0>(std::string("Hi"));
+ // When action 'a' is constructed, it makes a copy of the temporary
+ // string object passed to it, so it's OK to use 'a' later, when the
+ // temporary object has already died.
+ EXPECT_TRUE(a.Perform(std::make_tuple(&ByConstRef)));
+}
+
+// Tests using InvokeArgument with ByRef() and a function that takes a
+// const reference.
+TEST(InvokeArgumentTest, ByExplicitConstReferenceFunction) {
+ Action<bool(bool (*)(const double& x))> a = // NOLINT
+ InvokeArgument<0>(ByRef(g_double));
+ // The above line calls ByRef() on a const value.
+ EXPECT_TRUE(a.Perform(std::make_tuple(&ReferencesGlobalDouble)));
+
+ double x = 0;
+ a = InvokeArgument<0>(ByRef(x)); // This calls ByRef() on a non-const.
+ EXPECT_FALSE(a.Perform(std::make_tuple(&ReferencesGlobalDouble)));
+}
+
+// Tests DoAll(a1, a2).
+TEST(DoAllTest, TwoActions) {
+ int n = 0;
+ Action<int(int*)> a = DoAll(SetArgPointee<0>(1), // NOLINT
+ Return(2));
+ EXPECT_EQ(2, a.Perform(std::make_tuple(&n)));
+ EXPECT_EQ(1, n);
+}
+
+// Tests DoAll(a1, a2, a3).
+TEST(DoAllTest, ThreeActions) {
+ int m = 0, n = 0;
+ Action<int(int*, int*)> a = DoAll(SetArgPointee<0>(1), // NOLINT
+ SetArgPointee<1>(2), Return(3));
+ EXPECT_EQ(3, a.Perform(std::make_tuple(&m, &n)));
+ EXPECT_EQ(1, m);
+ EXPECT_EQ(2, n);
+}
+
+// Tests DoAll(a1, a2, a3, a4).
+TEST(DoAllTest, FourActions) {
+ int m = 0, n = 0;
+ char ch = '\0';
+ Action<int(int*, int*, char*)> a = // NOLINT
+ DoAll(SetArgPointee<0>(1), SetArgPointee<1>(2), SetArgPointee<2>('a'),
+ Return(3));
+ EXPECT_EQ(3, a.Perform(std::make_tuple(&m, &n, &ch)));
+ EXPECT_EQ(1, m);
+ EXPECT_EQ(2, n);
+ EXPECT_EQ('a', ch);
+}
+
+// Tests DoAll(a1, a2, a3, a4, a5).
+TEST(DoAllTest, FiveActions) {
+ int m = 0, n = 0;
+ char a = '\0', b = '\0';
+ Action<int(int*, int*, char*, char*)> action = // NOLINT
+ DoAll(SetArgPointee<0>(1), SetArgPointee<1>(2), SetArgPointee<2>('a'),
+ SetArgPointee<3>('b'), Return(3));
+ EXPECT_EQ(3, action.Perform(std::make_tuple(&m, &n, &a, &b)));
+ EXPECT_EQ(1, m);
+ EXPECT_EQ(2, n);
+ EXPECT_EQ('a', a);
+ EXPECT_EQ('b', b);
+}
+
+// Tests DoAll(a1, a2, ..., a6).
+TEST(DoAllTest, SixActions) {
+ int m = 0, n = 0;
+ char a = '\0', b = '\0', c = '\0';
+ Action<int(int*, int*, char*, char*, char*)> action = // NOLINT
+ DoAll(SetArgPointee<0>(1), SetArgPointee<1>(2), SetArgPointee<2>('a'),
+ SetArgPointee<3>('b'), SetArgPointee<4>('c'), Return(3));
+ EXPECT_EQ(3, action.Perform(std::make_tuple(&m, &n, &a, &b, &c)));
+ EXPECT_EQ(1, m);
+ EXPECT_EQ(2, n);
+ EXPECT_EQ('a', a);
+ EXPECT_EQ('b', b);
+ EXPECT_EQ('c', c);
+}
+
+// Tests DoAll(a1, a2, ..., a7).
+TEST(DoAllTest, SevenActions) {
+ int m = 0, n = 0;
+ char a = '\0', b = '\0', c = '\0', d = '\0';
+ Action<int(int*, int*, char*, char*, char*, char*)> action = // NOLINT
+ DoAll(SetArgPointee<0>(1), SetArgPointee<1>(2), SetArgPointee<2>('a'),
+ SetArgPointee<3>('b'), SetArgPointee<4>('c'), SetArgPointee<5>('d'),
+ Return(3));
+ EXPECT_EQ(3, action.Perform(std::make_tuple(&m, &n, &a, &b, &c, &d)));
+ EXPECT_EQ(1, m);
+ EXPECT_EQ(2, n);
+ EXPECT_EQ('a', a);
+ EXPECT_EQ('b', b);
+ EXPECT_EQ('c', c);
+ EXPECT_EQ('d', d);
+}
+
+// Tests DoAll(a1, a2, ..., a8).
+TEST(DoAllTest, EightActions) {
+ int m = 0, n = 0;
+ char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0';
+ Action<int(int*, int*, char*, char*, char*, char*, // NOLINT
+ char*)>
+ action =
+ DoAll(SetArgPointee<0>(1), SetArgPointee<1>(2), SetArgPointee<2>('a'),
+ SetArgPointee<3>('b'), SetArgPointee<4>('c'),
+ SetArgPointee<5>('d'), SetArgPointee<6>('e'), Return(3));
+ EXPECT_EQ(3, action.Perform(std::make_tuple(&m, &n, &a, &b, &c, &d, &e)));
+ EXPECT_EQ(1, m);
+ EXPECT_EQ(2, n);
+ EXPECT_EQ('a', a);
+ EXPECT_EQ('b', b);
+ EXPECT_EQ('c', c);
+ EXPECT_EQ('d', d);
+ EXPECT_EQ('e', e);
+}
+
+// Tests DoAll(a1, a2, ..., a9).
+TEST(DoAllTest, NineActions) {
+ int m = 0, n = 0;
+ char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0', f = '\0';
+ Action<int(int*, int*, char*, char*, char*, char*, // NOLINT
+ char*, char*)>
+ action = DoAll(SetArgPointee<0>(1), SetArgPointee<1>(2),
+ SetArgPointee<2>('a'), SetArgPointee<3>('b'),
+ SetArgPointee<4>('c'), SetArgPointee<5>('d'),
+ SetArgPointee<6>('e'), SetArgPointee<7>('f'), Return(3));
+ EXPECT_EQ(3, action.Perform(std::make_tuple(&m, &n, &a, &b, &c, &d, &e, &f)));
+ EXPECT_EQ(1, m);
+ EXPECT_EQ(2, n);
+ EXPECT_EQ('a', a);
+ EXPECT_EQ('b', b);
+ EXPECT_EQ('c', c);
+ EXPECT_EQ('d', d);
+ EXPECT_EQ('e', e);
+ EXPECT_EQ('f', f);
+}
+
+// Tests DoAll(a1, a2, ..., a10).
+TEST(DoAllTest, TenActions) {
+ int m = 0, n = 0;
+ char a = '\0', b = '\0', c = '\0', d = '\0';
+ char e = '\0', f = '\0', g = '\0';
+ Action<int(int*, int*, char*, char*, char*, char*, // NOLINT
+ char*, char*, char*)>
+ action =
+ DoAll(SetArgPointee<0>(1), SetArgPointee<1>(2), SetArgPointee<2>('a'),
+ SetArgPointee<3>('b'), SetArgPointee<4>('c'),
+ SetArgPointee<5>('d'), SetArgPointee<6>('e'),
+ SetArgPointee<7>('f'), SetArgPointee<8>('g'), Return(3));
+ EXPECT_EQ(
+ 3, action.Perform(std::make_tuple(&m, &n, &a, &b, &c, &d, &e, &f, &g)));
+ EXPECT_EQ(1, m);
+ EXPECT_EQ(2, n);
+ EXPECT_EQ('a', a);
+ EXPECT_EQ('b', b);
+ EXPECT_EQ('c', c);
+ EXPECT_EQ('d', d);
+ EXPECT_EQ('e', e);
+ EXPECT_EQ('f', f);
+ EXPECT_EQ('g', g);
+}
+
+TEST(DoAllTest, NoArgs) {
+ bool ran_first = false;
+ Action<bool()> a =
+ DoAll([&] { ran_first = true; }, [&] { return ran_first; });
+ EXPECT_TRUE(a.Perform({}));
+}
+
+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; });
+ EXPECT_EQ(7, a.Perform(std::make_tuple(std::unique_ptr<int>(new int(7)))));
+ EXPECT_TRUE(ran_first);
+}
+
+TEST(DoAllTest, ImplicitlyConvertsActionArguments) {
+ bool ran_first = false;
+ // Action<void(std::vector<int>)> isn't an
+ // Action<void(const std::vector<int>&) but can be converted.
+ Action<void(std::vector<int>)> first = [&] { ran_first = true; };
+ Action<int(std::vector<int>)> a =
+ DoAll(first, [](std::vector<int> arg) { return arg.front(); });
+ EXPECT_EQ(7, a.Perform(std::make_tuple(std::vector<int>{7})));
+ EXPECT_TRUE(ran_first);
+}
+
+// The ACTION*() macros trigger warning C4100 (unreferenced formal
+// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
+// the macro definition, as the warnings are generated when the macro
+// is expanded and macro expansion cannot contain #pragma. Therefore
+// we suppress them here.
+// Also suppress C4503 decorated name length exceeded, name was truncated
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4100)
+#pragma warning(disable : 4503)
+#endif
+// Tests the ACTION*() macro family.
+
+// Tests that ACTION() can define an action that doesn't reference the
+// mock function arguments.
+ACTION(Return5) { return 5; }
+
+TEST(ActionMacroTest, WorksWhenNotReferencingArguments) {
+ Action<double()> a1 = Return5();
+ EXPECT_DOUBLE_EQ(5, a1.Perform(std::make_tuple()));
+
+ Action<int(double, bool)> a2 = Return5();
+ EXPECT_EQ(5, a2.Perform(std::make_tuple(1, true)));
+}
+
+// Tests that ACTION() can define an action that returns void.
+ACTION(IncrementArg1) { (*arg1)++; }
+
+TEST(ActionMacroTest, WorksWhenReturningVoid) {
+ Action<void(int, int*)> a1 = IncrementArg1();
+ int n = 0;
+ a1.Perform(std::make_tuple(5, &n));
+ EXPECT_EQ(1, n);
+}
+
+// Tests that the body of ACTION() can reference the type of the
+// argument.
+ACTION(IncrementArg2) {
+ StaticAssertTypeEq<int*, arg2_type>();
+ arg2_type temp = arg2;
+ (*temp)++;
+}
+
+TEST(ActionMacroTest, CanReferenceArgumentType) {
+ Action<void(int, bool, int*)> a1 = IncrementArg2();
+ int n = 0;
+ a1.Perform(std::make_tuple(5, false, &n));
+ EXPECT_EQ(1, n);
+}
+
+// Tests that the body of ACTION() can reference the argument tuple
+// via args_type and args.
+ACTION(Sum2) {
+ StaticAssertTypeEq<std::tuple<int, char, int*>, args_type>();
+ args_type args_copy = args;
+ return std::get<0>(args_copy) + std::get<1>(args_copy);
+}
+
+TEST(ActionMacroTest, CanReferenceArgumentTuple) {
+ Action<int(int, char, int*)> a1 = Sum2();
+ int dummy = 0;
+ EXPECT_EQ(11, a1.Perform(std::make_tuple(5, Char(6), &dummy)));
+}
+
+namespace {
+
+// Tests that the body of ACTION() can reference the mock function
+// type.
+int Dummy(bool flag) { return flag ? 1 : 0; }
+
+} // namespace
+
+ACTION(InvokeDummy) {
+ StaticAssertTypeEq<int(bool), function_type>();
+ function_type* fp = &Dummy;
+ return (*fp)(true);
+}
+
+TEST(ActionMacroTest, CanReferenceMockFunctionType) {
+ Action<int(bool)> a1 = InvokeDummy();
+ EXPECT_EQ(1, a1.Perform(std::make_tuple(true)));
+ EXPECT_EQ(1, a1.Perform(std::make_tuple(false)));
+}
+
+// Tests that the body of ACTION() can reference the mock function's
+// return type.
+ACTION(InvokeDummy2) {
+ StaticAssertTypeEq<int, return_type>();
+ return_type result = Dummy(true);
+ return result;
+}
+
+TEST(ActionMacroTest, CanReferenceMockFunctionReturnType) {
+ Action<int(bool)> a1 = InvokeDummy2();
+ EXPECT_EQ(1, a1.Perform(std::make_tuple(true)));
+ EXPECT_EQ(1, a1.Perform(std::make_tuple(false)));
+}
+
+// Tests that ACTION() works for arguments passed by const reference.
+ACTION(ReturnAddrOfConstBoolReferenceArg) {
+ StaticAssertTypeEq<const bool&, arg1_type>();
+ return &arg1;
+}
+
+TEST(ActionMacroTest, WorksForConstReferenceArg) {
+ Action<const bool*(int, const bool&)> a = ReturnAddrOfConstBoolReferenceArg();
+ const bool b = false;
+ EXPECT_EQ(&b, a.Perform(std::tuple<int, const bool&>(0, b)));
+}
+
+// Tests that ACTION() works for arguments passed by non-const reference.
+ACTION(ReturnAddrOfIntReferenceArg) {
+ StaticAssertTypeEq<int&, arg0_type>();
+ return &arg0;
+}
+
+TEST(ActionMacroTest, WorksForNonConstReferenceArg) {
+ Action<int*(int&, bool, int)> a = ReturnAddrOfIntReferenceArg();
+ int n = 0;
+ EXPECT_EQ(&n, a.Perform(std::tuple<int&, bool, int>(n, true, 1)));
+}
+
+// Tests that ACTION() can be used in a namespace.
+namespace action_test {
+ACTION(Sum) { return arg0 + arg1; }
+} // namespace action_test
+
+TEST(ActionMacroTest, WorksInNamespace) {
+ Action<int(int, int)> a1 = action_test::Sum();
+ EXPECT_EQ(3, a1.Perform(std::make_tuple(1, 2)));
+}
+
+// Tests that the same ACTION definition works for mock functions with
+// different argument numbers.
+ACTION(PlusTwo) { return arg0 + 2; }
+
+TEST(ActionMacroTest, WorksForDifferentArgumentNumbers) {
+ Action<int(int)> a1 = PlusTwo();
+ EXPECT_EQ(4, a1.Perform(std::make_tuple(2)));
+
+ Action<double(float, void*)> a2 = PlusTwo();
+ int dummy;
+ EXPECT_DOUBLE_EQ(6, a2.Perform(std::make_tuple(4.0f, &dummy)));
+}
+
+// Tests that ACTION_P can define a parameterized action.
+ACTION_P(Plus, n) { return arg0 + n; }
+
+TEST(ActionPMacroTest, DefinesParameterizedAction) {
+ Action<int(int m, bool t)> a1 = Plus(9);
+ EXPECT_EQ(10, a1.Perform(std::make_tuple(1, true)));
+}
+
+// Tests that the body of ACTION_P can reference the argument types
+// and the parameter type.
+ACTION_P(TypedPlus, n) {
+ arg0_type t1 = arg0;
+ n_type t2 = n;
+ return t1 + t2;
+}
+
+TEST(ActionPMacroTest, CanReferenceArgumentAndParameterTypes) {
+ Action<int(char m, bool t)> a1 = TypedPlus(9);
+ EXPECT_EQ(10, a1.Perform(std::make_tuple(Char(1), true)));
+}
+
+// Tests that a parameterized action can be used in any mock function
+// whose type is compatible.
+TEST(ActionPMacroTest, WorksInCompatibleMockFunction) {
+ Action<std::string(const std::string& s)> a1 = Plus("tail");
+ const std::string re = "re";
+ std::tuple<const std::string> dummy = std::make_tuple(re);
+ EXPECT_EQ("retail", a1.Perform(dummy));
+}
+
+// Tests that we can use ACTION*() to define actions overloaded on the
+// number of parameters.
+
+ACTION(OverloadedAction) { return arg0 ? arg1 : "hello"; }
+
+ACTION_P(OverloadedAction, default_value) {
+ return arg0 ? arg1 : default_value;
+}
+
+ACTION_P2(OverloadedAction, true_value, false_value) {
+ return arg0 ? true_value : false_value;
+}
+
+TEST(ActionMacroTest, CanDefineOverloadedActions) {
+ using MyAction = Action<const char*(bool, const char*)>;
+
+ const MyAction a1 = OverloadedAction();
+ EXPECT_STREQ("hello", a1.Perform(std::make_tuple(false, CharPtr("world"))));
+ EXPECT_STREQ("world", a1.Perform(std::make_tuple(true, CharPtr("world"))));
+
+ const MyAction a2 = OverloadedAction("hi");
+ EXPECT_STREQ("hi", a2.Perform(std::make_tuple(false, CharPtr("world"))));
+ EXPECT_STREQ("world", a2.Perform(std::make_tuple(true, CharPtr("world"))));
+
+ const MyAction a3 = OverloadedAction("hi", "you");
+ EXPECT_STREQ("hi", a3.Perform(std::make_tuple(true, CharPtr("world"))));
+ EXPECT_STREQ("you", a3.Perform(std::make_tuple(false, CharPtr("world"))));
+}
+
+// Tests ACTION_Pn where n >= 3.
+
+ACTION_P3(Plus, m, n, k) { return arg0 + m + n + k; }
+
+TEST(ActionPnMacroTest, WorksFor3Parameters) {
+ Action<double(int m, bool t)> a1 = Plus(100, 20, 3.4);
+ EXPECT_DOUBLE_EQ(3123.4, a1.Perform(std::make_tuple(3000, true)));
+
+ Action<std::string(const std::string& s)> a2 = Plus("tail", "-", ">");
+ const std::string re = "re";
+ std::tuple<const std::string> dummy = std::make_tuple(re);
+ EXPECT_EQ("retail->", a2.Perform(dummy));
+}
+
+ACTION_P4(Plus, p0, p1, p2, p3) { return arg0 + p0 + p1 + p2 + p3; }
+
+TEST(ActionPnMacroTest, WorksFor4Parameters) {
+ Action<int(int)> a1 = Plus(1, 2, 3, 4);
+ EXPECT_EQ(10 + 1 + 2 + 3 + 4, a1.Perform(std::make_tuple(10)));
+}
+
+ACTION_P5(Plus, p0, p1, p2, p3, p4) { return arg0 + p0 + p1 + p2 + p3 + p4; }
+
+TEST(ActionPnMacroTest, WorksFor5Parameters) {
+ Action<int(int)> a1 = Plus(1, 2, 3, 4, 5);
+ EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5, a1.Perform(std::make_tuple(10)));
+}
+
+ACTION_P6(Plus, p0, p1, p2, p3, p4, p5) {
+ return arg0 + p0 + p1 + p2 + p3 + p4 + p5;
+}
+
+TEST(ActionPnMacroTest, WorksFor6Parameters) {
+ Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6);
+ EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6, a1.Perform(std::make_tuple(10)));
+}
+
+ACTION_P7(Plus, p0, p1, p2, p3, p4, p5, p6) {
+ return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6;
+}
+
+TEST(ActionPnMacroTest, WorksFor7Parameters) {
+ Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7);
+ EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7, a1.Perform(std::make_tuple(10)));
+}
+
+ACTION_P8(Plus, p0, p1, p2, p3, p4, p5, p6, p7) {
+ return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7;
+}
+
+TEST(ActionPnMacroTest, WorksFor8Parameters) {
+ Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8);
+ EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8,
+ a1.Perform(std::make_tuple(10)));
+}
+
+ACTION_P9(Plus, p0, p1, p2, p3, p4, p5, p6, p7, p8) {
+ return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8;
+}
+
+TEST(ActionPnMacroTest, WorksFor9Parameters) {
+ Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8, 9);
+ EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9,
+ a1.Perform(std::make_tuple(10)));
+}
+
+ACTION_P10(Plus, p0, p1, p2, p3, p4, p5, p6, p7, p8, last_param) {
+ arg0_type t0 = arg0;
+ last_param_type t9 = last_param;
+ return t0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + t9;
+}
+
+TEST(ActionPnMacroTest, WorksFor10Parameters) {
+ Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+ EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10,
+ a1.Perform(std::make_tuple(10)));
+}
+
+// Tests that the action body can promote the parameter types.
+
+ACTION_P2(PadArgument, prefix, suffix) {
+ // The following lines promote the two parameters to desired types.
+ std::string prefix_str(prefix);
+ char suffix_char = static_cast<char>(suffix);
+ return prefix_str + arg0 + suffix_char;
+}
+
+TEST(ActionPnMacroTest, SimpleTypePromotion) {
+ Action<std::string(const char*)> no_promo =
+ PadArgument(std::string("foo"), 'r');
+ Action<std::string(const char*)> promo =
+ PadArgument("foo", static_cast<int>('r'));
+ EXPECT_EQ("foobar", no_promo.Perform(std::make_tuple(CharPtr("ba"))));
+ EXPECT_EQ("foobar", promo.Perform(std::make_tuple(CharPtr("ba"))));
+}
+
+// Tests that we can partially restrict parameter types using a
+// straight-forward pattern.
+
+// Defines a generic action that doesn't restrict the types of its
+// parameters.
+ACTION_P3(ConcatImpl, a, b, c) {
+ std::stringstream ss;
+ ss << a << b << c;
+ return ss.str();
+}
+
+// Next, we try to restrict that either the first parameter is a
+// string, or the second parameter is an int.
+
+// Defines a partially specialized wrapper that restricts the first
+// parameter to std::string.
+template <typename T1, typename T2>
+// ConcatImplActionP3 is the class template ACTION_P3 uses to
+// implement ConcatImpl. We shouldn't change the name as this
+// pattern requires the user to use it directly.
+ConcatImplActionP3<std::string, T1, T2> Concat(const std::string& a, T1 b,
+ T2 c) {
+ GTEST_INTENTIONAL_CONST_COND_PUSH_()
+ if (true) {
+ GTEST_INTENTIONAL_CONST_COND_POP_()
+ // This branch verifies that ConcatImpl() can be invoked without
+ // explicit template arguments.
+ return ConcatImpl(a, b, c);
+ } else {
+ // This branch verifies that ConcatImpl() can also be invoked with
+ // explicit template arguments. It doesn't really need to be
+ // executed as this is a compile-time verification.
+ return ConcatImpl<std::string, T1, T2>(a, b, c);
+ }
+}
+
+// Defines another partially specialized wrapper that restricts the
+// second parameter to int.
+template <typename T1, typename T2>
+ConcatImplActionP3<T1, int, T2> Concat(T1 a, int b, T2 c) {
+ return ConcatImpl(a, b, c);
+}
+
+TEST(ActionPnMacroTest, CanPartiallyRestrictParameterTypes) {
+ Action<const std::string()> a1 = Concat("Hello", "1", 2);
+ EXPECT_EQ("Hello12", a1.Perform(std::make_tuple()));
+
+ a1 = Concat(1, 2, 3);
+ EXPECT_EQ("123", a1.Perform(std::make_tuple()));
+}
+
+// Verifies the type of an ACTION*.
+
+ACTION(DoFoo) {}
+ACTION_P(DoFoo, p) {}
+ACTION_P2(DoFoo, p0, p1) {}
+
+TEST(ActionPnMacroTest, TypesAreCorrect) {
+ // DoFoo() must be assignable to a DoFooAction variable.
+ DoFooAction a0 = DoFoo();
+
+ // DoFoo(1) must be assignable to a DoFooActionP variable.
+ DoFooActionP<int> a1 = DoFoo(1);
+
+ // DoFoo(p1, ..., pk) must be assignable to a DoFooActionPk
+ // variable, and so on.
+ DoFooActionP2<int, char> a2 = DoFoo(1, '2');
+ PlusActionP3<int, int, char> a3 = Plus(1, 2, '3');
+ PlusActionP4<int, int, int, char> a4 = Plus(1, 2, 3, '4');
+ PlusActionP5<int, int, int, int, char> a5 = Plus(1, 2, 3, 4, '5');
+ PlusActionP6<int, int, int, int, int, char> a6 = Plus(1, 2, 3, 4, 5, '6');
+ PlusActionP7<int, int, int, int, int, int, char> a7 =
+ Plus(1, 2, 3, 4, 5, 6, '7');
+ PlusActionP8<int, int, int, int, int, int, int, char> a8 =
+ Plus(1, 2, 3, 4, 5, 6, 7, '8');
+ PlusActionP9<int, int, int, int, int, int, int, int, char> a9 =
+ Plus(1, 2, 3, 4, 5, 6, 7, 8, '9');
+ PlusActionP10<int, int, int, int, int, int, int, int, int, char> a10 =
+ Plus(1, 2, 3, 4, 5, 6, 7, 8, 9, '0');
+
+ // Avoid "unused variable" warnings.
+ (void)a0;
+ (void)a1;
+ (void)a2;
+ (void)a3;
+ (void)a4;
+ (void)a5;
+ (void)a6;
+ (void)a7;
+ (void)a8;
+ (void)a9;
+ (void)a10;
+}
+
+// Tests that an ACTION_P*() action can be explicitly instantiated
+// with reference-typed parameters.
+
+ACTION_P(Plus1, x) { return x; }
+ACTION_P2(Plus2, x, y) { return x + y; }
+ACTION_P3(Plus3, x, y, z) { return x + y + z; }
+ACTION_P10(Plus10, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {
+ return a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9;
+}
+
+TEST(ActionPnMacroTest, CanExplicitlyInstantiateWithReferenceTypes) {
+ int x = 1, y = 2, z = 3;
+ const std::tuple<> empty = std::make_tuple();
+
+ Action<int()> a = Plus1<int&>(x);
+ EXPECT_EQ(1, a.Perform(empty));
+
+ a = Plus2<const int&, int&>(x, y);
+ EXPECT_EQ(3, a.Perform(empty));
+
+ a = Plus3<int&, const int&, int&>(x, y, z);
+ EXPECT_EQ(6, a.Perform(empty));
+
+ int n[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+ a = Plus10<const int&, int&, const int&, int&, const int&, int&, const int&,
+ int&, const int&, int&>(n[0], n[1], n[2], n[3], n[4], n[5], n[6],
+ n[7], n[8], n[9]);
+ EXPECT_EQ(55, a.Perform(empty));
+}
+
+class TenArgConstructorClass {
+ public:
+ TenArgConstructorClass(int a1, int a2, int a3, int a4, int a5, int a6, int a7,
+ int a8, int a9, int a10)
+ : value_(a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10) {}
+ int value_;
+};
+
+// Tests that ACTION_TEMPLATE works when there is no value parameter.
+ACTION_TEMPLATE(CreateNew, HAS_1_TEMPLATE_PARAMS(typename, T),
+ AND_0_VALUE_PARAMS()) {
+ return new T;
+}
+
+TEST(ActionTemplateTest, WorksWithoutValueParam) {
+ const Action<int*()> a = CreateNew<int>();
+ int* p = a.Perform(std::make_tuple());
+ delete p;
+}
+
+// Tests that ACTION_TEMPLATE works when there are value parameters.
+ACTION_TEMPLATE(CreateNew, HAS_1_TEMPLATE_PARAMS(typename, T),
+ AND_1_VALUE_PARAMS(a0)) {
+ return new T(a0);
+}
+
+TEST(ActionTemplateTest, WorksWithValueParams) {
+ const Action<int*()> a = CreateNew<int>(42);
+ int* p = a.Perform(std::make_tuple());
+ EXPECT_EQ(42, *p);
+ delete p;
+}
+
+// Tests that ACTION_TEMPLATE works for integral template parameters.
+ACTION_TEMPLATE(MyDeleteArg, HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_0_VALUE_PARAMS()) {
+ delete std::get<k>(args);
+}
+
+// Resets a bool variable in the destructor.
+class BoolResetter {
+ public:
+ explicit BoolResetter(bool* value) : value_(value) {}
+ ~BoolResetter() { *value_ = false; }
+
+ private:
+ bool* value_;
+};
+
+TEST(ActionTemplateTest, WorksForIntegralTemplateParams) {
+ const Action<void(int*, BoolResetter*)> a = MyDeleteArg<1>();
+ int n = 0;
+ bool b = true;
+ auto* resetter = new BoolResetter(&b);
+ a.Perform(std::make_tuple(&n, resetter));
+ EXPECT_FALSE(b); // Verifies that resetter is deleted.
+}
+
+// Tests that ACTION_TEMPLATES works for template template parameters.
+ACTION_TEMPLATE(ReturnSmartPointer,
+ HAS_1_TEMPLATE_PARAMS(template <typename Pointee> class,
+ Pointer),
+ AND_1_VALUE_PARAMS(pointee)) {
+ return Pointer<pointee_type>(new pointee_type(pointee));
+}
+
+TEST(ActionTemplateTest, WorksForTemplateTemplateParameters) {
+ const Action<std::shared_ptr<int>()> a =
+ ReturnSmartPointer<std::shared_ptr>(42);
+ std::shared_ptr<int> p = a.Perform(std::make_tuple());
+ EXPECT_EQ(42, *p);
+}
+
+// Tests that ACTION_TEMPLATE works for 10 template parameters.
+template <typename T1, typename T2, typename T3, int k4, bool k5,
+ unsigned int k6, typename T7, typename T8, typename T9>
+struct GiantTemplate {
+ public:
+ explicit GiantTemplate(int a_value) : value(a_value) {}
+ int value;
+};
+
+ACTION_TEMPLATE(ReturnGiant,
+ HAS_10_TEMPLATE_PARAMS(typename, T1, typename, T2, typename, T3,
+ int, k4, bool, k5, unsigned int, k6,
+ class, T7, class, T8, class, T9,
+ template <typename T> class, T10),
+ AND_1_VALUE_PARAMS(value)) {
+ return GiantTemplate<T10<T1>, T2, T3, k4, k5, k6, T7, T8, T9>(value);
+}
+
+TEST(ActionTemplateTest, WorksFor10TemplateParameters) {
+ using Giant = GiantTemplate<std::shared_ptr<int>, bool, double, 5, true, 6,
+ char, unsigned, int>;
+ const Action<Giant()> a = ReturnGiant<int, bool, double, 5, true, 6, char,
+ unsigned, int, std::shared_ptr>(42);
+ Giant giant = a.Perform(std::make_tuple());
+ EXPECT_EQ(42, giant.value);
+}
+
+// Tests that ACTION_TEMPLATE works for 10 value parameters.
+ACTION_TEMPLATE(ReturnSum, HAS_1_TEMPLATE_PARAMS(typename, Number),
+ AND_10_VALUE_PARAMS(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10)) {
+ return static_cast<Number>(v1) + v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9 + v10;
+}
+
+TEST(ActionTemplateTest, WorksFor10ValueParameters) {
+ const Action<int()> a = ReturnSum<int>(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+ EXPECT_EQ(55, a.Perform(std::make_tuple()));
+}
+
+// Tests that ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded
+// on the number of value parameters.
+
+ACTION(ReturnSum) { return 0; }
+
+ACTION_P(ReturnSum, x) { return x; }
+
+ACTION_TEMPLATE(ReturnSum, HAS_1_TEMPLATE_PARAMS(typename, Number),
+ AND_2_VALUE_PARAMS(v1, v2)) {
+ return static_cast<Number>(v1) + v2;
+}
+
+ACTION_TEMPLATE(ReturnSum, HAS_1_TEMPLATE_PARAMS(typename, Number),
+ AND_3_VALUE_PARAMS(v1, v2, v3)) {
+ return static_cast<Number>(v1) + v2 + v3;
+}
+
+ACTION_TEMPLATE(ReturnSum, HAS_2_TEMPLATE_PARAMS(typename, Number, int, k),
+ AND_4_VALUE_PARAMS(v1, v2, v3, v4)) {
+ return static_cast<Number>(v1) + v2 + v3 + v4 + k;
+}
+
+TEST(ActionTemplateTest, CanBeOverloadedOnNumberOfValueParameters) {
+ const Action<int()> a0 = ReturnSum();
+ const Action<int()> a1 = ReturnSum(1);
+ const Action<int()> a2 = ReturnSum<int>(1, 2);
+ const Action<int()> a3 = ReturnSum<int>(1, 2, 3);
+ const Action<int()> a4 = ReturnSum<int, 10000>(2000, 300, 40, 5);
+ EXPECT_EQ(0, a0.Perform(std::make_tuple()));
+ EXPECT_EQ(1, a1.Perform(std::make_tuple()));
+ EXPECT_EQ(3, a2.Perform(std::make_tuple()));
+ EXPECT_EQ(6, a3.Perform(std::make_tuple()));
+ EXPECT_EQ(12345, a4.Perform(std::make_tuple()));
+}
+
+} // namespace gmock_more_actions_test
} // namespace testing
diff --git a/googlemock/test/gmock_all_test.cc b/googlemock/test/gmock_all_test.cc
index 6187d4ad..fffbb8b6 100644
--- a/googlemock/test/gmock_all_test.cc
+++ b/googlemock/test/gmock_all_test.cc
@@ -37,7 +37,6 @@
// below list of actual *_test.cc files might change).
#include "test/gmock-actions_test.cc"
#include "test/gmock-cardinalities_test.cc"
-#include "test/gmock-generated-actions_test.cc"
#include "test/gmock-internal-utils_test.cc"
#include "test/gmock-matchers_test.cc"
#include "test/gmock-more-actions_test.cc"
diff --git a/googlemock/test/gmock_generated_actions_nc_test.py b/googlemock/test/gmock_generated_actions_nc_test.py
deleted file mode 100755
index 499a1031..00000000
--- a/googlemock/test/gmock_generated_actions_nc_test.py
+++ /dev/null
@@ -1,137 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2008, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# Google Mock - a framework for writing C++ mock classes.
-#
-# This file drives the negative compilation tests for script-generated
-# Google Mock actions.
-
-"""Driver for the NC tests for script-generated Google Mock actions."""
-
-import os
-import sys
-
-IS_LINUX = os.name == "posix" and os.uname()[0] == "Linux"
-if not IS_LINUX:
- sys.stderr.write(
- "WARNING: Negative compilation tests are not supported on this platform")
- sys.exit(0)
-
-# Suppresses the 'Import not at the top of the file' lint complaint.
-# pylint: disable-msg=C6204
-from google3.testing.pybase import fake_target_util
-from google3.testing.pybase import googletest
-# pylint: enable-msg=C6204
-
-
-class GMockGeneratedActionTest(googletest.TestCase):
- """Negative compilation tests for generated Google Mock actions."""
-
- # The class body is intentionally empty. The actual test*() methods
- # will be defined at run time by a call to
- # DefineNegativeCompilationTests() later.
- pass
-
-# Defines a list of test specs, where each element is a tuple
-# (test name, list of regexes for matching the compiler errors).
-TEST_SPECS = [
- ("NULLARY_WITH_ARGS", [
- r"no matching function for call to 'WithArgs",
- ]),
- ("TOO_FEW_ARGS_FOR_WITH_ARGS", [
- r"no known conversion",
- ]),
- ("TOO_MANY_ARGS_FOR_WITH_ARGS", [
- r"no known conversion",
- ]),
- ("INCOMPATIBLE_ARG_TYPES_FOR_WITH_ARGS", [
- r"no known conversion",
- ]),
- ("WRONG_ARG_TYPE_IN_ACTION_MACRO", [
- r"invalid operands",
- ]),
- (
- "WRONG_RETURN_TYPE_IN_ACTION_MACRO",
- [
- r"invalid conversion", # GCC
- r"cannot initialize return object", # Clang
- ]),
- (
- "EXCESSIVE_ARG_IN_ACTION_MACRO",
- [
- r"no match for 'operator\+'", # GCC
- r"invalid operands to binary expression", # Clang
- ]),
- (
- "ACTION_MACRO_IN_CLASS",
- [
- r"cannot define member function.*Bar.*within.*Foo", # GCC
- r"ACTION\(Bar\)", # Clang
- ]),
- (
- "ACTION_MACRO_IN_FUNCTION",
- [
- r"invalid declaration of member template in local class", # GCC
- r"templates cannot be declared inside of a local class", # Clang
- ]),
- ("SET_ARG_REFEREE_MUST_BE_USED_WITH_REFERENCE",
- [r"Argument must be a reference type"]),
- (
- "DELETE_ARG_MUST_BE_USED_WITH_POINTER",
- [
- r"argument given to 'delete', expected pointer", # GCC
- r"cannot delete expression of type", # Clang
- ]),
- (
- "CANNOT_OVERLOAD_ACTION_TEMPLATE_ON_TEMPLATE_PARAM_NUMBER",
- [
- r"wrong number of template arguments", # GCC
- r"too many template parameters", # Clang
- ]),
- (
- "CANNOT_OVERLOAD_ACTION_AND_ACTION_TEMPLATE_W_SAME_VALUE_PS",
- [
- r"wrong number of template arguments", # GCC
- r"too many template parameters", # Clang
- ]),
- ("SANITY", None),
-]
-
-# Define a test method in GMockGeneratedActionTest for each element in
-# TEST_SPECS.
-fake_target_util.DefineNegativeCompilationTests(
- GMockGeneratedActionTest,
- "google3/third_party/googletest/googlemock/test/gmock-generated-actions_nc", # fake target
- "gmock-generated-actions_nc.o", # object file
- TEST_SPECS)
-
-if __name__ == "__main__":
- googletest.main()
diff --git a/googlemock/test/pump_test.py b/googlemock/test/pump_test.py
deleted file mode 100755
index eb5a1313..00000000
--- a/googlemock/test/pump_test.py
+++ /dev/null
@@ -1,182 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2010, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-"""Tests for the Pump meta-programming tool."""
-
-from google3.testing.pybase import googletest
-import google3.third_party.googletest.googlemock.scripts.pump
-
-pump = google3.third_party.googletest.googlemock.scripts.pump
-Convert = pump.ConvertFromPumpSource
-StripMetaComments = pump.StripMetaComments
-
-
-class PumpTest(googletest.TestCase):
-
- def testConvertsEmptyToEmpty(self):
- self.assertEquals('', Convert('').strip())
-
- def testConvertsPlainCodeToSame(self):
- self.assertEquals('#include <stdio.h>\n',
- Convert('#include <stdio.h>\n'))
-
- def testConvertsLongIWYUPragmaToSame(self):
- long_line = '// IWYU pragma: private, include "' + (80*'a') + '.h"\n'
- self.assertEquals(long_line, Convert(long_line))
-
- def testConvertsIWYUPragmaWithLeadingSpaceToSame(self):
- long_line = ' // IWYU pragma: private, include "' + (80*'a') + '.h"\n'
- self.assertEquals(long_line, Convert(long_line))
-
- def testConvertsIWYUPragmaWithSlashStarLeaderToSame(self):
- long_line = '/* IWYU pragma: private, include "' + (80*'a') + '.h"\n'
- self.assertEquals(long_line, Convert(long_line))
-
- def testConvertsIWYUPragmaWithSlashStarAndSpacesToSame(self):
- long_line = ' /* IWYU pragma: private, include "' + (80*'a') + '.h"\n'
- self.assertEquals(long_line, Convert(long_line))
-
- def testIgnoresMetaComment(self):
- self.assertEquals('',
- Convert('$$ This is a Pump meta comment.\n').strip())
-
- def testSimpleVarDeclarationWorks(self):
- self.assertEquals('3\n',
- Convert('$var m = 3\n'
- '$m\n'))
-
- def testVarDeclarationCanReferenceEarlierVar(self):
- self.assertEquals('43 != 3;\n',
- Convert('$var a = 42\n'
- '$var b = a + 1\n'
- '$var c = (b - a)*3\n'
- '$b != $c;\n'))
-
- def testSimpleLoopWorks(self):
- self.assertEquals('1, 2, 3, 4, 5\n',
- Convert('$var n = 5\n'
- '$range i 1..n\n'
- '$for i, [[$i]]\n'))
-
- def testSimpleLoopWithCommentWorks(self):
- self.assertEquals('1, 2, 3, 4, 5\n',
- Convert('$var n = 5 $$ This is comment 1.\n'
- '$range i 1..n $$ This is comment 2.\n'
- '$for i, [[$i]]\n'))
-
- def testNonTrivialRangeExpressionsWork(self):
- self.assertEquals('1, 2, 3, 4\n',
- Convert('$var n = 5\n'
- '$range i (n/n)..(n - 1)\n'
- '$for i, [[$i]]\n'))
-
- def testLoopWithoutSeparatorWorks(self):
- self.assertEquals('a + 1 + 2 + 3;\n',
- Convert('$range i 1..3\n'
- 'a$for i [[ + $i]];\n'))
-
- def testCanGenerateDollarSign(self):
- self.assertEquals('$\n', Convert('$($)\n'))
-
- def testCanIterpolateExpressions(self):
- self.assertEquals('a[2] = 3;\n',
- Convert('$var i = 1\n'
- 'a[$(i + 1)] = $(i*4 - 1);\n'))
-
- def testConditionalWithoutElseBranchWorks(self):
- self.assertEquals('true\n',
- Convert('$var n = 5\n'
- '$if n > 0 [[true]]\n'))
-
- def testConditionalWithElseBranchWorks(self):
- self.assertEquals('true -- really false\n',
- Convert('$var n = 5\n'
- '$if n > 0 [[true]]\n'
- '$else [[false]] -- \n'
- '$if n > 10 [[really true]]\n'
- '$else [[really false]]\n'))
-
- def testConditionalWithCascadingElseBranchWorks(self):
- self.assertEquals('a\n',
- Convert('$var n = 5\n'
- '$if n > 0 [[a]]\n'
- '$elif n > 10 [[b]]\n'
- '$else [[c]]\n'))
- self.assertEquals('b\n',
- Convert('$var n = 5\n'
- '$if n > 10 [[a]]\n'
- '$elif n > 0 [[b]]\n'
- '$else [[c]]\n'))
- self.assertEquals('c\n',
- Convert('$var n = 5\n'
- '$if n > 10 [[a]]\n'
- '$elif n > 8 [[b]]\n'
- '$else [[c]]\n'))
-
- def testNestedLexicalBlocksWork(self):
- self.assertEquals('a = 5;\n',
- Convert('$var n = 5\n'
- 'a = [[$if n > 0 [[$n]]]];\n'))
-
-
-class StripMetaCommentsTest(googletest.TestCase):
-
- def testReturnsSameStringIfItContainsNoComment(self):
- self.assertEquals('', StripMetaComments(''))
- self.assertEquals(' blah ', StripMetaComments(' blah '))
- self.assertEquals('A single $ is fine.',
- StripMetaComments('A single $ is fine.'))
- self.assertEquals('multiple\nlines',
- StripMetaComments('multiple\nlines'))
-
- def testStripsSimpleComment(self):
- self.assertEquals('yes\n', StripMetaComments('yes $$ or no?\n'))
-
- def testStripsSimpleCommentWithMissingNewline(self):
- self.assertEquals('yes', StripMetaComments('yes $$ or no?'))
-
- def testStripsPureCommentLinesEntirely(self):
- self.assertEquals('yes\n',
- StripMetaComments('$$ a pure comment line.\n'
- 'yes $$ or no?\n'
- ' $$ another comment line.\n'))
-
- def testStripsCommentsFromMultiLineText(self):
- self.assertEquals('multi-\n'
- 'line\n'
- 'text is fine.',
- StripMetaComments('multi- $$ comment 1\n'
- 'line\n'
- 'text is fine. $$ comment 2'))
-
-
-if __name__ == '__main__':
- googletest.main()