diff options
79 files changed, 5463 insertions, 7767 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index f11bbb52..37e7b612 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,12 +10,8 @@ endif (POLICY CMP0048) project(googletest-distribution) set(GOOGLETEST_VERSION 1.10.0) -if (CMAKE_VERSION VERSION_LESS "3.1") - add_definitions(-std=c++11) -else() - set(CMAKE_CXX_STANDARD 11) - set(CMAKE_CXX_STANDARD_REQUIRED ON) - if(NOT CYGWIN) +if (CMAKE_VERSION VERSION_GREATER "3.0.2") + if(NOT CYGWIN AND NOT MSYS) set(CMAKE_CXX_EXTENSIONS OFF) endif() endif() diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4c184992..bd1843eb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -80,7 +80,7 @@ fairly rigid coding style, as defined by the will be expected to conform to the style outlined [here](https://google.github.io/styleguide/cppguide.html). Use [.clang-format](https://github.com/google/googletest/blob/master/.clang-format) -to check your formatting +to check your formatting. ## Requirements for Contributors @@ -102,6 +102,10 @@ runs tests from your binary in parallel to provide significant speed-up. is a VS Code extension allowing to view Google Tests in a tree view, and run/debug your tests. +[Catch2 and Google Test Explorer](https://github.com/matepek/vscode-catch2-test-adapter) +is a VS Code extension allowing to view Google Tests in a tree view, and +run/debug your tests. + [Cornichon](https://pypi.org/project/cornichon/) is a small Gherkin DSL parser that generates stub code for Google Test. diff --git a/appveyor.yml b/appveyor.yml index a58b7687..ec155a76 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -8,6 +8,7 @@ environment: generator: "Visual Studio 15 2017" build_system: cmake APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + enabled_on_pr: yes - compiler: msvc-15-seh generator: "Visual Studio 15 2017 Win64" @@ -28,6 +29,7 @@ environment: - compiler: msvc-14-seh build_system: cmake generator: "Visual Studio 14 2015 Win64" + enabled_on_pr: yes - compiler: gcc-6.3.0-posix build_system: cmake diff --git a/googlemock/CMakeLists.txt b/googlemock/CMakeLists.txt index d32b70b5..8ab59d7f 100644 --- a/googlemock/CMakeLists.txt +++ b/googlemock/CMakeLists.txt @@ -166,7 +166,6 @@ $env:Path = \"$project_bin;$env:Path\" 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-generated-function-mockers_test gmock_main) cxx_test(gmock-generated-matchers_test gmock_main) cxx_test(gmock-internal-utils_test gmock_main) cxx_test(gmock-matchers_test gmock_main) diff --git a/googlemock/cmake/gmock.pc.in b/googlemock/cmake/gmock.pc.in index 2ef0fbca..5780fcaa 100644 --- a/googlemock/cmake/gmock.pc.in +++ b/googlemock/cmake/gmock.pc.in @@ -7,4 +7,4 @@ Version: @PROJECT_VERSION@ URL: https://github.com/google/googletest Requires: gtest Libs: -L${libdir} -lgmock @CMAKE_THREAD_LIBS_INIT@ -Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ @CMAKE_THREAD_LIBS_INIT@ +Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ diff --git a/googlemock/cmake/gmock_main.pc.in b/googlemock/cmake/gmock_main.pc.in index 04658fe2..f2dfe69e 100644 --- a/googlemock/cmake/gmock_main.pc.in +++ b/googlemock/cmake/gmock_main.pc.in @@ -7,4 +7,4 @@ Version: @PROJECT_VERSION@ URL: https://github.com/google/googletest Requires: gmock Libs: -L${libdir} -lgmock_main @CMAKE_THREAD_LIBS_INIT@ -Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ @CMAKE_THREAD_LIBS_INIT@ +Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ diff --git a/googlemock/docs/cheat_sheet.md b/googlemock/docs/cheat_sheet.md index 975362bf..1e0541ba 100644 --- a/googlemock/docs/cheat_sheet.md +++ b/googlemock/docs/cheat_sheet.md @@ -266,7 +266,7 @@ Matcher | Description | `IsTrue()` | `argument` evaluates to `true` in a Boolean context. | | `IsNull()` | `argument` is a `NULL` pointer (raw or smart). | | `NotNull()` | `argument` is a non-null pointer (raw or smart). | -| `Optional(m)` | `argument` is `optional<>` that contains a value matching `m`. | +| `Optional(m)` | `argument` is `optional<>` that contains a value matching `m`. (For testing whether an `optional<>` is set, check for equality with `nullopt`. You may need to use `Eq(nullopt)` if the inner type doesn't have `==`.)| | `VariantWith<T>(m)` | `argument` is `variant<>` that holds the alternative of type T with a value matching `m`. | | `Ref(variable)` | `argument` is a reference to `variable`. | | `TypedEq<type>(value)` | `argument` has type `type` and is equal to `value`. You may need to use this instead of `Eq(value)` when the mock function is overloaded. | @@ -278,6 +278,12 @@ copy constructor, try wrap it in `ByRef()`, e.g. `Eq(ByRef(non_copyable_value))`. If you do that, make sure `non_copyable_value` is not changed afterwards, or the meaning of your matcher will be changed. +`IsTrue` and `IsFalse` are useful when you need to use a matcher, or for types +that can be explicitly converted to Boolean, but are not implicitly converted to +Boolean. In other cases, you can use the basic +[`EXPECT_TRUE` and `EXPECT_FALSE`](../../googletest/docs/primer#basic-assertions) +assertions. + #### Floating-Point Matchers {#FpMatchers} <!-- mdformat off(no multiline tables) --> @@ -483,7 +489,7 @@ which must be a permanent callback. | Matcher | Description | | :----------------------------------- | :------------------------------------ | | `MATCHER(IsEven, "") { return (arg % 2) == 0; }` | Defines a matcher `IsEven()` to match an even number. | -| `MATCHER_P(IsDivisibleBy, n, "") { *result_listener << "where the remainder is " << (arg % n); return (arg % n) == 0; }` | Defines a macher `IsDivisibleBy(n)` to match a number divisible by `n`. | +| `MATCHER_P(IsDivisibleBy, n, "") { *result_listener << "where the remainder is " << (arg % n); return (arg % n) == 0; }` | Defines a matcher `IsDivisibleBy(n)` to match a number divisible by `n`. | | `MATCHER_P2(IsBetween, a, b, std::string(negation ? "isn't" : "is") + " between " + PrintToString(a) + " and " + PrintToString(b)) { return a <= arg && arg <= b; }` | Defines a matcher `IsBetween(a, b)` to match a value in the range [`a`, `b`]. | <!-- mdformat on --> diff --git a/googlemock/docs/cook_book.md b/googlemock/docs/cook_book.md index ea55ab35..51eb94a9 100644 --- a/googlemock/docs/cook_book.md +++ b/googlemock/docs/cook_book.md @@ -421,7 +421,7 @@ sadly they are side effects of C++'s limitations): `NiceMock<StrictMock<MockFoo> >`) is **not** supported. 2. `NiceMock<MockFoo>` and `StrictMock<MockFoo>` may not work correctly if the destructor of `MockFoo` is not virtual. We would like to fix this, but it - requires cleaning up existing tests. http://b/28934720 tracks the issue. + requires cleaning up existing tests. 3. During the constructor or destructor of `MockFoo`, the mock object is *not* nice or strict. This may cause surprises if the constructor or destructor calls a mock method on `this` object. (This behavior, however, is consistent @@ -1024,9 +1024,8 @@ using ::testing::Lt; says that the first argument of `InRange()` must not be 0, and must be less than the second argument. -The expression inside `With()` must be a matcher of type -`Matcher< ::std::tuple<A1, ..., An> >`, where `A1`, ..., `An` are the types of -the function arguments. +The expression inside `With()` must be a matcher of type `Matcher<std::tuple<A1, +..., An>>`, where `A1`, ..., `An` are the types of the function arguments. You can also write `AllArgs(m)` instead of `m` inside `.With()`. The two forms are equivalent, but `.With(AllArgs(Lt()))` is more readable than `.With(Lt())`. @@ -1054,8 +1053,8 @@ complete list. Note that if you want to pass the arguments to a predicate of your own (e.g. `.With(Args<0, 1>(Truly(&MyPredicate)))`), that predicate MUST be written to -take a `::std::tuple` as its argument; gMock will pass the `n` selected -arguments as *one* single tuple to the predicate. +take a `std::tuple` as its argument; gMock will pass the `n` selected arguments +as *one* single tuple to the predicate. ### Using Matchers as Predicates @@ -1331,11 +1330,11 @@ class BarPlusBazEqMatcher : public MatcherInterface<const Foo&> { return (foo.bar() + foo.baz()) == expected_sum_; } - void DescribeTo(::std::ostream* os) const override { + void DescribeTo(std::ostream* os) const override { *os << "bar() + baz() equals " << expected_sum_; } - void DescribeNegationTo(::std::ostream* os) const override { + void DescribeNegationTo(std::ostream* os) const override { *os << "bar() + baz() does not equal " << expected_sum_; } private: @@ -2175,7 +2174,7 @@ own precedence order distinct from the `ON_CALL` precedence order. ### Using Functions/Methods/Functors/Lambdas as Actions {#FunctionsAsActions} If the built-in actions don't suit you, you can use an existing callable -(function, `std::function`, method, functor, lambda as an action. +(function, `std::function`, method, functor, lambda) as an action. <!-- GOOGLETEST_CM0024 DO NOT DELETE --> @@ -2203,7 +2202,8 @@ class Helper { .WillOnce(&CalculateSum) .WillRepeatedly(Invoke(NewPermanentCallback(Sum3, 1))); EXPECT_CALL(foo, ComplexJob(_)) - .WillOnce(Invoke(&helper, &Helper::ComplexJob)); + .WillOnce(Invoke(&helper, &Helper::ComplexJob)) + .WillOnce([] { return true; }) .WillRepeatedly([](int x) { return x > 0; }); foo.Sum(5, 6); // Invokes CalculateSum(5, 6). @@ -2213,11 +2213,11 @@ class Helper { ``` The only requirement is that the type of the function, etc must be *compatible* -with the signature of the mock function, meaning that the latter's arguments can -be implicitly converted to the corresponding arguments of the former, and the -former's return type can be implicitly converted to that of the latter. So, you -can invoke something whose type is *not* exactly the same as the mock function, -as long as it's safe to do so - nice, huh? +with the signature of the mock function, meaning that the latter's arguments (if +it takes any) can be implicitly converted to the corresponding arguments of the +former, and the former's return type can be implicitly converted to that of the +latter. So, you can invoke something whose type is *not* exactly the same as the +mock function, as long as it's safe to do so - nice, huh? **`Note:`{.escaped}** @@ -2268,19 +2268,20 @@ TEST_F(FooTest, Test) { ### Invoking a Function/Method/Functor/Lambda/Callback Without Arguments -`Invoke()` is very useful for doing actions that are more complex. It passes the -mock function's arguments to the function, etc being invoked such that the -callee has the full context of the call to work with. If the invoked function is -not interested in some or all of the arguments, it can simply ignore them. +`Invoke()` passes the mock function's arguments to the function, etc being +invoked such that the callee has the full context of the call to work with. If +the invoked function is not interested in some or all of the arguments, it can +simply ignore them. Yet, a common pattern is that a test author wants to invoke a function without -the arguments of the mock function. `Invoke()` allows her to do that using a -wrapper function that throws away the arguments before invoking an underlining -nullary function. Needless to say, this can be tedious and obscures the intent -of the test. +the arguments of the mock function. She could do that using a wrapper function +that throws away the arguments before invoking an underlining nullary function. +Needless to say, this can be tedious and obscures the intent of the test. -`InvokeWithoutArgs()` solves this problem. It's like `Invoke()` except that it -doesn't pass the mock function's arguments to the callee. Here's an example: +There are two solutions to this problem. First, you can pass any callable of +zero args as an action. Alternatively, use `InvokeWithoutArgs()`, which is like +`Invoke()` except that it doesn't pass the mock function's arguments to the +callee. Here's an example of each: ```cpp using ::testing::_; @@ -2297,7 +2298,7 @@ bool Job2(int n, char c) { ... } ... MockFoo foo; EXPECT_CALL(foo, ComplexJob(_)) - .WillOnce(InvokeWithoutArgs(Job1)) + .WillOnce([] { Job1(); }); .WillOnce(InvokeWithoutArgs(NewPermanentCallback(Job2, 5, 'a'))); foo.ComplexJob(10); // Invokes Job1(). @@ -3565,7 +3566,7 @@ class MatchResultListener { MatchResultListener& operator<<(const T& x); // Returns the underlying ostream. - ::std::ostream* stream(); + std::ostream* stream(); }; template <typename T> @@ -3578,10 +3579,10 @@ class MatcherInterface { virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0; // Describes this matcher to an ostream. - virtual void DescribeTo(::std::ostream* os) const = 0; + virtual void DescribeTo(std::ostream* os) const = 0; // Describes the negation of this matcher to an ostream. - virtual void DescribeNegationTo(::std::ostream* os) const; + virtual void DescribeNegationTo(std::ostream* os) const; }; ``` @@ -3609,11 +3610,11 @@ class DivisibleBy7Matcher : public MatcherInterface<int> { return (n % 7) == 0; } - void DescribeTo(::std::ostream* os) const override { + void DescribeTo(std::ostream* os) const override { *os << "is divisible by 7"; } - void DescribeNegationTo(::std::ostream* os) const override { + void DescribeNegationTo(std::ostream* os) const override { *os << "is not divisible by 7"; } }; @@ -3995,7 +3996,7 @@ ACTION_TEMPLATE(DuplicateArg, // Note the comma between int and k: HAS_2_TEMPLATE_PARAMS(int, k, typename, T), AND_1_VALUE_PARAMS(output)) { - *output = T(::std::get<k>(args)); + *output = T(std::get<k>(args)); } ``` @@ -4087,7 +4088,7 @@ class ActionInterface { // // For example, if F is int(bool, const string&), then Result would - // be int, and ArgumentTuple would be ::std::tuple<bool, const string&>. + // be int, and ArgumentTuple would be std::tuple<bool, const string&>. virtual Result Perform(const ArgumentTuple& args) = 0; }; ``` @@ -4102,8 +4103,8 @@ typedef int IncrementMethod(int*); class IncrementArgumentAction : public ActionInterface<IncrementMethod> { public: - int Perform(const ::std::tuple<int*>& args) override { - int* p = ::std::get<0>(args); // Grabs the first argument. + int Perform(const std::tuple<int*>& args) override { + int* p = std::get<0>(args); // Grabs the first argument. return *p++; } }; @@ -4148,8 +4149,8 @@ class ReturnSecondArgumentAction { public: template <typename Result, typename ArgumentTuple> Result Perform(const ArgumentTuple& args) const { - // To get the i-th (0-based) argument, use ::std::get(args). - return ::std::get<1>(args); + // To get the i-th (0-based) argument, use std::get(args). + return std::get<1>(args); } }; ``` diff --git a/googlemock/docs/for_dummies.md b/googlemock/docs/for_dummies.md index 93cf06f3..327e6cc3 100644 --- a/googlemock/docs/for_dummies.md +++ b/googlemock/docs/for_dummies.md @@ -374,7 +374,7 @@ convenient way of saying "any value". In the above examples, `100` and `50` are also matchers; implicitly, they are the same as `Eq(100)` and `Eq(50)`, which specify that the argument must be equal (using `operator==`) to the matcher argument. There are many -[built-in matchers](#MatcherList) for common types (as well as +[built-in matchers](cheat_sheet.md#MatcherList) for common types (as well as [custom matchers](cook_book.md#NewMatchers)); for example: ```cpp diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h index b040004a..615651b3 100644 --- a/googlemock/include/gmock/gmock-actions.h +++ b/googlemock/include/gmock/gmock-actions.h @@ -30,7 +30,100 @@ // Google Mock - a framework for writing C++ mock classes. // -// This file implements some commonly used actions. +// The ACTION* family of macros can be used in a namespace scope to +// define custom actions easily. The syntax: +// +// ACTION(name) { statements; } +// +// will define an action with the given name that executes the +// statements. The value returned by the statements will be used as +// the return value of the action. Inside the statements, you can +// refer to the K-th (0-based) argument of the mock function by +// 'argK', and refer to its type by 'argK_type'. For example: +// +// ACTION(IncrementArg1) { +// arg1_type temp = arg1; +// return ++(*temp); +// } +// +// allows you to write +// +// ...WillOnce(IncrementArg1()); +// +// You can also refer to the entire argument tuple and its type by +// 'args' and 'args_type', and refer to the mock function type and its +// return type by 'function_type' and 'return_type'. +// +// Note that you don't need to specify the types of the mock function +// arguments. However rest assured that your code is still type-safe: +// you'll get a compiler error if *arg1 doesn't support the ++ +// operator, or if the type of ++(*arg1) isn't compatible with the +// mock function's return type, for example. +// +// Sometimes you'll want to parameterize the action. For that you can use +// another macro: +// +// ACTION_P(name, param_name) { statements; } +// +// For example: +// +// ACTION_P(Add, n) { return arg0 + n; } +// +// will allow you to write: +// +// ...WillOnce(Add(5)); +// +// Note that you don't need to provide the type of the parameter +// either. If you need to reference the type of a parameter named +// 'foo', you can write 'foo_type'. For example, in the body of +// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type +// of 'n'. +// +// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P10 to support +// multi-parameter actions. +// +// For the purpose of typing, you can view +// +// ACTION_Pk(Foo, p1, ..., pk) { ... } +// +// as shorthand for +// +// template <typename p1_type, ..., typename pk_type> +// FooActionPk<p1_type, ..., pk_type> Foo(p1_type p1, ..., pk_type pk) { ... } +// +// In particular, you can provide the template type arguments +// explicitly when invoking Foo(), as in Foo<long, bool>(5, false); +// although usually you can rely on the compiler to infer the types +// for you automatically. You can assign the result of expression +// Foo(p1, ..., pk) to a variable of type FooActionPk<p1_type, ..., +// pk_type>. This can be useful when composing actions. +// +// You can also overload actions with different numbers of parameters: +// +// ACTION_P(Plus, a) { ... } +// ACTION_P2(Plus, a, b) { ... } +// +// While it's tempting to always use the ACTION* macros when defining +// a new action, you should also consider implementing ActionInterface +// or using MakePolymorphicAction() instead, especially if you need to +// use the action a lot. While these approaches require more work, +// they give you more control on the types of the mock function +// arguments and the action parameters, which in general leads to +// better compiler error messages that pay off in the long run. They +// also allow overloading actions based on parameter types (as opposed +// to just based on the number of parameters). +// +// CAVEAT: +// +// ACTION*() can only be used in a namespace scope as templates cannot be +// declared inside of a local class. +// Users can, however, define any local functors (e.g. a lambda) that +// can be used as actions. +// +// MORE INFORMATION: +// +// To learn more about using these macros, please search for 'ACTION' on +// https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md // GOOGLETEST_CM0002 DO NOT DELETE @@ -50,6 +143,7 @@ #include "gmock/internal/gmock-internal-utils.h" #include "gmock/internal/gmock-port.h" +#include "gmock/internal/gmock-pp.h" #ifdef _MSC_VER # pragma warning(push) @@ -162,13 +256,17 @@ GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned int, 0U); GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed int, 0); GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long, 0UL); // NOLINT GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long, 0L); // NOLINT -GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(UInt64, 0); -GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(Int64, 0); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long long, 0); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long long, 0); // NOLINT GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(float, 0); GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(double, 0); #undef GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_ +// Simple two-arg form of std::disjunction. +template <typename P, typename Q> +using disjunction = typename ::std::conditional<P::value, P, Q>::type; + } // namespace internal // When an unexpected function call is encountered, Google Mock will @@ -362,9 +460,15 @@ class Action { // This cannot take std::function directly, because then Action would not be // directly constructible from lambda (it would require two conversions). template <typename G, - typename = typename ::std::enable_if< - ::std::is_constructible<::std::function<F>, G>::value>::type> - Action(G&& fun) : fun_(::std::forward<G>(fun)) {} // NOLINT + typename IsCompatibleFunctor = + ::std::is_constructible<::std::function<F>, G>, + typename IsNoArgsFunctor = + ::std::is_constructible<::std::function<Result()>, G>, + typename = typename ::std::enable_if<internal::disjunction< + IsCompatibleFunctor, IsNoArgsFunctor>::value>::type> + Action(G&& fun) { // NOLINT + Init(::std::forward<G>(fun), IsCompatibleFunctor()); + } // Constructs an Action from its implementation. explicit Action(ActionInterface<F>* impl) @@ -396,6 +500,26 @@ class Action { template <typename G> friend class Action; + template <typename G> + void Init(G&& g, ::std::true_type) { + fun_ = ::std::forward<G>(g); + } + + template <typename G> + void Init(G&& g, ::std::false_type) { + fun_ = IgnoreArgs<typename ::std::decay<G>::type>{::std::forward<G>(g)}; + } + + template <typename FunctionImpl> + struct IgnoreArgs { + template <typename... Args> + Result operator()(const Args&...) const { + return function_impl(); + } + + FunctionImpl function_impl; + }; + // fun_ is an empty function if and only if this is the DoDefault() action. ::std::function<F> fun_; }; @@ -846,7 +970,8 @@ struct InvokeMethodWithoutArgsAction { Class* const obj_ptr; const MethodPtr method_ptr; - using ReturnType = typename std::result_of<MethodPtr(Class*)>::type; + using ReturnType = + decltype((std::declval<Class*>()->*std::declval<MethodPtr>())()); template <typename... Args> ReturnType operator()(const Args&...) const { @@ -916,7 +1041,8 @@ struct WithArgsAction { // We use the conversion operator to detect the signature of the inner Action. template <typename R, typename... Args> operator Action<R(Args...)>() const { // NOLINT - Action<R(typename std::tuple_element<I, std::tuple<Args...>>::type...)> + using TupleType = std::tuple<Args...>; + Action<R(typename std::tuple_element<I, TupleType>::type...)> converted(action); return [converted](Args... args) -> R { @@ -1183,6 +1309,254 @@ inline ::std::reference_wrapper<T> ByRef(T& l_value) { // NOLINT return ::std::reference_wrapper<T>(l_value); } +namespace internal { + +// A macro from the ACTION* family (defined later in gmock-generated-actions.h) +// defines an action that can be used in a mock function. Typically, +// these actions only care about a subset of the arguments of the mock +// function. For example, if such an action only uses the second +// argument, it can be used in any mock function that takes >= 2 +// arguments where the type of the second argument is compatible. +// +// Therefore, the action implementation must be prepared to take more +// arguments than it needs. The ExcessiveArg type is used to +// represent those excessive arguments. In order to keep the compiler +// error messages tractable, we define it in the testing namespace +// instead of testing::internal. However, this is an INTERNAL TYPE +// and subject to change without notice, so a user MUST NOT USE THIS +// TYPE DIRECTLY. +struct ExcessiveArg {}; + +// A helper class needed for implementing the ACTION* macros. +template <typename Result, class Impl> +class ActionHelper { + public: + template <typename... Ts> + static Result Perform(Impl* impl, const std::tuple<Ts...>& args) { + return Apply(impl, args, MakeIndexSequence<sizeof...(Ts)>{}, + MakeIndexSequence<10 - sizeof...(Ts)>{}); + } + + private: + template <typename... Ts, std::size_t... tuple_ids, std::size_t... rest_ids> + static Result Apply(Impl* impl, const std::tuple<Ts...>& args, + IndexSequence<tuple_ids...>, IndexSequence<rest_ids...>) { + return impl->template gmock_PerformImpl<Ts...>( + args, std::get<tuple_ids>(args)..., + ((void)rest_ids, ExcessiveArg())...); + } +}; + +// A helper base class needed for implementing the ACTION* macros. +// Implements constructor and conversion operator for Action. +// +// Template specialization for parameterless Action. +template <typename Derived> +class ActionImpl { + public: + ActionImpl() = default; + + template <typename F> + operator ::testing::Action<F>() const { // NOLINT(runtime/explicit) + return ::testing::Action<F>(new typename Derived::template gmock_Impl<F>()); + } +}; + +// Template specialization for parameterized Action. +template <template <typename...> class Derived, typename... Ts> +class ActionImpl<Derived<Ts...>> { + public: + explicit ActionImpl(Ts... params) : params_(std::forward<Ts>(params)...) {} + + template <typename F> + operator ::testing::Action<F>() const { // NOLINT(runtime/explicit) + return Apply<F>(MakeIndexSequence<sizeof...(Ts)>{}); + } + + private: + template <typename F, std::size_t... tuple_ids> + ::testing::Action<F> Apply(IndexSequence<tuple_ids...>) const { + return ::testing::Action<F>(new + typename Derived<Ts...>::template gmock_Impl<F>( + std::get<tuple_ids>(params_)...)); + } + + std::tuple<Ts...> params_; +}; + +namespace invoke_argument { + +// Appears in InvokeArgumentAdl's argument list to help avoid +// accidental calls to user functions of the same name. +struct AdlTag {}; + +// InvokeArgumentAdl - a helper for InvokeArgument. +// 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 InvokeArgumentAdl(AdlTag, F f, Args... args) -> decltype(f(args...)) { + return f(args...); +} + +} // namespace invoke_argument + +#define GMOCK_INTERNAL_ARG_UNUSED(i, data, el) \ + , const arg##i##_type& arg##i GTEST_ATTRIBUTE_UNUSED_ +#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \ + const args_type& args GTEST_ATTRIBUTE_UNUSED_ GMOCK_PP_REPEAT( \ + GMOCK_INTERNAL_ARG_UNUSED, , 10) + +#define GMOCK_INTERNAL_ARG(i, data, el) , const arg##i##_type& arg##i +#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_ \ + const args_type& args GMOCK_PP_REPEAT(GMOCK_INTERNAL_ARG, , 10) + +#define GMOCK_INTERNAL_TEMPLATE_ARG(i, data, el) , typename arg##i##_type +#define GMOCK_ACTION_TEMPLATE_ARGS_NAMES_ \ + GMOCK_PP_TAIL(GMOCK_PP_REPEAT(GMOCK_INTERNAL_TEMPLATE_ARG, , 10)) + +#define GMOCK_INTERNAL_TYPENAME_PARAM(i, data, param) , typename param##_type +#define GMOCK_ACTION_TYPENAME_PARAMS_(params) \ + GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPENAME_PARAM, , params)) + +#define GMOCK_INTERNAL_TYPE_PARAM(i, data, param) , param##_type +#define GMOCK_ACTION_TYPE_PARAMS_(params) \ + GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPE_PARAM, , params)) + +#define GMOCK_INTERNAL_TYPE_GVALUE_PARAM(i, data, param) \ + , param##_type gmock_p##i +#define GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params) \ + GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPE_GVALUE_PARAM, , params)) + +#define GMOCK_INTERNAL_GVALUE_PARAM(i, data, param) \ + , std::forward<param##_type>(gmock_p##i) +#define GMOCK_ACTION_GVALUE_PARAMS_(params) \ + GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GVALUE_PARAM, , params)) + +#define GMOCK_INTERNAL_INIT_PARAM(i, data, param) \ + , param(::std::forward<param##_type>(gmock_p##i)) +#define GMOCK_ACTION_INIT_PARAMS_(params) \ + GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_INIT_PARAM, , params)) + +#define GMOCK_INTERNAL_FIELD_PARAM(i, data, param) param##_type param; +#define GMOCK_ACTION_FIELD_PARAMS_(params) \ + GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_FIELD_PARAM, , params) + +#define GMOCK_INTERNAL_ACTION(name, full_name, params) \ + template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \ + class full_name : public ::testing::internal::ActionImpl< \ + full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>> { \ + using base_type = ::testing::internal::ActionImpl<full_name>; \ + \ + public: \ + using base_type::base_type; \ + template <typename F> \ + class gmock_Impl : public ::testing::ActionInterface<F> { \ + public: \ + typedef F function_type; \ + typedef typename ::testing::internal::Function<F>::Result return_type; \ + typedef \ + typename ::testing::internal::Function<F>::ArgumentTuple args_type; \ + explicit gmock_Impl(GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) \ + : GMOCK_ACTION_INIT_PARAMS_(params) {} \ + return_type Perform(const args_type& args) override { \ + return ::testing::internal::ActionHelper<return_type, \ + gmock_Impl>::Perform(this, \ + args); \ + } \ + template <GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \ + return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \ + GMOCK_ACTION_FIELD_PARAMS_(params) \ + \ + private: \ + GTEST_DISALLOW_ASSIGN_(gmock_Impl); \ + }; \ + \ + private: \ + GTEST_DISALLOW_ASSIGN_(full_name); \ + }; \ + template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \ + inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \ + GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) { \ + return full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>( \ + GMOCK_ACTION_GVALUE_PARAMS_(params)); \ + } \ + template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \ + template <typename F> \ + template <GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \ + typename ::testing::internal::Function<F>::Result \ + full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>::gmock_Impl< \ + F>::gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) \ + const + +} // namespace internal + +#define ACTION(name) \ + class name##Action : public ::testing::internal::ActionImpl<name##Action> { \ + using base_type = ::testing::internal::ActionImpl<name##Action>; \ + \ + public: \ + using base_type::base_type; \ + template <typename F> \ + class gmock_Impl : public ::testing::ActionInterface<F> { \ + public: \ + typedef F function_type; \ + typedef typename ::testing::internal::Function<F>::Result return_type; \ + typedef \ + typename ::testing::internal::Function<F>::ArgumentTuple args_type; \ + gmock_Impl() {} \ + return_type Perform(const args_type& args) override { \ + return ::testing::internal::ActionHelper<return_type, \ + gmock_Impl>::Perform(this, \ + args); \ + } \ + template <GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \ + return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \ + \ + private: \ + GTEST_DISALLOW_ASSIGN_(gmock_Impl); \ + }; \ + \ + private: \ + GTEST_DISALLOW_ASSIGN_(name##Action); \ + }; \ + inline name##Action name() { return name##Action(); } \ + template <typename F> \ + template <GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \ + typename ::testing::internal::Function<F>::Result \ + name##Action::gmock_Impl<F>::gmock_PerformImpl( \ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P(name, ...) \ + GMOCK_INTERNAL_ACTION(name, name##ActionP, (__VA_ARGS__)) + +#define ACTION_P2(name, ...) \ + GMOCK_INTERNAL_ACTION(name, name##ActionP2, (__VA_ARGS__)) + +#define ACTION_P3(name, ...) \ + GMOCK_INTERNAL_ACTION(name, name##ActionP3, (__VA_ARGS__)) + +#define ACTION_P4(name, ...) \ + GMOCK_INTERNAL_ACTION(name, name##ActionP4, (__VA_ARGS__)) + +#define ACTION_P5(name, ...) \ + GMOCK_INTERNAL_ACTION(name, name##ActionP5, (__VA_ARGS__)) + +#define ACTION_P6(name, ...) \ + GMOCK_INTERNAL_ACTION(name, name##ActionP6, (__VA_ARGS__)) + +#define ACTION_P7(name, ...) \ + GMOCK_INTERNAL_ACTION(name, name##ActionP7, (__VA_ARGS__)) + +#define ACTION_P8(name, ...) \ + GMOCK_INTERNAL_ACTION(name, name##ActionP8, (__VA_ARGS__)) + +#define ACTION_P9(name, ...) \ + GMOCK_INTERNAL_ACTION(name, name##ActionP9, (__VA_ARGS__)) + +#define ACTION_P10(name, ...) \ + GMOCK_INTERNAL_ACTION(name, name##ActionP10, (__VA_ARGS__)) + } // namespace testing #ifdef _MSC_VER diff --git a/googlemock/include/gmock/gmock-function-mocker.h b/googlemock/include/gmock/gmock-function-mocker.h index c5291412..317d6c2b 100644 --- a/googlemock/include/gmock/gmock-function-mocker.h +++ b/googlemock/include/gmock/gmock-function-mocker.h @@ -36,14 +36,36 @@ #ifndef THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT #define THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT -#include "gmock/gmock-generated-function-mockers.h" // NOLINT +#include <type_traits> // IWYU pragma: keep +#include <utility> // IWYU pragma: keep + +#include "gmock/gmock-spec-builders.h" +#include "gmock/internal/gmock-internal-utils.h" #include "gmock/internal/gmock-pp.h" namespace testing { namespace internal { template <typename T> using identity_t = T; + +template <typename MockType> +const MockType* AdjustConstness_const(const MockType* mock) { + return mock; +} + +template <typename MockType> +MockType* AdjustConstness_(const MockType* mock) { + return const_cast<MockType*>(mock); +} + } // namespace internal + +// The style guide prohibits "using" statements in a namespace scope +// inside a header file. However, the FunctionMocker class template +// is meant to be defined in the ::testing namespace. The following +// line is just a trick for working around a bug in MSVC 8.0, which +// cannot handle it if we define FunctionMocker in ::testing. +using internal::FunctionMocker; } // namespace testing #define MOCK_METHOD(...) \ @@ -241,36 +263,196 @@ using identity_t = T; GMOCK_PP_IDENTITY) \ (_elem) -#define GMOCK_INTERNAL_PARAMETER(_i, _Signature, _) \ - GMOCK_PP_COMMA_IF(_i) \ - GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \ - GMOCK_PP_REMOVE_PARENS(_Signature)) \ +#define GMOCK_INTERNAL_PARAMETER(_i, _Signature, _) \ + GMOCK_PP_COMMA_IF(_i) \ + GMOCK_INTERNAL_ARG_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature)) \ gmock_a##_i -#define GMOCK_INTERNAL_FORWARD_ARG(_i, _Signature, _) \ - GMOCK_PP_COMMA_IF(_i) \ - ::std::forward<GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \ - GMOCK_PP_REMOVE_PARENS(_Signature))>( \ - gmock_a##_i) +#define GMOCK_INTERNAL_FORWARD_ARG(_i, _Signature, _) \ + GMOCK_PP_COMMA_IF(_i) \ + ::std::forward<GMOCK_INTERNAL_ARG_O( \ + _i, GMOCK_PP_REMOVE_PARENS(_Signature))>(gmock_a##_i) -#define GMOCK_INTERNAL_MATCHER_PARAMETER(_i, _Signature, _) \ - GMOCK_PP_COMMA_IF(_i) \ - GMOCK_INTERNAL_MATCHER_O(typename, GMOCK_PP_INC(_i), \ - GMOCK_PP_REMOVE_PARENS(_Signature)) \ +#define GMOCK_INTERNAL_MATCHER_PARAMETER(_i, _Signature, _) \ + GMOCK_PP_COMMA_IF(_i) \ + GMOCK_INTERNAL_MATCHER_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature)) \ gmock_a##_i #define GMOCK_INTERNAL_MATCHER_ARGUMENT(_i, _1, _2) \ GMOCK_PP_COMMA_IF(_i) \ gmock_a##_i -#define GMOCK_INTERNAL_A_MATCHER_ARGUMENT(_i, _Signature, _) \ - GMOCK_PP_COMMA_IF(_i) \ - ::testing::A<GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \ - GMOCK_PP_REMOVE_PARENS(_Signature))>() - -#define GMOCK_INTERNAL_ARG_O(_tn, _i, ...) GMOCK_ARG_(_tn, _i, __VA_ARGS__) - -#define GMOCK_INTERNAL_MATCHER_O(_tn, _i, ...) \ - GMOCK_MATCHER_(_tn, _i, __VA_ARGS__) +#define GMOCK_INTERNAL_A_MATCHER_ARGUMENT(_i, _Signature, _) \ + GMOCK_PP_COMMA_IF(_i) \ + ::testing::A<GMOCK_INTERNAL_ARG_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature))>() + +#define GMOCK_INTERNAL_ARG_O(_i, ...) \ + typename ::testing::internal::Function<__VA_ARGS__>::template Arg<_i>::type + +#define GMOCK_INTERNAL_MATCHER_O(_i, ...) \ + const ::testing::Matcher<typename ::testing::internal::Function< \ + __VA_ARGS__>::template Arg<_i>::type>& + +#define MOCK_METHOD0(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 0, __VA_ARGS__) +#define MOCK_METHOD1(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 1, __VA_ARGS__) +#define MOCK_METHOD2(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 2, __VA_ARGS__) +#define MOCK_METHOD3(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 3, __VA_ARGS__) +#define MOCK_METHOD4(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 4, __VA_ARGS__) +#define MOCK_METHOD5(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 5, __VA_ARGS__) +#define MOCK_METHOD6(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 6, __VA_ARGS__) +#define MOCK_METHOD7(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 7, __VA_ARGS__) +#define MOCK_METHOD8(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 8, __VA_ARGS__) +#define MOCK_METHOD9(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 9, __VA_ARGS__) +#define MOCK_METHOD10(m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(, , m, 10, __VA_ARGS__) + +#define MOCK_CONST_METHOD0(m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, , m, 0, __VA_ARGS__) +#define MOCK_CONST_METHOD1(m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, , m, 1, __VA_ARGS__) +#define MOCK_CONST_METHOD2(m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, , m, 2, __VA_ARGS__) +#define MOCK_CONST_METHOD3(m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, , m, 3, __VA_ARGS__) +#define MOCK_CONST_METHOD4(m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, , m, 4, __VA_ARGS__) +#define MOCK_CONST_METHOD5(m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, , m, 5, __VA_ARGS__) +#define MOCK_CONST_METHOD6(m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, , m, 6, __VA_ARGS__) +#define MOCK_CONST_METHOD7(m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, , m, 7, __VA_ARGS__) +#define MOCK_CONST_METHOD8(m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, , m, 8, __VA_ARGS__) +#define MOCK_CONST_METHOD9(m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, , m, 9, __VA_ARGS__) +#define MOCK_CONST_METHOD10(m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, , m, 10, __VA_ARGS__) + +#define MOCK_METHOD0_T(m, ...) MOCK_METHOD0(m, __VA_ARGS__) +#define MOCK_METHOD1_T(m, ...) MOCK_METHOD1(m, __VA_ARGS__) +#define MOCK_METHOD2_T(m, ...) MOCK_METHOD2(m, __VA_ARGS__) +#define MOCK_METHOD3_T(m, ...) MOCK_METHOD3(m, __VA_ARGS__) +#define MOCK_METHOD4_T(m, ...) MOCK_METHOD4(m, __VA_ARGS__) +#define MOCK_METHOD5_T(m, ...) MOCK_METHOD5(m, __VA_ARGS__) +#define MOCK_METHOD6_T(m, ...) MOCK_METHOD6(m, __VA_ARGS__) +#define MOCK_METHOD7_T(m, ...) MOCK_METHOD7(m, __VA_ARGS__) +#define MOCK_METHOD8_T(m, ...) MOCK_METHOD8(m, __VA_ARGS__) +#define MOCK_METHOD9_T(m, ...) MOCK_METHOD9(m, __VA_ARGS__) +#define MOCK_METHOD10_T(m, ...) MOCK_METHOD10(m, __VA_ARGS__) + +#define MOCK_CONST_METHOD0_T(m, ...) MOCK_CONST_METHOD0(m, __VA_ARGS__) +#define MOCK_CONST_METHOD1_T(m, ...) MOCK_CONST_METHOD1(m, __VA_ARGS__) +#define MOCK_CONST_METHOD2_T(m, ...) MOCK_CONST_METHOD2(m, __VA_ARGS__) +#define MOCK_CONST_METHOD3_T(m, ...) MOCK_CONST_METHOD3(m, __VA_ARGS__) +#define MOCK_CONST_METHOD4_T(m, ...) MOCK_CONST_METHOD4(m, __VA_ARGS__) +#define MOCK_CONST_METHOD5_T(m, ...) MOCK_CONST_METHOD5(m, __VA_ARGS__) +#define MOCK_CONST_METHOD6_T(m, ...) MOCK_CONST_METHOD6(m, __VA_ARGS__) +#define MOCK_CONST_METHOD7_T(m, ...) MOCK_CONST_METHOD7(m, __VA_ARGS__) +#define MOCK_CONST_METHOD8_T(m, ...) MOCK_CONST_METHOD8(m, __VA_ARGS__) +#define MOCK_CONST_METHOD9_T(m, ...) MOCK_CONST_METHOD9(m, __VA_ARGS__) +#define MOCK_CONST_METHOD10_T(m, ...) MOCK_CONST_METHOD10(m, __VA_ARGS__) + +#define MOCK_METHOD0_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 0, __VA_ARGS__) +#define MOCK_METHOD1_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 1, __VA_ARGS__) +#define MOCK_METHOD2_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 2, __VA_ARGS__) +#define MOCK_METHOD3_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 3, __VA_ARGS__) +#define MOCK_METHOD4_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 4, __VA_ARGS__) +#define MOCK_METHOD5_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 5, __VA_ARGS__) +#define MOCK_METHOD6_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 6, __VA_ARGS__) +#define MOCK_METHOD7_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 7, __VA_ARGS__) +#define MOCK_METHOD8_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 8, __VA_ARGS__) +#define MOCK_METHOD9_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 9, __VA_ARGS__) +#define MOCK_METHOD10_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 10, __VA_ARGS__) + +#define MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 0, __VA_ARGS__) +#define MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 1, __VA_ARGS__) +#define MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 2, __VA_ARGS__) +#define MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 3, __VA_ARGS__) +#define MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 4, __VA_ARGS__) +#define MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 5, __VA_ARGS__) +#define MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 6, __VA_ARGS__) +#define MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 7, __VA_ARGS__) +#define MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 8, __VA_ARGS__) +#define MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 9, __VA_ARGS__) +#define MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 10, __VA_ARGS__) + +#define MOCK_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_METHOD0_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_METHOD1_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_METHOD2_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_METHOD3_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_METHOD4_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_METHOD5_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_METHOD6_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_METHOD7_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_METHOD8_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_METHOD9_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_METHOD10_WITH_CALLTYPE(ct, m, __VA_ARGS__) + +#define MOCK_CONST_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, __VA_ARGS__) + +#define GMOCK_INTERNAL_MOCK_METHODN(constness, ct, Method, args_num, ...) \ + GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE( \ + args_num, ::testing::internal::identity_t<__VA_ARGS__>); \ + GMOCK_INTERNAL_MOCK_METHOD_IMPL( \ + args_num, Method, GMOCK_PP_NARG0(constness), 0, 0, , ct, \ + (::testing::internal::identity_t<__VA_ARGS__>)) + +#define GMOCK_MOCKER_(arity, constness, Method) \ + GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__) #endif // THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ diff --git a/googlemock/include/gmock/gmock-generated-actions.h b/googlemock/include/gmock/gmock-generated-actions.h index cee96dae..c78debef 100644 --- a/googlemock/include/gmock/gmock-generated-actions.h +++ b/googlemock/include/gmock/gmock-generated-actions.h @@ -47,241 +47,6 @@ #include "gmock/gmock-actions.h" #include "gmock/internal/gmock-port.h" -namespace testing { -namespace internal { - -// A macro from the ACTION* family (defined later in this file) -// defines an action that can be used in a mock function. Typically, -// these actions only care about a subset of the arguments of the mock -// function. For example, if such an action only uses the second -// argument, it can be used in any mock function that takes >= 2 -// arguments where the type of the second argument is compatible. -// -// Therefore, the action implementation must be prepared to take more -// arguments than it needs. The ExcessiveArg type is used to -// represent those excessive arguments. In order to keep the compiler -// error messages tractable, we define it in the testing namespace -// instead of testing::internal. However, this is an INTERNAL TYPE -// and subject to change without notice, so a user MUST NOT USE THIS -// TYPE DIRECTLY. -struct ExcessiveArg {}; - -// A helper class needed for implementing the ACTION* macros. -template <typename Result, class Impl> -class ActionHelper { - public: - static Result Perform(Impl* impl, const ::std::tuple<>& args) { - return impl->template gmock_PerformImpl<>(args, ExcessiveArg(), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg()); - } - - template <typename A0> - static Result Perform(Impl* impl, const ::std::tuple<A0>& args) { - return impl->template gmock_PerformImpl<A0>(args, std::get<0>(args), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg()); - } - - template <typename A0, typename A1> - static Result Perform(Impl* impl, const ::std::tuple<A0, A1>& args) { - return impl->template gmock_PerformImpl<A0, A1>(args, std::get<0>(args), - std::get<1>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg()); - } - - template <typename A0, typename A1, typename A2> - static Result Perform(Impl* impl, const ::std::tuple<A0, A1, A2>& args) { - return impl->template gmock_PerformImpl<A0, A1, A2>(args, - std::get<0>(args), std::get<1>(args), std::get<2>(args), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg()); - } - - template <typename A0, typename A1, typename A2, typename A3> - static Result Perform(Impl* impl, const ::std::tuple<A0, A1, A2, A3>& args) { - return impl->template gmock_PerformImpl<A0, A1, A2, A3>(args, - std::get<0>(args), std::get<1>(args), std::get<2>(args), - std::get<3>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg()); - } - - template <typename A0, typename A1, typename A2, typename A3, typename A4> - static Result Perform(Impl* impl, const ::std::tuple<A0, A1, A2, A3, - A4>& args) { - return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4>(args, - std::get<0>(args), std::get<1>(args), std::get<2>(args), - std::get<3>(args), std::get<4>(args), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg()); - } - - template <typename A0, typename A1, typename A2, typename A3, typename A4, - typename A5> - static Result Perform(Impl* impl, const ::std::tuple<A0, A1, A2, A3, A4, - A5>& args) { - return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5>(args, - std::get<0>(args), std::get<1>(args), std::get<2>(args), - std::get<3>(args), std::get<4>(args), std::get<5>(args), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg()); - } - - template <typename A0, typename A1, typename A2, typename A3, typename A4, - typename A5, typename A6> - static Result Perform(Impl* impl, const ::std::tuple<A0, A1, A2, A3, A4, A5, - A6>& args) { - return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5, A6>(args, - std::get<0>(args), std::get<1>(args), std::get<2>(args), - std::get<3>(args), std::get<4>(args), std::get<5>(args), - std::get<6>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg()); - } - - template <typename A0, typename A1, typename A2, typename A3, typename A4, - typename A5, typename A6, typename A7> - static Result Perform(Impl* impl, const ::std::tuple<A0, A1, A2, A3, A4, A5, - A6, A7>& args) { - return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5, A6, - A7>(args, std::get<0>(args), std::get<1>(args), std::get<2>(args), - std::get<3>(args), std::get<4>(args), std::get<5>(args), - std::get<6>(args), std::get<7>(args), ExcessiveArg(), ExcessiveArg()); - } - - template <typename A0, typename A1, typename A2, typename A3, typename A4, - typename A5, typename A6, typename A7, typename A8> - static Result Perform(Impl* impl, const ::std::tuple<A0, A1, A2, A3, A4, A5, - A6, A7, A8>& args) { - return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5, A6, A7, - A8>(args, std::get<0>(args), std::get<1>(args), std::get<2>(args), - std::get<3>(args), std::get<4>(args), std::get<5>(args), - std::get<6>(args), std::get<7>(args), std::get<8>(args), - ExcessiveArg()); - } - - template <typename A0, typename A1, typename A2, typename A3, typename A4, - typename A5, typename A6, typename A7, typename A8, typename A9> - static Result Perform(Impl* impl, const ::std::tuple<A0, A1, A2, A3, A4, A5, - A6, A7, A8, A9>& args) { - return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5, A6, A7, A8, - A9>(args, std::get<0>(args), std::get<1>(args), std::get<2>(args), - std::get<3>(args), std::get<4>(args), std::get<5>(args), - std::get<6>(args), std::get<7>(args), std::get<8>(args), - std::get<9>(args)); - } -}; - -} // namespace internal -} // namespace testing - -// The ACTION* family of macros can be used in a namespace scope to -// define custom actions easily. The syntax: -// -// ACTION(name) { statements; } -// -// will define an action with the given name that executes the -// statements. The value returned by the statements will be used as -// the return value of the action. Inside the statements, you can -// refer to the K-th (0-based) argument of the mock function by -// 'argK', and refer to its type by 'argK_type'. For example: -// -// ACTION(IncrementArg1) { -// arg1_type temp = arg1; -// return ++(*temp); -// } -// -// allows you to write -// -// ...WillOnce(IncrementArg1()); -// -// You can also refer to the entire argument tuple and its type by -// 'args' and 'args_type', and refer to the mock function type and its -// return type by 'function_type' and 'return_type'. -// -// Note that you don't need to specify the types of the mock function -// arguments. However rest assured that your code is still type-safe: -// you'll get a compiler error if *arg1 doesn't support the ++ -// operator, or if the type of ++(*arg1) isn't compatible with the -// mock function's return type, for example. -// -// Sometimes you'll want to parameterize the action. For that you can use -// another macro: -// -// ACTION_P(name, param_name) { statements; } -// -// For example: -// -// ACTION_P(Add, n) { return arg0 + n; } -// -// will allow you to write: -// -// ...WillOnce(Add(5)); -// -// Note that you don't need to provide the type of the parameter -// either. If you need to reference the type of a parameter named -// 'foo', you can write 'foo_type'. For example, in the body of -// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type -// of 'n'. -// -// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P10 to support -// multi-parameter actions. -// -// For the purpose of typing, you can view -// -// ACTION_Pk(Foo, p1, ..., pk) { ... } -// -// as shorthand for -// -// template <typename p1_type, ..., typename pk_type> -// FooActionPk<p1_type, ..., pk_type> Foo(p1_type p1, ..., pk_type pk) { ... } -// -// In particular, you can provide the template type arguments -// explicitly when invoking Foo(), as in Foo<long, bool>(5, false); -// although usually you can rely on the compiler to infer the types -// for you automatically. You can assign the result of expression -// Foo(p1, ..., pk) to a variable of type FooActionPk<p1_type, ..., -// pk_type>. This can be useful when composing actions. -// -// You can also overload actions with different numbers of parameters: -// -// ACTION_P(Plus, a) { ... } -// ACTION_P2(Plus, a, b) { ... } -// -// While it's tempting to always use the ACTION* macros when defining -// a new action, you should also consider implementing ActionInterface -// or using MakePolymorphicAction() instead, especially if you need to -// use the action a lot. While these approaches require more work, -// they give you more control on the types of the mock function -// arguments and the action parameters, which in general leads to -// better compiler error messages that pay off in the long run. They -// also allow overloading actions based on parameter types (as opposed -// to just based on the number of parameters). -// -// CAVEAT: -// -// ACTION*() can only be used in a namespace scope as templates cannot be -// declared inside of a local class. -// Users can, however, define any local functors (e.g. a lambda) that -// can be used as actions. -// -// MORE INFORMATION: -// -// To learn more about using these macros, please search for 'ACTION' on -// https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md - -// An internal macro needed for implementing ACTION*(). -#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\ - const args_type& args GTEST_ATTRIBUTE_UNUSED_, \ - const arg0_type& arg0 GTEST_ATTRIBUTE_UNUSED_, \ - const arg1_type& arg1 GTEST_ATTRIBUTE_UNUSED_, \ - const arg2_type& arg2 GTEST_ATTRIBUTE_UNUSED_, \ - const arg3_type& arg3 GTEST_ATTRIBUTE_UNUSED_, \ - const arg4_type& arg4 GTEST_ATTRIBUTE_UNUSED_, \ - const arg5_type& arg5 GTEST_ATTRIBUTE_UNUSED_, \ - const arg6_type& arg6 GTEST_ATTRIBUTE_UNUSED_, \ - const arg7_type& arg7 GTEST_ATTRIBUTE_UNUSED_, \ - const arg8_type& arg8 GTEST_ATTRIBUTE_UNUSED_, \ - const arg9_type& arg9 GTEST_ATTRIBUTE_UNUSED_ // Sometimes you want to give an action explicit template parameters // that cannot be inferred from its value parameters. ACTION() and @@ -667,16 +432,8 @@ class ActionHelper { return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ Perform(this, args);\ }\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - return_type gmock_PerformImpl(const args_type& args, \ - const arg0_type& arg0, const arg1_type& arg1, \ - const arg2_type& arg2, const arg3_type& arg3, \ - const arg4_type& arg4, const arg5_type& arg5, \ - const arg6_type& arg6, const arg7_type& arg7, \ - const arg8_type& arg8, const arg9_type& arg9) const;\ + template <GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>\ + return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const;\ GMOCK_INTERNAL_DEFN_##value_params\ private:\ GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ @@ -703,10 +460,7 @@ class ActionHelper { template <GMOCK_INTERNAL_DECL_##template_params\ GMOCK_INTERNAL_DECL_TYPE_##value_params>\ template <typename F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ + template <GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>\ typename ::testing::internal::Function<F>::Result\ GMOCK_ACTION_CLASS_(name, value_params)<\ GMOCK_INTERNAL_LIST_##template_params\ @@ -714,876 +468,6 @@ class ActionHelper { gmock_PerformImpl(\ GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const -#define ACTION(name)\ - class name##Action {\ - public:\ - name##Action() {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - gmock_Impl() {}\ - return_type Perform(const args_type& args) override {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - return_type gmock_PerformImpl(const args_type& args, \ - const arg0_type& arg0, const arg1_type& arg1, \ - const arg2_type& arg2, const arg3_type& arg3, \ - const arg4_type& arg4, const arg5_type& arg5, \ - const arg6_type& arg6, const arg7_type& arg7, \ - const arg8_type& arg8, const arg9_type& arg9) const;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(new gmock_Impl<F>());\ - }\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##Action);\ - };\ - inline name##Action name() {\ - return name##Action();\ - }\ - template <typename F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - typename ::testing::internal::Function<F>::Result\ - name##Action::gmock_Impl<F>::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P(name, p0)\ - template <typename p0##_type>\ - class name##ActionP {\ - public:\ - explicit name##ActionP(p0##_type gmock_p0) : \ - p0(::std::forward<p0##_type>(gmock_p0)) {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - explicit gmock_Impl(p0##_type gmock_p0) : \ - p0(::std::forward<p0##_type>(gmock_p0)) {}\ - return_type Perform(const args_type& args) override {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - return_type gmock_PerformImpl(const args_type& args, \ - const arg0_type& arg0, const arg1_type& arg1, \ - const arg2_type& arg2, const arg3_type& arg3, \ - const arg4_type& arg4, const arg5_type& arg5, \ - const arg6_type& arg6, const arg7_type& arg7, \ - const arg8_type& arg8, const arg9_type& arg9) const;\ - p0##_type p0;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(new gmock_Impl<F>(p0));\ - }\ - p0##_type p0;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP);\ - };\ - template <typename p0##_type>\ - inline name##ActionP<p0##_type> name(p0##_type p0) {\ - return name##ActionP<p0##_type>(p0);\ - }\ - template <typename p0##_type>\ - template <typename F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - typename ::testing::internal::Function<F>::Result\ - name##ActionP<p0##_type>::gmock_Impl<F>::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P2(name, p0, p1)\ - template <typename p0##_type, typename p1##_type>\ - class name##ActionP2 {\ - public:\ - name##ActionP2(p0##_type gmock_p0, \ - p1##_type gmock_p1) : p0(::std::forward<p0##_type>(gmock_p0)), \ - p1(::std::forward<p1##_type>(gmock_p1)) {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - gmock_Impl(p0##_type gmock_p0, \ - p1##_type gmock_p1) : p0(::std::forward<p0##_type>(gmock_p0)), \ - p1(::std::forward<p1##_type>(gmock_p1)) {}\ - return_type Perform(const args_type& args) override {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - return_type gmock_PerformImpl(const args_type& args, \ - const arg0_type& arg0, const arg1_type& arg1, \ - const arg2_type& arg2, const arg3_type& arg3, \ - const arg4_type& arg4, const arg5_type& arg5, \ - const arg6_type& arg6, const arg7_type& arg7, \ - const arg8_type& arg8, const arg9_type& arg9) const;\ - p0##_type p0;\ - p1##_type p1;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(new gmock_Impl<F>(p0, p1));\ - }\ - p0##_type p0;\ - p1##_type p1;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP2);\ - };\ - template <typename p0##_type, typename p1##_type>\ - inline name##ActionP2<p0##_type, p1##_type> name(p0##_type p0, \ - p1##_type p1) {\ - return name##ActionP2<p0##_type, p1##_type>(p0, p1);\ - }\ - template <typename p0##_type, typename p1##_type>\ - template <typename F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - typename ::testing::internal::Function<F>::Result\ - name##ActionP2<p0##_type, p1##_type>::gmock_Impl<F>::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P3(name, p0, p1, p2)\ - template <typename p0##_type, typename p1##_type, typename p2##_type>\ - class name##ActionP3 {\ - public:\ - name##ActionP3(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2) : p0(::std::forward<p0##_type>(gmock_p0)), \ - p1(::std::forward<p1##_type>(gmock_p1)), \ - p2(::std::forward<p2##_type>(gmock_p2)) {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2) : p0(::std::forward<p0##_type>(gmock_p0)), \ - p1(::std::forward<p1##_type>(gmock_p1)), \ - p2(::std::forward<p2##_type>(gmock_p2)) {}\ - return_type Perform(const args_type& args) override {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - return_type gmock_PerformImpl(const args_type& args, \ - const arg0_type& arg0, const arg1_type& arg1, \ - const arg2_type& arg2, const arg3_type& arg3, \ - const arg4_type& arg4, const arg5_type& arg5, \ - const arg6_type& arg6, const arg7_type& arg7, \ - const arg8_type& arg8, const arg9_type& arg9) const;\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2));\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP3);\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type>\ - inline name##ActionP3<p0##_type, p1##_type, p2##_type> name(p0##_type p0, \ - p1##_type p1, p2##_type p2) {\ - return name##ActionP3<p0##_type, p1##_type, p2##_type>(p0, p1, p2);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type>\ - template <typename F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - typename ::testing::internal::Function<F>::Result\ - name##ActionP3<p0##_type, p1##_type, \ - p2##_type>::gmock_Impl<F>::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P4(name, p0, p1, p2, p3)\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type>\ - class name##ActionP4 {\ - public:\ - name##ActionP4(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, \ - p3##_type gmock_p3) : p0(::std::forward<p0##_type>(gmock_p0)), \ - p1(::std::forward<p1##_type>(gmock_p1)), \ - p2(::std::forward<p2##_type>(gmock_p2)), \ - p3(::std::forward<p3##_type>(gmock_p3)) {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3) : p0(::std::forward<p0##_type>(gmock_p0)), \ - p1(::std::forward<p1##_type>(gmock_p1)), \ - p2(::std::forward<p2##_type>(gmock_p2)), \ - p3(::std::forward<p3##_type>(gmock_p3)) {}\ - return_type Perform(const args_type& args) override {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - return_type gmock_PerformImpl(const args_type& args, \ - const arg0_type& arg0, const arg1_type& arg1, \ - const arg2_type& arg2, const arg3_type& arg3, \ - const arg4_type& arg4, const arg5_type& arg5, \ - const arg6_type& arg6, const arg7_type& arg7, \ - const arg8_type& arg8, const arg9_type& arg9) const;\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2, p3));\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP4);\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type>\ - inline name##ActionP4<p0##_type, p1##_type, p2##_type, \ - p3##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, \ - p3##_type p3) {\ - return name##ActionP4<p0##_type, p1##_type, p2##_type, p3##_type>(p0, p1, \ - p2, p3);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type>\ - template <typename F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - typename ::testing::internal::Function<F>::Result\ - name##ActionP4<p0##_type, p1##_type, p2##_type, \ - p3##_type>::gmock_Impl<F>::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P5(name, p0, p1, p2, p3, p4)\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type>\ - class name##ActionP5 {\ - public:\ - name##ActionP5(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, \ - p4##_type gmock_p4) : p0(::std::forward<p0##_type>(gmock_p0)), \ - p1(::std::forward<p1##_type>(gmock_p1)), \ - p2(::std::forward<p2##_type>(gmock_p2)), \ - p3(::std::forward<p3##_type>(gmock_p3)), \ - p4(::std::forward<p4##_type>(gmock_p4)) {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, \ - p4##_type gmock_p4) : p0(::std::forward<p0##_type>(gmock_p0)), \ - p1(::std::forward<p1##_type>(gmock_p1)), \ - p2(::std::forward<p2##_type>(gmock_p2)), \ - p3(::std::forward<p3##_type>(gmock_p3)), \ - p4(::std::forward<p4##_type>(gmock_p4)) {}\ - return_type Perform(const args_type& args) override {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - return_type gmock_PerformImpl(const args_type& args, \ - const arg0_type& arg0, const arg1_type& arg1, \ - const arg2_type& arg2, const arg3_type& arg3, \ - const arg4_type& arg4, const arg5_type& arg5, \ - const arg6_type& arg6, const arg7_type& arg7, \ - const arg8_type& arg8, const arg9_type& arg9) const;\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2, p3, p4));\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP5);\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type>\ - inline name##ActionP5<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ - p4##_type p4) {\ - return name##ActionP5<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type>(p0, p1, p2, p3, p4);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type>\ - template <typename F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - typename ::testing::internal::Function<F>::Result\ - name##ActionP5<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type>::gmock_Impl<F>::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P6(name, p0, p1, p2, p3, p4, p5)\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type>\ - class name##ActionP6 {\ - public:\ - name##ActionP6(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ - p5##_type gmock_p5) : p0(::std::forward<p0##_type>(gmock_p0)), \ - p1(::std::forward<p1##_type>(gmock_p1)), \ - p2(::std::forward<p2##_type>(gmock_p2)), \ - p3(::std::forward<p3##_type>(gmock_p3)), \ - p4(::std::forward<p4##_type>(gmock_p4)), \ - p5(::std::forward<p5##_type>(gmock_p5)) {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4, \ - p5##_type gmock_p5) : p0(::std::forward<p0##_type>(gmock_p0)), \ - p1(::std::forward<p1##_type>(gmock_p1)), \ - p2(::std::forward<p2##_type>(gmock_p2)), \ - p3(::std::forward<p3##_type>(gmock_p3)), \ - p4(::std::forward<p4##_type>(gmock_p4)), \ - p5(::std::forward<p5##_type>(gmock_p5)) {}\ - return_type Perform(const args_type& args) override {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - return_type gmock_PerformImpl(const args_type& args, \ - const arg0_type& arg0, const arg1_type& arg1, \ - const arg2_type& arg2, const arg3_type& arg3, \ - const arg4_type& arg4, const arg5_type& arg5, \ - const arg6_type& arg6, const arg7_type& arg7, \ - const arg8_type& arg8, const arg9_type& arg9) const;\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2, p3, p4, p5));\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP6);\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type>\ - inline name##ActionP6<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, \ - p3##_type p3, p4##_type p4, p5##_type p5) {\ - return name##ActionP6<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type>(p0, p1, p2, p3, p4, p5);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type>\ - template <typename F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - typename ::testing::internal::Function<F>::Result\ - name##ActionP6<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ - p5##_type>::gmock_Impl<F>::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P7(name, p0, p1, p2, p3, p4, p5, p6)\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type>\ - class name##ActionP7 {\ - public:\ - name##ActionP7(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ - p5##_type gmock_p5, \ - p6##_type gmock_p6) : p0(::std::forward<p0##_type>(gmock_p0)), \ - p1(::std::forward<p1##_type>(gmock_p1)), \ - p2(::std::forward<p2##_type>(gmock_p2)), \ - p3(::std::forward<p3##_type>(gmock_p3)), \ - p4(::std::forward<p4##_type>(gmock_p4)), \ - p5(::std::forward<p5##_type>(gmock_p5)), \ - p6(::std::forward<p6##_type>(gmock_p6)) {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ - p6##_type gmock_p6) : p0(::std::forward<p0##_type>(gmock_p0)), \ - p1(::std::forward<p1##_type>(gmock_p1)), \ - p2(::std::forward<p2##_type>(gmock_p2)), \ - p3(::std::forward<p3##_type>(gmock_p3)), \ - p4(::std::forward<p4##_type>(gmock_p4)), \ - p5(::std::forward<p5##_type>(gmock_p5)), \ - p6(::std::forward<p6##_type>(gmock_p6)) {}\ - return_type Perform(const args_type& args) override {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - return_type gmock_PerformImpl(const args_type& args, \ - const arg0_type& arg0, const arg1_type& arg1, \ - const arg2_type& arg2, const arg3_type& arg3, \ - const arg4_type& arg4, const arg5_type& arg5, \ - const arg6_type& arg6, const arg7_type& arg7, \ - const arg8_type& arg8, const arg9_type& arg9) const;\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2, p3, p4, p5, \ - p6));\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP7);\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type>\ - inline name##ActionP7<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type> name(p0##_type p0, p1##_type p1, \ - p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \ - p6##_type p6) {\ - return name##ActionP7<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type>(p0, p1, p2, p3, p4, p5, p6);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type>\ - template <typename F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - typename ::testing::internal::Function<F>::Result\ - name##ActionP7<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ - p5##_type, p6##_type>::gmock_Impl<F>::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P8(name, p0, p1, p2, p3, p4, p5, p6, p7)\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type>\ - class name##ActionP8 {\ - public:\ - name##ActionP8(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ - p5##_type gmock_p5, p6##_type gmock_p6, \ - p7##_type gmock_p7) : p0(::std::forward<p0##_type>(gmock_p0)), \ - p1(::std::forward<p1##_type>(gmock_p1)), \ - p2(::std::forward<p2##_type>(gmock_p2)), \ - p3(::std::forward<p3##_type>(gmock_p3)), \ - p4(::std::forward<p4##_type>(gmock_p4)), \ - p5(::std::forward<p5##_type>(gmock_p5)), \ - p6(::std::forward<p6##_type>(gmock_p6)), \ - p7(::std::forward<p7##_type>(gmock_p7)) {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ - p6##_type gmock_p6, \ - p7##_type gmock_p7) : p0(::std::forward<p0##_type>(gmock_p0)), \ - p1(::std::forward<p1##_type>(gmock_p1)), \ - p2(::std::forward<p2##_type>(gmock_p2)), \ - p3(::std::forward<p3##_type>(gmock_p3)), \ - p4(::std::forward<p4##_type>(gmock_p4)), \ - p5(::std::forward<p5##_type>(gmock_p5)), \ - p6(::std::forward<p6##_type>(gmock_p6)), \ - p7(::std::forward<p7##_type>(gmock_p7)) {}\ - return_type Perform(const args_type& args) override {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - return_type gmock_PerformImpl(const args_type& args, \ - const arg0_type& arg0, const arg1_type& arg1, \ - const arg2_type& arg2, const arg3_type& arg3, \ - const arg4_type& arg4, const arg5_type& arg5, \ - const arg6_type& arg6, const arg7_type& arg7, \ - const arg8_type& arg8, const arg9_type& arg9) const;\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - p7##_type p7;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2, p3, p4, p5, \ - p6, p7));\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - p7##_type p7;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP8);\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type>\ - inline name##ActionP8<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type> name(p0##_type p0, \ - p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \ - p6##_type p6, p7##_type p7) {\ - return name##ActionP8<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type>(p0, p1, p2, p3, p4, p5, \ - p6, p7);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type>\ - template <typename F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - typename ::testing::internal::Function<F>::Result\ - name##ActionP8<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ - p5##_type, p6##_type, \ - p7##_type>::gmock_Impl<F>::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8)\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type, typename p8##_type>\ - class name##ActionP9 {\ - public:\ - name##ActionP9(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ - p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \ - p8##_type gmock_p8) : p0(::std::forward<p0##_type>(gmock_p0)), \ - p1(::std::forward<p1##_type>(gmock_p1)), \ - p2(::std::forward<p2##_type>(gmock_p2)), \ - p3(::std::forward<p3##_type>(gmock_p3)), \ - p4(::std::forward<p4##_type>(gmock_p4)), \ - p5(::std::forward<p5##_type>(gmock_p5)), \ - p6(::std::forward<p6##_type>(gmock_p6)), \ - p7(::std::forward<p7##_type>(gmock_p7)), \ - p8(::std::forward<p8##_type>(gmock_p8)) {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ - p6##_type gmock_p6, p7##_type gmock_p7, \ - p8##_type gmock_p8) : p0(::std::forward<p0##_type>(gmock_p0)), \ - p1(::std::forward<p1##_type>(gmock_p1)), \ - p2(::std::forward<p2##_type>(gmock_p2)), \ - p3(::std::forward<p3##_type>(gmock_p3)), \ - p4(::std::forward<p4##_type>(gmock_p4)), \ - p5(::std::forward<p5##_type>(gmock_p5)), \ - p6(::std::forward<p6##_type>(gmock_p6)), \ - p7(::std::forward<p7##_type>(gmock_p7)), \ - p8(::std::forward<p8##_type>(gmock_p8)) {}\ - return_type Perform(const args_type& args) override {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - return_type gmock_PerformImpl(const args_type& args, \ - const arg0_type& arg0, const arg1_type& arg1, \ - const arg2_type& arg2, const arg3_type& arg3, \ - const arg4_type& arg4, const arg5_type& arg5, \ - const arg6_type& arg6, const arg7_type& arg7, \ - const arg8_type& arg8, const arg9_type& arg9) const;\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - p7##_type p7;\ - p8##_type p8;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2, p3, p4, p5, \ - p6, p7, p8));\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - p7##_type p7;\ - p8##_type p8;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP9);\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type, typename p8##_type>\ - inline name##ActionP9<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type, \ - p8##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ - p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, \ - p8##_type p8) {\ - return name##ActionP9<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type, p8##_type>(p0, p1, p2, \ - p3, p4, p5, p6, p7, p8);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type, typename p8##_type>\ - template <typename F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - typename ::testing::internal::Function<F>::Result\ - name##ActionP9<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ - p5##_type, p6##_type, p7##_type, \ - p8##_type>::gmock_Impl<F>::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type, typename p8##_type, \ - typename p9##_type>\ - class name##ActionP10 {\ - public:\ - name##ActionP10(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ - p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \ - p8##_type gmock_p8, \ - p9##_type gmock_p9) : p0(::std::forward<p0##_type>(gmock_p0)), \ - p1(::std::forward<p1##_type>(gmock_p1)), \ - p2(::std::forward<p2##_type>(gmock_p2)), \ - p3(::std::forward<p3##_type>(gmock_p3)), \ - p4(::std::forward<p4##_type>(gmock_p4)), \ - p5(::std::forward<p5##_type>(gmock_p5)), \ - p6(::std::forward<p6##_type>(gmock_p6)), \ - p7(::std::forward<p7##_type>(gmock_p7)), \ - p8(::std::forward<p8##_type>(gmock_p8)), \ - p9(::std::forward<p9##_type>(gmock_p9)) {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ - p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \ - p9##_type gmock_p9) : p0(::std::forward<p0##_type>(gmock_p0)), \ - p1(::std::forward<p1##_type>(gmock_p1)), \ - p2(::std::forward<p2##_type>(gmock_p2)), \ - p3(::std::forward<p3##_type>(gmock_p3)), \ - p4(::std::forward<p4##_type>(gmock_p4)), \ - p5(::std::forward<p5##_type>(gmock_p5)), \ - p6(::std::forward<p6##_type>(gmock_p6)), \ - p7(::std::forward<p7##_type>(gmock_p7)), \ - p8(::std::forward<p8##_type>(gmock_p8)), \ - p9(::std::forward<p9##_type>(gmock_p9)) {}\ - return_type Perform(const args_type& args) override {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - return_type gmock_PerformImpl(const args_type& args, \ - const arg0_type& arg0, const arg1_type& arg1, \ - const arg2_type& arg2, const arg3_type& arg3, \ - const arg4_type& arg4, const arg5_type& arg5, \ - const arg6_type& arg6, const arg7_type& arg7, \ - const arg8_type& arg8, const arg9_type& arg9) const;\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - p7##_type p7;\ - p8##_type p8;\ - p9##_type p9;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(new gmock_Impl<F>(p0, p1, p2, p3, p4, p5, \ - p6, p7, p8, p9));\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - p7##_type p7;\ - p8##_type p8;\ - p9##_type p9;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP10);\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type, typename p8##_type, \ - typename p9##_type>\ - inline name##ActionP10<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, \ - p9##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ - p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8, \ - p9##_type p9) {\ - return name##ActionP10<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, p9##_type>(p0, \ - p1, p2, p3, p4, p5, p6, p7, p8, p9);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type, typename p8##_type, \ - typename p9##_type>\ - template <typename F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ - typename ::testing::internal::Function<F>::Result\ - name##ActionP10<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ - p5##_type, p6##_type, p7##_type, p8##_type, \ - p9##_type>::gmock_Impl<F>::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const namespace testing { @@ -1628,175 +512,94 @@ namespace testing { // InvokeArgument action from temporary values and have it performed // later. -namespace internal { -namespace invoke_argument { - -// Appears in InvokeArgumentAdl's argument list to help avoid -// accidental calls to user functions of the same name. -struct AdlTag {}; - -// InvokeArgumentAdl - a helper for InvokeArgument. -// The basic overloads are provided here for generic functors. -// Overloads for other custom-callables are provided in the -// internal/custom/callback-actions.h header. - -template <typename R, typename F> -R InvokeArgumentAdl(AdlTag, F f) { - return f(); -} -template <typename R, typename F, typename A1> -R InvokeArgumentAdl(AdlTag, F f, A1 a1) { - return f(a1); -} -template <typename R, typename F, typename A1, typename A2> -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2) { - return f(a1, a2); -} -template <typename R, typename F, typename A1, typename A2, typename A3> -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3) { - return f(a1, a2, a3); -} -template <typename R, typename F, typename A1, typename A2, typename A3, - typename A4> -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4) { - return f(a1, a2, a3, a4); -} -template <typename R, typename F, typename A1, typename A2, typename A3, - typename A4, typename A5> -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { - return f(a1, a2, a3, a4, a5); -} -template <typename R, typename F, typename A1, typename A2, typename A3, - typename A4, typename A5, typename A6> -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) { - return f(a1, a2, a3, a4, a5, a6); -} -template <typename R, typename F, typename A1, typename A2, typename A3, - typename A4, typename A5, typename A6, typename A7> -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, - A7 a7) { - return f(a1, a2, a3, a4, a5, a6, a7); -} -template <typename R, typename F, typename A1, typename A2, typename A3, - typename A4, typename A5, typename A6, typename A7, typename A8> -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, - A7 a7, A8 a8) { - return f(a1, a2, a3, a4, a5, a6, a7, a8); -} -template <typename R, typename F, typename A1, typename A2, typename A3, - typename A4, typename A5, typename A6, typename A7, typename A8, - typename A9> -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, - A7 a7, A8 a8, A9 a9) { - return f(a1, a2, a3, a4, a5, a6, a7, a8, a9); -} -template <typename R, typename F, typename A1, typename A2, typename A3, - typename A4, typename A5, typename A6, typename A7, typename A8, - typename A9, typename A10> -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, - A7 a7, A8 a8, A9 a9, A10 a10) { - return f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); -} -} // namespace invoke_argument -} // namespace internal - ACTION_TEMPLATE(InvokeArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_0_VALUE_PARAMS()) { using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl<return_type>( - internal::invoke_argument::AdlTag(), - ::std::get<k>(args)); + return InvokeArgumentAdl(internal::invoke_argument::AdlTag(), + ::std::get<k>(args)); } ACTION_TEMPLATE(InvokeArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_1_VALUE_PARAMS(p0)) { using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl<return_type>( - internal::invoke_argument::AdlTag(), - ::std::get<k>(args), p0); + return InvokeArgumentAdl(internal::invoke_argument::AdlTag(), + ::std::get<k>(args), p0); } ACTION_TEMPLATE(InvokeArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_2_VALUE_PARAMS(p0, p1)) { using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl<return_type>( - internal::invoke_argument::AdlTag(), - ::std::get<k>(args), p0, p1); + return InvokeArgumentAdl(internal::invoke_argument::AdlTag(), + ::std::get<k>(args), p0, p1); } ACTION_TEMPLATE(InvokeArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_3_VALUE_PARAMS(p0, p1, p2)) { using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl<return_type>( - internal::invoke_argument::AdlTag(), - ::std::get<k>(args), p0, p1, p2); + return InvokeArgumentAdl(internal::invoke_argument::AdlTag(), + ::std::get<k>(args), p0, p1, p2); } ACTION_TEMPLATE(InvokeArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_4_VALUE_PARAMS(p0, p1, p2, p3)) { using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl<return_type>( - internal::invoke_argument::AdlTag(), - ::std::get<k>(args), p0, p1, p2, p3); + return InvokeArgumentAdl(internal::invoke_argument::AdlTag(), + ::std::get<k>(args), p0, p1, p2, p3); } ACTION_TEMPLATE(InvokeArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)) { using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl<return_type>( - internal::invoke_argument::AdlTag(), - ::std::get<k>(args), p0, p1, p2, p3, p4); + return InvokeArgumentAdl(internal::invoke_argument::AdlTag(), + ::std::get<k>(args), p0, p1, p2, p3, p4); } ACTION_TEMPLATE(InvokeArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)) { using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl<return_type>( - internal::invoke_argument::AdlTag(), - ::std::get<k>(args), p0, p1, p2, p3, p4, p5); + return InvokeArgumentAdl(internal::invoke_argument::AdlTag(), + ::std::get<k>(args), p0, p1, p2, p3, p4, p5); } ACTION_TEMPLATE(InvokeArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)) { using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl<return_type>( - internal::invoke_argument::AdlTag(), - ::std::get<k>(args), p0, p1, p2, p3, p4, p5, p6); + return InvokeArgumentAdl(internal::invoke_argument::AdlTag(), + ::std::get<k>(args), p0, p1, p2, p3, p4, p5, p6); } ACTION_TEMPLATE(InvokeArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)) { using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl<return_type>( - internal::invoke_argument::AdlTag(), - ::std::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7); + return InvokeArgumentAdl(internal::invoke_argument::AdlTag(), + ::std::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7); } ACTION_TEMPLATE(InvokeArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8)) { using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl<return_type>( - internal::invoke_argument::AdlTag(), - ::std::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7, p8); + return InvokeArgumentAdl(internal::invoke_argument::AdlTag(), + ::std::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7, + p8); } ACTION_TEMPLATE(InvokeArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)) { using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl<return_type>( - internal::invoke_argument::AdlTag(), - ::std::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); + return InvokeArgumentAdl(internal::invoke_argument::AdlTag(), + ::std::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7, + p8, p9); } // Various overloads for ReturnNew<T>(). diff --git a/googlemock/include/gmock/gmock-generated-actions.h.pump b/googlemock/include/gmock/gmock-generated-actions.h.pump index 283abcdc..be9d99fe 100644 --- a/googlemock/include/gmock/gmock-generated-actions.h.pump +++ b/googlemock/include/gmock/gmock-generated-actions.h.pump @@ -49,158 +49,9 @@ $$}} This meta comment fixes auto-indentation in editors. #include "gmock/gmock-actions.h" #include "gmock/internal/gmock-port.h" -namespace testing { -namespace internal { - -// A macro from the ACTION* family (defined later in this file) -// defines an action that can be used in a mock function. Typically, -// these actions only care about a subset of the arguments of the mock -// function. For example, if such an action only uses the second -// argument, it can be used in any mock function that takes >= 2 -// arguments where the type of the second argument is compatible. -// -// Therefore, the action implementation must be prepared to take more -// arguments than it needs. The ExcessiveArg type is used to -// represent those excessive arguments. In order to keep the compiler -// error messages tractable, we define it in the testing namespace -// instead of testing::internal. However, this is an INTERNAL TYPE -// and subject to change without notice, so a user MUST NOT USE THIS -// TYPE DIRECTLY. -struct ExcessiveArg {}; - -// A helper class needed for implementing the ACTION* macros. -template <typename Result, class Impl> -class ActionHelper { - public: -$range i 0..n -$for i - -[[ -$var template = [[$if i==0 [[]] $else [[ -$range j 0..i-1 - template <$for j, [[typename A$j]]> -]]]] -$range j 0..i-1 -$var As = [[$for j, [[A$j]]]] -$var as = [[$for j, [[std::get<$j>(args)]]]] -$range k 1..n-i -$var eas = [[$for k, [[ExcessiveArg()]]]] -$var arg_list = [[$if (i==0) | (i==n) [[$as$eas]] $else [[$as, $eas]]]] -$template - static Result Perform(Impl* impl, const ::std::tuple<$As>& args) { - return impl->template gmock_PerformImpl<$As>(args, $arg_list); - } - -]] -}; - -} // namespace internal -} // namespace testing - -// The ACTION* family of macros can be used in a namespace scope to -// define custom actions easily. The syntax: -// -// ACTION(name) { statements; } -// -// will define an action with the given name that executes the -// statements. The value returned by the statements will be used as -// the return value of the action. Inside the statements, you can -// refer to the K-th (0-based) argument of the mock function by -// 'argK', and refer to its type by 'argK_type'. For example: -// -// ACTION(IncrementArg1) { -// arg1_type temp = arg1; -// return ++(*temp); -// } -// -// allows you to write -// -// ...WillOnce(IncrementArg1()); -// -// You can also refer to the entire argument tuple and its type by -// 'args' and 'args_type', and refer to the mock function type and its -// return type by 'function_type' and 'return_type'. -// -// Note that you don't need to specify the types of the mock function -// arguments. However rest assured that your code is still type-safe: -// you'll get a compiler error if *arg1 doesn't support the ++ -// operator, or if the type of ++(*arg1) isn't compatible with the -// mock function's return type, for example. -// -// Sometimes you'll want to parameterize the action. For that you can use -// another macro: -// -// ACTION_P(name, param_name) { statements; } -// -// For example: -// -// ACTION_P(Add, n) { return arg0 + n; } -// -// will allow you to write: -// -// ...WillOnce(Add(5)); -// -// Note that you don't need to provide the type of the parameter -// either. If you need to reference the type of a parameter named -// 'foo', you can write 'foo_type'. For example, in the body of -// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type -// of 'n'. -// -// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P$n to support -// multi-parameter actions. -// -// For the purpose of typing, you can view -// -// ACTION_Pk(Foo, p1, ..., pk) { ... } -// -// as shorthand for -// -// template <typename p1_type, ..., typename pk_type> -// FooActionPk<p1_type, ..., pk_type> Foo(p1_type p1, ..., pk_type pk) { ... } -// -// In particular, you can provide the template type arguments -// explicitly when invoking Foo(), as in Foo<long, bool>(5, false); -// although usually you can rely on the compiler to infer the types -// for you automatically. You can assign the result of expression -// Foo(p1, ..., pk) to a variable of type FooActionPk<p1_type, ..., -// pk_type>. This can be useful when composing actions. -// -// You can also overload actions with different numbers of parameters: -// -// ACTION_P(Plus, a) { ... } -// ACTION_P2(Plus, a, b) { ... } -// -// While it's tempting to always use the ACTION* macros when defining -// a new action, you should also consider implementing ActionInterface -// or using MakePolymorphicAction() instead, especially if you need to -// use the action a lot. While these approaches require more work, -// they give you more control on the types of the mock function -// arguments and the action parameters, which in general leads to -// better compiler error messages that pay off in the long run. They -// also allow overloading actions based on parameter types (as opposed -// to just based on the number of parameters). -// -// CAVEAT: -// -// ACTION*() can only be used in a namespace scope as templates cannot be -// declared inside of a local class. -// Users can, however, define any local functors (e.g. a lambda) that -// can be used as actions. -// -// MORE INFORMATION: -// -// To learn more about using these macros, please search for 'ACTION' on -// https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md - $range i 0..n $range k 0..n-1 -// An internal macro needed for implementing ACTION*(). -#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\ - const args_type& args GTEST_ATTRIBUTE_UNUSED_ -$for k [[, \ - const arg$k[[]]_type& arg$k GTEST_ATTRIBUTE_UNUSED_]] - // Sometimes you want to give an action explicit template parameters // that cannot be inferred from its value parameters. ACTION() and @@ -399,9 +250,8 @@ $range k 0..n-1 return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ Perform(this, args);\ }\ - template <$for k, [[typename arg$k[[]]_type]]>\ - return_type gmock_PerformImpl(const args_type& args[[]] -$for k [[, const arg$k[[]]_type& arg$k]]) const;\ + template <GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>\ + return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const;\ GMOCK_INTERNAL_DEFN_##value_params\ private:\ GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ @@ -428,10 +278,7 @@ $for k [[, const arg$k[[]]_type& arg$k]]) const;\ template <GMOCK_INTERNAL_DECL_##template_params\ GMOCK_INTERNAL_DECL_TYPE_##value_params>\ template <typename F>\ - template <typename arg0_type, typename arg1_type, typename arg2_type, \ - typename arg3_type, typename arg4_type, typename arg5_type, \ - typename arg6_type, typename arg7_type, typename arg8_type, \ - typename arg9_type>\ + template <GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>\ typename ::testing::internal::Function<F>::Result\ GMOCK_ACTION_CLASS_(name, value_params)<\ GMOCK_INTERNAL_LIST_##template_params\ @@ -439,77 +286,6 @@ $for k [[, const arg$k[[]]_type& arg$k]]) const;\ gmock_PerformImpl(\ GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const -$for i - -[[ -$var template = [[$if i==0 [[]] $else [[ -$range j 0..i-1 - - template <$for j, [[typename p$j##_type]]>\ -]]]] -$var class_name = [[name##Action[[$if i==0 [[]] $elif i==1 [[P]] - $else [[P$i]]]]]] -$range j 0..i-1 -$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]] -$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]] -$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::std::forward<p$j##_type>(gmock_p$j))]]]]]] -$var param_field_decls = [[$for j -[[ - - p$j##_type p$j;\ -]]]] -$var param_field_decls2 = [[$for j -[[ - - p$j##_type p$j;\ -]]]] -$var params = [[$for j, [[p$j]]]] -$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]] -$var typename_arg_types = [[$for k, [[typename arg$k[[]]_type]]]] -$var arg_types_and_names = [[$for k, [[const arg$k[[]]_type& arg$k]]]] -$var macro_name = [[$if i==0 [[ACTION]] $elif i==1 [[ACTION_P]] - $else [[ACTION_P$i]]]] - -#define $macro_name(name$for j [[, p$j]])\$template - class $class_name {\ - public:\ - [[$if i==1 [[explicit ]]]]$class_name($ctor_param_list)$inits {}\ - template <typename F>\ - class gmock_Impl : public ::testing::ActionInterface<F> {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function<F>::Result return_type;\ - typedef typename ::testing::internal::Function<F>::ArgumentTuple\ - args_type;\ - [[$if i==1 [[explicit ]]]]gmock_Impl($ctor_param_list)$inits {}\ - return_type Perform(const args_type& args) override {\ - return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ - Perform(this, args);\ - }\ - template <$typename_arg_types>\ - return_type gmock_PerformImpl(const args_type& args, [[]] -$arg_types_and_names) const;\$param_field_decls - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template <typename F> operator ::testing::Action<F>() const {\ - return ::testing::Action<F>(new gmock_Impl<F>($params));\ - }\$param_field_decls2 - private:\ - GTEST_DISALLOW_ASSIGN_($class_name);\ - };\$template - inline $class_name$param_types name($param_types_and_names) {\ - return $class_name$param_types($params);\ - }\$template - template <typename F>\ - template <$typename_arg_types>\ - typename ::testing::internal::Function<F>::Result\ - $class_name$param_types::gmock_Impl<F>::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const -]] -$$ } // This meta comment fixes auto-indentation in Emacs. It won't -$$ // show up in the generated code. - namespace testing { @@ -554,32 +330,6 @@ namespace testing { // InvokeArgument action from temporary values and have it performed // later. -namespace internal { -namespace invoke_argument { - -// Appears in InvokeArgumentAdl's argument list to help avoid -// accidental calls to user functions of the same name. -struct AdlTag {}; - -// InvokeArgumentAdl - a helper for InvokeArgument. -// The basic overloads are provided here for generic functors. -// Overloads for other custom-callables are provided in the -// internal/custom/callback-actions.h header. - -$range i 0..n -$for i -[[ -$range j 1..i - -template <typename R, typename F[[$for j [[, typename A$j]]]]> -R InvokeArgumentAdl(AdlTag, F f[[$for j [[, A$j a$j]]]]) { - return f([[$for j, [[a$j]]]]); -} -]] - -} // namespace invoke_argument -} // namespace internal - $range i 0..n $for i [[ $range j 0..i-1 @@ -588,9 +338,8 @@ ACTION_TEMPLATE(InvokeArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])) { using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl<return_type>( - internal::invoke_argument::AdlTag(), - ::std::get<k>(args)$for j [[, p$j]]); + return InvokeArgumentAdl(internal::invoke_argument::AdlTag(), + ::std::get<k>(args)$for j[[, p$j]]); } ]] diff --git a/googlemock/include/gmock/gmock-generated-function-mockers.h b/googlemock/include/gmock/gmock-generated-function-mockers.h deleted file mode 100644 index cd957817..00000000 --- a/googlemock/include/gmock/gmock-generated-function-mockers.h +++ /dev/null @@ -1,752 +0,0 @@ -// This file was GENERATED by command: -// pump.py gmock-generated-function-mockers.h.pump -// DO NOT EDIT BY HAND!!! - -// 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 function mockers of various arities. - -// GOOGLETEST_CM0002 DO NOT DELETE - -#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ - -#include <functional> -#include <utility> - -#include "gmock/gmock-spec-builders.h" -#include "gmock/internal/gmock-internal-utils.h" - -namespace testing { -namespace internal { -// Removes the given pointer; this is a helper for the expectation setter method -// for parameterless matchers. -// -// We want to make sure that the user cannot set a parameterless expectation on -// overloaded methods, including methods which are overloaded on const. Example: -// -// class MockClass { -// MOCK_METHOD0(GetName, string&()); -// MOCK_CONST_METHOD0(GetName, const string&()); -// }; -// -// TEST() { -// // This should be an error, as it's not clear which overload is expected. -// EXPECT_CALL(mock, GetName).WillOnce(ReturnRef(value)); -// } -// -// Here are the generated expectation-setter methods: -// -// class MockClass { -// // Overload 1 -// MockSpec<string&()> gmock_GetName() { ... } -// // Overload 2. Declared const so that the compiler will generate an -// // error when trying to resolve between this and overload 4 in -// // 'gmock_GetName(WithoutMatchers(), nullptr)'. -// MockSpec<string&()> gmock_GetName( -// const WithoutMatchers&, const Function<string&()>*) const { -// // Removes const from this, calls overload 1 -// return AdjustConstness_(this)->gmock_GetName(); -// } -// -// // Overload 3 -// const string& gmock_GetName() const { ... } -// // Overload 4 -// MockSpec<const string&()> gmock_GetName( -// const WithoutMatchers&, const Function<const string&()>*) const { -// // Does not remove const, calls overload 3 -// return AdjustConstness_const(this)->gmock_GetName(); -// } -// } -// -template <typename MockType> -const MockType* AdjustConstness_const(const MockType* mock) { - return mock; -} - -// Removes const from and returns the given pointer; this is a helper for the -// expectation setter method for parameterless matchers. -template <typename MockType> -MockType* AdjustConstness_(const MockType* mock) { - return const_cast<MockType*>(mock); -} - -} // namespace internal - -// The style guide prohibits "using" statements in a namespace scope -// inside a header file. However, the FunctionMocker class template -// is meant to be defined in the ::testing namespace. The following -// line is just a trick for working around a bug in MSVC 8.0, which -// cannot handle it if we define FunctionMocker in ::testing. -using internal::FunctionMocker; - -// GMOCK_RESULT_(tn, F) expands to the result type of function type F. -// We define this as a variadic macro in case F contains unprotected -// commas (the same reason that we use variadic macros in other places -// in this file). -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_RESULT_(tn, ...) \ - tn ::testing::internal::Function<__VA_ARGS__>::Result - -// The type of argument N of the given function type. -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_ARG_(tn, N, ...) \ - tn ::testing::internal::Function<__VA_ARGS__>::template Arg<N-1>::type - -// The matcher type for argument N of the given function type. -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_MATCHER_(tn, N, ...) \ - const ::testing::Matcher<GMOCK_ARG_(tn, N, __VA_ARGS__)>& - -// The variable for mocking the given method. -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_MOCKER_(arity, constness, Method) \ - GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD0_(tn, constness, ct, Method, ...) \ - static_assert(0 == \ - ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ - "MOCK_METHOD<N> must match argument count.");\ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - ) constness { \ - GMOCK_MOCKER_(0, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(0, constness, Method).Invoke(); \ - } \ - ::testing::MockSpec<__VA_ARGS__> \ - gmock_##Method() constness { \ - GMOCK_MOCKER_(0, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(0, constness, Method).With(); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - const ::testing::internal::WithoutMatchers&, \ - constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ - return ::testing::internal::AdjustConstness_##constness(this)-> \ - gmock_##Method(); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(0, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD1_(tn, constness, ct, Method, ...) \ - static_assert(1 == \ - ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ - "MOCK_METHOD<N> must match argument count.");\ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1) constness { \ - GMOCK_MOCKER_(1, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(1, constness, \ - Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \ - __VA_ARGS__)>(gmock_a1)); \ - } \ - ::testing::MockSpec<__VA_ARGS__> \ - gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1) constness { \ - GMOCK_MOCKER_(1, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(1, constness, Method).With(gmock_a1); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - const ::testing::internal::WithoutMatchers&, \ - constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ - return ::testing::internal::AdjustConstness_##constness(this)-> \ - gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>()); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(1, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD2_(tn, constness, ct, Method, ...) \ - static_assert(2 == \ - ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ - "MOCK_METHOD<N> must match argument count.");\ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ - __VA_ARGS__) gmock_a2) constness { \ - GMOCK_MOCKER_(2, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(2, constness, \ - Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \ - __VA_ARGS__)>(gmock_a1), \ - ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2)); \ - } \ - ::testing::MockSpec<__VA_ARGS__> \ - gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2) constness { \ - GMOCK_MOCKER_(2, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(2, constness, Method).With(gmock_a1, gmock_a2); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - const ::testing::internal::WithoutMatchers&, \ - constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ - return ::testing::internal::AdjustConstness_##constness(this)-> \ - gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>()); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(2, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD3_(tn, constness, ct, Method, ...) \ - static_assert(3 == \ - ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ - "MOCK_METHOD<N> must match argument count.");\ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ - __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, \ - __VA_ARGS__) gmock_a3) constness { \ - GMOCK_MOCKER_(3, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(3, constness, \ - Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \ - __VA_ARGS__)>(gmock_a1), \ - ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \ - ::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3)); \ - } \ - ::testing::MockSpec<__VA_ARGS__> \ - gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3) constness { \ - GMOCK_MOCKER_(3, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(3, constness, Method).With(gmock_a1, gmock_a2, \ - gmock_a3); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - const ::testing::internal::WithoutMatchers&, \ - constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ - return ::testing::internal::AdjustConstness_##constness(this)-> \ - gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>()); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(3, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD4_(tn, constness, ct, Method, ...) \ - static_assert(4 == \ - ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ - "MOCK_METHOD<N> must match argument count.");\ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ - __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4) constness { \ - GMOCK_MOCKER_(4, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(4, constness, \ - Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \ - __VA_ARGS__)>(gmock_a1), \ - ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \ - ::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \ - ::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4)); \ - } \ - ::testing::MockSpec<__VA_ARGS__> \ - gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4) constness { \ - GMOCK_MOCKER_(4, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(4, constness, Method).With(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - const ::testing::internal::WithoutMatchers&, \ - constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ - return ::testing::internal::AdjustConstness_##constness(this)-> \ - gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>()); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(4, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD5_(tn, constness, ct, Method, ...) \ - static_assert(5 == \ - ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ - "MOCK_METHOD<N> must match argument count.");\ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ - __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \ - __VA_ARGS__) gmock_a5) constness { \ - GMOCK_MOCKER_(5, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(5, constness, \ - Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \ - __VA_ARGS__)>(gmock_a1), \ - ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \ - ::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \ - ::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \ - ::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5)); \ - } \ - ::testing::MockSpec<__VA_ARGS__> \ - gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5) constness { \ - GMOCK_MOCKER_(5, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(5, constness, Method).With(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4, gmock_a5); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - const ::testing::internal::WithoutMatchers&, \ - constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ - return ::testing::internal::AdjustConstness_##constness(this)-> \ - gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>()); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(5, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD6_(tn, constness, ct, Method, ...) \ - static_assert(6 == \ - ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ - "MOCK_METHOD<N> must match argument count.");\ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ - __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \ - __VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, \ - __VA_ARGS__) gmock_a6) constness { \ - GMOCK_MOCKER_(6, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(6, constness, \ - Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \ - __VA_ARGS__)>(gmock_a1), \ - ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \ - ::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \ - ::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \ - ::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5), \ - ::std::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(gmock_a6)); \ - } \ - ::testing::MockSpec<__VA_ARGS__> \ - gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ - GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6) constness { \ - GMOCK_MOCKER_(6, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(6, constness, Method).With(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4, gmock_a5, gmock_a6); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - const ::testing::internal::WithoutMatchers&, \ - constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ - return ::testing::internal::AdjustConstness_##constness(this)-> \ - gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>()); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(6, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD7_(tn, constness, ct, Method, ...) \ - static_assert(7 == \ - ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ - "MOCK_METHOD<N> must match argument count.");\ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ - __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \ - __VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ - GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7) constness { \ - GMOCK_MOCKER_(7, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(7, constness, \ - Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \ - __VA_ARGS__)>(gmock_a1), \ - ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \ - ::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \ - ::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \ - ::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5), \ - ::std::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(gmock_a6), \ - ::std::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(gmock_a7)); \ - } \ - ::testing::MockSpec<__VA_ARGS__> \ - gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ - GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \ - GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7) constness { \ - GMOCK_MOCKER_(7, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(7, constness, Method).With(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - const ::testing::internal::WithoutMatchers&, \ - constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ - return ::testing::internal::AdjustConstness_##constness(this)-> \ - gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 7, __VA_ARGS__)>()); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(7, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD8_(tn, constness, ct, Method, ...) \ - static_assert(8 == \ - ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ - "MOCK_METHOD<N> must match argument count.");\ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ - __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \ - __VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ - GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, GMOCK_ARG_(tn, 8, \ - __VA_ARGS__) gmock_a8) constness { \ - GMOCK_MOCKER_(8, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(8, constness, \ - Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \ - __VA_ARGS__)>(gmock_a1), \ - ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \ - ::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \ - ::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \ - ::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5), \ - ::std::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(gmock_a6), \ - ::std::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(gmock_a7), \ - ::std::forward<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(gmock_a8)); \ - } \ - ::testing::MockSpec<__VA_ARGS__> \ - gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ - GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \ - GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \ - GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8) constness { \ - GMOCK_MOCKER_(8, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(8, constness, Method).With(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - const ::testing::internal::WithoutMatchers&, \ - constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ - return ::testing::internal::AdjustConstness_##constness(this)-> \ - gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 8, __VA_ARGS__)>()); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(8, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD9_(tn, constness, ct, Method, ...) \ - static_assert(9 == \ - ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ - "MOCK_METHOD<N> must match argument count.");\ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ - __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \ - __VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ - GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, GMOCK_ARG_(tn, 8, \ - __VA_ARGS__) gmock_a8, GMOCK_ARG_(tn, 9, \ - __VA_ARGS__) gmock_a9) constness { \ - GMOCK_MOCKER_(9, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(9, constness, \ - Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \ - __VA_ARGS__)>(gmock_a1), \ - ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \ - ::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \ - ::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \ - ::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5), \ - ::std::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(gmock_a6), \ - ::std::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(gmock_a7), \ - ::std::forward<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(gmock_a8), \ - ::std::forward<GMOCK_ARG_(tn, 9, __VA_ARGS__)>(gmock_a9)); \ - } \ - ::testing::MockSpec<__VA_ARGS__> \ - gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ - GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \ - GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \ - GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \ - GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9) constness { \ - GMOCK_MOCKER_(9, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(9, constness, Method).With(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \ - gmock_a9); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - const ::testing::internal::WithoutMatchers&, \ - constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ - return ::testing::internal::AdjustConstness_##constness(this)-> \ - gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 9, __VA_ARGS__)>()); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(9, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD10_(tn, constness, ct, Method, ...) \ - static_assert(10 == \ - ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ - "MOCK_METHOD<N> must match argument count.");\ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ - __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \ - __VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ - GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, GMOCK_ARG_(tn, 8, \ - __VA_ARGS__) gmock_a8, GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9, \ - GMOCK_ARG_(tn, 10, __VA_ARGS__) gmock_a10) constness { \ - GMOCK_MOCKER_(10, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(10, constness, \ - Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \ - __VA_ARGS__)>(gmock_a1), \ - ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \ - ::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \ - ::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \ - ::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5), \ - ::std::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(gmock_a6), \ - ::std::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(gmock_a7), \ - ::std::forward<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(gmock_a8), \ - ::std::forward<GMOCK_ARG_(tn, 9, __VA_ARGS__)>(gmock_a9), \ - ::std::forward<GMOCK_ARG_(tn, 10, __VA_ARGS__)>(gmock_a10)); \ - } \ - ::testing::MockSpec<__VA_ARGS__> \ - gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ - GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \ - GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \ - GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \ - GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9, \ - GMOCK_MATCHER_(tn, 10, \ - __VA_ARGS__) gmock_a10) constness { \ - GMOCK_MOCKER_(10, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(10, constness, Method).With(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \ - gmock_a10); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - const ::testing::internal::WithoutMatchers&, \ - constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ - return ::testing::internal::AdjustConstness_##constness(this)-> \ - gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 9, __VA_ARGS__)>(), \ - ::testing::A<GMOCK_ARG_(tn, 10, __VA_ARGS__)>()); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(10, constness, \ - Method) - -#define MOCK_METHOD0(m, ...) GMOCK_METHOD0_(, , , m, __VA_ARGS__) -#define MOCK_METHOD1(m, ...) GMOCK_METHOD1_(, , , m, __VA_ARGS__) -#define MOCK_METHOD2(m, ...) GMOCK_METHOD2_(, , , m, __VA_ARGS__) -#define MOCK_METHOD3(m, ...) GMOCK_METHOD3_(, , , m, __VA_ARGS__) -#define MOCK_METHOD4(m, ...) GMOCK_METHOD4_(, , , m, __VA_ARGS__) -#define MOCK_METHOD5(m, ...) GMOCK_METHOD5_(, , , m, __VA_ARGS__) -#define MOCK_METHOD6(m, ...) GMOCK_METHOD6_(, , , m, __VA_ARGS__) -#define MOCK_METHOD7(m, ...) GMOCK_METHOD7_(, , , m, __VA_ARGS__) -#define MOCK_METHOD8(m, ...) GMOCK_METHOD8_(, , , m, __VA_ARGS__) -#define MOCK_METHOD9(m, ...) GMOCK_METHOD9_(, , , m, __VA_ARGS__) -#define MOCK_METHOD10(m, ...) GMOCK_METHOD10_(, , , m, __VA_ARGS__) - -#define MOCK_CONST_METHOD0(m, ...) GMOCK_METHOD0_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD1(m, ...) GMOCK_METHOD1_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD2(m, ...) GMOCK_METHOD2_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD3(m, ...) GMOCK_METHOD3_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD4(m, ...) GMOCK_METHOD4_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD5(m, ...) GMOCK_METHOD5_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD6(m, ...) GMOCK_METHOD6_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD7(m, ...) GMOCK_METHOD7_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD8(m, ...) GMOCK_METHOD8_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD9(m, ...) GMOCK_METHOD9_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD10(m, ...) GMOCK_METHOD10_(, const, , m, __VA_ARGS__) - -#define MOCK_METHOD0_T(m, ...) GMOCK_METHOD0_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD1_T(m, ...) GMOCK_METHOD1_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD2_T(m, ...) GMOCK_METHOD2_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD3_T(m, ...) GMOCK_METHOD3_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD4_T(m, ...) GMOCK_METHOD4_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD5_T(m, ...) GMOCK_METHOD5_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD6_T(m, ...) GMOCK_METHOD6_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD7_T(m, ...) GMOCK_METHOD7_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD8_T(m, ...) GMOCK_METHOD8_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD9_T(m, ...) GMOCK_METHOD9_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD10_T(m, ...) GMOCK_METHOD10_(typename, , , m, __VA_ARGS__) - -#define MOCK_CONST_METHOD0_T(m, ...) \ - GMOCK_METHOD0_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD1_T(m, ...) \ - GMOCK_METHOD1_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD2_T(m, ...) \ - GMOCK_METHOD2_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD3_T(m, ...) \ - GMOCK_METHOD3_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD4_T(m, ...) \ - GMOCK_METHOD4_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD5_T(m, ...) \ - GMOCK_METHOD5_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD6_T(m, ...) \ - GMOCK_METHOD6_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD7_T(m, ...) \ - GMOCK_METHOD7_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD8_T(m, ...) \ - GMOCK_METHOD8_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD9_T(m, ...) \ - GMOCK_METHOD9_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD10_T(m, ...) \ - GMOCK_METHOD10_(typename, const, , m, __VA_ARGS__) - -#define MOCK_METHOD0_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD0_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD1_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD1_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD2_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD2_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD3_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD3_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD4_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD4_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD5_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD5_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD6_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD6_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD7_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD7_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD8_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD8_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD9_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD9_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD10_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD10_(, , ct, m, __VA_ARGS__) - -#define MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD0_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD1_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD2_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD3_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD4_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD5_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD6_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD7_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD8_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD9_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD10_(, const, ct, m, __VA_ARGS__) - -#define MOCK_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD0_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD1_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD2_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD3_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD4_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD5_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD6_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD7_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD8_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD9_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD10_(typename, , ct, m, __VA_ARGS__) - -#define MOCK_CONST_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD0_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD1_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD2_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD3_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD4_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD5_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD6_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD7_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD8_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD9_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD10_(typename, const, ct, m, __VA_ARGS__) - -} // namespace testing - -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ diff --git a/googlemock/include/gmock/gmock-generated-function-mockers.h.pump b/googlemock/include/gmock/gmock-generated-function-mockers.h.pump deleted file mode 100644 index a56e132f..00000000 --- a/googlemock/include/gmock/gmock-generated-function-mockers.h.pump +++ /dev/null @@ -1,227 +0,0 @@ -$$ -*- mode: c++; -*- -$$ This is a Pump source file. Please use Pump to convert -$$ it to gmock-generated-function-mockers.h. -$$ -$var n = 10 $$ The maximum arity we support. -// 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 function mockers of various arities. - -// GOOGLETEST_CM0002 DO NOT DELETE - -#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ - -#include <functional> -#include <utility> - -#include "gmock/gmock-spec-builders.h" -#include "gmock/internal/gmock-internal-utils.h" - -namespace testing { -namespace internal { - -$range i 0..n -// Removes the given pointer; this is a helper for the expectation setter method -// for parameterless matchers. -// -// We want to make sure that the user cannot set a parameterless expectation on -// overloaded methods, including methods which are overloaded on const. Example: -// -// class MockClass { -// MOCK_METHOD0(GetName, string&()); -// MOCK_CONST_METHOD0(GetName, const string&()); -// }; -// -// TEST() { -// // This should be an error, as it's not clear which overload is expected. -// EXPECT_CALL(mock, GetName).WillOnce(ReturnRef(value)); -// } -// -// Here are the generated expectation-setter methods: -// -// class MockClass { -// // Overload 1 -// MockSpec<string&()> gmock_GetName() { ... } -// // Overload 2. Declared const so that the compiler will generate an -// // error when trying to resolve between this and overload 4 in -// // 'gmock_GetName(WithoutMatchers(), nullptr)'. -// MockSpec<string&()> gmock_GetName( -// const WithoutMatchers&, const Function<string&()>*) const { -// // Removes const from this, calls overload 1 -// return AdjustConstness_(this)->gmock_GetName(); -// } -// -// // Overload 3 -// const string& gmock_GetName() const { ... } -// // Overload 4 -// MockSpec<const string&()> gmock_GetName( -// const WithoutMatchers&, const Function<const string&()>*) const { -// // Does not remove const, calls overload 3 -// return AdjustConstness_const(this)->gmock_GetName(); -// } -// } -// -template <typename MockType> -const MockType* AdjustConstness_const(const MockType* mock) { - return mock; -} - -// Removes const from and returns the given pointer; this is a helper for the -// expectation setter method for parameterless matchers. -template <typename MockType> -MockType* AdjustConstness_(const MockType* mock) { - return const_cast<MockType*>(mock); -} - -} // namespace internal - -// The style guide prohibits "using" statements in a namespace scope -// inside a header file. However, the FunctionMocker class template -// is meant to be defined in the ::testing namespace. The following -// line is just a trick for working around a bug in MSVC 8.0, which -// cannot handle it if we define FunctionMocker in ::testing. -using internal::FunctionMocker; - -// GMOCK_RESULT_(tn, F) expands to the result type of function type F. -// We define this as a variadic macro in case F contains unprotected -// commas (the same reason that we use variadic macros in other places -// in this file). -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_RESULT_(tn, ...) \ - tn ::testing::internal::Function<__VA_ARGS__>::Result - -// The type of argument N of the given function type. -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_ARG_(tn, N, ...) \ - tn ::testing::internal::Function<__VA_ARGS__>::template Arg<N-1>::type - -// The matcher type for argument N of the given function type. -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_MATCHER_(tn, N, ...) \ - const ::testing::Matcher<GMOCK_ARG_(tn, N, __VA_ARGS__)>& - -// The variable for mocking the given method. -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_MOCKER_(arity, constness, Method) \ - GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__) - - -$for i [[ -$range j 1..i -$var arg_as = [[$for j, [[GMOCK_ARG_(tn, $j, __VA_ARGS__) gmock_a$j]]]] -$var as = [[$for j, \ - [[::std::forward<GMOCK_ARG_(tn, $j, __VA_ARGS__)>(gmock_a$j)]]]] -$var matcher_arg_as = [[$for j, \ - [[GMOCK_MATCHER_(tn, $j, __VA_ARGS__) gmock_a$j]]]] -$var matcher_as = [[$for j, [[gmock_a$j]]]] -$var anything_matchers = [[$for j, \ - [[::testing::A<GMOCK_ARG_(tn, $j, __VA_ARGS__)>()]]]] -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD$i[[]]_(tn, constness, ct, Method, ...) \ - static_assert($i == ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, "MOCK_METHOD<N> must match argument count.");\ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - $arg_as) constness { \ - GMOCK_MOCKER_($i, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_($i, constness, Method).Invoke($as); \ - } \ - ::testing::MockSpec<__VA_ARGS__> \ - gmock_##Method($matcher_arg_as) constness { \ - GMOCK_MOCKER_($i, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_($i, constness, Method).With($matcher_as); \ - } \ - ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ - const ::testing::internal::WithoutMatchers&, \ - constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ - return ::testing::internal::AdjustConstness_##constness(this)-> \ - gmock_##Method($anything_matchers); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_($i, constness, Method) - - -]] -$for i [[ -#define MOCK_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, , , m, __VA_ARGS__) - -]] - - -$for i [[ -#define MOCK_CONST_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, const, , m, __VA_ARGS__) - -]] - - -$for i [[ -#define MOCK_METHOD$i[[]]_T(m, ...) GMOCK_METHOD$i[[]]_(typename, , , m, __VA_ARGS__) - -]] - - -$for i [[ -#define MOCK_CONST_METHOD$i[[]]_T(m, ...) \ - GMOCK_METHOD$i[[]]_(typename, const, , m, __VA_ARGS__) - -]] - - -$for i [[ -#define MOCK_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD$i[[]]_(, , ct, m, __VA_ARGS__) - -]] - - -$for i [[ -#define MOCK_CONST_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD$i[[]]_(, const, ct, m, __VA_ARGS__) - -]] - - -$for i [[ -#define MOCK_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD$i[[]]_(typename, , ct, m, __VA_ARGS__) - -]] - - -$for i [[ -#define MOCK_CONST_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD$i[[]]_(typename, const, ct, m, __VA_ARGS__) - -]] - -} // namespace testing - -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ diff --git a/googlemock/include/gmock/gmock-generated-matchers.h b/googlemock/include/gmock/gmock-generated-matchers.h deleted file mode 100644 index 61892380..00000000 --- a/googlemock/include/gmock/gmock-generated-matchers.h +++ /dev/null @@ -1,1097 +0,0 @@ -// This file was GENERATED by command: -// pump.py gmock-generated-matchers.h.pump -// DO NOT EDIT BY HAND!!! - -// 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 implements some commonly used variadic matchers. - -// GOOGLETEST_CM0002 DO NOT DELETE - -#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ - -#include <iterator> -#include <sstream> -#include <string> -#include <utility> -#include <vector> -#include "gmock/gmock-matchers.h" - -// The MATCHER* family of macros can be used in a namespace scope to -// define custom matchers easily. -// -// Basic Usage -// =========== -// -// The syntax -// -// MATCHER(name, description_string) { statements; } -// -// defines a matcher with the given name that executes the statements, -// which must return a bool to indicate if the match succeeds. Inside -// the statements, you can refer to the value being matched by 'arg', -// and refer to its type by 'arg_type'. -// -// The description string documents what the matcher does, and is used -// to generate the failure message when the match fails. Since a -// MATCHER() is usually defined in a header file shared by multiple -// C++ source files, we require the description to be a C-string -// literal to avoid possible side effects. It can be empty, in which -// case we'll use the sequence of words in the matcher name as the -// description. -// -// For example: -// -// MATCHER(IsEven, "") { return (arg % 2) == 0; } -// -// allows you to write -// -// // Expects mock_foo.Bar(n) to be called where n is even. -// EXPECT_CALL(mock_foo, Bar(IsEven())); -// -// or, -// -// // Verifies that the value of some_expression is even. -// EXPECT_THAT(some_expression, IsEven()); -// -// If the above assertion fails, it will print something like: -// -// Value of: some_expression -// Expected: is even -// Actual: 7 -// -// where the description "is even" is automatically calculated from the -// matcher name IsEven. -// -// Argument Type -// ============= -// -// Note that the type of the value being matched (arg_type) is -// determined by the context in which you use the matcher and is -// supplied to you by the compiler, so you don't need to worry about -// declaring it (nor can you). This allows the matcher to be -// polymorphic. For example, IsEven() can be used to match any type -// where the value of "(arg % 2) == 0" can be implicitly converted to -// a bool. In the "Bar(IsEven())" example above, if method Bar() -// takes an int, 'arg_type' will be int; if it takes an unsigned long, -// 'arg_type' will be unsigned long; and so on. -// -// Parameterizing Matchers -// ======================= -// -// Sometimes you'll want to parameterize the matcher. For that you -// can use another macro: -// -// MATCHER_P(name, param_name, description_string) { statements; } -// -// For example: -// -// MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; } -// -// will allow you to write: -// -// EXPECT_THAT(Blah("a"), HasAbsoluteValue(n)); -// -// which may lead to this message (assuming n is 10): -// -// Value of: Blah("a") -// Expected: has absolute value 10 -// Actual: -9 -// -// Note that both the matcher description and its parameter are -// printed, making the message human-friendly. -// -// In the matcher definition body, you can write 'foo_type' to -// reference the type of a parameter named 'foo'. For example, in the -// body of MATCHER_P(HasAbsoluteValue, value) above, you can write -// 'value_type' to refer to the type of 'value'. -// -// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P10 to -// support multi-parameter matchers. -// -// Describing Parameterized Matchers -// ================================= -// -// The last argument to MATCHER*() is a string-typed expression. The -// expression can reference all of the matcher's parameters and a -// special bool-typed variable named 'negation'. When 'negation' is -// false, the expression should evaluate to the matcher's description; -// otherwise it should evaluate to the description of the negation of -// the matcher. For example, -// -// using testing::PrintToString; -// -// MATCHER_P2(InClosedRange, low, hi, -// std::string(negation ? "is not" : "is") + " in range [" + -// PrintToString(low) + ", " + PrintToString(hi) + "]") { -// return low <= arg && arg <= hi; -// } -// ... -// EXPECT_THAT(3, InClosedRange(4, 6)); -// EXPECT_THAT(3, Not(InClosedRange(2, 4))); -// -// would generate two failures that contain the text: -// -// Expected: is in range [4, 6] -// ... -// Expected: is not in range [2, 4] -// -// If you specify "" as the description, the failure message will -// contain the sequence of words in the matcher name followed by the -// parameter values printed as a tuple. For example, -// -// MATCHER_P2(InClosedRange, low, hi, "") { ... } -// ... -// EXPECT_THAT(3, InClosedRange(4, 6)); -// EXPECT_THAT(3, Not(InClosedRange(2, 4))); -// -// would generate two failures that contain the text: -// -// Expected: in closed range (4, 6) -// ... -// Expected: not (in closed range (2, 4)) -// -// Types of Matcher Parameters -// =========================== -// -// For the purpose of typing, you can view -// -// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... } -// -// as shorthand for -// -// template <typename p1_type, ..., typename pk_type> -// FooMatcherPk<p1_type, ..., pk_type> -// Foo(p1_type p1, ..., pk_type pk) { ... } -// -// When you write Foo(v1, ..., vk), the compiler infers the types of -// the parameters v1, ..., and vk for you. If you are not happy with -// the result of the type inference, you can specify the types by -// explicitly instantiating the template, as in Foo<long, bool>(5, -// false). As said earlier, you don't get to (or need to) specify -// 'arg_type' as that's determined by the context in which the matcher -// is used. You can assign the result of expression Foo(p1, ..., pk) -// to a variable of type FooMatcherPk<p1_type, ..., pk_type>. This -// can be useful when composing matchers. -// -// While you can instantiate a matcher template with reference types, -// passing the parameters by pointer usually makes your code more -// readable. If, however, you still want to pass a parameter by -// reference, be aware that in the failure message generated by the -// matcher you will see the value of the referenced object but not its -// address. -// -// Explaining Match Results -// ======================== -// -// Sometimes the matcher description alone isn't enough to explain why -// the match has failed or succeeded. For example, when expecting a -// long string, it can be very helpful to also print the diff between -// the expected string and the actual one. To achieve that, you can -// optionally stream additional information to a special variable -// named result_listener, whose type is a pointer to class -// MatchResultListener: -// -// MATCHER_P(EqualsLongString, str, "") { -// if (arg == str) return true; -// -// *result_listener << "the difference: " -/// << DiffStrings(str, arg); -// return false; -// } -// -// Overloading Matchers -// ==================== -// -// You can overload matchers with different numbers of parameters: -// -// MATCHER_P(Blah, a, description_string1) { ... } -// MATCHER_P2(Blah, a, b, description_string2) { ... } -// -// Caveats -// ======= -// -// When defining a new matcher, you should also consider implementing -// MatcherInterface or using MakePolymorphicMatcher(). These -// approaches require more work than the MATCHER* macros, but also -// give you more control on the types of the value being matched and -// the matcher parameters, which may leads to better compiler error -// messages when the matcher is used wrong. They also allow -// overloading matchers based on parameter types (as opposed to just -// based on the number of parameters). -// -// MATCHER*() can only be used in a namespace scope as templates cannot be -// declared inside of a local class. -// -// More Information -// ================ -// -// To learn more about using these macros, please search for 'MATCHER' -// on -// https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md - -#define MATCHER(name, description)\ - class name##Matcher {\ - public:\ - template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<\ - GTEST_REFERENCE_TO_CONST_(arg_type)> {\ - public:\ - gmock_Impl()\ - {}\ - bool MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener) const override;\ - void DescribeTo(::std::ostream* gmock_os) const override {\ - *gmock_os << FormatDescription(false);\ - }\ - void DescribeNegationTo(::std::ostream* gmock_os) const override {\ - *gmock_os << FormatDescription(true);\ - }\ - private:\ - ::std::string FormatDescription(bool negation) const {\ - ::std::string gmock_description = (description);\ - if (!gmock_description.empty()) {\ - return gmock_description;\ - }\ - return ::testing::internal::FormatMatcherDescription(\ - negation, #name, \ - ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::std::tuple<>()));\ - }\ - };\ - template <typename arg_type>\ - operator ::testing::Matcher<arg_type>() const {\ - return ::testing::Matcher<arg_type>(\ - new gmock_Impl<arg_type>());\ - }\ - name##Matcher() {\ - }\ - private:\ - };\ - inline name##Matcher name() {\ - return name##Matcher();\ - }\ - template <typename arg_type>\ - bool name##Matcher::gmock_Impl<arg_type>::MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P(name, p0, description)\ - template <typename p0##_type>\ - class name##MatcherP {\ - public:\ - template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<\ - GTEST_REFERENCE_TO_CONST_(arg_type)> {\ - public:\ - explicit gmock_Impl(p0##_type gmock_p0)\ - : p0(::std::move(gmock_p0)) {}\ - bool MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener) const override;\ - void DescribeTo(::std::ostream* gmock_os) const override {\ - *gmock_os << FormatDescription(false);\ - }\ - void DescribeNegationTo(::std::ostream* gmock_os) const override {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type const p0;\ - private:\ - ::std::string FormatDescription(bool negation) const {\ - ::std::string gmock_description = (description);\ - if (!gmock_description.empty()) {\ - return gmock_description;\ - }\ - return ::testing::internal::FormatMatcherDescription(\ - negation, #name, \ - ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::std::tuple<p0##_type>(p0)));\ - }\ - };\ - template <typename arg_type>\ - operator ::testing::Matcher<arg_type>() const {\ - return ::testing::Matcher<arg_type>(\ - new gmock_Impl<arg_type>(p0));\ - }\ - explicit name##MatcherP(p0##_type gmock_p0) : p0(::std::move(gmock_p0)) {\ - }\ - p0##_type const p0;\ - private:\ - };\ - template <typename p0##_type>\ - inline name##MatcherP<p0##_type> name(p0##_type p0) {\ - return name##MatcherP<p0##_type>(p0);\ - }\ - template <typename p0##_type>\ - template <typename arg_type>\ - bool name##MatcherP<p0##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P2(name, p0, p1, description)\ - template <typename p0##_type, typename p1##_type>\ - class name##MatcherP2 {\ - public:\ - template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<\ - GTEST_REFERENCE_TO_CONST_(arg_type)> {\ - public:\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1)\ - : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)) {}\ - bool MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener) const override;\ - void DescribeTo(::std::ostream* gmock_os) const override {\ - *gmock_os << FormatDescription(false);\ - }\ - void DescribeNegationTo(::std::ostream* gmock_os) const override {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - private:\ - ::std::string FormatDescription(bool negation) const {\ - ::std::string gmock_description = (description);\ - if (!gmock_description.empty()) {\ - return gmock_description;\ - }\ - return ::testing::internal::FormatMatcherDescription(\ - negation, #name, \ - ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::std::tuple<p0##_type, p1##_type>(p0, p1)));\ - }\ - };\ - template <typename arg_type>\ - operator ::testing::Matcher<arg_type>() const {\ - return ::testing::Matcher<arg_type>(\ - new gmock_Impl<arg_type>(p0, p1));\ - }\ - name##MatcherP2(p0##_type gmock_p0, \ - p1##_type gmock_p1) : p0(::std::move(gmock_p0)), \ - p1(::std::move(gmock_p1)) {\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - private:\ - };\ - template <typename p0##_type, typename p1##_type>\ - inline name##MatcherP2<p0##_type, p1##_type> name(p0##_type p0, \ - p1##_type p1) {\ - return name##MatcherP2<p0##_type, p1##_type>(p0, p1);\ - }\ - template <typename p0##_type, typename p1##_type>\ - template <typename arg_type>\ - bool name##MatcherP2<p0##_type, \ - p1##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P3(name, p0, p1, p2, description)\ - template <typename p0##_type, typename p1##_type, typename p2##_type>\ - class name##MatcherP3 {\ - public:\ - template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<\ - GTEST_REFERENCE_TO_CONST_(arg_type)> {\ - public:\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2)\ - : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \ - p2(::std::move(gmock_p2)) {}\ - bool MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener) const override;\ - void DescribeTo(::std::ostream* gmock_os) const override {\ - *gmock_os << FormatDescription(false);\ - }\ - void DescribeNegationTo(::std::ostream* gmock_os) const override {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - private:\ - ::std::string FormatDescription(bool negation) const {\ - ::std::string gmock_description = (description);\ - if (!gmock_description.empty()) {\ - return gmock_description;\ - }\ - return ::testing::internal::FormatMatcherDescription(\ - negation, #name, \ - ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::std::tuple<p0##_type, p1##_type, p2##_type>(p0, p1, p2)));\ - }\ - };\ - template <typename arg_type>\ - operator ::testing::Matcher<arg_type>() const {\ - return ::testing::Matcher<arg_type>(\ - new gmock_Impl<arg_type>(p0, p1, p2));\ - }\ - name##MatcherP3(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2) : p0(::std::move(gmock_p0)), \ - p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)) {\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - private:\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type>\ - inline name##MatcherP3<p0##_type, p1##_type, p2##_type> name(p0##_type p0, \ - p1##_type p1, p2##_type p2) {\ - return name##MatcherP3<p0##_type, p1##_type, p2##_type>(p0, p1, p2);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type>\ - template <typename arg_type>\ - bool name##MatcherP3<p0##_type, p1##_type, \ - p2##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P4(name, p0, p1, p2, p3, description)\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type>\ - class name##MatcherP4 {\ - public:\ - template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<\ - GTEST_REFERENCE_TO_CONST_(arg_type)> {\ - public:\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3)\ - : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \ - p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)) {}\ - bool MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener) const override;\ - void DescribeTo(::std::ostream* gmock_os) const override {\ - *gmock_os << FormatDescription(false);\ - }\ - void DescribeNegationTo(::std::ostream* gmock_os) const override {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - private:\ - ::std::string FormatDescription(bool negation) const {\ - ::std::string gmock_description = (description);\ - if (!gmock_description.empty()) {\ - return gmock_description;\ - }\ - return ::testing::internal::FormatMatcherDescription(\ - negation, #name, \ - ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::std::tuple<p0##_type, p1##_type, p2##_type, p3##_type>(p0, \ - p1, p2, p3)));\ - }\ - };\ - template <typename arg_type>\ - operator ::testing::Matcher<arg_type>() const {\ - return ::testing::Matcher<arg_type>(\ - new gmock_Impl<arg_type>(p0, p1, p2, p3));\ - }\ - name##MatcherP4(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3) : p0(::std::move(gmock_p0)), \ - p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ - p3(::std::move(gmock_p3)) {\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - private:\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type>\ - inline name##MatcherP4<p0##_type, p1##_type, p2##_type, \ - p3##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, \ - p3##_type p3) {\ - return name##MatcherP4<p0##_type, p1##_type, p2##_type, p3##_type>(p0, \ - p1, p2, p3);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type>\ - template <typename arg_type>\ - bool name##MatcherP4<p0##_type, p1##_type, p2##_type, \ - p3##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P5(name, p0, p1, p2, p3, p4, description)\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type>\ - class name##MatcherP5 {\ - public:\ - template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<\ - GTEST_REFERENCE_TO_CONST_(arg_type)> {\ - public:\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4)\ - : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \ - p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \ - p4(::std::move(gmock_p4)) {}\ - bool MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener) const override;\ - void DescribeTo(::std::ostream* gmock_os) const override {\ - *gmock_os << FormatDescription(false);\ - }\ - void DescribeNegationTo(::std::ostream* gmock_os) const override {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - p4##_type const p4;\ - private:\ - ::std::string FormatDescription(bool negation) const {\ - ::std::string gmock_description = (description);\ - if (!gmock_description.empty()) {\ - return gmock_description;\ - }\ - return ::testing::internal::FormatMatcherDescription(\ - negation, #name, \ - ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::std::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type>(p0, p1, p2, p3, p4)));\ - }\ - };\ - template <typename arg_type>\ - operator ::testing::Matcher<arg_type>() const {\ - return ::testing::Matcher<arg_type>(\ - new gmock_Impl<arg_type>(p0, p1, p2, p3, p4));\ - }\ - name##MatcherP5(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, \ - p4##_type gmock_p4) : p0(::std::move(gmock_p0)), \ - p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ - p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)) {\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - p4##_type const p4;\ - private:\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type>\ - inline name##MatcherP5<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ - p4##_type p4) {\ - return name##MatcherP5<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type>(p0, p1, p2, p3, p4);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type>\ - template <typename arg_type>\ - bool name##MatcherP5<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P6(name, p0, p1, p2, p3, p4, p5, description)\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type>\ - class name##MatcherP6 {\ - public:\ - template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<\ - GTEST_REFERENCE_TO_CONST_(arg_type)> {\ - public:\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5)\ - : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \ - p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \ - p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)) {}\ - bool MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener) const override;\ - void DescribeTo(::std::ostream* gmock_os) const override {\ - *gmock_os << FormatDescription(false);\ - }\ - void DescribeNegationTo(::std::ostream* gmock_os) const override {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - p4##_type const p4;\ - p5##_type const p5;\ - private:\ - ::std::string FormatDescription(bool negation) const {\ - ::std::string gmock_description = (description);\ - if (!gmock_description.empty()) {\ - return gmock_description;\ - }\ - return ::testing::internal::FormatMatcherDescription(\ - negation, #name, \ - ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::std::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type>(p0, p1, p2, p3, p4, p5)));\ - }\ - };\ - template <typename arg_type>\ - operator ::testing::Matcher<arg_type>() const {\ - return ::testing::Matcher<arg_type>(\ - new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5));\ - }\ - name##MatcherP6(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ - p5##_type gmock_p5) : p0(::std::move(gmock_p0)), \ - p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ - p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ - p5(::std::move(gmock_p5)) {\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - p4##_type const p4;\ - p5##_type const p5;\ - private:\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type>\ - inline name##MatcherP6<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, \ - p3##_type p3, p4##_type p4, p5##_type p5) {\ - return name##MatcherP6<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type>(p0, p1, p2, p3, p4, p5);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type>\ - template <typename arg_type>\ - bool name##MatcherP6<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ - p5##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P7(name, p0, p1, p2, p3, p4, p5, p6, description)\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type>\ - class name##MatcherP7 {\ - public:\ - template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<\ - GTEST_REFERENCE_TO_CONST_(arg_type)> {\ - public:\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ - p6##_type gmock_p6)\ - : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \ - p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \ - p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)), \ - p6(::std::move(gmock_p6)) {}\ - bool MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener) const override;\ - void DescribeTo(::std::ostream* gmock_os) const override {\ - *gmock_os << FormatDescription(false);\ - }\ - void DescribeNegationTo(::std::ostream* gmock_os) const override {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - p4##_type const p4;\ - p5##_type const p5;\ - p6##_type const p6;\ - private:\ - ::std::string FormatDescription(bool negation) const {\ - ::std::string gmock_description = (description);\ - if (!gmock_description.empty()) {\ - return gmock_description;\ - }\ - return ::testing::internal::FormatMatcherDescription(\ - negation, #name, \ - ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::std::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type>(p0, p1, p2, p3, p4, p5, \ - p6)));\ - }\ - };\ - template <typename arg_type>\ - operator ::testing::Matcher<arg_type>() const {\ - return ::testing::Matcher<arg_type>(\ - new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, p6));\ - }\ - name##MatcherP7(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ - p5##_type gmock_p5, p6##_type gmock_p6) : p0(::std::move(gmock_p0)), \ - p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ - p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ - p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)) {\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - p4##_type const p4;\ - p5##_type const p5;\ - p6##_type const p6;\ - private:\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type>\ - inline name##MatcherP7<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type> name(p0##_type p0, p1##_type p1, \ - p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \ - p6##_type p6) {\ - return name##MatcherP7<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type>(p0, p1, p2, p3, p4, p5, p6);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type>\ - template <typename arg_type>\ - bool name##MatcherP7<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ - p5##_type, p6##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P8(name, p0, p1, p2, p3, p4, p5, p6, p7, description)\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type>\ - class name##MatcherP8 {\ - public:\ - template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<\ - GTEST_REFERENCE_TO_CONST_(arg_type)> {\ - public:\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ - p6##_type gmock_p6, p7##_type gmock_p7)\ - : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \ - p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \ - p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)), \ - p6(::std::move(gmock_p6)), p7(::std::move(gmock_p7)) {}\ - bool MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener) const override;\ - void DescribeTo(::std::ostream* gmock_os) const override {\ - *gmock_os << FormatDescription(false);\ - }\ - void DescribeNegationTo(::std::ostream* gmock_os) const override {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - p4##_type const p4;\ - p5##_type const p5;\ - p6##_type const p6;\ - p7##_type const p7;\ - private:\ - ::std::string FormatDescription(bool negation) const {\ - ::std::string gmock_description = (description);\ - if (!gmock_description.empty()) {\ - return gmock_description;\ - }\ - return ::testing::internal::FormatMatcherDescription(\ - negation, #name, \ - ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::std::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type>(p0, p1, p2, \ - p3, p4, p5, p6, p7)));\ - }\ - };\ - template <typename arg_type>\ - operator ::testing::Matcher<arg_type>() const {\ - return ::testing::Matcher<arg_type>(\ - new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, p6, p7));\ - }\ - name##MatcherP8(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ - p5##_type gmock_p5, p6##_type gmock_p6, \ - p7##_type gmock_p7) : p0(::std::move(gmock_p0)), \ - p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ - p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ - p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \ - p7(::std::move(gmock_p7)) {\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - p4##_type const p4;\ - p5##_type const p5;\ - p6##_type const p6;\ - p7##_type const p7;\ - private:\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type>\ - inline name##MatcherP8<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type> name(p0##_type p0, \ - p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \ - p6##_type p6, p7##_type p7) {\ - return name##MatcherP8<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type>(p0, p1, p2, p3, p4, p5, \ - p6, p7);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type>\ - template <typename arg_type>\ - bool name##MatcherP8<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ - p5##_type, p6##_type, \ - p7##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, description)\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type, typename p8##_type>\ - class name##MatcherP9 {\ - public:\ - template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<\ - GTEST_REFERENCE_TO_CONST_(arg_type)> {\ - public:\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ - p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8)\ - : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \ - p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \ - p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)), \ - p6(::std::move(gmock_p6)), p7(::std::move(gmock_p7)), \ - p8(::std::move(gmock_p8)) {}\ - bool MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener) const override;\ - void DescribeTo(::std::ostream* gmock_os) const override {\ - *gmock_os << FormatDescription(false);\ - }\ - void DescribeNegationTo(::std::ostream* gmock_os) const override {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - p4##_type const p4;\ - p5##_type const p5;\ - p6##_type const p6;\ - p7##_type const p7;\ - p8##_type const p8;\ - private:\ - ::std::string FormatDescription(bool negation) const {\ - ::std::string gmock_description = (description);\ - if (!gmock_description.empty()) {\ - return gmock_description;\ - }\ - return ::testing::internal::FormatMatcherDescription(\ - negation, #name, \ - ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::std::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type, \ - p8##_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8)));\ - }\ - };\ - template <typename arg_type>\ - operator ::testing::Matcher<arg_type>() const {\ - return ::testing::Matcher<arg_type>(\ - new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8));\ - }\ - name##MatcherP9(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ - p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \ - p8##_type gmock_p8) : p0(::std::move(gmock_p0)), \ - p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ - p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ - p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \ - p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8)) {\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - p4##_type const p4;\ - p5##_type const p5;\ - p6##_type const p6;\ - p7##_type const p7;\ - p8##_type const p8;\ - private:\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type, typename p8##_type>\ - inline name##MatcherP9<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type, \ - p8##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ - p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, \ - p8##_type p8) {\ - return name##MatcherP9<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type, p8##_type>(p0, p1, p2, \ - p3, p4, p5, p6, p7, p8);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type, typename p8##_type>\ - template <typename arg_type>\ - bool name##MatcherP9<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ - p5##_type, p6##_type, p7##_type, \ - p8##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, description)\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type, typename p8##_type, \ - typename p9##_type>\ - class name##MatcherP10 {\ - public:\ - template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<\ - GTEST_REFERENCE_TO_CONST_(arg_type)> {\ - public:\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ - p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \ - p9##_type gmock_p9)\ - : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \ - p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \ - p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)), \ - p6(::std::move(gmock_p6)), p7(::std::move(gmock_p7)), \ - p8(::std::move(gmock_p8)), p9(::std::move(gmock_p9)) {}\ - bool MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener) const override;\ - void DescribeTo(::std::ostream* gmock_os) const override {\ - *gmock_os << FormatDescription(false);\ - }\ - void DescribeNegationTo(::std::ostream* gmock_os) const override {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - p4##_type const p4;\ - p5##_type const p5;\ - p6##_type const p6;\ - p7##_type const p7;\ - p8##_type const p8;\ - p9##_type const p9;\ - private:\ - ::std::string FormatDescription(bool negation) const {\ - ::std::string gmock_description = (description);\ - if (!gmock_description.empty()) {\ - return gmock_description;\ - }\ - return ::testing::internal::FormatMatcherDescription(\ - negation, #name, \ - ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::std::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, \ - p9##_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)));\ - }\ - };\ - template <typename arg_type>\ - operator ::testing::Matcher<arg_type>() const {\ - return ::testing::Matcher<arg_type>(\ - new gmock_Impl<arg_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9));\ - }\ - name##MatcherP10(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ - p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \ - p8##_type gmock_p8, p9##_type gmock_p9) : p0(::std::move(gmock_p0)), \ - p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ - p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ - p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \ - p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8)), \ - p9(::std::move(gmock_p9)) {\ - }\ - p0##_type const p0;\ - p1##_type const p1;\ - p2##_type const p2;\ - p3##_type const p3;\ - p4##_type const p4;\ - p5##_type const p5;\ - p6##_type const p6;\ - p7##_type const p7;\ - p8##_type const p8;\ - p9##_type const p9;\ - private:\ - };\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type, typename p8##_type, \ - typename p9##_type>\ - inline name##MatcherP10<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, \ - p9##_type> name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ - p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8, \ - p9##_type p9) {\ - return name##MatcherP10<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, p9##_type>(p0, \ - p1, p2, p3, p4, p5, p6, p7, p8, p9);\ - }\ - template <typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type, typename p8##_type, \ - typename p9##_type>\ - template <typename arg_type>\ - bool name##MatcherP10<p0##_type, p1##_type, p2##_type, p3##_type, \ - p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, \ - p9##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ diff --git a/googlemock/include/gmock/gmock-generated-matchers.h.pump b/googlemock/include/gmock/gmock-generated-matchers.h.pump deleted file mode 100644 index 69d2ae41..00000000 --- a/googlemock/include/gmock/gmock-generated-matchers.h.pump +++ /dev/null @@ -1,346 +0,0 @@ -$$ -*- mode: c++; -*- -$$ This is a Pump source file. Please use Pump to convert -$$ it to gmock-generated-matchers.h. -$$ -$var n = 10 $$ The maximum arity we support. -$$ }} This line fixes auto-indentation of the following code in Emacs. -// 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 implements some commonly used variadic matchers. - -// GOOGLETEST_CM0002 DO NOT DELETE - -#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ - -#include <iterator> -#include <sstream> -#include <string> -#include <utility> -#include <vector> -#include "gmock/gmock-matchers.h" - -// The MATCHER* family of macros can be used in a namespace scope to -// define custom matchers easily. -// -// Basic Usage -// =========== -// -// The syntax -// -// MATCHER(name, description_string) { statements; } -// -// defines a matcher with the given name that executes the statements, -// which must return a bool to indicate if the match succeeds. Inside -// the statements, you can refer to the value being matched by 'arg', -// and refer to its type by 'arg_type'. -// -// The description string documents what the matcher does, and is used -// to generate the failure message when the match fails. Since a -// MATCHER() is usually defined in a header file shared by multiple -// C++ source files, we require the description to be a C-string -// literal to avoid possible side effects. It can be empty, in which -// case we'll use the sequence of words in the matcher name as the -// description. -// -// For example: -// -// MATCHER(IsEven, "") { return (arg % 2) == 0; } -// -// allows you to write -// -// // Expects mock_foo.Bar(n) to be called where n is even. -// EXPECT_CALL(mock_foo, Bar(IsEven())); -// -// or, -// -// // Verifies that the value of some_expression is even. -// EXPECT_THAT(some_expression, IsEven()); -// -// If the above assertion fails, it will print something like: -// -// Value of: some_expression -// Expected: is even -// Actual: 7 -// -// where the description "is even" is automatically calculated from the -// matcher name IsEven. -// -// Argument Type -// ============= -// -// Note that the type of the value being matched (arg_type) is -// determined by the context in which you use the matcher and is -// supplied to you by the compiler, so you don't need to worry about -// declaring it (nor can you). This allows the matcher to be -// polymorphic. For example, IsEven() can be used to match any type -// where the value of "(arg % 2) == 0" can be implicitly converted to -// a bool. In the "Bar(IsEven())" example above, if method Bar() -// takes an int, 'arg_type' will be int; if it takes an unsigned long, -// 'arg_type' will be unsigned long; and so on. -// -// Parameterizing Matchers -// ======================= -// -// Sometimes you'll want to parameterize the matcher. For that you -// can use another macro: -// -// MATCHER_P(name, param_name, description_string) { statements; } -// -// For example: -// -// MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; } -// -// will allow you to write: -// -// EXPECT_THAT(Blah("a"), HasAbsoluteValue(n)); -// -// which may lead to this message (assuming n is 10): -// -// Value of: Blah("a") -// Expected: has absolute value 10 -// Actual: -9 -// -// Note that both the matcher description and its parameter are -// printed, making the message human-friendly. -// -// In the matcher definition body, you can write 'foo_type' to -// reference the type of a parameter named 'foo'. For example, in the -// body of MATCHER_P(HasAbsoluteValue, value) above, you can write -// 'value_type' to refer to the type of 'value'. -// -// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P$n to -// support multi-parameter matchers. -// -// Describing Parameterized Matchers -// ================================= -// -// The last argument to MATCHER*() is a string-typed expression. The -// expression can reference all of the matcher's parameters and a -// special bool-typed variable named 'negation'. When 'negation' is -// false, the expression should evaluate to the matcher's description; -// otherwise it should evaluate to the description of the negation of -// the matcher. For example, -// -// using testing::PrintToString; -// -// MATCHER_P2(InClosedRange, low, hi, -// std::string(negation ? "is not" : "is") + " in range [" + -// PrintToString(low) + ", " + PrintToString(hi) + "]") { -// return low <= arg && arg <= hi; -// } -// ... -// EXPECT_THAT(3, InClosedRange(4, 6)); -// EXPECT_THAT(3, Not(InClosedRange(2, 4))); -// -// would generate two failures that contain the text: -// -// Expected: is in range [4, 6] -// ... -// Expected: is not in range [2, 4] -// -// If you specify "" as the description, the failure message will -// contain the sequence of words in the matcher name followed by the -// parameter values printed as a tuple. For example, -// -// MATCHER_P2(InClosedRange, low, hi, "") { ... } -// ... -// EXPECT_THAT(3, InClosedRange(4, 6)); -// EXPECT_THAT(3, Not(InClosedRange(2, 4))); -// -// would generate two failures that contain the text: -// -// Expected: in closed range (4, 6) -// ... -// Expected: not (in closed range (2, 4)) -// -// Types of Matcher Parameters -// =========================== -// -// For the purpose of typing, you can view -// -// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... } -// -// as shorthand for -// -// template <typename p1_type, ..., typename pk_type> -// FooMatcherPk<p1_type, ..., pk_type> -// Foo(p1_type p1, ..., pk_type pk) { ... } -// -// When you write Foo(v1, ..., vk), the compiler infers the types of -// the parameters v1, ..., and vk for you. If you are not happy with -// the result of the type inference, you can specify the types by -// explicitly instantiating the template, as in Foo<long, bool>(5, -// false). As said earlier, you don't get to (or need to) specify -// 'arg_type' as that's determined by the context in which the matcher -// is used. You can assign the result of expression Foo(p1, ..., pk) -// to a variable of type FooMatcherPk<p1_type, ..., pk_type>. This -// can be useful when composing matchers. -// -// While you can instantiate a matcher template with reference types, -// passing the parameters by pointer usually makes your code more -// readable. If, however, you still want to pass a parameter by -// reference, be aware that in the failure message generated by the -// matcher you will see the value of the referenced object but not its -// address. -// -// Explaining Match Results -// ======================== -// -// Sometimes the matcher description alone isn't enough to explain why -// the match has failed or succeeded. For example, when expecting a -// long string, it can be very helpful to also print the diff between -// the expected string and the actual one. To achieve that, you can -// optionally stream additional information to a special variable -// named result_listener, whose type is a pointer to class -// MatchResultListener: -// -// MATCHER_P(EqualsLongString, str, "") { -// if (arg == str) return true; -// -// *result_listener << "the difference: " -/// << DiffStrings(str, arg); -// return false; -// } -// -// Overloading Matchers -// ==================== -// -// You can overload matchers with different numbers of parameters: -// -// MATCHER_P(Blah, a, description_string1) { ... } -// MATCHER_P2(Blah, a, b, description_string2) { ... } -// -// Caveats -// ======= -// -// When defining a new matcher, you should also consider implementing -// MatcherInterface or using MakePolymorphicMatcher(). These -// approaches require more work than the MATCHER* macros, but also -// give you more control on the types of the value being matched and -// the matcher parameters, which may leads to better compiler error -// messages when the matcher is used wrong. They also allow -// overloading matchers based on parameter types (as opposed to just -// based on the number of parameters). -// -// MATCHER*() can only be used in a namespace scope as templates cannot be -// declared inside of a local class. -// -// More Information -// ================ -// -// To learn more about using these macros, please search for 'MATCHER' -// on -// https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md - -$range i 0..n -$for i - -[[ -$var macro_name = [[$if i==0 [[MATCHER]] $elif i==1 [[MATCHER_P]] - $else [[MATCHER_P$i]]]] -$var class_name = [[name##Matcher[[$if i==0 [[]] $elif i==1 [[P]] - $else [[P$i]]]]]] -$range j 0..i-1 -$var template = [[$if i==0 [[]] $else [[ - - template <$for j, [[typename p$j##_type]]>\ -]]]] -$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]] -$var impl_ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]] -$var impl_inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::std::move(gmock_p$j))]]]]]] -$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::std::move(gmock_p$j))]]]]]] -$var params = [[$for j, [[p$j]]]] -$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]] -$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]] -$var param_field_decls = [[$for j -[[ - - p$j##_type const p$j;\ -]]]] -$var param_field_decls2 = [[$for j -[[ - - p$j##_type const p$j;\ -]]]] - -#define $macro_name(name$for j [[, p$j]], description)\$template - class $class_name {\ - public:\ - template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<\ - GTEST_REFERENCE_TO_CONST_(arg_type)> {\ - public:\ - [[$if i==1 [[explicit ]]]]gmock_Impl($impl_ctor_param_list)\ - $impl_inits {}\ - bool MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener) const override;\ - void DescribeTo(::std::ostream* gmock_os) const override {\ - *gmock_os << FormatDescription(false);\ - }\ - void DescribeNegationTo(::std::ostream* gmock_os) const override {\ - *gmock_os << FormatDescription(true);\ - }\$param_field_decls - private:\ - ::std::string FormatDescription(bool negation) const {\ - ::std::string gmock_description = (description);\ - if (!gmock_description.empty()) {\ - return gmock_description;\ - }\ - return ::testing::internal::FormatMatcherDescription(\ - negation, #name, \ - ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::std::tuple<$for j, [[p$j##_type]]>($for j, [[p$j]])));\ - }\ - };\ - template <typename arg_type>\ - operator ::testing::Matcher<arg_type>() const {\ - return ::testing::Matcher<arg_type>(\ - new gmock_Impl<arg_type>($params));\ - }\ - [[$if i==1 [[explicit ]]]]$class_name($ctor_param_list)$inits {\ - }\$param_field_decls2 - private:\ - };\$template - inline $class_name$param_types name($param_types_and_names) {\ - return $class_name$param_types($params);\ - }\$template - template <typename arg_type>\ - bool $class_name$param_types::gmock_Impl<arg_type>::MatchAndExplain(\ - GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const -]] - - -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index e71570bc..fe88a7c7 100644 --- a/googlemock/include/gmock/gmock-matchers.h +++ b/googlemock/include/gmock/gmock-matchers.h @@ -30,7 +30,220 @@ // Google Mock - a framework for writing C++ mock classes. // -// This file implements some commonly used argument matchers. More +// The MATCHER* family of macros can be used in a namespace scope to +// define custom matchers easily. +// +// Basic Usage +// =========== +// +// The syntax +// +// MATCHER(name, description_string) { statements; } +// +// defines a matcher with the given name that executes the statements, +// which must return a bool to indicate if the match succeeds. Inside +// the statements, you can refer to the value being matched by 'arg', +// and refer to its type by 'arg_type'. +// +// The description string documents what the matcher does, and is used +// to generate the failure message when the match fails. Since a +// MATCHER() is usually defined in a header file shared by multiple +// C++ source files, we require the description to be a C-string +// literal to avoid possible side effects. It can be empty, in which +// case we'll use the sequence of words in the matcher name as the +// description. +// +// For example: +// +// MATCHER(IsEven, "") { return (arg % 2) == 0; } +// +// allows you to write +// +// // Expects mock_foo.Bar(n) to be called where n is even. +// EXPECT_CALL(mock_foo, Bar(IsEven())); +// +// or, +// +// // Verifies that the value of some_expression is even. +// EXPECT_THAT(some_expression, IsEven()); +// +// If the above assertion fails, it will print something like: +// +// Value of: some_expression +// Expected: is even +// Actual: 7 +// +// where the description "is even" is automatically calculated from the +// matcher name IsEven. +// +// Argument Type +// ============= +// +// Note that the type of the value being matched (arg_type) is +// determined by the context in which you use the matcher and is +// supplied to you by the compiler, so you don't need to worry about +// declaring it (nor can you). This allows the matcher to be +// polymorphic. For example, IsEven() can be used to match any type +// where the value of "(arg % 2) == 0" can be implicitly converted to +// a bool. In the "Bar(IsEven())" example above, if method Bar() +// takes an int, 'arg_type' will be int; if it takes an unsigned long, +// 'arg_type' will be unsigned long; and so on. +// +// Parameterizing Matchers +// ======================= +// +// Sometimes you'll want to parameterize the matcher. For that you +// can use another macro: +// +// MATCHER_P(name, param_name, description_string) { statements; } +// +// For example: +// +// MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; } +// +// will allow you to write: +// +// EXPECT_THAT(Blah("a"), HasAbsoluteValue(n)); +// +// which may lead to this message (assuming n is 10): +// +// Value of: Blah("a") +// Expected: has absolute value 10 +// Actual: -9 +// +// Note that both the matcher description and its parameter are +// printed, making the message human-friendly. +// +// In the matcher definition body, you can write 'foo_type' to +// reference the type of a parameter named 'foo'. For example, in the +// body of MATCHER_P(HasAbsoluteValue, value) above, you can write +// 'value_type' to refer to the type of 'value'. +// +// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P$n to +// support multi-parameter matchers. +// +// Describing Parameterized Matchers +// ================================= +// +// The last argument to MATCHER*() is a string-typed expression. The +// expression can reference all of the matcher's parameters and a +// special bool-typed variable named 'negation'. When 'negation' is +// false, the expression should evaluate to the matcher's description; +// otherwise it should evaluate to the description of the negation of +// the matcher. For example, +// +// using testing::PrintToString; +// +// MATCHER_P2(InClosedRange, low, hi, +// std::string(negation ? "is not" : "is") + " in range [" + +// PrintToString(low) + ", " + PrintToString(hi) + "]") { +// return low <= arg && arg <= hi; +// } +// ... +// EXPECT_THAT(3, InClosedRange(4, 6)); +// EXPECT_THAT(3, Not(InClosedRange(2, 4))); +// +// would generate two failures that contain the text: +// +// Expected: is in range [4, 6] +// ... +// Expected: is not in range [2, 4] +// +// If you specify "" as the description, the failure message will +// contain the sequence of words in the matcher name followed by the +// parameter values printed as a tuple. For example, +// +// MATCHER_P2(InClosedRange, low, hi, "") { ... } +// ... +// EXPECT_THAT(3, InClosedRange(4, 6)); +// EXPECT_THAT(3, Not(InClosedRange(2, 4))); +// +// would generate two failures that contain the text: +// +// Expected: in closed range (4, 6) +// ... +// Expected: not (in closed range (2, 4)) +// +// Types of Matcher Parameters +// =========================== +// +// For the purpose of typing, you can view +// +// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... } +// +// as shorthand for +// +// template <typename p1_type, ..., typename pk_type> +// FooMatcherPk<p1_type, ..., pk_type> +// Foo(p1_type p1, ..., pk_type pk) { ... } +// +// When you write Foo(v1, ..., vk), the compiler infers the types of +// the parameters v1, ..., and vk for you. If you are not happy with +// the result of the type inference, you can specify the types by +// explicitly instantiating the template, as in Foo<long, bool>(5, +// false). As said earlier, you don't get to (or need to) specify +// 'arg_type' as that's determined by the context in which the matcher +// is used. You can assign the result of expression Foo(p1, ..., pk) +// to a variable of type FooMatcherPk<p1_type, ..., pk_type>. This +// can be useful when composing matchers. +// +// While you can instantiate a matcher template with reference types, +// passing the parameters by pointer usually makes your code more +// readable. If, however, you still want to pass a parameter by +// reference, be aware that in the failure message generated by the +// matcher you will see the value of the referenced object but not its +// address. +// +// Explaining Match Results +// ======================== +// +// Sometimes the matcher description alone isn't enough to explain why +// the match has failed or succeeded. For example, when expecting a +// long string, it can be very helpful to also print the diff between +// the expected string and the actual one. To achieve that, you can +// optionally stream additional information to a special variable +// named result_listener, whose type is a pointer to class +// MatchResultListener: +// +// MATCHER_P(EqualsLongString, str, "") { +// if (arg == str) return true; +// +// *result_listener << "the difference: " +/// << DiffStrings(str, arg); +// return false; +// } +// +// Overloading Matchers +// ==================== +// +// You can overload matchers with different numbers of parameters: +// +// MATCHER_P(Blah, a, description_string1) { ... } +// MATCHER_P2(Blah, a, b, description_string2) { ... } +// +// Caveats +// ======= +// +// When defining a new matcher, you should also consider implementing +// MatcherInterface or using MakePolymorphicMatcher(). These +// approaches require more work than the MATCHER* macros, but also +// give you more control on the types of the value being matched and +// the matcher parameters, which may leads to better compiler error +// messages when the matcher is used wrong. They also allow +// overloading matchers based on parameter types (as opposed to just +// based on the number of parameters). +// +// MATCHER*() can only be used in a namespace scope as templates cannot be +// declared inside of a local class. +// +// More Information +// ================ +// +// To learn more about using these macros, please search for 'MATCHER' +// on +// https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md +// +// This file also implements some commonly used argument matchers. More // matchers can be defined by the user implementing the // MatcherInterface<T> interface if necessary. // @@ -57,6 +270,7 @@ #include "gmock/internal/gmock-internal-utils.h" #include "gmock/internal/gmock-port.h" +#include "gmock/internal/gmock-pp.h" #include "gtest/gtest.h" // MSVC warning C5046 is new as of VS2017 version 15.8. @@ -210,7 +424,14 @@ class MatcherCastImpl<T, Matcher<U> > { !std::is_base_of<FromType, ToType>::value, "Can't implicitly convert from <base> to <derived>"); - return source_matcher_.MatchAndExplain(static_cast<U>(x), listener); + // Do the cast to `U` explicitly if necessary. + // Otherwise, let implicit conversions do the trick. + using CastType = + typename std::conditional<std::is_convertible<T&, const U&>::value, + T&, U>::type; + + return source_matcher_.MatchAndExplain(static_cast<CastType>(x), + listener); } void DescribeTo(::std::ostream* os) const override { @@ -236,6 +457,50 @@ class MatcherCastImpl<T, Matcher<T> > { static Matcher<T> Cast(const Matcher<T>& matcher) { return matcher; } }; +// Template specialization for parameterless Matcher. +template <typename Derived> +class MatcherBaseImpl { + public: + MatcherBaseImpl() = default; + + template <typename T> + operator ::testing::Matcher<T>() const { // NOLINT(runtime/explicit) + return ::testing::Matcher<T>(new + typename Derived::template gmock_Impl<T>()); + } +}; + +// Template specialization for Matcher with parameters. +template <template <typename...> class Derived, typename... Ts> +class MatcherBaseImpl<Derived<Ts...>> { + public: + // Mark the constructor explicit for single argument T to avoid implicit + // conversions. + template <typename E = std::enable_if<sizeof...(Ts) == 1>, + typename E::type* = nullptr> + explicit MatcherBaseImpl(Ts... params) + : params_(std::forward<Ts>(params)...) {} + template <typename E = std::enable_if<sizeof...(Ts) != 1>, + typename = typename E::type> + MatcherBaseImpl(Ts... params) // NOLINT + : params_(std::forward<Ts>(params)...) {} + + template <typename F> + operator ::testing::Matcher<F>() const { // NOLINT(runtime/explicit) + return Apply<F>(MakeIndexSequence<sizeof...(Ts)>{}); + } + + private: + template <typename F, std::size_t... tuple_ids> + ::testing::Matcher<F> Apply(IndexSequence<tuple_ids...>) const { + return ::testing::Matcher<F>( + new typename Derived<Ts...>::template gmock_Impl<F>( + std::get<tuple_ids>(params_)...)); + } + + const std::tuple<Ts...> params_; +}; + } // namespace internal // In order to be safe and clear, casting between different matcher @@ -247,56 +512,43 @@ inline Matcher<T> MatcherCast(const M& matcher) { return internal::MatcherCastImpl<T, M>::Cast(matcher); } -// Implements SafeMatcherCast(). -// -// FIXME: The intermediate SafeMatcherCastImpl class was introduced as a -// workaround for a compiler bug, and can now be removed. -template <typename T> -class SafeMatcherCastImpl { - public: - // This overload handles polymorphic matchers and values only since - // monomorphic matchers are handled by the next one. - template <typename M> - static inline Matcher<T> Cast(const M& polymorphic_matcher_or_value) { - return internal::MatcherCastImpl<T, M>::Cast(polymorphic_matcher_or_value); - } - - // This overload handles monomorphic matchers. - // - // In general, if type T can be implicitly converted to type U, we can - // safely convert a Matcher<U> to a Matcher<T> (i.e. Matcher is - // contravariant): just keep a copy of the original Matcher<U>, convert the - // argument from type T to U, and then pass it to the underlying Matcher<U>. - // The only exception is when U is a reference and T is not, as the - // underlying Matcher<U> may be interested in the argument's address, which - // is not preserved in the conversion from T to U. - template <typename U> - static inline Matcher<T> Cast(const Matcher<U>& matcher) { - // Enforce that T can be implicitly converted to U. - GTEST_COMPILE_ASSERT_((std::is_convertible<T, U>::value), - "T must be implicitly convertible to U"); - // Enforce that we are not converting a non-reference type T to a reference - // type U. - GTEST_COMPILE_ASSERT_( - std::is_reference<T>::value || !std::is_reference<U>::value, - cannot_convert_non_reference_arg_to_reference); - // In case both T and U are arithmetic types, enforce that the - // conversion is not lossy. - typedef GTEST_REMOVE_REFERENCE_AND_CONST_(T) RawT; - typedef GTEST_REMOVE_REFERENCE_AND_CONST_(U) RawU; - const bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther; - const bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther; - GTEST_COMPILE_ASSERT_( - kTIsOther || kUIsOther || - (internal::LosslessArithmeticConvertible<RawT, RawU>::value), - conversion_of_arithmetic_types_must_be_lossless); - return MatcherCast<T>(matcher); - } -}; - +// This overload handles polymorphic matchers and values only since +// monomorphic matchers are handled by the next one. template <typename T, typename M> -inline Matcher<T> SafeMatcherCast(const M& polymorphic_matcher) { - return SafeMatcherCastImpl<T>::Cast(polymorphic_matcher); +inline Matcher<T> SafeMatcherCast(const M& polymorphic_matcher_or_value) { + return MatcherCast<T>(polymorphic_matcher_or_value); +} + +// This overload handles monomorphic matchers. +// +// In general, if type T can be implicitly converted to type U, we can +// safely convert a Matcher<U> to a Matcher<T> (i.e. Matcher is +// contravariant): just keep a copy of the original Matcher<U>, convert the +// argument from type T to U, and then pass it to the underlying Matcher<U>. +// The only exception is when U is a reference and T is not, as the +// underlying Matcher<U> may be interested in the argument's address, which +// is not preserved in the conversion from T to U. +template <typename T, typename U> +inline Matcher<T> SafeMatcherCast(const Matcher<U>& matcher) { + // Enforce that T can be implicitly converted to U. + static_assert(std::is_convertible<const T&, const U&>::value, + "T must be implicitly convertible to U"); + // Enforce that we are not converting a non-reference type T to a reference + // type U. + GTEST_COMPILE_ASSERT_( + std::is_reference<T>::value || !std::is_reference<U>::value, + cannot_convert_non_reference_arg_to_reference); + // In case both T and U are arithmetic types, enforce that the + // conversion is not lossy. + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(T) RawT; + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(U) RawU; + constexpr bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther; + constexpr bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther; + GTEST_COMPILE_ASSERT_( + kTIsOther || kUIsOther || + (internal::LosslessArithmeticConvertible<RawT, RawU>::value), + conversion_of_arithmetic_types_must_be_lossless); + return MatcherCast<T>(matcher); } // A<T>() returns a matcher that matches any value of type T. @@ -661,15 +913,15 @@ class StrEqualityMatcher { bool case_sensitive) : string_(str), expect_eq_(expect_eq), case_sensitive_(case_sensitive) {} -#if GTEST_HAS_ABSL - bool MatchAndExplain(const absl::string_view& s, +#if GTEST_INTERNAL_HAS_STRING_VIEW + bool MatchAndExplain(const internal::StringView& s, MatchResultListener* listener) const { - // This should fail to compile if absl::string_view is used with wide + // This should fail to compile if StringView is used with wide // strings. const StringType& str = std::string(s); return MatchAndExplain(str, listener); } -#endif // GTEST_HAS_ABSL +#endif // GTEST_INTERNAL_HAS_STRING_VIEW // Accepts pointer types, particularly: // const char* @@ -687,11 +939,11 @@ class StrEqualityMatcher { // Matches anything that can convert to StringType. // // This is a template, not just a plain function with const StringType&, - // because absl::string_view has some interfering non-explicit constructors. + // because StringView has some interfering non-explicit constructors. template <typename MatcheeStringType> bool MatchAndExplain(const MatcheeStringType& s, MatchResultListener* /* listener */) const { - const StringType& s2(s); + const StringType s2(s); const bool eq = case_sensitive_ ? s2 == string_ : CaseInsensitiveStringEquals(s2, string_); return expect_eq_ == eq; @@ -731,15 +983,15 @@ class HasSubstrMatcher { explicit HasSubstrMatcher(const StringType& substring) : substring_(substring) {} -#if GTEST_HAS_ABSL - bool MatchAndExplain(const absl::string_view& s, +#if GTEST_INTERNAL_HAS_STRING_VIEW + bool MatchAndExplain(const internal::StringView& s, MatchResultListener* listener) const { - // This should fail to compile if absl::string_view is used with wide + // This should fail to compile if StringView is used with wide // strings. const StringType& str = std::string(s); return MatchAndExplain(str, listener); } -#endif // GTEST_HAS_ABSL +#endif // GTEST_INTERNAL_HAS_STRING_VIEW // Accepts pointer types, particularly: // const char* @@ -754,7 +1006,7 @@ class HasSubstrMatcher { // Matches anything that can convert to StringType. // // This is a template, not just a plain function with const StringType&, - // because absl::string_view has some interfering non-explicit constructors. + // because StringView has some interfering non-explicit constructors. template <typename MatcheeStringType> bool MatchAndExplain(const MatcheeStringType& s, MatchResultListener* /* listener */) const { @@ -787,15 +1039,15 @@ class StartsWithMatcher { explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) { } -#if GTEST_HAS_ABSL - bool MatchAndExplain(const absl::string_view& s, +#if GTEST_INTERNAL_HAS_STRING_VIEW + bool MatchAndExplain(const internal::StringView& s, MatchResultListener* listener) const { - // This should fail to compile if absl::string_view is used with wide + // This should fail to compile if StringView is used with wide // strings. const StringType& str = std::string(s); return MatchAndExplain(str, listener); } -#endif // GTEST_HAS_ABSL +#endif // GTEST_INTERNAL_HAS_STRING_VIEW // Accepts pointer types, particularly: // const char* @@ -810,7 +1062,7 @@ class StartsWithMatcher { // Matches anything that can convert to StringType. // // This is a template, not just a plain function with const StringType&, - // because absl::string_view has some interfering non-explicit constructors. + // because StringView has some interfering non-explicit constructors. template <typename MatcheeStringType> bool MatchAndExplain(const MatcheeStringType& s, MatchResultListener* /* listener */) const { @@ -843,15 +1095,15 @@ class EndsWithMatcher { public: explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {} -#if GTEST_HAS_ABSL - bool MatchAndExplain(const absl::string_view& s, +#if GTEST_INTERNAL_HAS_STRING_VIEW + bool MatchAndExplain(const internal::StringView& s, MatchResultListener* listener) const { - // This should fail to compile if absl::string_view is used with wide + // This should fail to compile if StringView is used with wide // strings. const StringType& str = std::string(s); return MatchAndExplain(str, listener); } -#endif // GTEST_HAS_ABSL +#endif // GTEST_INTERNAL_HAS_STRING_VIEW // Accepts pointer types, particularly: // const char* @@ -866,7 +1118,7 @@ class EndsWithMatcher { // Matches anything that can convert to StringType. // // This is a template, not just a plain function with const StringType&, - // because absl::string_view has some interfering non-explicit constructors. + // because StringView has some interfering non-explicit constructors. template <typename MatcheeStringType> bool MatchAndExplain(const MatcheeStringType& s, MatchResultListener* /* listener */) const { @@ -3182,6 +3434,8 @@ class BoundSecondMatcher { BoundSecondMatcher(const Tuple2Matcher& tm, const Second& second) : tuple2_matcher_(tm), second_value_(second) {} + BoundSecondMatcher(const BoundSecondMatcher& other) = default; + template <typename T> operator Matcher<T>() const { return MakeMatcher(new Impl<T>(tuple2_matcher_, second_value_)); @@ -4057,11 +4311,7 @@ template <typename Container> inline PolymorphicMatcher<internal::ContainerEqMatcher< typename std::remove_const<Container>::type>> ContainerEq(const Container& rhs) { - // This following line is for working around a bug in MSVC 8.0, - // which causes Container to be a const type sometimes. - typedef typename std::remove_const<Container>::type RawContainer; - return MakePolymorphicMatcher( - internal::ContainerEqMatcher<RawContainer>(rhs)); + return MakePolymorphicMatcher(internal::ContainerEqMatcher<Container>(rhs)); } // Returns a matcher that matches a container that, when sorted using @@ -4094,12 +4344,8 @@ template <typename TupleMatcher, typename Container> inline internal::PointwiseMatcher<TupleMatcher, typename std::remove_const<Container>::type> Pointwise(const TupleMatcher& tuple_matcher, const Container& rhs) { - // This following line is for working around a bug in MSVC 8.0, - // which causes Container to be a const type sometimes (e.g. when - // rhs is a const int[]).. - typedef typename std::remove_const<Container>::type RawContainer; - return internal::PointwiseMatcher<TupleMatcher, RawContainer>( - tuple_matcher, rhs); + return internal::PointwiseMatcher<TupleMatcher, Container>(tuple_matcher, + rhs); } @@ -4130,14 +4376,9 @@ inline internal::UnorderedElementsAreArrayMatcher< typename std::remove_const<RhsContainer>::type>::type::value_type>> UnorderedPointwise(const Tuple2Matcher& tuple2_matcher, const RhsContainer& rhs_container) { - // This following line is for working around a bug in MSVC 8.0, - // which causes RhsContainer to be a const type sometimes (e.g. when - // rhs_container is a const int[]). - typedef typename std::remove_const<RhsContainer>::type RawRhsContainer; - // RhsView allows the same code to handle RhsContainer being a // STL-style container and it being a native C-style array. - typedef typename internal::StlContainerView<RawRhsContainer> RhsView; + typedef typename internal::StlContainerView<RhsContainer> RhsView; typedef typename RhsView::type RhsStlContainer; typedef typename RhsStlContainer::value_type Second; const RhsStlContainer& rhs_stl_container = @@ -4579,6 +4820,156 @@ PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T> > VariantWith( #define EXPECT_THAT(value, matcher) EXPECT_PRED_FORMAT1(\ ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value) +// MATCHER* macroses itself are listed below. +#define MATCHER(name, description) \ + class name##Matcher \ + : public ::testing::internal::MatcherBaseImpl<name##Matcher> { \ + public: \ + template <typename arg_type> \ + class gmock_Impl : public ::testing::MatcherInterface<const arg_type&> { \ + public: \ + gmock_Impl() {} \ + bool MatchAndExplain( \ + const arg_type& arg, \ + ::testing::MatchResultListener* result_listener) const override; \ + void DescribeTo(::std::ostream* gmock_os) const override { \ + *gmock_os << FormatDescription(false); \ + } \ + void DescribeNegationTo(::std::ostream* gmock_os) const override { \ + *gmock_os << FormatDescription(true); \ + } \ + \ + private: \ + ::std::string FormatDescription(bool negation) const { \ + ::std::string gmock_description = (description); \ + if (!gmock_description.empty()) { \ + return gmock_description; \ + } \ + return ::testing::internal::FormatMatcherDescription(negation, #name, \ + {}); \ + } \ + }; \ + }; \ + GTEST_ATTRIBUTE_UNUSED_ inline name##Matcher name() { return {}; } \ + template <typename arg_type> \ + bool name##Matcher::gmock_Impl<arg_type>::MatchAndExplain( \ + const arg_type& arg, \ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_) \ + const + +#define MATCHER_P(name, p0, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP, description, (p0)) +#define MATCHER_P2(name, p0, p1, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP2, description, (p0, p1)) +#define MATCHER_P3(name, p0, p1, p2, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP3, description, (p0, p1, p2)) +#define MATCHER_P4(name, p0, p1, p2, p3, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP4, description, (p0, p1, p2, p3)) +#define MATCHER_P5(name, p0, p1, p2, p3, p4, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP5, description, \ + (p0, p1, p2, p3, p4)) +#define MATCHER_P6(name, p0, p1, p2, p3, p4, p5, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP6, description, \ + (p0, p1, p2, p3, p4, p5)) +#define MATCHER_P7(name, p0, p1, p2, p3, p4, p5, p6, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP7, description, \ + (p0, p1, p2, p3, p4, p5, p6)) +#define MATCHER_P8(name, p0, p1, p2, p3, p4, p5, p6, p7, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP8, description, \ + (p0, p1, p2, p3, p4, p5, p6, p7)) +#define MATCHER_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP9, description, \ + (p0, p1, p2, p3, p4, p5, p6, p7, p8)) +#define MATCHER_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP10, description, \ + (p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)) + +#define GMOCK_INTERNAL_MATCHER(name, full_name, description, args) \ + template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)> \ + class full_name : public ::testing::internal::MatcherBaseImpl< \ + full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>> { \ + public: \ + using full_name::MatcherBaseImpl::MatcherBaseImpl; \ + template <typename arg_type> \ + class gmock_Impl : public ::testing::MatcherInterface<const arg_type&> { \ + public: \ + explicit gmock_Impl(GMOCK_INTERNAL_MATCHER_FUNCTION_ARGS(args)) \ + : GMOCK_INTERNAL_MATCHER_FORWARD_ARGS(args) {} \ + bool MatchAndExplain( \ + const arg_type& arg, \ + ::testing::MatchResultListener* result_listener) const override; \ + void DescribeTo(::std::ostream* gmock_os) const override { \ + *gmock_os << FormatDescription(false); \ + } \ + void DescribeNegationTo(::std::ostream* gmock_os) const override { \ + *gmock_os << FormatDescription(true); \ + } \ + GMOCK_INTERNAL_MATCHER_MEMBERS(args) \ + \ + private: \ + ::std::string FormatDescription(bool negation) const { \ + ::std::string gmock_description = (description); \ + if (!gmock_description.empty()) { \ + return gmock_description; \ + } \ + return ::testing::internal::FormatMatcherDescription( \ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings( \ + ::std::tuple<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>( \ + GMOCK_INTERNAL_MATCHER_MEMBERS_USAGE(args)))); \ + } \ + }; \ + }; \ + template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)> \ + inline full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)> name( \ + GMOCK_INTERNAL_MATCHER_FUNCTION_ARGS(args)) { \ + return full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>( \ + GMOCK_INTERNAL_MATCHER_ARGS_USAGE(args)); \ + } \ + template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)> \ + template <typename arg_type> \ + bool full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>::gmock_Impl< \ + arg_type>::MatchAndExplain(const arg_type& arg, \ + ::testing::MatchResultListener* \ + result_listener GTEST_ATTRIBUTE_UNUSED_) \ + const + +#define GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args) \ + GMOCK_PP_TAIL( \ + GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAM, , args)) +#define GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAM(i_unused, data_unused, arg) \ + , typename arg##_type + +#define GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args) \ + GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_TYPE_PARAM, , args)) +#define GMOCK_INTERNAL_MATCHER_TYPE_PARAM(i_unused, data_unused, arg) \ + , arg##_type + +#define GMOCK_INTERNAL_MATCHER_FUNCTION_ARGS(args) \ + GMOCK_PP_TAIL(dummy_first GMOCK_PP_FOR_EACH( \ + GMOCK_INTERNAL_MATCHER_FUNCTION_ARG, , args)) +#define GMOCK_INTERNAL_MATCHER_FUNCTION_ARG(i, data_unused, arg) \ + , arg##_type gmock_p##i + +#define GMOCK_INTERNAL_MATCHER_FORWARD_ARGS(args) \ + GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_FORWARD_ARG, , args)) +#define GMOCK_INTERNAL_MATCHER_FORWARD_ARG(i, data_unused, arg) \ + , arg(::std::forward<arg##_type>(gmock_p##i)) + +#define GMOCK_INTERNAL_MATCHER_MEMBERS(args) \ + GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_MEMBER, , args) +#define GMOCK_INTERNAL_MATCHER_MEMBER(i_unused, data_unused, arg) \ + const arg##_type arg; + +#define GMOCK_INTERNAL_MATCHER_MEMBERS_USAGE(args) \ + GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_MEMBER_USAGE, , args)) +#define GMOCK_INTERNAL_MATCHER_MEMBER_USAGE(i_unused, data_unused, arg) , arg + +#define GMOCK_INTERNAL_MATCHER_ARGS_USAGE(args) \ + GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_ARG_USAGE, , args)) +#define GMOCK_INTERNAL_MATCHER_ARG_USAGE(i, data_unused, arg_unused) \ + , gmock_p##i + } // namespace testing GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 5046 diff --git a/googlemock/include/gmock/gmock-more-matchers.h b/googlemock/include/gmock/gmock-more-matchers.h index 1c9a399a..b306dd60 100644 --- a/googlemock/include/gmock/gmock-more-matchers.h +++ b/googlemock/include/gmock/gmock-more-matchers.h @@ -30,7 +30,7 @@ // Google Mock - a framework for writing C++ mock classes. // -// This file implements some matchers that depend on gmock-generated-matchers.h. +// This file implements some matchers that depend on gmock-matchers.h. // // Note that tests are implemented in gmock-matchers_test.cc rather than // gmock-more-matchers-test.cc. @@ -40,7 +40,7 @@ #ifndef GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_ #define GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_ -#include "gmock/gmock-generated-matchers.h" +#include "gmock/gmock-matchers.h" namespace testing { diff --git a/googlemock/include/gmock/gmock-spec-builders.h b/googlemock/include/gmock/gmock-spec-builders.h index 80c13b55..4b5fc661 100644 --- a/googlemock/include/gmock/gmock-spec-builders.h +++ b/googlemock/include/gmock/gmock-spec-builders.h @@ -1350,12 +1350,6 @@ class ReferenceOrValueWrapper<T&> { T* value_ptr_; }; -// MSVC warns about using 'this' in base member initializer list, so -// we need to temporarily disable the warning. We have to do it for -// the entire class to suppress the warning, even though it's about -// the constructor only. -GTEST_DISABLE_MSC_WARNINGS_PUSH_(4355) - // C++ treats the void type specially. For example, you cannot define // a void-typed variable or pass a void value to a function. // ActionResultHolder<T> holds a value of type T, where T must be a @@ -1786,18 +1780,85 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase { } }; // class FunctionMocker -GTEST_DISABLE_MSC_WARNINGS_POP_() // 4355 - // Reports an uninteresting call (whose description is in msg) in the // manner specified by 'reaction'. void ReportUninterestingCall(CallReaction reaction, const std::string& msg); } // namespace internal -// A MockFunction<F> class has one mock method whose type is F. It is -// useful when you just want your test code to emit some messages and -// have Google Mock verify the right messages are sent (and perhaps at -// the right times). For example, if you are exercising code: +namespace internal { + +template <typename F> +class MockFunction; + +template <typename R, typename... Args> +class MockFunction<R(Args...)> { + public: + MockFunction(const MockFunction&) = delete; + MockFunction& operator=(const MockFunction&) = delete; + + std::function<R(Args...)> AsStdFunction() { + return [this](Args... args) -> R { + return this->Call(std::forward<Args>(args)...); + }; + } + + // Implementation detail: the expansion of the MOCK_METHOD macro. + R Call(Args... args) { + mock_.SetOwnerAndName(this, "Call"); + return mock_.Invoke(std::forward<Args>(args)...); + } + + MockSpec<R(Args...)> gmock_Call(Matcher<Args>... m) { + mock_.RegisterOwner(this); + return mock_.With(std::move(m)...); + } + + MockSpec<R(Args...)> gmock_Call(const WithoutMatchers&, R (*)(Args...)) { + return this->gmock_Call(::testing::A<Args>()...); + } + + protected: + MockFunction() = default; + ~MockFunction() = default; + + private: + FunctionMocker<R(Args...)> mock_; +}; + +/* +The SignatureOf<F> struct is a meta-function returning function signature +corresponding to the provided F argument. + +It makes use of MockFunction easier by allowing it to accept more F arguments +than just function signatures. + +Specializations provided here cover only a signature type itself and +std::function. However, if need be it can be easily extended to cover also other +types (like for example boost::function). +*/ + +template <typename F> +struct SignatureOf; + +template <typename R, typename... Args> +struct SignatureOf<R(Args...)> { + using type = R(Args...); +}; + +template <typename F> +struct SignatureOf<std::function<F>> : SignatureOf<F> {}; + +template <typename F> +using SignatureOfT = typename SignatureOf<F>::type; + +} // namespace internal + +// A MockFunction<F> type has one mock method whose type is +// internal::SignatureOfT<F>. It is useful when you just want your +// test code to emit some messages and have Google Mock verify the +// right messages are sent (and perhaps at the right times). For +// example, if you are exercising code: // // Foo(1); // Foo(2); @@ -1831,49 +1892,34 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg); // Bar("a") is called by which call to Foo(). // // MockFunction<F> can also be used to exercise code that accepts -// std::function<F> callbacks. To do so, use AsStdFunction() method -// to create std::function proxy forwarding to original object's Call. -// Example: +// std::function<internal::SignatureOfT<F>> callbacks. To do so, use +// AsStdFunction() method to create std::function proxy forwarding to +// original object's Call. Example: // // TEST(FooTest, RunsCallbackWithBarArgument) { // MockFunction<int(string)> callback; // EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1)); // Foo(callback.AsStdFunction()); // } +// +// The internal::SignatureOfT<F> indirection allows to use other types +// than just function signature type. This is typically useful when +// providing a mock for a predefined std::function type. Example: +// +// using FilterPredicate = std::function<bool(string)>; +// void MyFilterAlgorithm(FilterPredicate predicate); +// +// TEST(FooTest, FilterPredicateAlwaysAccepts) { +// MockFunction<FilterPredicate> predicateMock; +// EXPECT_CALL(predicateMock, Call(_)).WillRepeatedly(Return(true)); +// MyFilterAlgorithm(predicateMock.AsStdFunction()); +// } template <typename F> -class MockFunction; +class MockFunction : public internal::MockFunction<internal::SignatureOfT<F>> { + using Base = internal::MockFunction<internal::SignatureOfT<F>>; -template <typename R, typename... Args> -class MockFunction<R(Args...)> { public: - MockFunction() {} - MockFunction(const MockFunction&) = delete; - MockFunction& operator=(const MockFunction&) = delete; - - std::function<R(Args...)> AsStdFunction() { - return [this](Args... args) -> R { - return this->Call(std::forward<Args>(args)...); - }; - } - - // Implementation detail: the expansion of the MOCK_METHOD macro. - R Call(Args... args) { - mock_.SetOwnerAndName(this, "Call"); - return mock_.Invoke(std::forward<Args>(args)...); - } - - internal::MockSpec<R(Args...)> gmock_Call(Matcher<Args>... m) { - mock_.RegisterOwner(this); - return mock_.With(std::move(m)...); - } - - internal::MockSpec<R(Args...)> gmock_Call(const internal::WithoutMatchers&, - R (*)(Args...)) { - return this->gmock_Call(::testing::A<Args>()...); - } - - private: - internal::FunctionMocker<R(Args...)> mock_; + using Base::Base; }; // The style guide prohibits "using" statements in a namespace scope diff --git a/googlemock/include/gmock/gmock.h b/googlemock/include/gmock/gmock.h index 99c3d787..3c317b6d 100644 --- a/googlemock/include/gmock/gmock.h +++ b/googlemock/include/gmock/gmock.h @@ -60,8 +60,6 @@ #include "gmock/gmock-cardinalities.h" #include "gmock/gmock-function-mocker.h" #include "gmock/gmock-generated-actions.h" -#include "gmock/gmock-generated-function-mockers.h" -#include "gmock/gmock-generated-matchers.h" #include "gmock/gmock-matchers.h" #include "gmock/gmock-more-actions.h" #include "gmock/gmock-more-matchers.h" diff --git a/googlemock/include/gmock/internal/gmock-internal-utils.h b/googlemock/include/gmock/internal/gmock-internal-utils.h index 5fd169e9..66cf857b 100644 --- a/googlemock/include/gmock/internal/gmock-internal-utils.h +++ b/googlemock/include/gmock/internal/gmock-internal-utils.h @@ -136,15 +136,13 @@ GMOCK_DECLARE_KIND_(int, kInteger); GMOCK_DECLARE_KIND_(unsigned int, kInteger); GMOCK_DECLARE_KIND_(long, kInteger); // NOLINT GMOCK_DECLARE_KIND_(unsigned long, kInteger); // NOLINT +GMOCK_DECLARE_KIND_(long long, kInteger); // NOLINT +GMOCK_DECLARE_KIND_(unsigned long long, kInteger); // NOLINT #if GMOCK_WCHAR_T_IS_NATIVE_ GMOCK_DECLARE_KIND_(wchar_t, kInteger); #endif -// Non-standard integer types. -GMOCK_DECLARE_KIND_(Int64, kInteger); -GMOCK_DECLARE_KIND_(UInt64, kInteger); - // All standard floating-point types. GMOCK_DECLARE_KIND_(float, kFloatingPoint); GMOCK_DECLARE_KIND_(double, kFloatingPoint); diff --git a/googlemock/include/gmock/internal/gmock-port.h b/googlemock/include/gmock/internal/gmock-port.h index 063e2929..70872ef3 100644 --- a/googlemock/include/gmock/internal/gmock-port.h +++ b/googlemock/include/gmock/internal/gmock-port.h @@ -42,6 +42,7 @@ #include <assert.h> #include <stdlib.h> +#include <cstdint> #include <iostream> // Most of the utilities needed for porting Google Mock are also @@ -69,8 +70,7 @@ // Macros for declaring flags. # define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name) -# define GMOCK_DECLARE_int32_(name) \ - extern GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) +# define GMOCK_DECLARE_int32_(name) extern GTEST_API_ int32_t GMOCK_FLAG(name) # define GMOCK_DECLARE_string_(name) \ extern GTEST_API_ ::std::string GMOCK_FLAG(name) @@ -78,7 +78,7 @@ # define GMOCK_DEFINE_bool_(name, default_val, doc) \ GTEST_API_ bool GMOCK_FLAG(name) = (default_val) # define GMOCK_DEFINE_int32_(name, default_val, doc) \ - GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) = (default_val) + GTEST_API_ int32_t GMOCK_FLAG(name) = (default_val) # define GMOCK_DEFINE_string_(name, default_val, doc) \ GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val) diff --git a/googlemock/include/gmock/internal/gmock-pp.h b/googlemock/include/gmock/internal/gmock-pp.h index c3759f66..d13e75f3 100644 --- a/googlemock/include/gmock/internal/gmock-pp.h +++ b/googlemock/include/gmock/internal/gmock-pp.h @@ -86,6 +86,14 @@ #define GMOCK_PP_IF(_Cond, _Then, _Else) \ GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IF_, _Cond)(_Then, _Else) +// Similar to GMOCK_PP_IF but takes _Then and _Else in parentheses. +// +// GMOCK_PP_GENERIC_IF(1, (a, b, c), (d, e, f)) => a, b, c +// GMOCK_PP_GENERIC_IF(0, (a, b, c), (d, e, f)) => d, e, f +// +#define GMOCK_PP_GENERIC_IF(_Cond, _Then, _Else) \ + GMOCK_PP_REMOVE_PARENS(GMOCK_PP_IF(_Cond, _Then, _Else)) + // Evaluates to the number of arguments after expansion. Identifies 'empty' as // 0. // diff --git a/googlemock/scripts/README.md b/googlemock/scripts/README.md index fa359fed..a3301e5b 100644 --- a/googlemock/scripts/README.md +++ b/googlemock/scripts/README.md @@ -1,5 +1,5 @@ # Please Note: Files in this directory are no longer supported by the maintainers. They -represent mosty historical artifacts and supported by the community only. There +represent mostly historical artifacts and supported by the community only. There is no guarantee whatsoever that these scripts still work. diff --git a/googlemock/scripts/generator/cpp/ast.py b/googlemock/scripts/generator/cpp/ast.py index f6331d80..b4890a54 100755 --- a/googlemock/scripts/generator/cpp/ast.py +++ b/googlemock/scripts/generator/cpp/ast.py @@ -30,11 +30,11 @@ try: - # Python 3.x - import builtins + # Python 3.x + import builtins except ImportError: - # Python 2.x - import __builtin__ as builtins + # Python 2.x + import __builtin__ as builtins import sys import traceback @@ -45,15 +45,15 @@ from cpp import utils if not hasattr(builtins, 'reversed'): - # Support Python 2.3 and earlier. - def reversed(seq): - for i in range(len(seq)-1, -1, -1): - yield seq[i] + # Support Python 2.3 and earlier. + def reversed(seq): + for i in range(len(seq)-1, -1, -1): + yield seq[i] if not hasattr(builtins, 'next'): - # Support Python 2.5 and earlier. - def next(obj): - return obj.next() + # Support Python 2.5 and earlier. + def next(obj): + return obj.next() VISIBILITY_PUBLIC, VISIBILITY_PROTECTED, VISIBILITY_PRIVATE = range(3) @@ -98,1598 +98,1610 @@ _NAMESPACE_POP = 'ns-pop' # TODO(nnorwitz): use this as a singleton for templated_types, etc # where we don't want to create a new empty dict each time. It is also const. class _NullDict(object): - __contains__ = lambda self: False - keys = values = items = iterkeys = itervalues = iteritems = lambda self: () + __contains__ = lambda self: False + keys = values = items = iterkeys = itervalues = iteritems = lambda self: () # TODO(nnorwitz): move AST nodes into a separate module. class Node(object): - """Base AST node.""" + """Base AST node.""" - def __init__(self, start, end): - self.start = start - self.end = end + def __init__(self, start, end): + self.start = start + self.end = end - def IsDeclaration(self): - """Returns bool if this node is a declaration.""" - return False + def IsDeclaration(self): + """Returns bool if this node is a declaration.""" + return False - def IsDefinition(self): - """Returns bool if this node is a definition.""" - return False + def IsDefinition(self): + """Returns bool if this node is a definition.""" + return False - def IsExportable(self): - """Returns bool if this node exportable from a header file.""" - return False + def IsExportable(self): + """Returns bool if this node exportable from a header file.""" + return False - def Requires(self, node): - """Does this AST node require the definition of the node passed in?""" - return False + def Requires(self, node): + """Does this AST node require the definition of the node passed in?""" + return False - def XXX__str__(self): - return self._StringHelper(self.__class__.__name__, '') + def XXX__str__(self): + return self._StringHelper(self.__class__.__name__, '') - def _StringHelper(self, name, suffix): - if not utils.DEBUG: - return '%s(%s)' % (name, suffix) - return '%s(%d, %d, %s)' % (name, self.start, self.end, suffix) + def _StringHelper(self, name, suffix): + if not utils.DEBUG: + return '%s(%s)' % (name, suffix) + return '%s(%d, %d, %s)' % (name, self.start, self.end, suffix) - def __repr__(self): - return str(self) + def __repr__(self): + return str(self) class Define(Node): - def __init__(self, start, end, name, definition): - Node.__init__(self, start, end) - self.name = name - self.definition = definition + def __init__(self, start, end, name, definition): + Node.__init__(self, start, end) + self.name = name + self.definition = definition - def __str__(self): - value = '%s %s' % (self.name, self.definition) - return self._StringHelper(self.__class__.__name__, value) + def __str__(self): + value = '%s %s' % (self.name, self.definition) + return self._StringHelper(self.__class__.__name__, value) class Include(Node): - def __init__(self, start, end, filename, system): - Node.__init__(self, start, end) - self.filename = filename - self.system = system + def __init__(self, start, end, filename, system): + Node.__init__(self, start, end) + self.filename = filename + self.system = system - def __str__(self): - fmt = '"%s"' - if self.system: - fmt = '<%s>' - return self._StringHelper(self.__class__.__name__, fmt % self.filename) + def __str__(self): + fmt = '"%s"' + if self.system: + fmt = '<%s>' + return self._StringHelper(self.__class__.__name__, fmt % self.filename) class Goto(Node): - def __init__(self, start, end, label): - Node.__init__(self, start, end) - self.label = label + def __init__(self, start, end, label): + Node.__init__(self, start, end) + self.label = label - def __str__(self): - return self._StringHelper(self.__class__.__name__, str(self.label)) + def __str__(self): + return self._StringHelper(self.__class__.__name__, str(self.label)) class Expr(Node): - def __init__(self, start, end, expr): - Node.__init__(self, start, end) - self.expr = expr + def __init__(self, start, end, expr): + Node.__init__(self, start, end) + self.expr = expr - def Requires(self, node): - # TODO(nnorwitz): impl. - return False + def Requires(self, node): + # TODO(nnorwitz): impl. + return False - def __str__(self): - return self._StringHelper(self.__class__.__name__, str(self.expr)) + def __str__(self): + return self._StringHelper(self.__class__.__name__, str(self.expr)) class Return(Expr): - pass + pass class Delete(Expr): - pass + pass class Friend(Expr): - def __init__(self, start, end, expr, namespace): - Expr.__init__(self, start, end, expr) - self.namespace = namespace[:] + def __init__(self, start, end, expr, namespace): + Expr.__init__(self, start, end, expr) + self.namespace = namespace[:] class Using(Node): - def __init__(self, start, end, names): - Node.__init__(self, start, end) - self.names = names + def __init__(self, start, end, names): + Node.__init__(self, start, end) + self.names = names - def __str__(self): - return self._StringHelper(self.__class__.__name__, str(self.names)) + def __str__(self): + return self._StringHelper(self.__class__.__name__, str(self.names)) class Parameter(Node): - def __init__(self, start, end, name, parameter_type, default): - Node.__init__(self, start, end) - self.name = name - self.type = parameter_type - self.default = default + def __init__(self, start, end, name, parameter_type, default): + Node.__init__(self, start, end) + self.name = name + self.type = parameter_type + self.default = default - def Requires(self, node): - # TODO(nnorwitz): handle namespaces, etc. - return self.type.name == node.name + def Requires(self, node): + # TODO(nnorwitz): handle namespaces, etc. + return self.type.name == node.name - def __str__(self): - name = str(self.type) - suffix = '%s %s' % (name, self.name) - if self.default: - suffix += ' = ' + ''.join([d.name for d in self.default]) - return self._StringHelper(self.__class__.__name__, suffix) + def __str__(self): + name = str(self.type) + suffix = '%s %s' % (name, self.name) + if self.default: + suffix += ' = ' + ''.join([d.name for d in self.default]) + return self._StringHelper(self.__class__.__name__, suffix) class _GenericDeclaration(Node): - def __init__(self, start, end, name, namespace): - Node.__init__(self, start, end) - self.name = name - self.namespace = namespace[:] + def __init__(self, start, end, name, namespace): + Node.__init__(self, start, end) + self.name = name + self.namespace = namespace[:] - def FullName(self): - prefix = '' - if self.namespace and self.namespace[-1]: - prefix = '::'.join(self.namespace) + '::' - return prefix + self.name + def FullName(self): + prefix = '' + if self.namespace and self.namespace[-1]: + prefix = '::'.join(self.namespace) + '::' + return prefix + self.name - def _TypeStringHelper(self, suffix): - if self.namespace: - names = [n or '<anonymous>' for n in self.namespace] - suffix += ' in ' + '::'.join(names) - return self._StringHelper(self.__class__.__name__, suffix) + def _TypeStringHelper(self, suffix): + if self.namespace: + names = [n or '<anonymous>' for n in self.namespace] + suffix += ' in ' + '::'.join(names) + return self._StringHelper(self.__class__.__name__, suffix) # TODO(nnorwitz): merge with Parameter in some way? class VariableDeclaration(_GenericDeclaration): - def __init__(self, start, end, name, var_type, initial_value, namespace): - _GenericDeclaration.__init__(self, start, end, name, namespace) - self.type = var_type - self.initial_value = initial_value + def __init__(self, start, end, name, var_type, initial_value, namespace): + _GenericDeclaration.__init__(self, start, end, name, namespace) + self.type = var_type + self.initial_value = initial_value - def Requires(self, node): - # TODO(nnorwitz): handle namespaces, etc. - return self.type.name == node.name + def Requires(self, node): + # TODO(nnorwitz): handle namespaces, etc. + return self.type.name == node.name - def ToString(self): - """Return a string that tries to reconstitute the variable decl.""" - suffix = '%s %s' % (self.type, self.name) - if self.initial_value: - suffix += ' = ' + self.initial_value - return suffix + def ToString(self): + """Return a string that tries to reconstitute the variable decl.""" + suffix = '%s %s' % (self.type, self.name) + if self.initial_value: + suffix += ' = ' + self.initial_value + return suffix - def __str__(self): - return self._StringHelper(self.__class__.__name__, self.ToString()) + def __str__(self): + return self._StringHelper(self.__class__.__name__, self.ToString()) class Typedef(_GenericDeclaration): - def __init__(self, start, end, name, alias, namespace): - _GenericDeclaration.__init__(self, start, end, name, namespace) - self.alias = alias + def __init__(self, start, end, name, alias, namespace): + _GenericDeclaration.__init__(self, start, end, name, namespace) + self.alias = alias - def IsDefinition(self): - return True + def IsDefinition(self): + return True - def IsExportable(self): - return True + def IsExportable(self): + return True - def Requires(self, node): - # TODO(nnorwitz): handle namespaces, etc. - name = node.name - for token in self.alias: - if token is not None and name == token.name: - return True - return False + def Requires(self, node): + # TODO(nnorwitz): handle namespaces, etc. + name = node.name + for token in self.alias: + if token is not None and name == token.name: + return True + return False - def __str__(self): - suffix = '%s, %s' % (self.name, self.alias) - return self._TypeStringHelper(suffix) + def __str__(self): + suffix = '%s, %s' % (self.name, self.alias) + return self._TypeStringHelper(suffix) class _NestedType(_GenericDeclaration): - def __init__(self, start, end, name, fields, namespace): - _GenericDeclaration.__init__(self, start, end, name, namespace) - self.fields = fields + def __init__(self, start, end, name, fields, namespace): + _GenericDeclaration.__init__(self, start, end, name, namespace) + self.fields = fields - def IsDefinition(self): - return True + def IsDefinition(self): + return True - def IsExportable(self): - return True + def IsExportable(self): + return True - def __str__(self): - suffix = '%s, {%s}' % (self.name, self.fields) - return self._TypeStringHelper(suffix) + def __str__(self): + suffix = '%s, {%s}' % (self.name, self.fields) + return self._TypeStringHelper(suffix) class Union(_NestedType): - pass + pass class Enum(_NestedType): - pass + pass class Class(_GenericDeclaration): - def __init__(self, start, end, name, bases, templated_types, body, namespace): - _GenericDeclaration.__init__(self, start, end, name, namespace) - self.bases = bases - self.body = body - self.templated_types = templated_types - - def IsDeclaration(self): - return self.bases is None and self.body is None - - def IsDefinition(self): - return not self.IsDeclaration() - - def IsExportable(self): - return not self.IsDeclaration() - - def Requires(self, node): - # TODO(nnorwitz): handle namespaces, etc. - if self.bases: - for token_list in self.bases: - # TODO(nnorwitz): bases are tokens, do name comparision. - for token in token_list: - if token.name == node.name: - return True - # TODO(nnorwitz): search in body too. - return False - - def __str__(self): - name = self.name - if self.templated_types: - name += '<%s>' % self.templated_types - suffix = '%s, %s, %s' % (name, self.bases, self.body) - return self._TypeStringHelper(suffix) + def __init__(self, start, end, name, bases, templated_types, body, namespace): + _GenericDeclaration.__init__(self, start, end, name, namespace) + self.bases = bases + self.body = body + self.templated_types = templated_types + + def IsDeclaration(self): + return self.bases is None and self.body is None + + def IsDefinition(self): + return not self.IsDeclaration() + + def IsExportable(self): + return not self.IsDeclaration() + + def Requires(self, node): + # TODO(nnorwitz): handle namespaces, etc. + if self.bases: + for token_list in self.bases: + # TODO(nnorwitz): bases are tokens, do name comparision. + for token in token_list: + if token.name == node.name: + return True + # TODO(nnorwitz): search in body too. + return False + + def __str__(self): + name = self.name + if self.templated_types: + name += '<%s>' % self.templated_types + suffix = '%s, %s, %s' % (name, self.bases, self.body) + return self._TypeStringHelper(suffix) class Struct(Class): - pass + pass class Function(_GenericDeclaration): - def __init__(self, start, end, name, return_type, parameters, - modifiers, templated_types, body, namespace): - _GenericDeclaration.__init__(self, start, end, name, namespace) - converter = TypeConverter(namespace) - self.return_type = converter.CreateReturnType(return_type) - self.parameters = converter.ToParameters(parameters) - self.modifiers = modifiers - self.body = body - self.templated_types = templated_types - - def IsDeclaration(self): - return self.body is None - - def IsDefinition(self): - return self.body is not None - - def IsExportable(self): - if self.return_type and 'static' in self.return_type.modifiers: - return False - return None not in self.namespace - - def Requires(self, node): - if self.parameters: - # TODO(nnorwitz): parameters are tokens, do name comparision. - for p in self.parameters: - if p.name == node.name: - return True - # TODO(nnorwitz): search in body too. - return False - - def __str__(self): - # TODO(nnorwitz): add templated_types. - suffix = ('%s %s(%s), 0x%02x, %s' % - (self.return_type, self.name, self.parameters, - self.modifiers, self.body)) - return self._TypeStringHelper(suffix) + def __init__(self, start, end, name, return_type, parameters, + modifiers, templated_types, body, namespace): + _GenericDeclaration.__init__(self, start, end, name, namespace) + converter = TypeConverter(namespace) + self.return_type = converter.CreateReturnType(return_type) + self.parameters = converter.ToParameters(parameters) + self.modifiers = modifiers + self.body = body + self.templated_types = templated_types + + def IsDeclaration(self): + return self.body is None + + def IsDefinition(self): + return self.body is not None + + def IsExportable(self): + if self.return_type and 'static' in self.return_type.modifiers: + return False + return None not in self.namespace + + def Requires(self, node): + if self.parameters: + # TODO(nnorwitz): parameters are tokens, do name comparision. + for p in self.parameters: + if p.name == node.name: + return True + # TODO(nnorwitz): search in body too. + return False + + def __str__(self): + # TODO(nnorwitz): add templated_types. + suffix = ('%s %s(%s), 0x%02x, %s' % + (self.return_type, self.name, self.parameters, + self.modifiers, self.body)) + return self._TypeStringHelper(suffix) class Method(Function): - def __init__(self, start, end, name, in_class, return_type, parameters, - modifiers, templated_types, body, namespace): - Function.__init__(self, start, end, name, return_type, parameters, - modifiers, templated_types, body, namespace) - # TODO(nnorwitz): in_class could also be a namespace which can - # mess up finding functions properly. - self.in_class = in_class + def __init__(self, start, end, name, in_class, return_type, parameters, + modifiers, templated_types, body, namespace): + Function.__init__(self, start, end, name, return_type, parameters, + modifiers, templated_types, body, namespace) + # TODO(nnorwitz): in_class could also be a namespace which can + # mess up finding functions properly. + self.in_class = in_class class Type(_GenericDeclaration): - """Type used for any variable (eg class, primitive, struct, etc).""" + """Type used for any variable (eg class, primitive, struct, etc).""" - def __init__(self, start, end, name, templated_types, modifiers, - reference, pointer, array): - """ + def __init__(self, start, end, name, templated_types, modifiers, + reference, pointer, array): + """ Args: name: str name of main type templated_types: [Class (Type?)] template type info between <> modifiers: [str] type modifiers (keywords) eg, const, mutable, etc. reference, pointer, array: bools """ - _GenericDeclaration.__init__(self, start, end, name, []) - self.templated_types = templated_types - if not name and modifiers: - self.name = modifiers.pop() - self.modifiers = modifiers - self.reference = reference - self.pointer = pointer - self.array = array - - def __str__(self): - prefix = '' - if self.modifiers: - prefix = ' '.join(self.modifiers) + ' ' - name = str(self.name) - if self.templated_types: - name += '<%s>' % self.templated_types - suffix = prefix + name - if self.reference: - suffix += '&' - if self.pointer: - suffix += '*' - if self.array: - suffix += '[]' - return self._TypeStringHelper(suffix) - - # By definition, Is* are always False. A Type can only exist in - # some sort of variable declaration, parameter, or return value. - def IsDeclaration(self): - return False - - def IsDefinition(self): - return False - - def IsExportable(self): - return False + _GenericDeclaration.__init__(self, start, end, name, []) + self.templated_types = templated_types + if not name and modifiers: + self.name = modifiers.pop() + self.modifiers = modifiers + self.reference = reference + self.pointer = pointer + self.array = array + + def __str__(self): + prefix = '' + if self.modifiers: + prefix = ' '.join(self.modifiers) + ' ' + name = str(self.name) + if self.templated_types: + name += '<%s>' % self.templated_types + suffix = prefix + name + if self.reference: + suffix += '&' + if self.pointer: + suffix += '*' + if self.array: + suffix += '[]' + return self._TypeStringHelper(suffix) + + # By definition, Is* are always False. A Type can only exist in + # some sort of variable declaration, parameter, or return value. + def IsDeclaration(self): + return False + + def IsDefinition(self): + return False + + def IsExportable(self): + return False class TypeConverter(object): - def __init__(self, namespace_stack): - self.namespace_stack = namespace_stack - - def _GetTemplateEnd(self, tokens, start): - count = 1 - end = start - while 1: - token = tokens[end] - end += 1 - if token.name == '<': - count += 1 - elif token.name == '>': - count -= 1 - if count == 0: - break - return tokens[start:end-1], end - - def ToType(self, tokens): - """Convert [Token,...] to [Class(...), ] useful for base classes. + def __init__(self, namespace_stack): + self.namespace_stack = namespace_stack + + def _GetTemplateEnd(self, tokens, start): + count = 1 + end = start + while 1: + token = tokens[end] + end += 1 + if token.name == '<': + count += 1 + elif token.name == '>': + count -= 1 + if count == 0: + break + return tokens[start:end-1], end + + def ToType(self, tokens): + """Convert [Token,...] to [Class(...), ] useful for base classes. For example, code like class Foo : public Bar<x, y> { ... }; the "Bar<x, y>" portion gets converted to an AST. Returns: [Class(...), ...] """ - result = [] - name_tokens = [] + result = [] + name_tokens = [] + reference = pointer = array = False + + def AddType(templated_types): + # Partition tokens into name and modifier tokens. + names = [] + modifiers = [] + for t in name_tokens: + if keywords.IsKeyword(t.name): + modifiers.append(t.name) + else: + names.append(t.name) + name = ''.join(names) + if name_tokens: + result.append(Type(name_tokens[0].start, name_tokens[-1].end, + name, templated_types, modifiers, + reference, pointer, array)) + del name_tokens[:] + + i = 0 + end = len(tokens) + while i < end: + token = tokens[i] + if token.name == '<': + new_tokens, new_end = self._GetTemplateEnd(tokens, i+1) + AddType(self.ToType(new_tokens)) + # If there is a comma after the template, we need to consume + # that here otherwise it becomes part of the name. + i = new_end reference = pointer = array = False - - def AddType(templated_types): - # Partition tokens into name and modifier tokens. - names = [] - modifiers = [] - for t in name_tokens: - if keywords.IsKeyword(t.name): - modifiers.append(t.name) - else: - names.append(t.name) - name = ''.join(names) - if name_tokens: - result.append(Type(name_tokens[0].start, name_tokens[-1].end, - name, templated_types, modifiers, - reference, pointer, array)) - del name_tokens[:] - - i = 0 - end = len(tokens) - while i < end: - token = tokens[i] - if token.name == '<': - new_tokens, new_end = self._GetTemplateEnd(tokens, i+1) - AddType(self.ToType(new_tokens)) - # If there is a comma after the template, we need to consume - # that here otherwise it becomes part of the name. - i = new_end - reference = pointer = array = False - elif token.name == ',': - AddType([]) - reference = pointer = array = False - elif token.name == '*': - pointer = True - elif token.name == '&': - reference = True - elif token.name == '[': - pointer = True - elif token.name == ']': - pass - else: - name_tokens.append(token) - i += 1 - - if name_tokens: - # No '<' in the tokens, just a simple name and no template. - AddType([]) - return result - - def DeclarationToParts(self, parts, needs_name_removed): - name = None - default = [] - if needs_name_removed: - # Handle default (initial) values properly. - for i, t in enumerate(parts): - if t.name == '=': - default = parts[i+1:] - name = parts[i-1].name - if name == ']' and parts[i-2].name == '[': - name = parts[i-3].name - i -= 1 - parts = parts[:i-1] - break - else: - if parts[-1].token_type == tokenize.NAME: - name = parts.pop().name - else: - # TODO(nnorwitz): this is a hack that happens for code like - # Register(Foo<T>); where it thinks this is a function call - # but it's actually a declaration. - name = '???' - modifiers = [] - type_name = [] - other_tokens = [] - templated_types = [] - i = 0 - end = len(parts) - while i < end: - p = parts[i] - if keywords.IsKeyword(p.name): - modifiers.append(p.name) - elif p.name == '<': - templated_tokens, new_end = self._GetTemplateEnd(parts, i+1) - templated_types = self.ToType(templated_tokens) - i = new_end - 1 - # Don't add a spurious :: to data members being initialized. - next_index = i + 1 - if next_index < end and parts[next_index].name == '::': - i += 1 - elif p.name in ('[', ']', '='): - # These are handled elsewhere. - other_tokens.append(p) - elif p.name not in ('*', '&', '>'): - # Ensure that names have a space between them. - if (type_name and type_name[-1].token_type == tokenize.NAME and - p.token_type == tokenize.NAME): - type_name.append(tokenize.Token(tokenize.SYNTAX, ' ', 0, 0)) - type_name.append(p) - else: - other_tokens.append(p) - i += 1 - type_name = ''.join([t.name for t in type_name]) - return name, type_name, templated_types, modifiers, default, other_tokens - - def ToParameters(self, tokens): - if not tokens: - return [] - - result = [] + elif token.name == ',': + AddType([]) + reference = pointer = array = False + elif token.name == '*': + pointer = True + elif token.name == '&': + reference = True + elif token.name == '[': + pointer = True + elif token.name == ']': + pass + else: + name_tokens.append(token) + i += 1 + + if name_tokens: + # No '<' in the tokens, just a simple name and no template. + AddType([]) + return result + + def DeclarationToParts(self, parts, needs_name_removed): + name = None + default = [] + if needs_name_removed: + # Handle default (initial) values properly. + for i, t in enumerate(parts): + if t.name == '=': + default = parts[i+1:] + name = parts[i-1].name + if name == ']' and parts[i-2].name == '[': + name = parts[i-3].name + i -= 1 + parts = parts[:i-1] + break + else: + if parts[-1].token_type == tokenize.NAME: + name = parts.pop().name + else: + # TODO(nnorwitz): this is a hack that happens for code like + # Register(Foo<T>); where it thinks this is a function call + # but it's actually a declaration. + name = '???' + modifiers = [] + type_name = [] + other_tokens = [] + templated_types = [] + i = 0 + end = len(parts) + while i < end: + p = parts[i] + if keywords.IsKeyword(p.name): + modifiers.append(p.name) + elif p.name == '<': + templated_tokens, new_end = self._GetTemplateEnd(parts, i+1) + templated_types = self.ToType(templated_tokens) + i = new_end - 1 + # Don't add a spurious :: to data members being initialized. + next_index = i + 1 + if next_index < end and parts[next_index].name == '::': + i += 1 + elif p.name in ('[', ']', '='): + # These are handled elsewhere. + other_tokens.append(p) + elif p.name not in ('*', '&', '>'): + # Ensure that names have a space between them. + if (type_name and type_name[-1].token_type == tokenize.NAME and + p.token_type == tokenize.NAME): + type_name.append(tokenize.Token(tokenize.SYNTAX, ' ', 0, 0)) + type_name.append(p) + else: + other_tokens.append(p) + i += 1 + type_name = ''.join([t.name for t in type_name]) + return name, type_name, templated_types, modifiers, default, other_tokens + + def ToParameters(self, tokens): + if not tokens: + return [] + + result = [] + name = type_name = '' + type_modifiers = [] + pointer = reference = array = False + first_token = None + default = [] + + def AddParameter(end): + if default: + del default[0] # Remove flag. + parts = self.DeclarationToParts(type_modifiers, True) + (name, type_name, templated_types, modifiers, + unused_default, unused_other_tokens) = parts + parameter_type = Type(first_token.start, first_token.end, + type_name, templated_types, modifiers, + reference, pointer, array) + p = Parameter(first_token.start, end, name, + parameter_type, default) + result.append(p) + + template_count = 0 + brace_count = 0 + for s in tokens: + if not first_token: + first_token = s + + # Check for braces before templates, as we can have unmatched '<>' + # inside default arguments. + if s.name == '{': + brace_count += 1 + elif s.name == '}': + brace_count -= 1 + if brace_count > 0: + type_modifiers.append(s) + continue + + if s.name == '<': + template_count += 1 + elif s.name == '>': + template_count -= 1 + if template_count > 0: + type_modifiers.append(s) + continue + + if s.name == ',': + AddParameter(s.start) name = type_name = '' type_modifiers = [] pointer = reference = array = False first_token = None default = [] - - def AddParameter(end): - if default: - del default[0] # Remove flag. - parts = self.DeclarationToParts(type_modifiers, True) - (name, type_name, templated_types, modifiers, - unused_default, unused_other_tokens) = parts - parameter_type = Type(first_token.start, first_token.end, - type_name, templated_types, modifiers, - reference, pointer, array) - p = Parameter(first_token.start, end, name, - parameter_type, default) - result.append(p) - - template_count = 0 - for s in tokens: - if not first_token: - first_token = s - if s.name == '<': - template_count += 1 - elif s.name == '>': - template_count -= 1 - if template_count > 0: - type_modifiers.append(s) - continue - - if s.name == ',': - AddParameter(s.start) - name = type_name = '' - type_modifiers = [] - pointer = reference = array = False - first_token = None - default = [] - elif s.name == '*': - pointer = True - elif s.name == '&': - reference = True - elif s.name == '[': - array = True - elif s.name == ']': - pass # Just don't add to type_modifiers. - elif s.name == '=': - # Got a default value. Add any value (None) as a flag. - default.append(None) - elif default: - default.append(s) - else: - type_modifiers.append(s) - AddParameter(tokens[-1].end) - return result - - def CreateReturnType(self, return_type_seq): - if not return_type_seq: - return None - start = return_type_seq[0].start - end = return_type_seq[-1].end - _, name, templated_types, modifiers, default, other_tokens = \ - self.DeclarationToParts(return_type_seq, False) - names = [n.name for n in other_tokens] - reference = '&' in names - pointer = '*' in names - array = '[' in names - return Type(start, end, name, templated_types, modifiers, - reference, pointer, array) - - def GetTemplateIndices(self, names): - # names is a list of strings. - start = names.index('<') - end = len(names) - 1 - while end > 0: - if names[end] == '>': - break - end -= 1 - return start, end+1 + elif s.name == '*': + pointer = True + elif s.name == '&': + reference = True + elif s.name == '[': + array = True + elif s.name == ']': + pass # Just don't add to type_modifiers. + elif s.name == '=': + # Got a default value. Add any value (None) as a flag. + default.append(None) + elif default: + default.append(s) + else: + type_modifiers.append(s) + AddParameter(tokens[-1].end) + return result + + def CreateReturnType(self, return_type_seq): + if not return_type_seq: + return None + start = return_type_seq[0].start + end = return_type_seq[-1].end + _, name, templated_types, modifiers, default, other_tokens = \ + self.DeclarationToParts(return_type_seq, False) + names = [n.name for n in other_tokens] + reference = '&' in names + pointer = '*' in names + array = '[' in names + return Type(start, end, name, templated_types, modifiers, + reference, pointer, array) + + def GetTemplateIndices(self, names): + # names is a list of strings. + start = names.index('<') + end = len(names) - 1 + while end > 0: + if names[end] == '>': + break + end -= 1 + return start, end+1 class AstBuilder(object): - def __init__(self, token_stream, filename, in_class='', visibility=None, - namespace_stack=[]): - self.tokens = token_stream - self.filename = filename - # TODO(nnorwitz): use a better data structure (deque) for the queue. - # Switching directions of the "queue" improved perf by about 25%. - # Using a deque should be even better since we access from both sides. - self.token_queue = [] - self.namespace_stack = namespace_stack[:] - self.in_class = in_class - if in_class is None: - self.in_class_name_only = None - else: - self.in_class_name_only = in_class.split('::')[-1] - self.visibility = visibility - self.in_function = False - self.current_token = None - # Keep the state whether we are currently handling a typedef or not. - self._handling_typedef = False - - self.converter = TypeConverter(self.namespace_stack) - - def HandleError(self, msg, token): - printable_queue = list(reversed(self.token_queue[-20:])) - sys.stderr.write('Got %s in %s @ %s %s\n' % - (msg, self.filename, token, printable_queue)) - - def Generate(self): - while 1: - token = self._GetNextToken() - if not token: - break - - # Get the next token. - self.current_token = token - - # Dispatch on the next token type. - if token.token_type == _INTERNAL_TOKEN: - if token.name == _NAMESPACE_POP: - self.namespace_stack.pop() - continue - - try: - result = self._GenerateOne(token) - if result is not None: - yield result - except: - self.HandleError('exception', token) - raise - - def _CreateVariable(self, pos_token, name, type_name, type_modifiers, - ref_pointer_name_seq, templated_types, value=None): - reference = '&' in ref_pointer_name_seq - pointer = '*' in ref_pointer_name_seq - array = '[' in ref_pointer_name_seq - var_type = Type(pos_token.start, pos_token.end, type_name, - templated_types, type_modifiers, - reference, pointer, array) - return VariableDeclaration(pos_token.start, pos_token.end, - name, var_type, value, self.namespace_stack) - - def _GenerateOne(self, token): - if token.token_type == tokenize.NAME: - if (keywords.IsKeyword(token.name) and - not keywords.IsBuiltinType(token.name)): - if token.name == 'enum': - # Pop the next token and only put it back if it's not - # 'class'. This allows us to support the two-token - # 'enum class' keyword as if it were simply 'enum'. - next = self._GetNextToken() - if next.name != 'class': - self._AddBackToken(next) - - method = getattr(self, 'handle_' + token.name) - return method() - elif token.name == self.in_class_name_only: - # The token name is the same as the class, must be a ctor if - # there is a paren. Otherwise, it's the return type. - # Peek ahead to get the next token to figure out which. - next = self._GetNextToken() - self._AddBackToken(next) - if next.token_type == tokenize.SYNTAX and next.name == '(': - return self._GetMethod([token], FUNCTION_CTOR, None, True) - # Fall through--handle like any other method. - - # Handle data or function declaration/definition. - syntax = tokenize.SYNTAX - temp_tokens, last_token = \ - self._GetVarTokensUpToIgnoringTemplates(syntax, - '(', ';', '{', '[') - temp_tokens.insert(0, token) - if last_token.name == '(': - # If there is an assignment before the paren, - # this is an expression, not a method. - expr = bool([e for e in temp_tokens if e.name == '=']) - if expr: - new_temp = self._GetTokensUpTo(tokenize.SYNTAX, ';') - temp_tokens.append(last_token) - temp_tokens.extend(new_temp) - last_token = tokenize.Token(tokenize.SYNTAX, ';', 0, 0) - - if last_token.name == '[': - # Handle array, this isn't a method, unless it's an operator. - # TODO(nnorwitz): keep the size somewhere. - # unused_size = self._GetTokensUpTo(tokenize.SYNTAX, ']') - temp_tokens.append(last_token) - if temp_tokens[-2].name == 'operator': - temp_tokens.append(self._GetNextToken()) - else: - temp_tokens2, last_token = \ - self._GetVarTokensUpTo(tokenize.SYNTAX, ';') - temp_tokens.extend(temp_tokens2) - - if last_token.name == ';': - # Handle data, this isn't a method. - parts = self.converter.DeclarationToParts(temp_tokens, True) - (name, type_name, templated_types, modifiers, default, - unused_other_tokens) = parts - - t0 = temp_tokens[0] - names = [t.name for t in temp_tokens] - if templated_types: - start, end = self.converter.GetTemplateIndices(names) - names = names[:start] + names[end:] - default = ''.join([t.name for t in default]) - return self._CreateVariable(t0, name, type_name, modifiers, - names, templated_types, default) - if last_token.name == '{': - self._AddBackTokens(temp_tokens[1:]) - self._AddBackToken(last_token) - method_name = temp_tokens[0].name - method = getattr(self, 'handle_' + method_name, None) - if not method: - # Must be declaring a variable. - # TODO(nnorwitz): handle the declaration. - return None - return method() - return self._GetMethod(temp_tokens, 0, None, False) - elif token.token_type == tokenize.SYNTAX: - if token.name == '~' and self.in_class: - # Must be a dtor (probably not in method body). - token = self._GetNextToken() - # self.in_class can contain A::Name, but the dtor will only - # be Name. Make sure to compare against the right value. - if (token.token_type == tokenize.NAME and - token.name == self.in_class_name_only): - return self._GetMethod([token], FUNCTION_DTOR, None, True) - # TODO(nnorwitz): handle a lot more syntax. - elif token.token_type == tokenize.PREPROCESSOR: - # TODO(nnorwitz): handle more preprocessor directives. - # token starts with a #, so remove it and strip whitespace. - name = token.name[1:].lstrip() - if name.startswith('include'): - # Remove "include". - name = name[7:].strip() - assert name - # Handle #include \<newline> "header-on-second-line.h". - if name.startswith('\\'): - name = name[1:].strip() - assert name[0] in '<"', token - assert name[-1] in '>"', token - system = name[0] == '<' - filename = name[1:-1] - return Include(token.start, token.end, filename, system) - if name.startswith('define'): - # Remove "define". - name = name[6:].strip() - assert name - value = '' - for i, c in enumerate(name): - if c.isspace(): - value = name[i:].lstrip() - name = name[:i] - break - return Define(token.start, token.end, name, value) - if name.startswith('if') and name[2:3].isspace(): - condition = name[3:].strip() - if condition.startswith('0') or condition.startswith('(0)'): - self._SkipIf0Blocks() - return None - - def _GetTokensUpTo(self, expected_token_type, expected_token): - return self._GetVarTokensUpTo(expected_token_type, expected_token)[0] - - def _GetVarTokensUpTo(self, expected_token_type, *expected_tokens): - last_token = self._GetNextToken() - tokens = [] - while (last_token.token_type != expected_token_type or - last_token.name not in expected_tokens): - tokens.append(last_token) - last_token = self._GetNextToken() - return tokens, last_token - - # Same as _GetVarTokensUpTo, but skips over '<...>' which could contain an - # expected token. - def _GetVarTokensUpToIgnoringTemplates(self, expected_token_type, - *expected_tokens): - last_token = self._GetNextToken() - tokens = [] - nesting = 0 - while (nesting > 0 or - last_token.token_type != expected_token_type or - last_token.name not in expected_tokens): - tokens.append(last_token) - last_token = self._GetNextToken() - if last_token.name == '<': - nesting += 1 - elif last_token.name == '>': - nesting -= 1 - return tokens, last_token - - # TODO(nnorwitz): remove _IgnoreUpTo() it shouldn't be necesary. - def _IgnoreUpTo(self, token_type, token): - unused_tokens = self._GetTokensUpTo(token_type, token) - - def _SkipIf0Blocks(self): - count = 1 - while 1: - token = self._GetNextToken() - if token.token_type != tokenize.PREPROCESSOR: - continue - - name = token.name[1:].lstrip() - if name.startswith('endif'): - count -= 1 - if count == 0: - break - elif name.startswith('if'): - count += 1 - - def _GetMatchingChar(self, open_paren, close_paren, GetNextToken=None): - if GetNextToken is None: - GetNextToken = self._GetNextToken - # Assumes the current token is open_paren and we will consume - # and return up to the close_paren. - count = 1 - token = GetNextToken() - while 1: - if token.token_type == tokenize.SYNTAX: - if token.name == open_paren: - count += 1 - elif token.name == close_paren: - count -= 1 - if count == 0: - break - yield token - token = GetNextToken() - yield token - - def _GetParameters(self): - return self._GetMatchingChar('(', ')') - - def GetScope(self): - return self._GetMatchingChar('{', '}') - - def _GetNextToken(self): - if self.token_queue: - return self.token_queue.pop() - try: - return next(self.tokens) - except StopIteration: - return - - def _AddBackToken(self, token): - if token.whence == tokenize.WHENCE_STREAM: - token.whence = tokenize.WHENCE_QUEUE - self.token_queue.insert(0, token) + def __init__(self, token_stream, filename, in_class='', visibility=None, + namespace_stack=[]): + self.tokens = token_stream + self.filename = filename + # TODO(nnorwitz): use a better data structure (deque) for the queue. + # Switching directions of the "queue" improved perf by about 25%. + # Using a deque should be even better since we access from both sides. + self.token_queue = [] + self.namespace_stack = namespace_stack[:] + self.in_class = in_class + if in_class is None: + self.in_class_name_only = None + else: + self.in_class_name_only = in_class.split('::')[-1] + self.visibility = visibility + self.in_function = False + self.current_token = None + # Keep the state whether we are currently handling a typedef or not. + self._handling_typedef = False + + self.converter = TypeConverter(self.namespace_stack) + + def HandleError(self, msg, token): + printable_queue = list(reversed(self.token_queue[-20:])) + sys.stderr.write('Got %s in %s @ %s %s\n' % + (msg, self.filename, token, printable_queue)) + + def Generate(self): + while 1: + token = self._GetNextToken() + if not token: + break + + # Get the next token. + self.current_token = token + + # Dispatch on the next token type. + if token.token_type == _INTERNAL_TOKEN: + if token.name == _NAMESPACE_POP: + self.namespace_stack.pop() + continue + + try: + result = self._GenerateOne(token) + if result is not None: + yield result + except: + self.HandleError('exception', token) + raise + + def _CreateVariable(self, pos_token, name, type_name, type_modifiers, + ref_pointer_name_seq, templated_types, value=None): + reference = '&' in ref_pointer_name_seq + pointer = '*' in ref_pointer_name_seq + array = '[' in ref_pointer_name_seq + var_type = Type(pos_token.start, pos_token.end, type_name, + templated_types, type_modifiers, + reference, pointer, array) + return VariableDeclaration(pos_token.start, pos_token.end, + name, var_type, value, self.namespace_stack) + + def _GenerateOne(self, token): + if token.token_type == tokenize.NAME: + if (keywords.IsKeyword(token.name) and + not keywords.IsBuiltinType(token.name)): + if token.name == 'enum': + # Pop the next token and only put it back if it's not + # 'class'. This allows us to support the two-token + # 'enum class' keyword as if it were simply 'enum'. + next = self._GetNextToken() + if next.name != 'class': + self._AddBackToken(next) + + method = getattr(self, 'handle_' + token.name) + return method() + elif token.name == self.in_class_name_only: + # The token name is the same as the class, must be a ctor if + # there is a paren. Otherwise, it's the return type. + # Peek ahead to get the next token to figure out which. + next = self._GetNextToken() + self._AddBackToken(next) + if next.token_type == tokenize.SYNTAX and next.name == '(': + return self._GetMethod([token], FUNCTION_CTOR, None, True) + # Fall through--handle like any other method. + + # Handle data or function declaration/definition. + syntax = tokenize.SYNTAX + temp_tokens, last_token = \ + self._GetVarTokensUpToIgnoringTemplates(syntax, + '(', ';', '{', '[') + temp_tokens.insert(0, token) + if last_token.name == '(': + # If there is an assignment before the paren, + # this is an expression, not a method. + expr = bool([e for e in temp_tokens if e.name == '=']) + if expr: + new_temp = self._GetTokensUpTo(tokenize.SYNTAX, ';') + temp_tokens.append(last_token) + temp_tokens.extend(new_temp) + last_token = tokenize.Token(tokenize.SYNTAX, ';', 0, 0) + + if last_token.name == '[': + # Handle array, this isn't a method, unless it's an operator. + # TODO(nnorwitz): keep the size somewhere. + # unused_size = self._GetTokensUpTo(tokenize.SYNTAX, ']') + temp_tokens.append(last_token) + if temp_tokens[-2].name == 'operator': + temp_tokens.append(self._GetNextToken()) else: - assert token.whence == tokenize.WHENCE_QUEUE, token - self.token_queue.append(token) - - def _AddBackTokens(self, tokens): - if tokens: - if tokens[-1].whence == tokenize.WHENCE_STREAM: - for token in tokens: - token.whence = tokenize.WHENCE_QUEUE - self.token_queue[:0] = reversed(tokens) - else: - assert tokens[-1].whence == tokenize.WHENCE_QUEUE, tokens - self.token_queue.extend(reversed(tokens)) - - def GetName(self, seq=None): - """Returns ([tokens], next_token_info).""" - GetNextToken = self._GetNextToken - if seq is not None: - it = iter(seq) - GetNextToken = lambda: next(it) - next_token = GetNextToken() - tokens = [] - last_token_was_name = False - while (next_token.token_type == tokenize.NAME or - (next_token.token_type == tokenize.SYNTAX and - next_token.name in ('::', '<'))): - # Two NAMEs in a row means the identifier should terminate. - # It's probably some sort of variable declaration. - if last_token_was_name and next_token.token_type == tokenize.NAME: - break - last_token_was_name = next_token.token_type == tokenize.NAME - tokens.append(next_token) - # Handle templated names. - if next_token.name == '<': - tokens.extend(self._GetMatchingChar('<', '>', GetNextToken)) - last_token_was_name = True - next_token = GetNextToken() - return tokens, next_token - - def GetMethod(self, modifiers, templated_types): - return_type_and_name = self._GetTokensUpTo(tokenize.SYNTAX, '(') - assert len(return_type_and_name) >= 1 - return self._GetMethod(return_type_and_name, modifiers, templated_types, - False) - - def _GetMethod(self, return_type_and_name, modifiers, templated_types, - get_paren): - template_portion = None - if get_paren: - token = self._GetNextToken() - assert token.token_type == tokenize.SYNTAX, token - if token.name == '<': - # Handle templatized dtors. - template_portion = [token] - template_portion.extend(self._GetMatchingChar('<', '>')) - token = self._GetNextToken() - assert token.token_type == tokenize.SYNTAX, token - assert token.name == '(', token - - name = return_type_and_name.pop() - # Handle templatized ctors. - if name.name == '>': - index = 1 - while return_type_and_name[index].name != '<': - index += 1 - template_portion = return_type_and_name[index:] + [name] - del return_type_and_name[index:] - name = return_type_and_name.pop() - elif name.name == ']': - rt = return_type_and_name - assert rt[-1].name == '[', return_type_and_name - assert rt[-2].name == 'operator', return_type_and_name - name_seq = return_type_and_name[-2:] - del return_type_and_name[-2:] - name = tokenize.Token(tokenize.NAME, 'operator[]', - name_seq[0].start, name.end) - # Get the open paren so _GetParameters() below works. - unused_open_paren = self._GetNextToken() - - # TODO(nnorwitz): store template_portion. - return_type = return_type_and_name - indices = name - if return_type: - indices = return_type[0] - - # Force ctor for templatized ctors. - if name.name == self.in_class and not modifiers: - modifiers |= FUNCTION_CTOR - parameters = list(self._GetParameters()) - del parameters[-1] # Remove trailing ')'. - - # Handling operator() is especially weird. - if name.name == 'operator' and not parameters: - token = self._GetNextToken() - assert token.name == '(', token - parameters = list(self._GetParameters()) - del parameters[-1] # Remove trailing ')'. - + temp_tokens2, last_token = \ + self._GetVarTokensUpTo(tokenize.SYNTAX, ';') + temp_tokens.extend(temp_tokens2) + + if last_token.name == ';': + # Handle data, this isn't a method. + parts = self.converter.DeclarationToParts(temp_tokens, True) + (name, type_name, templated_types, modifiers, default, + unused_other_tokens) = parts + + t0 = temp_tokens[0] + names = [t.name for t in temp_tokens] + if templated_types: + start, end = self.converter.GetTemplateIndices(names) + names = names[:start] + names[end:] + default = ''.join([t.name for t in default]) + return self._CreateVariable(t0, name, type_name, modifiers, + names, templated_types, default) + if last_token.name == '{': + self._AddBackTokens(temp_tokens[1:]) + self._AddBackToken(last_token) + method_name = temp_tokens[0].name + method = getattr(self, 'handle_' + method_name, None) + if not method: + # Must be declaring a variable. + # TODO(nnorwitz): handle the declaration. + return None + return method() + return self._GetMethod(temp_tokens, 0, None, False) + elif token.token_type == tokenize.SYNTAX: + if token.name == '~' and self.in_class: + # Must be a dtor (probably not in method body). + token = self._GetNextToken() + # self.in_class can contain A::Name, but the dtor will only + # be Name. Make sure to compare against the right value. + if (token.token_type == tokenize.NAME and + token.name == self.in_class_name_only): + return self._GetMethod([token], FUNCTION_DTOR, None, True) + # TODO(nnorwitz): handle a lot more syntax. + elif token.token_type == tokenize.PREPROCESSOR: + # TODO(nnorwitz): handle more preprocessor directives. + # token starts with a #, so remove it and strip whitespace. + name = token.name[1:].lstrip() + if name.startswith('include'): + # Remove "include". + name = name[7:].strip() + assert name + # Handle #include \<newline> "header-on-second-line.h". + if name.startswith('\\'): + name = name[1:].strip() + assert name[0] in '<"', token + assert name[-1] in '>"', token + system = name[0] == '<' + filename = name[1:-1] + return Include(token.start, token.end, filename, system) + if name.startswith('define'): + # Remove "define". + name = name[6:].strip() + assert name + value = '' + for i, c in enumerate(name): + if c.isspace(): + value = name[i:].lstrip() + name = name[:i] + break + return Define(token.start, token.end, name, value) + if name.startswith('if') and name[2:3].isspace(): + condition = name[3:].strip() + if condition.startswith('0') or condition.startswith('(0)'): + self._SkipIf0Blocks() + return None + + def _GetTokensUpTo(self, expected_token_type, expected_token): + return self._GetVarTokensUpTo(expected_token_type, expected_token)[0] + + def _GetVarTokensUpTo(self, expected_token_type, *expected_tokens): + last_token = self._GetNextToken() + tokens = [] + while (last_token.token_type != expected_token_type or + last_token.name not in expected_tokens): + tokens.append(last_token) + last_token = self._GetNextToken() + return tokens, last_token + + # Same as _GetVarTokensUpTo, but skips over '<...>' which could contain an + # expected token. + def _GetVarTokensUpToIgnoringTemplates(self, expected_token_type, + *expected_tokens): + last_token = self._GetNextToken() + tokens = [] + nesting = 0 + while (nesting > 0 or + last_token.token_type != expected_token_type or + last_token.name not in expected_tokens): + tokens.append(last_token) + last_token = self._GetNextToken() + if last_token.name == '<': + nesting += 1 + elif last_token.name == '>': + nesting -= 1 + return tokens, last_token + + # TODO(nnorwitz): remove _IgnoreUpTo() it shouldn't be necesary. + def _IgnoreUpTo(self, token_type, token): + unused_tokens = self._GetTokensUpTo(token_type, token) + + def _SkipIf0Blocks(self): + count = 1 + while 1: + token = self._GetNextToken() + if token.token_type != tokenize.PREPROCESSOR: + continue + + name = token.name[1:].lstrip() + if name.startswith('endif'): + count -= 1 + if count == 0: + break + elif name.startswith('if'): + count += 1 + + def _GetMatchingChar(self, open_paren, close_paren, GetNextToken=None): + if GetNextToken is None: + GetNextToken = self._GetNextToken + # Assumes the current token is open_paren and we will consume + # and return up to the close_paren. + count = 1 + token = GetNextToken() + while 1: + if token.token_type == tokenize.SYNTAX: + if token.name == open_paren: + count += 1 + elif token.name == close_paren: + count -= 1 + if count == 0: + break + yield token + token = GetNextToken() + yield token + + def _GetParameters(self): + return self._GetMatchingChar('(', ')') + + def GetScope(self): + return self._GetMatchingChar('{', '}') + + def _GetNextToken(self): + if self.token_queue: + return self.token_queue.pop() + try: + return next(self.tokens) + except StopIteration: + return + + def _AddBackToken(self, token): + if token.whence == tokenize.WHENCE_STREAM: + token.whence = tokenize.WHENCE_QUEUE + self.token_queue.insert(0, token) + else: + assert token.whence == tokenize.WHENCE_QUEUE, token + self.token_queue.append(token) + + def _AddBackTokens(self, tokens): + if tokens: + if tokens[-1].whence == tokenize.WHENCE_STREAM: + for token in tokens: + token.whence = tokenize.WHENCE_QUEUE + self.token_queue[:0] = reversed(tokens) + else: + assert tokens[-1].whence == tokenize.WHENCE_QUEUE, tokens + self.token_queue.extend(reversed(tokens)) + + def GetName(self, seq=None): + """Returns ([tokens], next_token_info).""" + GetNextToken = self._GetNextToken + if seq is not None: + it = iter(seq) + GetNextToken = lambda: next(it) + next_token = GetNextToken() + tokens = [] + last_token_was_name = False + while (next_token.token_type == tokenize.NAME or + (next_token.token_type == tokenize.SYNTAX and + next_token.name in ('::', '<'))): + # Two NAMEs in a row means the identifier should terminate. + # It's probably some sort of variable declaration. + if last_token_was_name and next_token.token_type == tokenize.NAME: + break + last_token_was_name = next_token.token_type == tokenize.NAME + tokens.append(next_token) + # Handle templated names. + if next_token.name == '<': + tokens.extend(self._GetMatchingChar('<', '>', GetNextToken)) + last_token_was_name = True + next_token = GetNextToken() + return tokens, next_token + + def GetMethod(self, modifiers, templated_types): + return_type_and_name = self._GetTokensUpTo(tokenize.SYNTAX, '(') + assert len(return_type_and_name) >= 1 + return self._GetMethod(return_type_and_name, modifiers, templated_types, + False) + + def _GetMethod(self, return_type_and_name, modifiers, templated_types, + get_paren): + template_portion = None + if get_paren: + token = self._GetNextToken() + assert token.token_type == tokenize.SYNTAX, token + if token.name == '<': + # Handle templatized dtors. + template_portion = [token] + template_portion.extend(self._GetMatchingChar('<', '>')) + token = self._GetNextToken() + assert token.token_type == tokenize.SYNTAX, token + assert token.name == '(', token + + name = return_type_and_name.pop() + # Handle templatized ctors. + if name.name == '>': + index = 1 + while return_type_and_name[index].name != '<': + index += 1 + template_portion = return_type_and_name[index:] + [name] + del return_type_and_name[index:] + name = return_type_and_name.pop() + elif name.name == ']': + rt = return_type_and_name + assert rt[-1].name == '[', return_type_and_name + assert rt[-2].name == 'operator', return_type_and_name + name_seq = return_type_and_name[-2:] + del return_type_and_name[-2:] + name = tokenize.Token(tokenize.NAME, 'operator[]', + name_seq[0].start, name.end) + # Get the open paren so _GetParameters() below works. + unused_open_paren = self._GetNextToken() + + # TODO(nnorwitz): store template_portion. + return_type = return_type_and_name + indices = name + if return_type: + indices = return_type[0] + + # Force ctor for templatized ctors. + if name.name == self.in_class and not modifiers: + modifiers |= FUNCTION_CTOR + parameters = list(self._GetParameters()) + del parameters[-1] # Remove trailing ')'. + + # Handling operator() is especially weird. + if name.name == 'operator' and not parameters: + token = self._GetNextToken() + assert token.name == '(', token + parameters = list(self._GetParameters()) + del parameters[-1] # Remove trailing ')'. + + token = self._GetNextToken() + while token.token_type == tokenize.NAME: + modifier_token = token + token = self._GetNextToken() + if modifier_token.name == 'const': + modifiers |= FUNCTION_CONST + elif modifier_token.name == '__attribute__': + # TODO(nnorwitz): handle more __attribute__ details. + modifiers |= FUNCTION_ATTRIBUTE + assert token.name == '(', token + # Consume everything between the (parens). + unused_tokens = list(self._GetMatchingChar('(', ')')) + token = self._GetNextToken() + elif modifier_token.name == 'throw': + modifiers |= FUNCTION_THROW + assert token.name == '(', token + # Consume everything between the (parens). + unused_tokens = list(self._GetMatchingChar('(', ')')) + token = self._GetNextToken() + elif modifier_token.name == 'override': + modifiers |= FUNCTION_OVERRIDE + elif modifier_token.name == modifier_token.name.upper(): + # HACK(nnorwitz): assume that all upper-case names + # are some macro we aren't expanding. + modifiers |= FUNCTION_UNKNOWN_ANNOTATION + else: + self.HandleError('unexpected token', modifier_token) + + assert token.token_type == tokenize.SYNTAX, token + # Handle ctor initializers. + if token.name == ':': + # TODO(nnorwitz): anything else to handle for initializer list? + while token.name != ';' and token.name != '{': token = self._GetNextToken() - while token.token_type == tokenize.NAME: - modifier_token = token - token = self._GetNextToken() - if modifier_token.name == 'const': - modifiers |= FUNCTION_CONST - elif modifier_token.name == '__attribute__': - # TODO(nnorwitz): handle more __attribute__ details. - modifiers |= FUNCTION_ATTRIBUTE - assert token.name == '(', token - # Consume everything between the (parens). - unused_tokens = list(self._GetMatchingChar('(', ')')) - token = self._GetNextToken() - elif modifier_token.name == 'throw': - modifiers |= FUNCTION_THROW - assert token.name == '(', token - # Consume everything between the (parens). - unused_tokens = list(self._GetMatchingChar('(', ')')) - token = self._GetNextToken() - elif modifier_token.name == 'override': - modifiers |= FUNCTION_OVERRIDE - elif modifier_token.name == modifier_token.name.upper(): - # HACK(nnorwitz): assume that all upper-case names - # are some macro we aren't expanding. - modifiers |= FUNCTION_UNKNOWN_ANNOTATION - else: - self.HandleError('unexpected token', modifier_token) + # Handle pointer to functions that are really data but look + # like method declarations. + if token.name == '(': + if parameters[0].name == '*': + # name contains the return type. + name = parameters.pop() + # parameters contains the name of the data. + modifiers = [p.name for p in parameters] + # Already at the ( to open the parameter list. + function_parameters = list(self._GetMatchingChar('(', ')')) + del function_parameters[-1] # Remove trailing ')'. + # TODO(nnorwitz): store the function_parameters. + token = self._GetNextToken() assert token.token_type == tokenize.SYNTAX, token - # Handle ctor initializers. - if token.name == ':': - # TODO(nnorwitz): anything else to handle for initializer list? - while token.name != ';' and token.name != '{': - token = self._GetNextToken() - - # Handle pointer to functions that are really data but look - # like method declarations. - if token.name == '(': - if parameters[0].name == '*': - # name contains the return type. - name = parameters.pop() - # parameters contains the name of the data. - modifiers = [p.name for p in parameters] - # Already at the ( to open the parameter list. - function_parameters = list(self._GetMatchingChar('(', ')')) - del function_parameters[-1] # Remove trailing ')'. - # TODO(nnorwitz): store the function_parameters. - token = self._GetNextToken() - assert token.token_type == tokenize.SYNTAX, token - assert token.name == ';', token - return self._CreateVariable(indices, name.name, indices.name, - modifiers, '', None) - # At this point, we got something like: - # return_type (type::*name_)(params); - # This is a data member called name_ that is a function pointer. - # With this code: void (sq_type::*field_)(string&); - # We get: name=void return_type=[] parameters=sq_type ... field_ - # TODO(nnorwitz): is return_type always empty? - # TODO(nnorwitz): this isn't even close to being correct. - # Just put in something so we don't crash and can move on. - real_name = parameters[-1] - modifiers = [p.name for p in self._GetParameters()] - del modifiers[-1] # Remove trailing ')'. - return self._CreateVariable(indices, real_name.name, indices.name, - modifiers, '', None) - - if token.name == '{': - body = list(self.GetScope()) - del body[-1] # Remove trailing '}'. - else: - body = None - if token.name == '=': - token = self._GetNextToken() - - if token.name == 'default' or token.name == 'delete': - # Ignore explicitly defaulted and deleted special members - # in C++11. - token = self._GetNextToken() - else: - # Handle pure-virtual declarations. - assert token.token_type == tokenize.CONSTANT, token - assert token.name == '0', token - modifiers |= FUNCTION_PURE_VIRTUAL - token = self._GetNextToken() - - if token.name == '[': - # TODO(nnorwitz): store tokens and improve parsing. - # template <typename T, size_t N> char (&ASH(T (&seq)[N]))[N]; - tokens = list(self._GetMatchingChar('[', ']')) - token = self._GetNextToken() - - assert token.name == ';', (token, return_type_and_name, parameters) - - # Looks like we got a method, not a function. - if len(return_type) > 2 and return_type[-1].name == '::': - return_type, in_class = \ - self._GetReturnTypeAndClassName(return_type) - return Method(indices.start, indices.end, name.name, in_class, - return_type, parameters, modifiers, templated_types, - body, self.namespace_stack) - return Function(indices.start, indices.end, name.name, return_type, - parameters, modifiers, templated_types, body, - self.namespace_stack) - - def _GetReturnTypeAndClassName(self, token_seq): - # Splitting the return type from the class name in a method - # can be tricky. For example, Return::Type::Is::Hard::To::Find(). - # Where is the return type and where is the class name? - # The heuristic used is to pull the last name as the class name. - # This includes all the templated type info. - # TODO(nnorwitz): if there is only One name like in the - # example above, punt and assume the last bit is the class name. - - # Ignore a :: prefix, if exists so we can find the first real name. - i = 0 - if token_seq[0].name == '::': - i = 1 - # Ignore a :: suffix, if exists. - end = len(token_seq) - 1 - if token_seq[end-1].name == '::': - end -= 1 - - # Make a copy of the sequence so we can append a sentinel - # value. This is required for GetName will has to have some - # terminating condition beyond the last name. - seq_copy = token_seq[i:end] - seq_copy.append(tokenize.Token(tokenize.SYNTAX, '', 0, 0)) - names = [] - while i < end: - # Iterate through the sequence parsing out each name. - new_name, next = self.GetName(seq_copy[i:]) - assert new_name, 'Got empty new_name, next=%s' % next - # We got a pointer or ref. Add it to the name. - if next and next.token_type == tokenize.SYNTAX: - new_name.append(next) - names.append(new_name) - i += len(new_name) - - # Now that we have the names, it's time to undo what we did. - - # Remove the sentinel value. - names[-1].pop() - # Flatten the token sequence for the return type. - return_type = [e for seq in names[:-1] for e in seq] - # The class name is the last name. - class_name = names[-1] - return return_type, class_name - - def handle_bool(self): - pass - - def handle_char(self): - pass - - def handle_int(self): - pass + assert token.name == ';', token + return self._CreateVariable(indices, name.name, indices.name, + modifiers, '', None) + # At this point, we got something like: + # return_type (type::*name_)(params); + # This is a data member called name_ that is a function pointer. + # With this code: void (sq_type::*field_)(string&); + # We get: name=void return_type=[] parameters=sq_type ... field_ + # TODO(nnorwitz): is return_type always empty? + # TODO(nnorwitz): this isn't even close to being correct. + # Just put in something so we don't crash and can move on. + real_name = parameters[-1] + modifiers = [p.name for p in self._GetParameters()] + del modifiers[-1] # Remove trailing ')'. + return self._CreateVariable(indices, real_name.name, indices.name, + modifiers, '', None) + + if token.name == '{': + body = list(self.GetScope()) + del body[-1] # Remove trailing '}'. + else: + body = None + if token.name == '=': + token = self._GetNextToken() - def handle_long(self): - pass + if token.name == 'default' or token.name == 'delete': + # Ignore explicitly defaulted and deleted special members + # in C++11. + token = self._GetNextToken() + else: + # Handle pure-virtual declarations. + assert token.token_type == tokenize.CONSTANT, token + assert token.name == '0', token + modifiers |= FUNCTION_PURE_VIRTUAL + token = self._GetNextToken() + + if token.name == '[': + # TODO(nnorwitz): store tokens and improve parsing. + # template <typename T, size_t N> char (&ASH(T (&seq)[N]))[N]; + tokens = list(self._GetMatchingChar('[', ']')) + token = self._GetNextToken() - def handle_short(self): - pass + assert token.name == ';', (token, return_type_and_name, parameters) + + # Looks like we got a method, not a function. + if len(return_type) > 2 and return_type[-1].name == '::': + return_type, in_class = \ + self._GetReturnTypeAndClassName(return_type) + return Method(indices.start, indices.end, name.name, in_class, + return_type, parameters, modifiers, templated_types, + body, self.namespace_stack) + return Function(indices.start, indices.end, name.name, return_type, + parameters, modifiers, templated_types, body, + self.namespace_stack) + + def _GetReturnTypeAndClassName(self, token_seq): + # Splitting the return type from the class name in a method + # can be tricky. For example, Return::Type::Is::Hard::To::Find(). + # Where is the return type and where is the class name? + # The heuristic used is to pull the last name as the class name. + # This includes all the templated type info. + # TODO(nnorwitz): if there is only One name like in the + # example above, punt and assume the last bit is the class name. + + # Ignore a :: prefix, if exists so we can find the first real name. + i = 0 + if token_seq[0].name == '::': + i = 1 + # Ignore a :: suffix, if exists. + end = len(token_seq) - 1 + if token_seq[end-1].name == '::': + end -= 1 + + # Make a copy of the sequence so we can append a sentinel + # value. This is required for GetName will has to have some + # terminating condition beyond the last name. + seq_copy = token_seq[i:end] + seq_copy.append(tokenize.Token(tokenize.SYNTAX, '', 0, 0)) + names = [] + while i < end: + # Iterate through the sequence parsing out each name. + new_name, next = self.GetName(seq_copy[i:]) + assert new_name, 'Got empty new_name, next=%s' % next + # We got a pointer or ref. Add it to the name. + if next and next.token_type == tokenize.SYNTAX: + new_name.append(next) + names.append(new_name) + i += len(new_name) + + # Now that we have the names, it's time to undo what we did. + + # Remove the sentinel value. + names[-1].pop() + # Flatten the token sequence for the return type. + return_type = [e for seq in names[:-1] for e in seq] + # The class name is the last name. + class_name = names[-1] + return return_type, class_name + + def handle_bool(self): + pass - def handle_double(self): - pass + def handle_char(self): + pass - def handle_float(self): - pass + def handle_int(self): + pass - def handle_void(self): - pass + def handle_long(self): + pass - def handle_wchar_t(self): - pass + def handle_short(self): + pass - def handle_unsigned(self): - pass + def handle_double(self): + pass - def handle_signed(self): - pass + def handle_float(self): + pass - def _GetNestedType(self, ctor): - name = None - name_tokens, token = self.GetName() - if name_tokens: - name = ''.join([t.name for t in name_tokens]) - - # Handle forward declarations. - if token.token_type == tokenize.SYNTAX and token.name == ';': - return ctor(token.start, token.end, name, None, - self.namespace_stack) - - if token.token_type == tokenize.NAME and self._handling_typedef: - self._AddBackToken(token) - return ctor(token.start, token.end, name, None, - self.namespace_stack) - - # Must be the type declaration. - fields = list(self._GetMatchingChar('{', '}')) - del fields[-1] # Remove trailing '}'. - if token.token_type == tokenize.SYNTAX and token.name == '{': - next = self._GetNextToken() - new_type = ctor(token.start, token.end, name, fields, - self.namespace_stack) - # A name means this is an anonymous type and the name - # is the variable declaration. - if next.token_type != tokenize.NAME: - return new_type - name = new_type - token = next - - # Must be variable declaration using the type prefixed with keyword. - assert token.token_type == tokenize.NAME, token - return self._CreateVariable(token, token.name, name, [], '', None) - - def handle_struct(self): - # Special case the handling typedef/aliasing of structs here. - # It would be a pain to handle in the class code. - name_tokens, var_token = self.GetName() - if name_tokens: - next_token = self._GetNextToken() - is_syntax = (var_token.token_type == tokenize.SYNTAX and - var_token.name[0] in '*&') - is_variable = (var_token.token_type == tokenize.NAME and - next_token.name == ';') - variable = var_token - if is_syntax and not is_variable: - variable = next_token - temp = self._GetNextToken() - if temp.token_type == tokenize.SYNTAX and temp.name == '(': - # Handle methods declared to return a struct. - t0 = name_tokens[0] - struct = tokenize.Token(tokenize.NAME, 'struct', - t0.start-7, t0.start-2) - type_and_name = [struct] - type_and_name.extend(name_tokens) - type_and_name.extend((var_token, next_token)) - return self._GetMethod(type_and_name, 0, None, False) - assert temp.name == ';', (temp, name_tokens, var_token) - if is_syntax or (is_variable and not self._handling_typedef): - modifiers = ['struct'] - type_name = ''.join([t.name for t in name_tokens]) - position = name_tokens[0] - return self._CreateVariable(position, variable.name, type_name, - modifiers, var_token.name, None) - name_tokens.extend((var_token, next_token)) - self._AddBackTokens(name_tokens) - else: - self._AddBackToken(var_token) - return self._GetClass(Struct, VISIBILITY_PUBLIC, None) + def handle_void(self): + pass - def handle_union(self): - return self._GetNestedType(Union) + def handle_wchar_t(self): + pass - def handle_enum(self): - return self._GetNestedType(Enum) + def handle_unsigned(self): + pass - def handle_auto(self): - # TODO(nnorwitz): warn about using auto? Probably not since it - # will be reclaimed and useful for C++0x. - pass + def handle_signed(self): + pass - def handle_register(self): - pass + def _GetNestedType(self, ctor): + name = None + name_tokens, token = self.GetName() + if name_tokens: + name = ''.join([t.name for t in name_tokens]) + + # Handle forward declarations. + if token.token_type == tokenize.SYNTAX and token.name == ';': + return ctor(token.start, token.end, name, None, + self.namespace_stack) + + if token.token_type == tokenize.NAME and self._handling_typedef: + self._AddBackToken(token) + return ctor(token.start, token.end, name, None, + self.namespace_stack) + + # Must be the type declaration. + fields = list(self._GetMatchingChar('{', '}')) + del fields[-1] # Remove trailing '}'. + if token.token_type == tokenize.SYNTAX and token.name == '{': + next = self._GetNextToken() + new_type = ctor(token.start, token.end, name, fields, + self.namespace_stack) + # A name means this is an anonymous type and the name + # is the variable declaration. + if next.token_type != tokenize.NAME: + return new_type + name = new_type + token = next + + # Must be variable declaration using the type prefixed with keyword. + assert token.token_type == tokenize.NAME, token + return self._CreateVariable(token, token.name, name, [], '', None) + + def handle_struct(self): + # Special case the handling typedef/aliasing of structs here. + # It would be a pain to handle in the class code. + name_tokens, var_token = self.GetName() + if name_tokens: + next_token = self._GetNextToken() + is_syntax = (var_token.token_type == tokenize.SYNTAX and + var_token.name[0] in '*&') + is_variable = (var_token.token_type == tokenize.NAME and + next_token.name == ';') + variable = var_token + if is_syntax and not is_variable: + variable = next_token + temp = self._GetNextToken() + if temp.token_type == tokenize.SYNTAX and temp.name == '(': + # Handle methods declared to return a struct. + t0 = name_tokens[0] + struct = tokenize.Token(tokenize.NAME, 'struct', + t0.start-7, t0.start-2) + type_and_name = [struct] + type_and_name.extend(name_tokens) + type_and_name.extend((var_token, next_token)) + return self._GetMethod(type_and_name, 0, None, False) + assert temp.name == ';', (temp, name_tokens, var_token) + if is_syntax or (is_variable and not self._handling_typedef): + modifiers = ['struct'] + type_name = ''.join([t.name for t in name_tokens]) + position = name_tokens[0] + return self._CreateVariable(position, variable.name, type_name, + modifiers, var_token.name, None) + name_tokens.extend((var_token, next_token)) + self._AddBackTokens(name_tokens) + else: + self._AddBackToken(var_token) + return self._GetClass(Struct, VISIBILITY_PUBLIC, None) + + def handle_union(self): + return self._GetNestedType(Union) + + def handle_enum(self): + return self._GetNestedType(Enum) + + def handle_auto(self): + # TODO(nnorwitz): warn about using auto? Probably not since it + # will be reclaimed and useful for C++0x. + pass - def handle_const(self): - pass + def handle_register(self): + pass - def handle_inline(self): - pass + def handle_const(self): + pass - def handle_extern(self): - pass + def handle_inline(self): + pass - def handle_static(self): - pass + def handle_extern(self): + pass - def handle_virtual(self): - # What follows must be a method. - token = token2 = self._GetNextToken() - if token.name == 'inline': - # HACK(nnorwitz): handle inline dtors by ignoring 'inline'. - token2 = self._GetNextToken() - if token2.token_type == tokenize.SYNTAX and token2.name == '~': - return self.GetMethod(FUNCTION_VIRTUAL + FUNCTION_DTOR, None) - assert token.token_type == tokenize.NAME or token.name == '::', token - return_type_and_name, _ = self._GetVarTokensUpToIgnoringTemplates( - tokenize.SYNTAX, '(') # ) - return_type_and_name.insert(0, token) - if token2 is not token: - return_type_and_name.insert(1, token2) - return self._GetMethod(return_type_and_name, FUNCTION_VIRTUAL, - None, False) - - def handle_volatile(self): - pass + def handle_static(self): + pass - def handle_mutable(self): - pass + def handle_virtual(self): + # What follows must be a method. + token = token2 = self._GetNextToken() + if token.name == 'inline': + # HACK(nnorwitz): handle inline dtors by ignoring 'inline'. + token2 = self._GetNextToken() + if token2.token_type == tokenize.SYNTAX and token2.name == '~': + return self.GetMethod(FUNCTION_VIRTUAL + FUNCTION_DTOR, None) + assert token.token_type == tokenize.NAME or token.name == '::', token + return_type_and_name, _ = self._GetVarTokensUpToIgnoringTemplates( + tokenize.SYNTAX, '(') # ) + return_type_and_name.insert(0, token) + if token2 is not token: + return_type_and_name.insert(1, token2) + return self._GetMethod(return_type_and_name, FUNCTION_VIRTUAL, + None, False) + + def handle_volatile(self): + pass - def handle_public(self): - assert self.in_class - self.visibility = VISIBILITY_PUBLIC + def handle_mutable(self): + pass - def handle_protected(self): - assert self.in_class - self.visibility = VISIBILITY_PROTECTED + def handle_public(self): + assert self.in_class + self.visibility = VISIBILITY_PUBLIC - def handle_private(self): - assert self.in_class - self.visibility = VISIBILITY_PRIVATE + def handle_protected(self): + assert self.in_class + self.visibility = VISIBILITY_PROTECTED - def handle_friend(self): - tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';') - assert tokens - t0 = tokens[0] - return Friend(t0.start, t0.end, tokens, self.namespace_stack) + def handle_private(self): + assert self.in_class + self.visibility = VISIBILITY_PRIVATE - def handle_static_cast(self): - pass + def handle_friend(self): + tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';') + assert tokens + t0 = tokens[0] + return Friend(t0.start, t0.end, tokens, self.namespace_stack) - def handle_const_cast(self): - pass + def handle_static_cast(self): + pass - def handle_dynamic_cast(self): - pass + def handle_const_cast(self): + pass - def handle_reinterpret_cast(self): - pass + def handle_dynamic_cast(self): + pass - def handle_new(self): - pass + def handle_reinterpret_cast(self): + pass - def handle_delete(self): - tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';') - assert tokens - return Delete(tokens[0].start, tokens[0].end, tokens) + def handle_new(self): + pass - def handle_typedef(self): - token = self._GetNextToken() - if (token.token_type == tokenize.NAME and - keywords.IsKeyword(token.name)): - # Token must be struct/enum/union/class. - method = getattr(self, 'handle_' + token.name) - self._handling_typedef = True - tokens = [method()] - self._handling_typedef = False + def handle_delete(self): + tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';') + assert tokens + return Delete(tokens[0].start, tokens[0].end, tokens) + + def handle_typedef(self): + token = self._GetNextToken() + if (token.token_type == tokenize.NAME and + keywords.IsKeyword(token.name)): + # Token must be struct/enum/union/class. + method = getattr(self, 'handle_' + token.name) + self._handling_typedef = True + tokens = [method()] + self._handling_typedef = False + else: + tokens = [token] + + # Get the remainder of the typedef up to the semi-colon. + tokens.extend(self._GetTokensUpTo(tokenize.SYNTAX, ';')) + + # TODO(nnorwitz): clean all this up. + assert tokens + name = tokens.pop() + indices = name + if tokens: + indices = tokens[0] + if not indices: + indices = token + if name.name == ')': + # HACK(nnorwitz): Handle pointers to functions "properly". + if (len(tokens) >= 4 and + tokens[1].name == '(' and tokens[2].name == '*'): + tokens.append(name) + name = tokens[3] + elif name.name == ']': + # HACK(nnorwitz): Handle arrays properly. + if len(tokens) >= 2: + tokens.append(name) + name = tokens[1] + new_type = tokens + if tokens and isinstance(tokens[0], tokenize.Token): + new_type = self.converter.ToType(tokens)[0] + return Typedef(indices.start, indices.end, name.name, + new_type, self.namespace_stack) + + def handle_typeid(self): + pass # Not needed yet. + + def handle_typename(self): + pass # Not needed yet. + + def _GetTemplatedTypes(self): + result = {} + tokens = list(self._GetMatchingChar('<', '>')) + len_tokens = len(tokens) - 1 # Ignore trailing '>'. + i = 0 + while i < len_tokens: + key = tokens[i].name + i += 1 + if keywords.IsKeyword(key) or key == ',': + continue + type_name = default = None + if i < len_tokens: + i += 1 + if tokens[i-1].name == '=': + assert i < len_tokens, '%s %s' % (i, tokens) + default, unused_next_token = self.GetName(tokens[i:]) + i += len(default) else: - tokens = [token] - - # Get the remainder of the typedef up to the semi-colon. - tokens.extend(self._GetTokensUpTo(tokenize.SYNTAX, ';')) - - # TODO(nnorwitz): clean all this up. - assert tokens - name = tokens.pop() - indices = name - if tokens: - indices = tokens[0] - if not indices: - indices = token - if name.name == ')': - # HACK(nnorwitz): Handle pointers to functions "properly". - if (len(tokens) >= 4 and - tokens[1].name == '(' and tokens[2].name == '*'): - tokens.append(name) - name = tokens[3] - elif name.name == ']': - # HACK(nnorwitz): Handle arrays properly. - if len(tokens) >= 2: - tokens.append(name) - name = tokens[1] - new_type = tokens - if tokens and isinstance(tokens[0], tokenize.Token): - new_type = self.converter.ToType(tokens)[0] - return Typedef(indices.start, indices.end, name.name, - new_type, self.namespace_stack) - - def handle_typeid(self): - pass # Not needed yet. - - def handle_typename(self): - pass # Not needed yet. - - def _GetTemplatedTypes(self): - result = {} - tokens = list(self._GetMatchingChar('<', '>')) - len_tokens = len(tokens) - 1 # Ignore trailing '>'. - i = 0 - while i < len_tokens: - key = tokens[i].name - i += 1 - if keywords.IsKeyword(key) or key == ',': - continue - type_name = default = None - if i < len_tokens: - i += 1 - if tokens[i-1].name == '=': - assert i < len_tokens, '%s %s' % (i, tokens) - default, unused_next_token = self.GetName(tokens[i:]) - i += len(default) - else: - if tokens[i-1].name != ',': - # We got something like: Type variable. - # Re-adjust the key (variable) and type_name (Type). - key = tokens[i-1].name - type_name = tokens[i-2] - - result[key] = (type_name, default) - return result - - def handle_template(self): - token = self._GetNextToken() - assert token.token_type == tokenize.SYNTAX, token - assert token.name == '<', token - templated_types = self._GetTemplatedTypes() - # TODO(nnorwitz): for now, just ignore the template params. - token = self._GetNextToken() - if token.token_type == tokenize.NAME: - if token.name == 'class': - return self._GetClass(Class, VISIBILITY_PRIVATE, templated_types) - elif token.name == 'struct': - return self._GetClass(Struct, VISIBILITY_PUBLIC, templated_types) - elif token.name == 'friend': - return self.handle_friend() + if tokens[i-1].name != ',': + # We got something like: Type variable. + # Re-adjust the key (variable) and type_name (Type). + key = tokens[i-1].name + type_name = tokens[i-2] + + result[key] = (type_name, default) + return result + + def handle_template(self): + token = self._GetNextToken() + assert token.token_type == tokenize.SYNTAX, token + assert token.name == '<', token + templated_types = self._GetTemplatedTypes() + # TODO(nnorwitz): for now, just ignore the template params. + token = self._GetNextToken() + if token.token_type == tokenize.NAME: + if token.name == 'class': + return self._GetClass(Class, VISIBILITY_PRIVATE, templated_types) + elif token.name == 'struct': + return self._GetClass(Struct, VISIBILITY_PUBLIC, templated_types) + elif token.name == 'friend': + return self.handle_friend() + self._AddBackToken(token) + tokens, last = self._GetVarTokensUpTo(tokenize.SYNTAX, '(', ';') + tokens.append(last) + self._AddBackTokens(tokens) + if last.name == '(': + return self.GetMethod(FUNCTION_NONE, templated_types) + # Must be a variable definition. + return None + + def handle_true(self): + pass # Nothing to do. + + def handle_false(self): + pass # Nothing to do. + + def handle_asm(self): + pass # Not needed yet. + + def handle_class(self): + return self._GetClass(Class, VISIBILITY_PRIVATE, None) + + def _GetBases(self): + # Get base classes. + bases = [] + while 1: + token = self._GetNextToken() + assert token.token_type == tokenize.NAME, token + # TODO(nnorwitz): store kind of inheritance...maybe. + if token.name not in ('public', 'protected', 'private'): + # If inheritance type is not specified, it is private. + # Just put the token back so we can form a name. + # TODO(nnorwitz): it would be good to warn about this. self._AddBackToken(token) - tokens, last = self._GetVarTokensUpTo(tokenize.SYNTAX, '(', ';') - tokens.append(last) - self._AddBackTokens(tokens) - if last.name == '(': - return self.GetMethod(FUNCTION_NONE, templated_types) - # Must be a variable definition. - return None - - def handle_true(self): - pass # Nothing to do. - - def handle_false(self): - pass # Nothing to do. - - def handle_asm(self): - pass # Not needed yet. - - def handle_class(self): - return self._GetClass(Class, VISIBILITY_PRIVATE, None) - - def _GetBases(self): - # Get base classes. - bases = [] - while 1: - token = self._GetNextToken() - assert token.token_type == tokenize.NAME, token - # TODO(nnorwitz): store kind of inheritance...maybe. - if token.name not in ('public', 'protected', 'private'): - # If inheritance type is not specified, it is private. - # Just put the token back so we can form a name. - # TODO(nnorwitz): it would be good to warn about this. - self._AddBackToken(token) - else: - # Check for virtual inheritance. - token = self._GetNextToken() - if token.name != 'virtual': - self._AddBackToken(token) - else: - # TODO(nnorwitz): store that we got virtual for this base. - pass - base, next_token = self.GetName() - bases_ast = self.converter.ToType(base) - assert len(bases_ast) == 1, bases_ast - bases.append(bases_ast[0]) - assert next_token.token_type == tokenize.SYNTAX, next_token - if next_token.name == '{': - token = next_token - break - # Support multiple inheritance. - assert next_token.name == ',', next_token - return bases, token - - def _GetClass(self, class_type, visibility, templated_types): - class_name = None - class_token = self._GetNextToken() - if class_token.token_type != tokenize.NAME: - assert class_token.token_type == tokenize.SYNTAX, class_token - token = class_token + else: + # Check for virtual inheritance. + token = self._GetNextToken() + if token.name != 'virtual': + self._AddBackToken(token) else: - # Skip any macro (e.g. storage class specifiers) after the - # 'class' keyword. - next_token = self._GetNextToken() - if next_token.token_type == tokenize.NAME: - self._AddBackToken(next_token) - else: - self._AddBackTokens([class_token, next_token]) - name_tokens, token = self.GetName() - class_name = ''.join([t.name for t in name_tokens]) - bases = None - if token.token_type == tokenize.SYNTAX: - if token.name == ';': - # Forward declaration. - return class_type(class_token.start, class_token.end, - class_name, None, templated_types, None, - self.namespace_stack) - if token.name in '*&': - # Inline forward declaration. Could be method or data. - name_token = self._GetNextToken() - next_token = self._GetNextToken() - if next_token.name == ';': - # Handle data - modifiers = ['class'] - return self._CreateVariable(class_token, name_token.name, - class_name, - modifiers, token.name, None) - else: - # Assume this is a method. - tokens = (class_token, token, name_token, next_token) - self._AddBackTokens(tokens) - return self.GetMethod(FUNCTION_NONE, None) - if token.name == ':': - bases, token = self._GetBases() - - body = None - if token.token_type == tokenize.SYNTAX and token.name == '{': - assert token.token_type == tokenize.SYNTAX, token - assert token.name == '{', token - - ast = AstBuilder(self.GetScope(), self.filename, class_name, - visibility, self.namespace_stack) - body = list(ast.Generate()) - - if not self._handling_typedef: - token = self._GetNextToken() - if token.token_type != tokenize.NAME: - assert token.token_type == tokenize.SYNTAX, token - assert token.name == ';', token - else: - new_class = class_type(class_token.start, class_token.end, - class_name, bases, None, - body, self.namespace_stack) - - modifiers = [] - return self._CreateVariable(class_token, - token.name, new_class, - modifiers, token.name, None) + # TODO(nnorwitz): store that we got virtual for this base. + pass + base, next_token = self.GetName() + bases_ast = self.converter.ToType(base) + assert len(bases_ast) == 1, bases_ast + bases.append(bases_ast[0]) + assert next_token.token_type == tokenize.SYNTAX, next_token + if next_token.name == '{': + token = next_token + break + # Support multiple inheritance. + assert next_token.name == ',', next_token + return bases, token + + def _GetClass(self, class_type, visibility, templated_types): + class_name = None + class_token = self._GetNextToken() + if class_token.token_type != tokenize.NAME: + assert class_token.token_type == tokenize.SYNTAX, class_token + token = class_token + else: + # Skip any macro (e.g. storage class specifiers) after the + # 'class' keyword. + next_token = self._GetNextToken() + if next_token.token_type == tokenize.NAME: + self._AddBackToken(next_token) + else: + self._AddBackTokens([class_token, next_token]) + name_tokens, token = self.GetName() + class_name = ''.join([t.name for t in name_tokens]) + bases = None + if token.token_type == tokenize.SYNTAX: + if token.name == ';': + # Forward declaration. + return class_type(class_token.start, class_token.end, + class_name, None, templated_types, None, + self.namespace_stack) + if token.name in '*&': + # Inline forward declaration. Could be method or data. + name_token = self._GetNextToken() + next_token = self._GetNextToken() + if next_token.name == ';': + # Handle data + modifiers = ['class'] + return self._CreateVariable(class_token, name_token.name, + class_name, + modifiers, token.name, None) else: - if not self._handling_typedef: - self.HandleError('non-typedef token', token) - self._AddBackToken(token) - - return class_type(class_token.start, class_token.end, class_name, - bases, templated_types, body, self.namespace_stack) - - def handle_namespace(self): + # Assume this is a method. + tokens = (class_token, token, name_token, next_token) + self._AddBackTokens(tokens) + return self.GetMethod(FUNCTION_NONE, None) + if token.name == ':': + bases, token = self._GetBases() + + body = None + if token.token_type == tokenize.SYNTAX and token.name == '{': + assert token.token_type == tokenize.SYNTAX, token + assert token.name == '{', token + + ast = AstBuilder(self.GetScope(), self.filename, class_name, + visibility, self.namespace_stack) + body = list(ast.Generate()) + + if not self._handling_typedef: token = self._GetNextToken() - # Support anonymous namespaces. - name = None - if token.token_type == tokenize.NAME: - name = token.name - token = self._GetNextToken() - self.namespace_stack.append(name) - assert token.token_type == tokenize.SYNTAX, token - # Create an internal token that denotes when the namespace is complete. - internal_token = tokenize.Token(_INTERNAL_TOKEN, _NAMESPACE_POP, - None, None) - internal_token.whence = token.whence - if token.name == '=': - # TODO(nnorwitz): handle aliasing namespaces. - name, next_token = self.GetName() - assert next_token.name == ';', next_token - self._AddBackToken(internal_token) + if token.token_type != tokenize.NAME: + assert token.token_type == tokenize.SYNTAX, token + assert token.name == ';', token else: - assert token.name == '{', token - tokens = list(self.GetScope()) - # Replace the trailing } with the internal namespace pop token. - tokens[-1] = internal_token - # Handle namespace with nothing in it. - self._AddBackTokens(tokens) - return None - - def handle_using(self): - tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';') - assert tokens - return Using(tokens[0].start, tokens[0].end, tokens) - - def handle_explicit(self): - assert self.in_class - # Nothing much to do. - # TODO(nnorwitz): maybe verify the method name == class name. - # This must be a ctor. - return self.GetMethod(FUNCTION_CTOR, None) - - def handle_this(self): - pass # Nothing to do. - - def handle_operator(self): - # Pull off the next token(s?) and make that part of the method name. - pass + new_class = class_type(class_token.start, class_token.end, + class_name, bases, None, + body, self.namespace_stack) + + modifiers = [] + return self._CreateVariable(class_token, + token.name, new_class, + modifiers, token.name, None) + else: + if not self._handling_typedef: + self.HandleError('non-typedef token', token) + self._AddBackToken(token) + + return class_type(class_token.start, class_token.end, class_name, + bases, templated_types, body, self.namespace_stack) + + def handle_namespace(self): + token = self._GetNextToken() + # Support anonymous namespaces. + name = None + if token.token_type == tokenize.NAME: + name = token.name + token = self._GetNextToken() + self.namespace_stack.append(name) + assert token.token_type == tokenize.SYNTAX, token + # Create an internal token that denotes when the namespace is complete. + internal_token = tokenize.Token(_INTERNAL_TOKEN, _NAMESPACE_POP, + None, None) + internal_token.whence = token.whence + if token.name == '=': + # TODO(nnorwitz): handle aliasing namespaces. + name, next_token = self.GetName() + assert next_token.name == ';', next_token + self._AddBackToken(internal_token) + else: + assert token.name == '{', token + tokens = list(self.GetScope()) + # Replace the trailing } with the internal namespace pop token. + tokens[-1] = internal_token + # Handle namespace with nothing in it. + self._AddBackTokens(tokens) + return None + + def handle_using(self): + tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';') + assert tokens + return Using(tokens[0].start, tokens[0].end, tokens) + + def handle_explicit(self): + assert self.in_class + # Nothing much to do. + # TODO(nnorwitz): maybe verify the method name == class name. + # This must be a ctor. + return self.GetMethod(FUNCTION_CTOR, None) + + def handle_this(self): + pass # Nothing to do. + + def handle_operator(self): + # Pull off the next token(s?) and make that part of the method name. + pass - def handle_sizeof(self): - pass + def handle_sizeof(self): + pass - def handle_case(self): - pass + def handle_case(self): + pass - def handle_switch(self): - pass + def handle_switch(self): + pass - def handle_default(self): - token = self._GetNextToken() - assert token.token_type == tokenize.SYNTAX - assert token.name == ':' + def handle_default(self): + token = self._GetNextToken() + assert token.token_type == tokenize.SYNTAX + assert token.name == ':' - def handle_if(self): - pass + def handle_if(self): + pass - def handle_else(self): - pass + def handle_else(self): + pass - def handle_return(self): - tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';') - if not tokens: - return Return(self.current_token.start, self.current_token.end, None) - return Return(tokens[0].start, tokens[0].end, tokens) + def handle_return(self): + tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';') + if not tokens: + return Return(self.current_token.start, self.current_token.end, None) + return Return(tokens[0].start, tokens[0].end, tokens) - def handle_goto(self): - tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';') - assert len(tokens) == 1, str(tokens) - return Goto(tokens[0].start, tokens[0].end, tokens[0].name) + def handle_goto(self): + tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';') + assert len(tokens) == 1, str(tokens) + return Goto(tokens[0].start, tokens[0].end, tokens[0].name) - def handle_try(self): - pass # Not needed yet. + def handle_try(self): + pass # Not needed yet. - def handle_catch(self): - pass # Not needed yet. + def handle_catch(self): + pass # Not needed yet. - def handle_throw(self): - pass # Not needed yet. + def handle_throw(self): + pass # Not needed yet. - def handle_while(self): - pass + def handle_while(self): + pass - def handle_do(self): - pass + def handle_do(self): + pass - def handle_for(self): - pass + def handle_for(self): + pass - def handle_break(self): - self._IgnoreUpTo(tokenize.SYNTAX, ';') + def handle_break(self): + self._IgnoreUpTo(tokenize.SYNTAX, ';') - def handle_continue(self): - self._IgnoreUpTo(tokenize.SYNTAX, ';') + def handle_continue(self): + self._IgnoreUpTo(tokenize.SYNTAX, ';') def BuilderFromSource(source, filename): - """Utility method that returns an AstBuilder from source code. + """Utility method that returns an AstBuilder from source code. Args: source: 'C++ source code' @@ -1698,64 +1710,64 @@ def BuilderFromSource(source, filename): Returns: AstBuilder """ - return AstBuilder(tokenize.GetTokens(source), filename) + return AstBuilder(tokenize.GetTokens(source), filename) def PrintIndentifiers(filename, should_print): - """Prints all identifiers for a C++ source file. + """Prints all identifiers for a C++ source file. Args: filename: 'file1' should_print: predicate with signature: bool Function(token) """ - source = utils.ReadFile(filename, False) - if source is None: - sys.stderr.write('Unable to find: %s\n' % filename) - return - - #print('Processing %s' % actual_filename) - builder = BuilderFromSource(source, filename) - try: - for node in builder.Generate(): - if should_print(node): - print(node.name) - except KeyboardInterrupt: - return - except: - pass + source = utils.ReadFile(filename, False) + if source is None: + sys.stderr.write('Unable to find: %s\n' % filename) + return + + #print('Processing %s' % actual_filename) + builder = BuilderFromSource(source, filename) + try: + for node in builder.Generate(): + if should_print(node): + print(node.name) + except KeyboardInterrupt: + return + except: + pass def PrintAllIndentifiers(filenames, should_print): - """Prints all identifiers for each C++ source file in filenames. + """Prints all identifiers for each C++ source file in filenames. Args: filenames: ['file1', 'file2', ...] should_print: predicate with signature: bool Function(token) """ - for path in filenames: - PrintIndentifiers(path, should_print) + for path in filenames: + PrintIndentifiers(path, should_print) def main(argv): - for filename in argv[1:]: - source = utils.ReadFile(filename) - if source is None: - continue - - print('Processing %s' % filename) - builder = BuilderFromSource(source, filename) - try: - entire_ast = filter(None, builder.Generate()) - except KeyboardInterrupt: - return - except: - # Already printed a warning, print the traceback and continue. - traceback.print_exc() - else: - if utils.DEBUG: - for ast in entire_ast: - print(ast) + for filename in argv[1:]: + source = utils.ReadFile(filename) + if source is None: + continue + + print('Processing %s' % filename) + builder = BuilderFromSource(source, filename) + try: + entire_ast = filter(None, builder.Generate()) + except KeyboardInterrupt: + return + except: + # Already printed a warning, print the traceback and continue. + traceback.print_exc() + else: + if utils.DEBUG: + for ast in entire_ast: + print(ast) if __name__ == '__main__': - main(sys.argv) + main(sys.argv) diff --git a/googlemock/scripts/generator/cpp/gmock_class.py b/googlemock/scripts/generator/cpp/gmock_class.py index 89862ae1..488cc153 100755 --- a/googlemock/scripts/generator/cpp/gmock_class.py +++ b/googlemock/scripts/generator/cpp/gmock_class.py @@ -35,11 +35,11 @@ from cpp import utils # Preserve compatibility with Python 2.3. try: - _dummy = set + _dummy = set except NameError: - import sets + import sets - set = sets.Set + set = sets.Set _VERSION = (1, 0, 1) # The version of this script. # How many spaces to indent. Can set me with the INDENT environment variable. @@ -47,202 +47,199 @@ _INDENT = 2 def _RenderType(ast_type): - """Renders the potentially recursively templated type into a string. + """Renders the potentially recursively templated type into a string. Args: ast_type: The AST of the type. Returns: - Rendered string and a boolean to indicate whether we have multiple args - (which is not handled correctly). + Rendered string of the type. """ - has_multiarg_error = False - # Add modifiers like 'const'. - modifiers = '' - if ast_type.modifiers: - modifiers = ' '.join(ast_type.modifiers) + ' ' - return_type = modifiers + ast_type.name - if ast_type.templated_types: - # Collect template args. - template_args = [] - for arg in ast_type.templated_types: - rendered_arg, e = _RenderType(arg) - if e: has_multiarg_error = True - template_args.append(rendered_arg) - return_type += '<' + ', '.join(template_args) + '>' - # We are actually not handling multi-template-args correctly. So mark it. - if len(template_args) > 1: - has_multiarg_error = True - if ast_type.pointer: - return_type += '*' - if ast_type.reference: - return_type += '&' - return return_type, has_multiarg_error - - -def _GetNumParameters(parameters, source): - num_parameters = len(parameters) - if num_parameters == 1: - first_param = parameters[0] - if source[first_param.start:first_param.end].strip() == 'void': - # We must treat T(void) as a function with no parameters. - return 0 - return num_parameters + # Add modifiers like 'const'. + modifiers = '' + if ast_type.modifiers: + modifiers = ' '.join(ast_type.modifiers) + ' ' + return_type = modifiers + ast_type.name + if ast_type.templated_types: + # Collect template args. + template_args = [] + for arg in ast_type.templated_types: + rendered_arg = _RenderType(arg) + template_args.append(rendered_arg) + return_type += '<' + ', '.join(template_args) + '>' + if ast_type.pointer: + return_type += '*' + if ast_type.reference: + return_type += '&' + return return_type + + +def _GenerateArg(source): + """Strips out comments, default arguments, and redundant spaces from a single argument. + + Args: + source: A string for a single argument. + + Returns: + Rendered string of the argument. + """ + # Remove end of line comments before eliminating newlines. + arg = re.sub(r'//.*', '', source) + + # Remove c-style comments. + arg = re.sub(r'/\*.*\*/', '', arg) + + # Remove default arguments. + arg = re.sub(r'=.*', '', arg) + + # Collapse spaces and newlines into a single space. + arg = re.sub(r'\s+', ' ', arg) + return arg.strip() + + +def _EscapeForMacro(s): + """Escapes a string for use as an argument to a C++ macro.""" + paren_count = 0 + for c in s: + if c == '(': + paren_count += 1 + elif c == ')': + paren_count -= 1 + elif c == ',' and paren_count == 0: + return '(' + s + ')' + return s def _GenerateMethods(output_lines, source, class_node): - function_type = (ast.FUNCTION_VIRTUAL | ast.FUNCTION_PURE_VIRTUAL | - ast.FUNCTION_OVERRIDE) - ctor_or_dtor = ast.FUNCTION_CTOR | ast.FUNCTION_DTOR - indent = ' ' * _INDENT - - for node in class_node.body: - # We only care about virtual functions. - if (isinstance(node, ast.Function) and - node.modifiers & function_type and - not node.modifiers & ctor_or_dtor): - # Pick out all the elements we need from the original function. - const = '' - if node.modifiers & ast.FUNCTION_CONST: - const = 'CONST_' - num_parameters = _GetNumParameters(node.parameters, source) - return_type = 'void' - if node.return_type: - return_type, has_multiarg_error = _RenderType(node.return_type) - if has_multiarg_error: - for line in [ - '// The following line won\'t really compile, as the return', - '// type has multiple template arguments. To fix it, use a', - '// typedef for the return type.']: - output_lines.append(indent + line) - tmpl = '' - if class_node.templated_types: - tmpl = '_T' - mock_method_macro = 'MOCK_%sMETHOD%d%s' % (const, num_parameters, tmpl) - - args = '' - if node.parameters: - # Get the full text of the parameters from the start - # of the first parameter to the end of the last parameter. - start = node.parameters[0].start - end = node.parameters[-1].end - # Remove // comments. - args_strings = re.sub(r'//.*', '', source[start:end]) - # Remove /* comments */. - args_strings = re.sub(r'/\*.*\*/', '', args_strings) - # Remove default arguments. - args_strings = re.sub(r'=.*,', ',', args_strings) - args_strings = re.sub(r'=.*', '', args_strings) - # Condense multiple spaces and eliminate newlines putting the - # parameters together on a single line. Ensure there is a - # space in an argument which is split by a newline without - # intervening whitespace, e.g.: int\nBar - args = re.sub(' +', ' ', args_strings.replace('\n', ' ')) - - # Create the mock method definition. - output_lines.extend(['%s%s(%s,' % (indent, mock_method_macro, node.name), - '%s%s(%s));' % (indent * 3, return_type, args)]) + function_type = ( + ast.FUNCTION_VIRTUAL | ast.FUNCTION_PURE_VIRTUAL | ast.FUNCTION_OVERRIDE) + ctor_or_dtor = ast.FUNCTION_CTOR | ast.FUNCTION_DTOR + indent = ' ' * _INDENT + + for node in class_node.body: + # We only care about virtual functions. + if (isinstance(node, ast.Function) and node.modifiers & function_type and + not node.modifiers & ctor_or_dtor): + # Pick out all the elements we need from the original function. + modifiers = 'override' + if node.modifiers & ast.FUNCTION_CONST: + modifiers = 'const, ' + modifiers + + return_type = 'void' + if node.return_type: + return_type = _EscapeForMacro(_RenderType(node.return_type)) + + args = [] + for p in node.parameters: + arg = _GenerateArg(source[p.start:p.end]) + args.append(_EscapeForMacro(arg)) + + # Create the mock method definition. + output_lines.extend([ + '%sMOCK_METHOD(%s, %s, (%s), (%s));' % + (indent, return_type, node.name, ', '.join(args), modifiers) + ]) def _GenerateMocks(filename, source, ast_list, desired_class_names): - processed_class_names = set() - lines = [] - for node in ast_list: - if (isinstance(node, ast.Class) and node.body and - # desired_class_names being None means that all classes are selected. - (not desired_class_names or node.name in desired_class_names)): - class_name = node.name - parent_name = class_name - processed_class_names.add(class_name) - class_node = node - # Add namespace before the class. - if class_node.namespace: - lines.extend(['namespace %s {' % n for n in class_node.namespace]) # } - lines.append('') - - # Add template args for templated classes. - if class_node.templated_types: - # TODO(paulchang): The AST doesn't preserve template argument order, - # so we have to make up names here. - # TODO(paulchang): Handle non-type template arguments (e.g. - # template<typename T, int N>). - template_arg_count = len(class_node.templated_types.keys()) - template_args = ['T%d' % n for n in range(template_arg_count)] - template_decls = ['typename ' + arg for arg in template_args] - lines.append('template <' + ', '.join(template_decls) + '>') - parent_name += '<' + ', '.join(template_args) + '>' - - # Add the class prolog. - lines.append('class Mock%s : public %s {' # } - % (class_name, parent_name)) - lines.append('%spublic:' % (' ' * (_INDENT // 2))) - - # Add all the methods. - _GenerateMethods(lines, source, class_node) - - # Close the class. - if lines: - # If there are no virtual methods, no need for a public label. - if len(lines) == 2: - del lines[-1] - - # Only close the class if there really is a class. - lines.append('};') - lines.append('') # Add an extra newline. - - # Close the namespace. - if class_node.namespace: - for i in range(len(class_node.namespace) - 1, -1, -1): - lines.append('} // namespace %s' % class_node.namespace[i]) - lines.append('') # Add an extra newline. - - if desired_class_names: - missing_class_name_list = list(desired_class_names - processed_class_names) - if missing_class_name_list: - missing_class_name_list.sort() - sys.stderr.write('Class(es) not found in %s: %s\n' % - (filename, ', '.join(missing_class_name_list))) - elif not processed_class_names: - sys.stderr.write('No class found in %s\n' % filename) - - return lines + processed_class_names = set() + lines = [] + for node in ast_list: + if (isinstance(node, ast.Class) and node.body and + # desired_class_names being None means that all classes are selected. + (not desired_class_names or node.name in desired_class_names)): + class_name = node.name + parent_name = class_name + processed_class_names.add(class_name) + class_node = node + # Add namespace before the class. + if class_node.namespace: + lines.extend(['namespace %s {' % n for n in class_node.namespace]) # } + lines.append('') + + # Add template args for templated classes. + if class_node.templated_types: + # TODO(paulchang): The AST doesn't preserve template argument order, + # so we have to make up names here. + # TODO(paulchang): Handle non-type template arguments (e.g. + # template<typename T, int N>). + template_arg_count = len(class_node.templated_types.keys()) + template_args = ['T%d' % n for n in range(template_arg_count)] + template_decls = ['typename ' + arg for arg in template_args] + lines.append('template <' + ', '.join(template_decls) + '>') + parent_name += '<' + ', '.join(template_args) + '>' + + # Add the class prolog. + lines.append('class Mock%s : public %s {' # } + % (class_name, parent_name)) + lines.append('%spublic:' % (' ' * (_INDENT // 2))) + + # Add all the methods. + _GenerateMethods(lines, source, class_node) + + # Close the class. + if lines: + # If there are no virtual methods, no need for a public label. + if len(lines) == 2: + del lines[-1] + + # Only close the class if there really is a class. + lines.append('};') + lines.append('') # Add an extra newline. + + # Close the namespace. + if class_node.namespace: + for i in range(len(class_node.namespace) - 1, -1, -1): + lines.append('} // namespace %s' % class_node.namespace[i]) + lines.append('') # Add an extra newline. + + if desired_class_names: + missing_class_name_list = list(desired_class_names - processed_class_names) + if missing_class_name_list: + missing_class_name_list.sort() + sys.stderr.write('Class(es) not found in %s: %s\n' % + (filename, ', '.join(missing_class_name_list))) + elif not processed_class_names: + sys.stderr.write('No class found in %s\n' % filename) + + return lines def main(argv=sys.argv): - if len(argv) < 2: - sys.stderr.write('Google Mock Class Generator v%s\n\n' % - '.'.join(map(str, _VERSION))) - sys.stderr.write(__doc__) - return 1 - - global _INDENT - try: - _INDENT = int(os.environ['INDENT']) - except KeyError: - pass - except: - sys.stderr.write('Unable to use indent of %s\n' % os.environ.get('INDENT')) - - filename = argv[1] - desired_class_names = None # None means all classes in the source file. - if len(argv) >= 3: - desired_class_names = set(argv[2:]) - source = utils.ReadFile(filename) - if source is None: - return 1 - - builder = ast.BuilderFromSource(source, filename) - try: - entire_ast = filter(None, builder.Generate()) - except KeyboardInterrupt: - return - except: - # An error message was already printed since we couldn't parse. - sys.exit(1) - else: - lines = _GenerateMocks(filename, source, entire_ast, desired_class_names) - sys.stdout.write('\n'.join(lines)) + if len(argv) < 2: + sys.stderr.write('Google Mock Class Generator v%s\n\n' % + '.'.join(map(str, _VERSION))) + sys.stderr.write(__doc__) + return 1 + + global _INDENT + try: + _INDENT = int(os.environ['INDENT']) + except KeyError: + pass + except: + sys.stderr.write('Unable to use indent of %s\n' % os.environ.get('INDENT')) + + filename = argv[1] + desired_class_names = None # None means all classes in the source file. + if len(argv) >= 3: + desired_class_names = set(argv[2:]) + source = utils.ReadFile(filename) + if source is None: + return 1 + + builder = ast.BuilderFromSource(source, filename) + try: + entire_ast = filter(None, builder.Generate()) + except KeyboardInterrupt: + return + except: + # An error message was already printed since we couldn't parse. + sys.exit(1) + else: + lines = _GenerateMocks(filename, source, entire_ast, desired_class_names) + sys.stdout.write('\n'.join(lines)) if __name__ == '__main__': - main(sys.argv) + main(sys.argv) diff --git a/googlemock/scripts/generator/cpp/gmock_class_test.py b/googlemock/scripts/generator/cpp/gmock_class_test.py index 211a92dd..74655692 100755 --- a/googlemock/scripts/generator/cpp/gmock_class_test.py +++ b/googlemock/scripts/generator/cpp/gmock_class_test.py @@ -29,43 +29,43 @@ from cpp import gmock_class class TestCase(unittest.TestCase): - """Helper class that adds assert methods.""" + """Helper class that adds assert methods.""" - @staticmethod - def StripLeadingWhitespace(lines): - """Strip leading whitespace in each line in 'lines'.""" - return '\n'.join([s.lstrip() for s in lines.split('\n')]) + @staticmethod + def StripLeadingWhitespace(lines): + """Strip leading whitespace in each line in 'lines'.""" + return '\n'.join([s.lstrip() for s in lines.split('\n')]) - def assertEqualIgnoreLeadingWhitespace(self, expected_lines, lines): - """Specialized assert that ignores the indent level.""" - self.assertEqual(expected_lines, self.StripLeadingWhitespace(lines)) + def assertEqualIgnoreLeadingWhitespace(self, expected_lines, lines): + """Specialized assert that ignores the indent level.""" + self.assertEqual(expected_lines, self.StripLeadingWhitespace(lines)) class GenerateMethodsTest(TestCase): - @staticmethod - def GenerateMethodSource(cpp_source): - """Convert C++ source to Google Mock output source lines.""" - method_source_lines = [] - # <test> is a pseudo-filename, it is not read or written. - builder = ast.BuilderFromSource(cpp_source, '<test>') - ast_list = list(builder.Generate()) - gmock_class._GenerateMethods(method_source_lines, cpp_source, ast_list[0]) - return '\n'.join(method_source_lines) - - def testSimpleMethod(self): - source = """ + @staticmethod + def GenerateMethodSource(cpp_source): + """Convert C++ source to Google Mock output source lines.""" + method_source_lines = [] + # <test> is a pseudo-filename, it is not read or written. + builder = ast.BuilderFromSource(cpp_source, '<test>') + ast_list = list(builder.Generate()) + gmock_class._GenerateMethods(method_source_lines, cpp_source, ast_list[0]) + return '\n'.join(method_source_lines) + + def testSimpleMethod(self): + source = """ class Foo { public: virtual int Bar(); }; """ - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD0(Bar,\nint());', - self.GenerateMethodSource(source)) + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(int, Bar, (), (override));', + self.GenerateMethodSource(source)) - def testSimpleConstructorsAndDestructor(self): - source = """ + def testSimpleConstructorsAndDestructor(self): + source = """ class Foo { public: Foo(); @@ -76,26 +76,26 @@ class Foo { virtual int Bar() = 0; }; """ - # The constructors and destructor should be ignored. - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD0(Bar,\nint());', - self.GenerateMethodSource(source)) + # The constructors and destructor should be ignored. + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(int, Bar, (), (override));', + self.GenerateMethodSource(source)) - def testVirtualDestructor(self): - source = """ + def testVirtualDestructor(self): + source = """ class Foo { public: virtual ~Foo(); virtual int Bar() = 0; }; """ - # The destructor should be ignored. - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD0(Bar,\nint());', - self.GenerateMethodSource(source)) + # The destructor should be ignored. + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(int, Bar, (), (override));', + self.GenerateMethodSource(source)) - def testExplicitlyDefaultedConstructorsAndDestructor(self): - source = """ + def testExplicitlyDefaultedConstructorsAndDestructor(self): + source = """ class Foo { public: Foo() = default; @@ -105,13 +105,13 @@ class Foo { virtual int Bar() = 0; }; """ - # The constructors and destructor should be ignored. - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD0(Bar,\nint());', - self.GenerateMethodSource(source)) + # The constructors and destructor should be ignored. + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(int, Bar, (), (override));', + self.GenerateMethodSource(source)) - def testExplicitlyDeletedConstructorsAndDestructor(self): - source = """ + def testExplicitlyDeletedConstructorsAndDestructor(self): + source = """ class Foo { public: Foo() = delete; @@ -121,69 +121,69 @@ class Foo { virtual int Bar() = 0; }; """ - # The constructors and destructor should be ignored. - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD0(Bar,\nint());', - self.GenerateMethodSource(source)) + # The constructors and destructor should be ignored. + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(int, Bar, (), (override));', + self.GenerateMethodSource(source)) - def testSimpleOverrideMethod(self): - source = """ + def testSimpleOverrideMethod(self): + source = """ class Foo { public: int Bar() override; }; """ - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD0(Bar,\nint());', - self.GenerateMethodSource(source)) + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(int, Bar, (), (override));', + self.GenerateMethodSource(source)) - def testSimpleConstMethod(self): - source = """ + def testSimpleConstMethod(self): + source = """ class Foo { public: virtual void Bar(bool flag) const; }; """ - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_CONST_METHOD1(Bar,\nvoid(bool flag));', - self.GenerateMethodSource(source)) + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(void, Bar, (bool flag), (const, override));', + self.GenerateMethodSource(source)) - def testExplicitVoid(self): - source = """ + def testExplicitVoid(self): + source = """ class Foo { public: virtual int Bar(void); }; """ - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD0(Bar,\nint(void));', - self.GenerateMethodSource(source)) + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(int, Bar, (void), (override));', + self.GenerateMethodSource(source)) - def testStrangeNewlineInParameter(self): - source = """ + def testStrangeNewlineInParameter(self): + source = """ class Foo { public: virtual void Bar(int a) = 0; }; """ - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD1(Bar,\nvoid(int a));', - self.GenerateMethodSource(source)) + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(void, Bar, (int a), (override));', + self.GenerateMethodSource(source)) - def testDefaultParameters(self): - source = """ + def testDefaultParameters(self): + source = """ class Foo { public: virtual void Bar(int a, char c = 'x') = 0; }; """ - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD2(Bar,\nvoid(int a, char c ));', - self.GenerateMethodSource(source)) + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(void, Bar, (int a, char c), (override));', + self.GenerateMethodSource(source)) - def testMultipleDefaultParameters(self): - source = """ + def testMultipleDefaultParameters(self): + source = """ class Foo { public: virtual void Bar( @@ -195,47 +195,58 @@ class Foo { int const *& rp = aDefaultPointer) = 0; }; """ - self.assertEqualIgnoreLeadingWhitespace( - "MOCK_METHOD7(Bar,\n" - "void(int a , char c , const int* const p , const std::string& s , char tab[] , int const *& rp ));", - self.GenerateMethodSource(source)) + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(void, Bar, ' + '(int a, char c, const int* const p, const std::string& s, char tab[], int const *& rp), ' + '(override));', self.GenerateMethodSource(source)) - def testConstDefaultParameter(self): - source = """ + def testMultipleSingleLineDefaultParameters(self): + source = """ +class Foo { + public: + virtual void Bar(int a = 42, int b = 43, int c = 44) = 0; +}; +""" + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(void, Bar, (int a, int b, int c), (override));', + self.GenerateMethodSource(source)) + + def testConstDefaultParameter(self): + source = """ class Test { public: virtual bool Bar(const int test_arg = 42) = 0; }; """ - expected = 'MOCK_METHOD1(Bar,\nbool(const int test_arg ));' - self.assertEqualIgnoreLeadingWhitespace( - expected, self.GenerateMethodSource(source)) + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(bool, Bar, (const int test_arg), (override));', + self.GenerateMethodSource(source)) - def testConstRefDefaultParameter(self): - source = """ + def testConstRefDefaultParameter(self): + source = """ class Test { public: virtual bool Bar(const std::string& test_arg = "42" ) = 0; }; """ - expected = 'MOCK_METHOD1(Bar,\nbool(const std::string& test_arg ));' - self.assertEqualIgnoreLeadingWhitespace( - expected, self.GenerateMethodSource(source)) + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(bool, Bar, (const std::string& test_arg), (override));', + self.GenerateMethodSource(source)) - def testRemovesCommentsWhenDefaultsArePresent(self): - source = """ + def testRemovesCommentsWhenDefaultsArePresent(self): + source = """ class Foo { public: virtual void Bar(int a = 42 /* a comment */, char /* other comment */ c= 'x') = 0; }; """ - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD2(Bar,\nvoid(int a , char c));', - self.GenerateMethodSource(source)) + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(void, Bar, (int a, char c), (override));', + self.GenerateMethodSource(source)) - def testDoubleSlashCommentsInParameterListAreRemoved(self): - source = """ + def testDoubleSlashCommentsInParameterListAreRemoved(self): + source = """ class Foo { public: virtual void Bar(int a, // inline comments should be elided. @@ -243,117 +254,111 @@ class Foo { ) const = 0; }; """ - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_CONST_METHOD2(Bar,\nvoid(int a, int b));', - self.GenerateMethodSource(source)) + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(void, Bar, (int a, int b), (const, override));', + self.GenerateMethodSource(source)) - def testCStyleCommentsInParameterListAreNotRemoved(self): - # NOTE(nnorwitz): I'm not sure if it's the best behavior to keep these - # comments. Also note that C style comments after the last parameter - # are still elided. - source = """ + def testCStyleCommentsInParameterListAreNotRemoved(self): + # NOTE(nnorwitz): I'm not sure if it's the best behavior to keep these + # comments. Also note that C style comments after the last parameter + # are still elided. + source = """ class Foo { public: virtual const string& Bar(int /* keeper */, int b); }; """ - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD2(Bar,\nconst string&(int , int b));', - self.GenerateMethodSource(source)) + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(const string&, Bar, (int, int b), (override));', + self.GenerateMethodSource(source)) - def testArgsOfTemplateTypes(self): - source = """ + def testArgsOfTemplateTypes(self): + source = """ class Foo { public: virtual int Bar(const vector<int>& v, map<int, string>* output); };""" - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD2(Bar,\n' - 'int(const vector<int>& v, map<int, string>* output));', - self.GenerateMethodSource(source)) + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(int, Bar, (const vector<int>& v, (map<int, string>* output)), (override));', + self.GenerateMethodSource(source)) - def testReturnTypeWithOneTemplateArg(self): - source = """ + def testReturnTypeWithOneTemplateArg(self): + source = """ class Foo { public: virtual vector<int>* Bar(int n); };""" - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD1(Bar,\nvector<int>*(int n));', - self.GenerateMethodSource(source)) + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(vector<int>*, Bar, (int n), (override));', + self.GenerateMethodSource(source)) - def testReturnTypeWithManyTemplateArgs(self): - source = """ + def testReturnTypeWithManyTemplateArgs(self): + source = """ class Foo { public: virtual map<int, string> Bar(); };""" - # Comparing the comment text is brittle - we'll think of something - # better in case this gets annoying, but for now let's keep it simple. - self.assertEqualIgnoreLeadingWhitespace( - '// The following line won\'t really compile, as the return\n' - '// type has multiple template arguments. To fix it, use a\n' - '// typedef for the return type.\n' - 'MOCK_METHOD0(Bar,\nmap<int, string>());', - self.GenerateMethodSource(source)) - - def testSimpleMethodInTemplatedClass(self): - source = """ + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD((map<int, string>), Bar, (), (override));', + self.GenerateMethodSource(source)) + + def testSimpleMethodInTemplatedClass(self): + source = """ template<class T> class Foo { public: virtual int Bar(); }; """ - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD0_T(Bar,\nint());', - self.GenerateMethodSource(source)) + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(int, Bar, (), (override));', + self.GenerateMethodSource(source)) - def testPointerArgWithoutNames(self): - source = """ + def testPointerArgWithoutNames(self): + source = """ class Foo { virtual int Bar(C*); }; """ - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD1(Bar,\nint(C*));', - self.GenerateMethodSource(source)) + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(int, Bar, (C*), (override));', + self.GenerateMethodSource(source)) - def testReferenceArgWithoutNames(self): - source = """ + def testReferenceArgWithoutNames(self): + source = """ class Foo { virtual int Bar(C&); }; """ - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD1(Bar,\nint(C&));', - self.GenerateMethodSource(source)) + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(int, Bar, (C&), (override));', + self.GenerateMethodSource(source)) - def testArrayArgWithoutNames(self): - source = """ + def testArrayArgWithoutNames(self): + source = """ class Foo { virtual int Bar(C[]); }; """ - self.assertEqualIgnoreLeadingWhitespace( - 'MOCK_METHOD1(Bar,\nint(C[]));', - self.GenerateMethodSource(source)) + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(int, Bar, (C[]), (override));', + self.GenerateMethodSource(source)) class GenerateMocksTest(TestCase): - @staticmethod - def GenerateMocks(cpp_source): - """Convert C++ source to complete Google Mock output source.""" - # <test> is a pseudo-filename, it is not read or written. - filename = '<test>' - builder = ast.BuilderFromSource(cpp_source, filename) - ast_list = list(builder.Generate()) - lines = gmock_class._GenerateMocks(filename, cpp_source, ast_list, None) - return '\n'.join(lines) - - def testNamespaces(self): - source = """ + @staticmethod + def GenerateMocks(cpp_source): + """Convert C++ source to complete Google Mock output source.""" + # <test> is a pseudo-filename, it is not read or written. + filename = '<test>' + builder = ast.BuilderFromSource(cpp_source, filename) + ast_list = list(builder.Generate()) + lines = gmock_class._GenerateMocks(filename, cpp_source, ast_list, None) + return '\n'.join(lines) + + def testNamespaces(self): + source = """ namespace Foo { namespace Bar { class Forward; } namespace Baz { @@ -366,96 +371,91 @@ class Test { } // namespace Baz } // namespace Foo """ - expected = """\ + expected = """\ namespace Foo { namespace Baz { class MockTest : public Test { public: -MOCK_METHOD0(Foo, -void()); +MOCK_METHOD(void, Foo, (), (override)); }; } // namespace Baz } // namespace Foo """ - self.assertEqualIgnoreLeadingWhitespace( - expected, self.GenerateMocks(source)) + self.assertEqualIgnoreLeadingWhitespace(expected, + self.GenerateMocks(source)) - def testClassWithStorageSpecifierMacro(self): - source = """ + def testClassWithStorageSpecifierMacro(self): + source = """ class STORAGE_SPECIFIER Test { public: virtual void Foo(); }; """ - expected = """\ + expected = """\ class MockTest : public Test { public: -MOCK_METHOD0(Foo, -void()); +MOCK_METHOD(void, Foo, (), (override)); }; """ - self.assertEqualIgnoreLeadingWhitespace( - expected, self.GenerateMocks(source)) + self.assertEqualIgnoreLeadingWhitespace(expected, + self.GenerateMocks(source)) - def testTemplatedForwardDeclaration(self): - source = """ + def testTemplatedForwardDeclaration(self): + source = """ template <class T> class Forward; // Forward declaration should be ignored. class Test { public: virtual void Foo(); }; """ - expected = """\ + expected = """\ class MockTest : public Test { public: -MOCK_METHOD0(Foo, -void()); +MOCK_METHOD(void, Foo, (), (override)); }; """ - self.assertEqualIgnoreLeadingWhitespace( - expected, self.GenerateMocks(source)) + self.assertEqualIgnoreLeadingWhitespace(expected, + self.GenerateMocks(source)) - def testTemplatedClass(self): - source = """ + def testTemplatedClass(self): + source = """ template <typename S, typename T> class Test { public: virtual void Foo(); }; """ - expected = """\ + expected = """\ template <typename T0, typename T1> class MockTest : public Test<T0, T1> { public: -MOCK_METHOD0_T(Foo, -void()); +MOCK_METHOD(void, Foo, (), (override)); }; """ - self.assertEqualIgnoreLeadingWhitespace( - expected, self.GenerateMocks(source)) + self.assertEqualIgnoreLeadingWhitespace(expected, + self.GenerateMocks(source)) - def testTemplateInATemplateTypedef(self): - source = """ + def testTemplateInATemplateTypedef(self): + source = """ class Test { public: typedef std::vector<std::list<int>> FooType; virtual void Bar(const FooType& test_arg); }; """ - expected = """\ + expected = """\ class MockTest : public Test { public: -MOCK_METHOD1(Bar, -void(const FooType& test_arg)); +MOCK_METHOD(void, Bar, (const FooType& test_arg), (override)); }; """ - self.assertEqualIgnoreLeadingWhitespace( - expected, self.GenerateMocks(source)) + self.assertEqualIgnoreLeadingWhitespace(expected, + self.GenerateMocks(source)) - def testTemplateInATemplateTypedefWithComma(self): - source = """ + def testTemplateInATemplateTypedefWithComma(self): + source = """ class Test { public: typedef std::function<void( @@ -463,18 +463,33 @@ class Test { virtual void Bar(const FooType& test_arg); }; """ - expected = """\ + expected = """\ +class MockTest : public Test { +public: +MOCK_METHOD(void, Bar, (const FooType& test_arg), (override)); +}; +""" + self.assertEqualIgnoreLeadingWhitespace(expected, + self.GenerateMocks(source)) + + def testParenthesizedCommaInArg(self): + source = """ +class Test { + public: + virtual void Bar(std::function<void(int, int)> f); +}; +""" + expected = """\ class MockTest : public Test { public: -MOCK_METHOD1(Bar, -void(const FooType& test_arg)); +MOCK_METHOD(void, Bar, (std::function<void(int, int)> f), (override)); }; """ - self.assertEqualIgnoreLeadingWhitespace( - expected, self.GenerateMocks(source)) + self.assertEqualIgnoreLeadingWhitespace(expected, + self.GenerateMocks(source)) - def testEnumType(self): - source = """ + def testEnumType(self): + source = """ class Test { public: enum Bar { @@ -483,18 +498,17 @@ class Test { virtual void Foo(); }; """ - expected = """\ + expected = """\ class MockTest : public Test { public: -MOCK_METHOD0(Foo, -void()); +MOCK_METHOD(void, Foo, (), (override)); }; """ - self.assertEqualIgnoreLeadingWhitespace( - expected, self.GenerateMocks(source)) + self.assertEqualIgnoreLeadingWhitespace(expected, + self.GenerateMocks(source)) - def testEnumClassType(self): - source = """ + def testEnumClassType(self): + source = """ class Test { public: enum class Bar { @@ -503,18 +517,17 @@ class Test { virtual void Foo(); }; """ - expected = """\ + expected = """\ class MockTest : public Test { public: -MOCK_METHOD0(Foo, -void()); +MOCK_METHOD(void, Foo, (), (override)); }; """ - self.assertEqualIgnoreLeadingWhitespace( - expected, self.GenerateMocks(source)) + self.assertEqualIgnoreLeadingWhitespace(expected, + self.GenerateMocks(source)) - def testStdFunction(self): - source = """ + def testStdFunction(self): + source = """ class Test { public: Test(std::function<int(std::string)> foo) : foo_(foo) {} @@ -525,16 +538,15 @@ class Test { std::function<int(std::string)> foo_; }; """ - expected = """\ + expected = """\ class MockTest : public Test { public: -MOCK_METHOD0(foo, -std::function<int (std::string)>()); +MOCK_METHOD(std::function<int (std::string)>, foo, (), (override)); }; """ - self.assertEqualIgnoreLeadingWhitespace( - expected, self.GenerateMocks(source)) + self.assertEqualIgnoreLeadingWhitespace(expected, + self.GenerateMocks(source)) if __name__ == '__main__': - unittest.main() + unittest.main() diff --git a/googlemock/src/gmock-matchers.cc b/googlemock/src/gmock-matchers.cc index 4a3f7af2..4f73e0a6 100644 --- a/googlemock/src/gmock-matchers.cc +++ b/googlemock/src/gmock-matchers.cc @@ -34,7 +34,6 @@ // utilities for defining matchers. #include "gmock/gmock-matchers.h" -#include "gmock/gmock-generated-matchers.h" #include <string.h> #include <iostream> diff --git a/googlemock/test/BUILD.bazel b/googlemock/test/BUILD.bazel index da95ed58..4aa9a75e 100644 --- a/googlemock/test/BUILD.bazel +++ b/googlemock/test/BUILD.bazel @@ -28,8 +28,6 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -# Author: misterg@google.com (Gennadiy Civil) -# # Bazel Build for Google C++ Testing Framework(Google Test)-googlemock load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test") diff --git a/googlemock/test/gmock-actions_test.cc b/googlemock/test/gmock-actions_test.cc index ae4fa20e..d1229ac9 100644 --- a/googlemock/test/gmock-actions_test.cc +++ b/googlemock/test/gmock-actions_test.cc @@ -80,8 +80,6 @@ using testing::SetArgumentPointee; using testing::Unused; using testing::WithArgs; using testing::internal::BuiltInDefaultValue; -using testing::internal::Int64; -using testing::internal::UInt64; #if !GTEST_OS_WINDOWS_MOBILE using testing::SetErrnoAndReturn; @@ -123,8 +121,9 @@ TEST(BuiltInDefaultValueTest, IsZeroForNumericTypes) { EXPECT_EQ(0U, BuiltInDefaultValue<unsigned long>::Get()); // NOLINT EXPECT_EQ(0, BuiltInDefaultValue<signed long>::Get()); // NOLINT EXPECT_EQ(0, BuiltInDefaultValue<long>::Get()); // NOLINT - EXPECT_EQ(0U, BuiltInDefaultValue<UInt64>::Get()); - EXPECT_EQ(0, BuiltInDefaultValue<Int64>::Get()); + EXPECT_EQ(0U, BuiltInDefaultValue<unsigned long long>::Get()); // NOLINT + EXPECT_EQ(0, BuiltInDefaultValue<signed long long>::Get()); // NOLINT + EXPECT_EQ(0, BuiltInDefaultValue<long long>::Get()); // NOLINT EXPECT_EQ(0, BuiltInDefaultValue<float>::Get()); EXPECT_EQ(0, BuiltInDefaultValue<double>::Get()); } @@ -147,8 +146,9 @@ TEST(BuiltInDefaultValueTest, ExistsForNumericTypes) { EXPECT_TRUE(BuiltInDefaultValue<unsigned long>::Exists()); // NOLINT EXPECT_TRUE(BuiltInDefaultValue<signed long>::Exists()); // NOLINT EXPECT_TRUE(BuiltInDefaultValue<long>::Exists()); // NOLINT - EXPECT_TRUE(BuiltInDefaultValue<UInt64>::Exists()); - EXPECT_TRUE(BuiltInDefaultValue<Int64>::Exists()); + EXPECT_TRUE(BuiltInDefaultValue<unsigned long long>::Exists()); // NOLINT + EXPECT_TRUE(BuiltInDefaultValue<signed long long>::Exists()); // NOLINT + EXPECT_TRUE(BuiltInDefaultValue<long long>::Exists()); // NOLINT EXPECT_TRUE(BuiltInDefaultValue<float>::Exists()); EXPECT_TRUE(BuiltInDefaultValue<double>::Exists()); } @@ -1470,8 +1470,19 @@ TEST(FunctorActionTest, TypeConversion) { EXPECT_EQ(1, s2.Perform(std::make_tuple("hello"))); // Also between the lambda and the action itself. - const Action<bool(std::string)> x = [](Unused) { return 42; }; - EXPECT_TRUE(x.Perform(std::make_tuple("hello"))); + const Action<bool(std::string)> x1 = [](Unused) { return 42; }; + const Action<bool(std::string)> x2 = [] { return 42; }; + EXPECT_TRUE(x1.Perform(std::make_tuple("hello"))); + EXPECT_TRUE(x2.Perform(std::make_tuple("hello"))); + + // Ensure decay occurs where required. + std::function<int()> f = [] { return 7; }; + Action<int(int)> d = f; + f = nullptr; + EXPECT_EQ(7, d.Perform(std::make_tuple(1))); + + // Ensure creation of an empty action succeeds. + Action<void(int)>(nullptr); } TEST(FunctorActionTest, UnusedArguments) { diff --git a/googlemock/test/gmock-function-mocker_test.cc b/googlemock/test/gmock-function-mocker_test.cc index 90d6b5f1..94aaafba 100644 --- a/googlemock/test/gmock-function-mocker_test.cc +++ b/googlemock/test/gmock-function-mocker_test.cc @@ -31,7 +31,7 @@ // Google Mock - a framework for writing C++ mock classes. // // This file tests the function mocker classes. -#include "gmock/gmock-generated-function-mockers.h" +#include "gmock/gmock-function-mocker.h" #if GTEST_OS_WINDOWS // MSDN says the header file to be included for STDMETHOD is BaseTyps.h but @@ -40,6 +40,7 @@ # include <objbase.h> #endif // GTEST_OS_WINDOWS +#include <functional> #include <map> #include <string> #include <type_traits> @@ -183,182 +184,238 @@ class MockFoo : public FooInterface { private: GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo); }; + +class LegacyMockFoo : public FooInterface { + public: + LegacyMockFoo() {} + + // Makes sure that a mock function parameter can be named. + MOCK_METHOD1(VoidReturning, void(int n)); // NOLINT + + MOCK_METHOD0(Nullary, int()); // NOLINT + + // Makes sure that a mock function parameter can be unnamed. + MOCK_METHOD1(Unary, bool(int)); // NOLINT + MOCK_METHOD2(Binary, long(short, int)); // NOLINT + MOCK_METHOD10(Decimal, int(bool, char, short, int, long, float, // NOLINT + double, unsigned, char*, const std::string& str)); + + MOCK_METHOD1(TakesNonConstReference, bool(int&)); // NOLINT + MOCK_METHOD1(TakesConstReference, std::string(const int&)); + MOCK_METHOD1(TakesConst, bool(const int)); // NOLINT + + // Tests that the function return type can contain unprotected comma. + MOCK_METHOD0(ReturnTypeWithComma, std::map<int, std::string>()); + MOCK_CONST_METHOD1(ReturnTypeWithComma, + std::map<int, std::string>(int)); // NOLINT + + MOCK_METHOD0(OverloadedOnArgumentNumber, int()); // NOLINT + MOCK_METHOD1(OverloadedOnArgumentNumber, int(int)); // NOLINT + + MOCK_METHOD1(OverloadedOnArgumentType, int(int)); // NOLINT + MOCK_METHOD1(OverloadedOnArgumentType, char(char)); // NOLINT + + MOCK_METHOD0(OverloadedOnConstness, int()); // NOLINT + MOCK_CONST_METHOD0(OverloadedOnConstness, char()); // NOLINT + + MOCK_METHOD1(TypeWithHole, int(int (*)())); // NOLINT + MOCK_METHOD1(TypeWithComma, + int(const std::map<int, std::string>&)); // NOLINT + MOCK_METHOD1(TypeWithTemplatedCopyCtor, + int(const TemplatedCopyable<int>&)); // NOLINT + + MOCK_METHOD1(ReturnsFunctionPointer1, int (*(int))(bool)); + MOCK_METHOD1(ReturnsFunctionPointer2, fn_ptr(int)); + +#if GTEST_OS_WINDOWS + MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTNullary, int()); + MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTUnary, bool(int)); // NOLINT + MOCK_METHOD10_WITH_CALLTYPE(STDMETHODCALLTYPE, CTDecimal, + int(bool b, char c, short d, int e, // NOLINT + long f, float g, double h, // NOLINT + unsigned i, char* j, const std::string& k)); + MOCK_CONST_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTConst, + char(int)); // NOLINT + + // Tests that the function return type can contain unprotected comma. + MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTReturnTypeWithComma, + std::map<int, std::string>()); +#endif // GTEST_OS_WINDOWS + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockFoo); +}; + #ifdef _MSC_VER # pragma warning(pop) #endif -class MockMethodFunctionMockerTest : public testing::Test { +template <class T> +class FunctionMockerTest : public testing::Test { protected: - MockMethodFunctionMockerTest() : foo_(&mock_foo_) {} + FunctionMockerTest() : foo_(&mock_foo_) {} FooInterface* const foo_; - MockFoo mock_foo_; + T mock_foo_; }; +using FunctionMockerTestTypes = ::testing::Types<MockFoo, LegacyMockFoo>; +TYPED_TEST_SUITE(FunctionMockerTest, FunctionMockerTestTypes); // Tests mocking a void-returning function. -TEST_F(MockMethodFunctionMockerTest, MocksVoidFunction) { - EXPECT_CALL(mock_foo_, VoidReturning(Lt(100))); - foo_->VoidReturning(0); +TYPED_TEST(FunctionMockerTest, MocksVoidFunction) { + EXPECT_CALL(this->mock_foo_, VoidReturning(Lt(100))); + this->foo_->VoidReturning(0); } // Tests mocking a nullary function. -TEST_F(MockMethodFunctionMockerTest, MocksNullaryFunction) { - EXPECT_CALL(mock_foo_, Nullary()) +TYPED_TEST(FunctionMockerTest, MocksNullaryFunction) { + EXPECT_CALL(this->mock_foo_, Nullary()) .WillOnce(DoDefault()) .WillOnce(Return(1)); - EXPECT_EQ(0, foo_->Nullary()); - EXPECT_EQ(1, foo_->Nullary()); + EXPECT_EQ(0, this->foo_->Nullary()); + EXPECT_EQ(1, this->foo_->Nullary()); } // Tests mocking a unary function. -TEST_F(MockMethodFunctionMockerTest, MocksUnaryFunction) { - EXPECT_CALL(mock_foo_, Unary(Eq(2))) - .Times(2) - .WillOnce(Return(true)); +TYPED_TEST(FunctionMockerTest, MocksUnaryFunction) { + EXPECT_CALL(this->mock_foo_, Unary(Eq(2))).Times(2).WillOnce(Return(true)); - EXPECT_TRUE(foo_->Unary(2)); - EXPECT_FALSE(foo_->Unary(2)); + EXPECT_TRUE(this->foo_->Unary(2)); + EXPECT_FALSE(this->foo_->Unary(2)); } // Tests mocking a binary function. -TEST_F(MockMethodFunctionMockerTest, MocksBinaryFunction) { - EXPECT_CALL(mock_foo_, Binary(2, _)) - .WillOnce(Return(3)); +TYPED_TEST(FunctionMockerTest, MocksBinaryFunction) { + EXPECT_CALL(this->mock_foo_, Binary(2, _)).WillOnce(Return(3)); - EXPECT_EQ(3, foo_->Binary(2, 1)); + EXPECT_EQ(3, this->foo_->Binary(2, 1)); } // Tests mocking a decimal function. -TEST_F(MockMethodFunctionMockerTest, MocksDecimalFunction) { - EXPECT_CALL(mock_foo_, Decimal(true, 'a', 0, 0, 1L, A<float>(), - Lt(100), 5U, NULL, "hi")) +TYPED_TEST(FunctionMockerTest, MocksDecimalFunction) { + EXPECT_CALL(this->mock_foo_, + Decimal(true, 'a', 0, 0, 1L, A<float>(), Lt(100), 5U, NULL, "hi")) .WillOnce(Return(5)); - EXPECT_EQ(5, foo_->Decimal(true, 'a', 0, 0, 1, 0, 0, 5, nullptr, "hi")); + EXPECT_EQ(5, this->foo_->Decimal(true, 'a', 0, 0, 1, 0, 0, 5, nullptr, "hi")); } // Tests mocking a function that takes a non-const reference. -TEST_F(MockMethodFunctionMockerTest, - MocksFunctionWithNonConstReferenceArgument) { +TYPED_TEST(FunctionMockerTest, MocksFunctionWithNonConstReferenceArgument) { int a = 0; - EXPECT_CALL(mock_foo_, TakesNonConstReference(Ref(a))) + EXPECT_CALL(this->mock_foo_, TakesNonConstReference(Ref(a))) .WillOnce(Return(true)); - EXPECT_TRUE(foo_->TakesNonConstReference(a)); + EXPECT_TRUE(this->foo_->TakesNonConstReference(a)); } // Tests mocking a function that takes a const reference. -TEST_F(MockMethodFunctionMockerTest, MocksFunctionWithConstReferenceArgument) { +TYPED_TEST(FunctionMockerTest, MocksFunctionWithConstReferenceArgument) { int a = 0; - EXPECT_CALL(mock_foo_, TakesConstReference(Ref(a))) + EXPECT_CALL(this->mock_foo_, TakesConstReference(Ref(a))) .WillOnce(Return("Hello")); - EXPECT_EQ("Hello", foo_->TakesConstReference(a)); + EXPECT_EQ("Hello", this->foo_->TakesConstReference(a)); } // Tests mocking a function that takes a const variable. -TEST_F(MockMethodFunctionMockerTest, MocksFunctionWithConstArgument) { - EXPECT_CALL(mock_foo_, TakesConst(Lt(10))) - .WillOnce(DoDefault()); +TYPED_TEST(FunctionMockerTest, MocksFunctionWithConstArgument) { + EXPECT_CALL(this->mock_foo_, TakesConst(Lt(10))).WillOnce(DoDefault()); - EXPECT_FALSE(foo_->TakesConst(5)); + EXPECT_FALSE(this->foo_->TakesConst(5)); } // Tests mocking functions overloaded on the number of arguments. -TEST_F(MockMethodFunctionMockerTest, MocksFunctionsOverloadedOnArgumentNumber) { - EXPECT_CALL(mock_foo_, OverloadedOnArgumentNumber()) +TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentNumber) { + EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentNumber()) .WillOnce(Return(1)); - EXPECT_CALL(mock_foo_, OverloadedOnArgumentNumber(_)) + EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentNumber(_)) .WillOnce(Return(2)); - EXPECT_EQ(2, foo_->OverloadedOnArgumentNumber(1)); - EXPECT_EQ(1, foo_->OverloadedOnArgumentNumber()); + EXPECT_EQ(2, this->foo_->OverloadedOnArgumentNumber(1)); + EXPECT_EQ(1, this->foo_->OverloadedOnArgumentNumber()); } // Tests mocking functions overloaded on the types of argument. -TEST_F(MockMethodFunctionMockerTest, MocksFunctionsOverloadedOnArgumentType) { - EXPECT_CALL(mock_foo_, OverloadedOnArgumentType(An<int>())) +TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentType) { + EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentType(An<int>())) .WillOnce(Return(1)); - EXPECT_CALL(mock_foo_, OverloadedOnArgumentType(TypedEq<char>('a'))) + EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentType(TypedEq<char>('a'))) .WillOnce(Return('b')); - EXPECT_EQ(1, foo_->OverloadedOnArgumentType(0)); - EXPECT_EQ('b', foo_->OverloadedOnArgumentType('a')); + EXPECT_EQ(1, this->foo_->OverloadedOnArgumentType(0)); + EXPECT_EQ('b', this->foo_->OverloadedOnArgumentType('a')); } // Tests mocking functions overloaded on the const-ness of this object. -TEST_F(MockMethodFunctionMockerTest, - MocksFunctionsOverloadedOnConstnessOfThis) { - EXPECT_CALL(mock_foo_, OverloadedOnConstness()); - EXPECT_CALL(Const(mock_foo_), OverloadedOnConstness()) +TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnConstnessOfThis) { + EXPECT_CALL(this->mock_foo_, OverloadedOnConstness()); + EXPECT_CALL(Const(this->mock_foo_), OverloadedOnConstness()) .WillOnce(Return('a')); - EXPECT_EQ(0, foo_->OverloadedOnConstness()); - EXPECT_EQ('a', Const(*foo_).OverloadedOnConstness()); + EXPECT_EQ(0, this->foo_->OverloadedOnConstness()); + EXPECT_EQ('a', Const(*this->foo_).OverloadedOnConstness()); } -TEST_F(MockMethodFunctionMockerTest, MocksReturnTypeWithComma) { +TYPED_TEST(FunctionMockerTest, MocksReturnTypeWithComma) { const std::map<int, std::string> a_map; - EXPECT_CALL(mock_foo_, ReturnTypeWithComma()) - .WillOnce(Return(a_map)); - EXPECT_CALL(mock_foo_, ReturnTypeWithComma(42)) - .WillOnce(Return(a_map)); + EXPECT_CALL(this->mock_foo_, ReturnTypeWithComma()).WillOnce(Return(a_map)); + EXPECT_CALL(this->mock_foo_, ReturnTypeWithComma(42)).WillOnce(Return(a_map)); - EXPECT_EQ(a_map, mock_foo_.ReturnTypeWithComma()); - EXPECT_EQ(a_map, mock_foo_.ReturnTypeWithComma(42)); + EXPECT_EQ(a_map, this->mock_foo_.ReturnTypeWithComma()); + EXPECT_EQ(a_map, this->mock_foo_.ReturnTypeWithComma(42)); } -TEST_F(MockMethodFunctionMockerTest, MocksTypeWithTemplatedCopyCtor) { - EXPECT_CALL(mock_foo_, TypeWithTemplatedCopyCtor(_)).WillOnce(Return(true)); - EXPECT_TRUE(foo_->TypeWithTemplatedCopyCtor(TemplatedCopyable<int>())); +TYPED_TEST(FunctionMockerTest, MocksTypeWithTemplatedCopyCtor) { + EXPECT_CALL(this->mock_foo_, TypeWithTemplatedCopyCtor(_)) + .WillOnce(Return(true)); + EXPECT_TRUE(this->foo_->TypeWithTemplatedCopyCtor(TemplatedCopyable<int>())); } #if GTEST_OS_WINDOWS // Tests mocking a nullary function with calltype. -TEST_F(MockMethodFunctionMockerTest, MocksNullaryFunctionWithCallType) { - EXPECT_CALL(mock_foo_, CTNullary()) +TYPED_TEST(FunctionMockerTest, MocksNullaryFunctionWithCallType) { + EXPECT_CALL(this->mock_foo_, CTNullary()) .WillOnce(Return(-1)) .WillOnce(Return(0)); - EXPECT_EQ(-1, foo_->CTNullary()); - EXPECT_EQ(0, foo_->CTNullary()); + EXPECT_EQ(-1, this->foo_->CTNullary()); + EXPECT_EQ(0, this->foo_->CTNullary()); } // Tests mocking a unary function with calltype. -TEST_F(MockMethodFunctionMockerTest, MocksUnaryFunctionWithCallType) { - EXPECT_CALL(mock_foo_, CTUnary(Eq(2))) +TYPED_TEST(FunctionMockerTest, MocksUnaryFunctionWithCallType) { + EXPECT_CALL(this->mock_foo_, CTUnary(Eq(2))) .Times(2) .WillOnce(Return(true)) .WillOnce(Return(false)); - EXPECT_TRUE(foo_->CTUnary(2)); - EXPECT_FALSE(foo_->CTUnary(2)); + EXPECT_TRUE(this->foo_->CTUnary(2)); + EXPECT_FALSE(this->foo_->CTUnary(2)); } // Tests mocking a decimal function with calltype. -TEST_F(MockMethodFunctionMockerTest, MocksDecimalFunctionWithCallType) { - EXPECT_CALL(mock_foo_, CTDecimal(true, 'a', 0, 0, 1L, A<float>(), - Lt(100), 5U, NULL, "hi")) +TYPED_TEST(FunctionMockerTest, MocksDecimalFunctionWithCallType) { + EXPECT_CALL(this->mock_foo_, CTDecimal(true, 'a', 0, 0, 1L, A<float>(), + Lt(100), 5U, NULL, "hi")) .WillOnce(Return(10)); - EXPECT_EQ(10, foo_->CTDecimal(true, 'a', 0, 0, 1, 0, 0, 5, NULL, "hi")); + EXPECT_EQ(10, this->foo_->CTDecimal(true, 'a', 0, 0, 1, 0, 0, 5, NULL, "hi")); } // Tests mocking functions overloaded on the const-ness of this object. -TEST_F(MockMethodFunctionMockerTest, MocksFunctionsConstFunctionWithCallType) { - EXPECT_CALL(Const(mock_foo_), CTConst(_)) - .WillOnce(Return('a')); +TYPED_TEST(FunctionMockerTest, MocksFunctionsConstFunctionWithCallType) { + EXPECT_CALL(Const(this->mock_foo_), CTConst(_)).WillOnce(Return('a')); - EXPECT_EQ('a', Const(*foo_).CTConst(0)); + EXPECT_EQ('a', Const(*this->foo_).CTConst(0)); } -TEST_F(MockMethodFunctionMockerTest, MocksReturnTypeWithCommaAndCallType) { +TYPED_TEST(FunctionMockerTest, MocksReturnTypeWithCommaAndCallType) { const std::map<int, std::string> a_map; - EXPECT_CALL(mock_foo_, CTReturnTypeWithComma()) - .WillOnce(Return(a_map)); + EXPECT_CALL(this->mock_foo_, CTReturnTypeWithComma()).WillOnce(Return(a_map)); - EXPECT_EQ(a_map, mock_foo_.CTReturnTypeWithComma()); + EXPECT_EQ(a_map, this->mock_foo_.CTReturnTypeWithComma()); } #endif // GTEST_OS_WINDOWS @@ -373,20 +430,33 @@ class MockB { GTEST_DISALLOW_COPY_AND_ASSIGN_(MockB); }; +class LegacyMockB { + public: + LegacyMockB() {} + + MOCK_METHOD0(DoB, void()); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockB); +}; + +template <typename T> +class ExpectCallTest : public ::testing::Test {}; +using ExpectCallTestTypes = ::testing::Types<MockB, LegacyMockB>; +TYPED_TEST_SUITE(ExpectCallTest, ExpectCallTestTypes); + // Tests that functions with no EXPECT_CALL() rules can be called any // number of times. -TEST(MockMethodExpectCallTest, UnmentionedFunctionCanBeCalledAnyNumberOfTimes) { - { - MockB b; - } +TYPED_TEST(ExpectCallTest, UnmentionedFunctionCanBeCalledAnyNumberOfTimes) { + { TypeParam b; } { - MockB b; + TypeParam b; b.DoB(); } { - MockB b; + TypeParam b; b.DoB(); b.DoB(); } @@ -425,9 +495,33 @@ class MockStack : public StackInterface<T> { GTEST_DISALLOW_COPY_AND_ASSIGN_(MockStack); }; +template <typename T> +class LegacyMockStack : public StackInterface<T> { + public: + LegacyMockStack() {} + + MOCK_METHOD1_T(Push, void(const T& elem)); + MOCK_METHOD0_T(Pop, void()); + MOCK_CONST_METHOD0_T(GetSize, int()); // NOLINT + MOCK_CONST_METHOD0_T(GetTop, const T&()); + + // Tests that the function return type can contain unprotected comma. + MOCK_METHOD0_T(ReturnTypeWithComma, std::map<int, int>()); + MOCK_CONST_METHOD1_T(ReturnTypeWithComma, std::map<int, int>(int)); // NOLINT + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockStack); +}; + +template <typename T> +class TemplateMockTest : public ::testing::Test {}; +using TemplateMockTestTypes = + ::testing::Types<MockStack<int>, LegacyMockStack<int>>; +TYPED_TEST_SUITE(TemplateMockTest, TemplateMockTestTypes); + // Tests that template mock works. -TEST(MockMethodTemplateMockTest, Works) { - MockStack<int> mock; +TYPED_TEST(TemplateMockTest, Works) { + TypeParam mock; EXPECT_CALL(mock, GetSize()) .WillOnce(Return(0)) @@ -448,8 +542,8 @@ TEST(MockMethodTemplateMockTest, Works) { EXPECT_EQ(0, mock.GetSize()); } -TEST(MockMethodTemplateMockTest, MethodWithCommaInReturnTypeWorks) { - MockStack<int> mock; +TYPED_TEST(TemplateMockTest, MethodWithCommaInReturnTypeWorks) { + TypeParam mock; const std::map<int, int> a_map; EXPECT_CALL(mock, ReturnTypeWithComma()) @@ -493,9 +587,31 @@ class MockStackWithCallType : public StackInterfaceWithCallType<T> { GTEST_DISALLOW_COPY_AND_ASSIGN_(MockStackWithCallType); }; +template <typename T> +class LegacyMockStackWithCallType : public StackInterfaceWithCallType<T> { + public: + LegacyMockStackWithCallType() {} + + MOCK_METHOD1_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Push, void(const T& elem)); + MOCK_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Pop, void()); + MOCK_CONST_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, GetSize, int()); + MOCK_CONST_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, GetTop, const T&()); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockStackWithCallType); +}; + +template <typename T> +class TemplateMockTestWithCallType : public ::testing::Test {}; +using TemplateMockTestWithCallTypeTypes = + ::testing::Types<MockStackWithCallType<int>, + LegacyMockStackWithCallType<int>>; +TYPED_TEST_SUITE(TemplateMockTestWithCallType, + TemplateMockTestWithCallTypeTypes); + // Tests that template mock with calltype works. -TEST(MockMethodTemplateMockTestWithCallType, Works) { - MockStackWithCallType<int> mock; +TYPED_TEST(TemplateMockTestWithCallType, Works) { + TypeParam mock; EXPECT_CALL(mock, GetSize()) .WillOnce(Return(0)) @@ -522,6 +638,11 @@ TEST(MockMethodTemplateMockTestWithCallType, Works) { MOCK_METHOD(int, Overloaded, (int), (const)); \ MOCK_METHOD(bool, Overloaded, (bool f, int n)) +#define LEGACY_MY_MOCK_METHODS1_ \ + MOCK_METHOD0(Overloaded, void()); \ + MOCK_CONST_METHOD1(Overloaded, int(int n)); \ + MOCK_METHOD2(Overloaded, bool(bool f, int n)) + class MockOverloadedOnArgNumber { public: MockOverloadedOnArgNumber() {} @@ -532,8 +653,25 @@ class MockOverloadedOnArgNumber { GTEST_DISALLOW_COPY_AND_ASSIGN_(MockOverloadedOnArgNumber); }; -TEST(MockMethodOverloadedMockMethodTest, CanOverloadOnArgNumberInMacroBody) { - MockOverloadedOnArgNumber mock; +class LegacyMockOverloadedOnArgNumber { + public: + LegacyMockOverloadedOnArgNumber() {} + + LEGACY_MY_MOCK_METHODS1_; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockOverloadedOnArgNumber); +}; + +template <typename T> +class OverloadedMockMethodTest : public ::testing::Test {}; +using OverloadedMockMethodTestTypes = + ::testing::Types<MockOverloadedOnArgNumber, + LegacyMockOverloadedOnArgNumber>; +TYPED_TEST_SUITE(OverloadedMockMethodTest, OverloadedMockMethodTestTypes); + +TYPED_TEST(OverloadedMockMethodTest, CanOverloadOnArgNumberInMacroBody) { + TypeParam mock; EXPECT_CALL(mock, Overloaded()); EXPECT_CALL(mock, Overloaded(1)).WillOnce(Return(2)); EXPECT_CALL(mock, Overloaded(true, 1)).WillOnce(Return(true)); @@ -641,6 +779,56 @@ TEST(MockMethodMockFunctionTest, AsStdFunctionWithReferenceParameter) { EXPECT_EQ(-1, call(foo.AsStdFunction(), i)); } +namespace { + +template <typename Expected, typename F> +static constexpr bool IsMockFunctionTemplateArgumentDeducedTo( + const MockFunction<F>&) { + return std::is_same<F, Expected>::value; +} + +} // namespace + +template <typename F> +class MockMethodMockFunctionSignatureTest : public Test {}; + +using MockMethodMockFunctionSignatureTypes = + Types<void(), int(), void(int), int(int), int(bool, int), + int(bool, char, int, int, int, int, int, char, int, bool)>; +TYPED_TEST_SUITE(MockMethodMockFunctionSignatureTest, + MockMethodMockFunctionSignatureTypes); + +TYPED_TEST(MockMethodMockFunctionSignatureTest, + IsMockFunctionTemplateArgumentDeducedForRawSignature) { + using Argument = TypeParam; + MockFunction<Argument> foo; + EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<Argument>(foo)); +} + +TYPED_TEST(MockMethodMockFunctionSignatureTest, + IsMockFunctionTemplateArgumentDeducedForStdFunction) { + using Argument = std::function<TypeParam>; + MockFunction<Argument> foo; + EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<Argument>(foo)); +} + +TYPED_TEST( + MockMethodMockFunctionSignatureTest, + IsMockFunctionCallMethodSignatureTheSameForRawSignatureAndStdFunction) { + using ForRawSignature = decltype(&MockFunction<TypeParam>::Call); + using ForStdFunction = + decltype(&MockFunction<std::function<TypeParam>>::Call); + EXPECT_TRUE((std::is_same<ForRawSignature, ForStdFunction>::value)); +} + +TYPED_TEST( + MockMethodMockFunctionSignatureTest, + IsMockFunctionAsStdFunctionMethodSignatureTheSameForRawSignatureAndStdFunction) { + using ForRawSignature = decltype(&MockFunction<TypeParam>::AsStdFunction); + using ForStdFunction = + decltype(&MockFunction<std::function<TypeParam>>::AsStdFunction); + EXPECT_TRUE((std::is_same<ForRawSignature, ForStdFunction>::value)); +} struct MockMethodSizes0 { MOCK_METHOD(void, func, ()); @@ -658,11 +846,35 @@ struct MockMethodSizes4 { MOCK_METHOD(void, func, (int, int, int, int)); }; +struct LegacyMockMethodSizes0 { + MOCK_METHOD0(func, void()); +}; +struct LegacyMockMethodSizes1 { + MOCK_METHOD1(func, void(int)); +}; +struct LegacyMockMethodSizes2 { + MOCK_METHOD2(func, void(int, int)); +}; +struct LegacyMockMethodSizes3 { + MOCK_METHOD3(func, void(int, int, int)); +}; +struct LegacyMockMethodSizes4 { + MOCK_METHOD4(func, void(int, int, int, int)); +}; + + TEST(MockMethodMockFunctionTest, MockMethodSizeOverhead) { EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes1)); EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes2)); EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes3)); EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes4)); + + EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes1)); + EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes2)); + EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes3)); + EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes4)); + + EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(MockMethodSizes0)); } void hasTwoParams(int, int); diff --git a/googlemock/test/gmock-generated-function-mockers_test.cc b/googlemock/test/gmock-generated-function-mockers_test.cc deleted file mode 100644 index dff3a9f0..00000000 --- a/googlemock/test/gmock-generated-function-mockers_test.cc +++ /dev/null @@ -1,659 +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 function mocker classes. - -#include "gmock/gmock-generated-function-mockers.h" - -#if GTEST_OS_WINDOWS -// MSDN says the header file to be included for STDMETHOD is BaseTyps.h but -// we are getting compiler errors if we use basetyps.h, hence including -// objbase.h for definition of STDMETHOD. -# include <objbase.h> -#endif // GTEST_OS_WINDOWS - -#include <map> -#include <string> -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -namespace testing { -namespace gmock_generated_function_mockers_test { - -using testing::_; -using testing::A; -using testing::An; -using testing::AnyNumber; -using testing::Const; -using testing::DoDefault; -using testing::Eq; -using testing::Lt; -using testing::MockFunction; -using testing::Ref; -using testing::Return; -using testing::ReturnRef; -using testing::TypedEq; - -template<typename T> -class TemplatedCopyable { - public: - TemplatedCopyable() {} - - template <typename U> - TemplatedCopyable(const U& other) {} // NOLINT -}; - -class FooInterface { - public: - virtual ~FooInterface() {} - - virtual void VoidReturning(int x) = 0; - - virtual int Nullary() = 0; - virtual bool Unary(int x) = 0; - virtual long Binary(short x, int y) = 0; // NOLINT - virtual int Decimal(bool b, char c, short d, int e, long f, // NOLINT - float g, double h, unsigned i, char* j, - const std::string& k) = 0; - - virtual bool TakesNonConstReference(int& n) = 0; // NOLINT - virtual std::string TakesConstReference(const int& n) = 0; - virtual bool TakesConst(const int x) = 0; - - virtual int OverloadedOnArgumentNumber() = 0; - virtual int OverloadedOnArgumentNumber(int n) = 0; - - virtual int OverloadedOnArgumentType(int n) = 0; - virtual char OverloadedOnArgumentType(char c) = 0; - - virtual int OverloadedOnConstness() = 0; - virtual char OverloadedOnConstness() const = 0; - - virtual int TypeWithHole(int (*func)()) = 0; - virtual int TypeWithComma(const std::map<int, std::string>& a_map) = 0; - virtual int TypeWithTemplatedCopyCtor( - const TemplatedCopyable<int>& a_vector) = 0; - -#if GTEST_OS_WINDOWS - STDMETHOD_(int, CTNullary)() = 0; - STDMETHOD_(bool, CTUnary)(int x) = 0; - STDMETHOD_(int, CTDecimal) - (bool b, char c, short d, int e, long f, // NOLINT - float g, double h, unsigned i, char* j, const std::string& k) = 0; - STDMETHOD_(char, CTConst)(int x) const = 0; -#endif // GTEST_OS_WINDOWS -}; - -// Const qualifiers on arguments were once (incorrectly) considered -// significant in determining whether two virtual functions had the same -// signature. This was fixed in Visual Studio 2008. However, the compiler -// still emits a warning that alerts about this change in behavior. -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable : 4373) -#endif -class MockFoo : public FooInterface { - public: - MockFoo() {} - - // Makes sure that a mock function parameter can be named. - MOCK_METHOD1(VoidReturning, void(int n)); // NOLINT - - MOCK_METHOD0(Nullary, int()); // NOLINT - - // Makes sure that a mock function parameter can be unnamed. - MOCK_METHOD1(Unary, bool(int)); // NOLINT - MOCK_METHOD2(Binary, long(short, int)); // NOLINT - MOCK_METHOD10(Decimal, int(bool, char, short, int, long, float, // NOLINT - double, unsigned, char*, const std::string& str)); - - MOCK_METHOD1(TakesNonConstReference, bool(int&)); // NOLINT - MOCK_METHOD1(TakesConstReference, std::string(const int&)); - MOCK_METHOD1(TakesConst, bool(const int)); // NOLINT - - // Tests that the function return type can contain unprotected comma. - MOCK_METHOD0(ReturnTypeWithComma, std::map<int, std::string>()); - MOCK_CONST_METHOD1(ReturnTypeWithComma, - std::map<int, std::string>(int)); // NOLINT - - MOCK_METHOD0(OverloadedOnArgumentNumber, int()); // NOLINT - MOCK_METHOD1(OverloadedOnArgumentNumber, int(int)); // NOLINT - - MOCK_METHOD1(OverloadedOnArgumentType, int(int)); // NOLINT - MOCK_METHOD1(OverloadedOnArgumentType, char(char)); // NOLINT - - MOCK_METHOD0(OverloadedOnConstness, int()); // NOLINT - MOCK_CONST_METHOD0(OverloadedOnConstness, char()); // NOLINT - - MOCK_METHOD1(TypeWithHole, int(int (*)())); // NOLINT - MOCK_METHOD1(TypeWithComma, - int(const std::map<int, std::string>&)); // NOLINT - MOCK_METHOD1(TypeWithTemplatedCopyCtor, - int(const TemplatedCopyable<int>&)); // NOLINT - -#if GTEST_OS_WINDOWS - MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTNullary, int()); - MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTUnary, bool(int)); - MOCK_METHOD10_WITH_CALLTYPE(STDMETHODCALLTYPE, CTDecimal, - int(bool b, char c, short d, int e, long f, - float g, double h, unsigned i, char* j, - const std::string& k)); - MOCK_CONST_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTConst, char(int)); - - // Tests that the function return type can contain unprotected comma. - MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTReturnTypeWithComma, - std::map<int, std::string>()); -#endif // GTEST_OS_WINDOWS - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo); -}; -#ifdef _MSC_VER -# pragma warning(pop) -#endif - -class FunctionMockerTest : public testing::Test { - protected: - FunctionMockerTest() : foo_(&mock_foo_) {} - - FooInterface* const foo_; - MockFoo mock_foo_; -}; - -// Tests mocking a void-returning function. -TEST_F(FunctionMockerTest, MocksVoidFunction) { - EXPECT_CALL(mock_foo_, VoidReturning(Lt(100))); - foo_->VoidReturning(0); -} - -// Tests mocking a nullary function. -TEST_F(FunctionMockerTest, MocksNullaryFunction) { - EXPECT_CALL(mock_foo_, Nullary()) - .WillOnce(DoDefault()) - .WillOnce(Return(1)); - - EXPECT_EQ(0, foo_->Nullary()); - EXPECT_EQ(1, foo_->Nullary()); -} - -// Tests mocking a unary function. -TEST_F(FunctionMockerTest, MocksUnaryFunction) { - EXPECT_CALL(mock_foo_, Unary(Eq(2))) - .Times(2) - .WillOnce(Return(true)); - - EXPECT_TRUE(foo_->Unary(2)); - EXPECT_FALSE(foo_->Unary(2)); -} - -// Tests mocking a binary function. -TEST_F(FunctionMockerTest, MocksBinaryFunction) { - EXPECT_CALL(mock_foo_, Binary(2, _)) - .WillOnce(Return(3)); - - EXPECT_EQ(3, foo_->Binary(2, 1)); -} - -// Tests mocking a decimal function. -TEST_F(FunctionMockerTest, MocksDecimalFunction) { - EXPECT_CALL(mock_foo_, Decimal(true, 'a', 0, 0, 1L, A<float>(), Lt(100), 5U, - nullptr, "hi")) - .WillOnce(Return(5)); - - EXPECT_EQ(5, foo_->Decimal(true, 'a', 0, 0, 1, 0, 0, 5, nullptr, "hi")); -} - -// Tests mocking a function that takes a non-const reference. -TEST_F(FunctionMockerTest, MocksFunctionWithNonConstReferenceArgument) { - int a = 0; - EXPECT_CALL(mock_foo_, TakesNonConstReference(Ref(a))) - .WillOnce(Return(true)); - - EXPECT_TRUE(foo_->TakesNonConstReference(a)); -} - -// Tests mocking a function that takes a const reference. -TEST_F(FunctionMockerTest, MocksFunctionWithConstReferenceArgument) { - int a = 0; - EXPECT_CALL(mock_foo_, TakesConstReference(Ref(a))) - .WillOnce(Return("Hello")); - - EXPECT_EQ("Hello", foo_->TakesConstReference(a)); -} - -// Tests mocking a function that takes a const variable. -TEST_F(FunctionMockerTest, MocksFunctionWithConstArgument) { - EXPECT_CALL(mock_foo_, TakesConst(Lt(10))) - .WillOnce(DoDefault()); - - EXPECT_FALSE(foo_->TakesConst(5)); -} - -// Tests mocking functions overloaded on the number of arguments. -TEST_F(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentNumber) { - EXPECT_CALL(mock_foo_, OverloadedOnArgumentNumber()) - .WillOnce(Return(1)); - EXPECT_CALL(mock_foo_, OverloadedOnArgumentNumber(_)) - .WillOnce(Return(2)); - - EXPECT_EQ(2, foo_->OverloadedOnArgumentNumber(1)); - EXPECT_EQ(1, foo_->OverloadedOnArgumentNumber()); -} - -// Tests mocking functions overloaded on the types of argument. -TEST_F(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentType) { - EXPECT_CALL(mock_foo_, OverloadedOnArgumentType(An<int>())) - .WillOnce(Return(1)); - EXPECT_CALL(mock_foo_, OverloadedOnArgumentType(TypedEq<char>('a'))) - .WillOnce(Return('b')); - - EXPECT_EQ(1, foo_->OverloadedOnArgumentType(0)); - EXPECT_EQ('b', foo_->OverloadedOnArgumentType('a')); -} - -// Tests mocking functions overloaded on the const-ness of this object. -TEST_F(FunctionMockerTest, MocksFunctionsOverloadedOnConstnessOfThis) { - EXPECT_CALL(mock_foo_, OverloadedOnConstness()); - EXPECT_CALL(Const(mock_foo_), OverloadedOnConstness()) - .WillOnce(Return('a')); - - EXPECT_EQ(0, foo_->OverloadedOnConstness()); - EXPECT_EQ('a', Const(*foo_).OverloadedOnConstness()); -} - -TEST_F(FunctionMockerTest, MocksReturnTypeWithComma) { - const std::map<int, std::string> a_map; - EXPECT_CALL(mock_foo_, ReturnTypeWithComma()) - .WillOnce(Return(a_map)); - EXPECT_CALL(mock_foo_, ReturnTypeWithComma(42)) - .WillOnce(Return(a_map)); - - EXPECT_EQ(a_map, mock_foo_.ReturnTypeWithComma()); - EXPECT_EQ(a_map, mock_foo_.ReturnTypeWithComma(42)); -} - -TEST_F(FunctionMockerTest, MocksTypeWithTemplatedCopyCtor) { - EXPECT_CALL(mock_foo_, TypeWithTemplatedCopyCtor(_)).WillOnce(Return(true)); - EXPECT_TRUE(foo_->TypeWithTemplatedCopyCtor(TemplatedCopyable<int>())); -} - -#if GTEST_OS_WINDOWS -// Tests mocking a nullary function with calltype. -TEST_F(FunctionMockerTest, MocksNullaryFunctionWithCallType) { - EXPECT_CALL(mock_foo_, CTNullary()) - .WillOnce(Return(-1)) - .WillOnce(Return(0)); - - EXPECT_EQ(-1, foo_->CTNullary()); - EXPECT_EQ(0, foo_->CTNullary()); -} - -// Tests mocking a unary function with calltype. -TEST_F(FunctionMockerTest, MocksUnaryFunctionWithCallType) { - EXPECT_CALL(mock_foo_, CTUnary(Eq(2))) - .Times(2) - .WillOnce(Return(true)) - .WillOnce(Return(false)); - - EXPECT_TRUE(foo_->CTUnary(2)); - EXPECT_FALSE(foo_->CTUnary(2)); -} - -// Tests mocking a decimal function with calltype. -TEST_F(FunctionMockerTest, MocksDecimalFunctionWithCallType) { - EXPECT_CALL(mock_foo_, CTDecimal(true, 'a', 0, 0, 1L, A<float>(), Lt(100), 5U, - nullptr, "hi")) - .WillOnce(Return(10)); - - EXPECT_EQ(10, foo_->CTDecimal(true, 'a', 0, 0, 1, 0, 0, 5, nullptr, "hi")); -} - -// Tests mocking functions overloaded on the const-ness of this object. -TEST_F(FunctionMockerTest, MocksFunctionsConstFunctionWithCallType) { - EXPECT_CALL(Const(mock_foo_), CTConst(_)) - .WillOnce(Return('a')); - - EXPECT_EQ('a', Const(*foo_).CTConst(0)); -} - -TEST_F(FunctionMockerTest, MocksReturnTypeWithCommaAndCallType) { - const std::map<int, std::string> a_map; - EXPECT_CALL(mock_foo_, CTReturnTypeWithComma()) - .WillOnce(Return(a_map)); - - EXPECT_EQ(a_map, mock_foo_.CTReturnTypeWithComma()); -} - -#endif // GTEST_OS_WINDOWS - -class MockB { - public: - MockB() {} - - MOCK_METHOD0(DoB, void()); - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockB); -}; - -// Tests that functions with no EXPECT_CALL() ruls can be called any -// number of times. -TEST(ExpectCallTest, UnmentionedFunctionCanBeCalledAnyNumberOfTimes) { - { - MockB b; - } - - { - MockB b; - b.DoB(); - } - - { - MockB b; - b.DoB(); - b.DoB(); - } -} - -// Tests mocking template interfaces. - -template <typename T> -class StackInterface { - public: - virtual ~StackInterface() {} - - // Template parameter appears in function parameter. - virtual void Push(const T& value) = 0; - virtual void Pop() = 0; - virtual int GetSize() const = 0; - // Template parameter appears in function return type. - virtual const T& GetTop() const = 0; -}; - -template <typename T> -class MockStack : public StackInterface<T> { - public: - MockStack() {} - - MOCK_METHOD1_T(Push, void(const T& elem)); - MOCK_METHOD0_T(Pop, void()); - MOCK_CONST_METHOD0_T(GetSize, int()); // NOLINT - MOCK_CONST_METHOD0_T(GetTop, const T&()); - - // Tests that the function return type can contain unprotected comma. - MOCK_METHOD0_T(ReturnTypeWithComma, std::map<int, int>()); - MOCK_CONST_METHOD1_T(ReturnTypeWithComma, std::map<int, int>(int)); // NOLINT - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockStack); -}; - -// Tests that template mock works. -TEST(TemplateMockTest, Works) { - MockStack<int> mock; - - EXPECT_CALL(mock, GetSize()) - .WillOnce(Return(0)) - .WillOnce(Return(1)) - .WillOnce(Return(0)); - EXPECT_CALL(mock, Push(_)); - int n = 5; - EXPECT_CALL(mock, GetTop()) - .WillOnce(ReturnRef(n)); - EXPECT_CALL(mock, Pop()) - .Times(AnyNumber()); - - EXPECT_EQ(0, mock.GetSize()); - mock.Push(5); - EXPECT_EQ(1, mock.GetSize()); - EXPECT_EQ(5, mock.GetTop()); - mock.Pop(); - EXPECT_EQ(0, mock.GetSize()); -} - -TEST(TemplateMockTest, MethodWithCommaInReturnTypeWorks) { - MockStack<int> mock; - - const std::map<int, int> a_map; - EXPECT_CALL(mock, ReturnTypeWithComma()) - .WillOnce(Return(a_map)); - EXPECT_CALL(mock, ReturnTypeWithComma(1)) - .WillOnce(Return(a_map)); - - EXPECT_EQ(a_map, mock.ReturnTypeWithComma()); - EXPECT_EQ(a_map, mock.ReturnTypeWithComma(1)); -} - -#if GTEST_OS_WINDOWS -// Tests mocking template interfaces with calltype. - -template <typename T> -class StackInterfaceWithCallType { - public: - virtual ~StackInterfaceWithCallType() {} - - // Template parameter appears in function parameter. - STDMETHOD_(void, Push)(const T& value) = 0; - STDMETHOD_(void, Pop)() = 0; - STDMETHOD_(int, GetSize)() const = 0; - // Template parameter appears in function return type. - STDMETHOD_(const T&, GetTop)() const = 0; -}; - -template <typename T> -class MockStackWithCallType : public StackInterfaceWithCallType<T> { - public: - MockStackWithCallType() {} - - MOCK_METHOD1_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Push, void(const T& elem)); - MOCK_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Pop, void()); - MOCK_CONST_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, GetSize, int()); - MOCK_CONST_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, GetTop, const T&()); - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockStackWithCallType); -}; - -// Tests that template mock with calltype works. -TEST(TemplateMockTestWithCallType, Works) { - MockStackWithCallType<int> mock; - - EXPECT_CALL(mock, GetSize()) - .WillOnce(Return(0)) - .WillOnce(Return(1)) - .WillOnce(Return(0)); - EXPECT_CALL(mock, Push(_)); - int n = 5; - EXPECT_CALL(mock, GetTop()) - .WillOnce(ReturnRef(n)); - EXPECT_CALL(mock, Pop()) - .Times(AnyNumber()); - - EXPECT_EQ(0, mock.GetSize()); - mock.Push(5); - EXPECT_EQ(1, mock.GetSize()); - EXPECT_EQ(5, mock.GetTop()); - mock.Pop(); - EXPECT_EQ(0, mock.GetSize()); -} -#endif // GTEST_OS_WINDOWS - -#define MY_MOCK_METHODS1_ \ - MOCK_METHOD0(Overloaded, void()); \ - MOCK_CONST_METHOD1(Overloaded, int(int n)); \ - MOCK_METHOD2(Overloaded, bool(bool f, int n)) - -class MockOverloadedOnArgNumber { - public: - MockOverloadedOnArgNumber() {} - - MY_MOCK_METHODS1_; - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockOverloadedOnArgNumber); -}; - -TEST(OverloadedMockMethodTest, CanOverloadOnArgNumberInMacroBody) { - MockOverloadedOnArgNumber mock; - EXPECT_CALL(mock, Overloaded()); - EXPECT_CALL(mock, Overloaded(1)).WillOnce(Return(2)); - EXPECT_CALL(mock, Overloaded(true, 1)).WillOnce(Return(true)); - - mock.Overloaded(); - EXPECT_EQ(2, mock.Overloaded(1)); - EXPECT_TRUE(mock.Overloaded(true, 1)); -} - -#define MY_MOCK_METHODS2_ \ - MOCK_CONST_METHOD1(Overloaded, int(int n)); \ - MOCK_METHOD1(Overloaded, int(int n)) - -class MockOverloadedOnConstness { - public: - MockOverloadedOnConstness() {} - - MY_MOCK_METHODS2_; - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockOverloadedOnConstness); -}; - -TEST(OverloadedMockMethodTest, CanOverloadOnConstnessInMacroBody) { - MockOverloadedOnConstness mock; - const MockOverloadedOnConstness* const_mock = &mock; - EXPECT_CALL(mock, Overloaded(1)).WillOnce(Return(2)); - EXPECT_CALL(*const_mock, Overloaded(1)).WillOnce(Return(3)); - - EXPECT_EQ(2, mock.Overloaded(1)); - EXPECT_EQ(3, const_mock->Overloaded(1)); -} - -TEST(MockFunctionTest, WorksForVoidNullary) { - MockFunction<void()> foo; - EXPECT_CALL(foo, Call()); - foo.Call(); -} - -TEST(MockFunctionTest, WorksForNonVoidNullary) { - MockFunction<int()> foo; - EXPECT_CALL(foo, Call()) - .WillOnce(Return(1)) - .WillOnce(Return(2)); - EXPECT_EQ(1, foo.Call()); - EXPECT_EQ(2, foo.Call()); -} - -TEST(MockFunctionTest, WorksForVoidUnary) { - MockFunction<void(int)> foo; - EXPECT_CALL(foo, Call(1)); - foo.Call(1); -} - -TEST(MockFunctionTest, WorksForNonVoidBinary) { - MockFunction<int(bool, int)> foo; - EXPECT_CALL(foo, Call(false, 42)) - .WillOnce(Return(1)) - .WillOnce(Return(2)); - EXPECT_CALL(foo, Call(true, Ge(100))) - .WillOnce(Return(3)); - EXPECT_EQ(1, foo.Call(false, 42)); - EXPECT_EQ(2, foo.Call(false, 42)); - EXPECT_EQ(3, foo.Call(true, 120)); -} - -TEST(MockFunctionTest, WorksFor10Arguments) { - MockFunction<int(bool a0, char a1, int a2, int a3, int a4, - int a5, int a6, char a7, int a8, bool a9)> foo; - EXPECT_CALL(foo, Call(_, 'a', _, _, _, _, _, _, _, _)) - .WillOnce(Return(1)) - .WillOnce(Return(2)); - EXPECT_EQ(1, foo.Call(false, 'a', 0, 0, 0, 0, 0, 'b', 0, true)); - EXPECT_EQ(2, foo.Call(true, 'a', 0, 0, 0, 0, 0, 'b', 1, false)); -} - -TEST(MockFunctionTest, AsStdFunction) { - MockFunction<int(int)> foo; - auto call = [](const std::function<int(int)> &f, int i) { - return f(i); - }; - EXPECT_CALL(foo, Call(1)).WillOnce(Return(-1)); - EXPECT_CALL(foo, Call(2)).WillOnce(Return(-2)); - EXPECT_EQ(-1, call(foo.AsStdFunction(), 1)); - EXPECT_EQ(-2, call(foo.AsStdFunction(), 2)); -} - -TEST(MockFunctionTest, AsStdFunctionReturnsReference) { - MockFunction<int&()> foo; - int value = 1; - EXPECT_CALL(foo, Call()).WillOnce(ReturnRef(value)); - int& ref = foo.AsStdFunction()(); - EXPECT_EQ(1, ref); - value = 2; - EXPECT_EQ(2, ref); -} - -TEST(MockFunctionTest, AsStdFunctionWithReferenceParameter) { - MockFunction<int(int &)> foo; - auto call = [](const std::function<int(int& )> &f, int &i) { - return f(i); - }; - int i = 42; - EXPECT_CALL(foo, Call(i)).WillOnce(Return(-1)); - EXPECT_EQ(-1, call(foo.AsStdFunction(), i)); -} - - -struct MockMethodSizes0 { - MOCK_METHOD0(func, void()); -}; -struct MockMethodSizes1 { - MOCK_METHOD1(func, void(int)); -}; -struct MockMethodSizes2 { - MOCK_METHOD2(func, void(int, int)); -}; -struct MockMethodSizes3 { - MOCK_METHOD3(func, void(int, int, int)); -}; -struct MockMethodSizes4 { - MOCK_METHOD4(func, void(int, int, int, int)); -}; - -TEST(MockFunctionTest, MockMethodSizeOverhead) { - EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes1)); - EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes2)); - EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes3)); - EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes4)); -} - -} // namespace gmock_generated_function_mockers_test -} // namespace testing diff --git a/googlemock/test/gmock-generated-matchers_test.cc b/googlemock/test/gmock-generated-matchers_test.cc index f3f49a68..26c41f68 100644 --- a/googlemock/test/gmock-generated-matchers_test.cc +++ b/googlemock/test/gmock-generated-matchers_test.cc @@ -39,7 +39,7 @@ # pragma warning(disable:4100) #endif -#include "gmock/gmock-generated-matchers.h" +#include "gmock/gmock-matchers.h" #include <array> #include <iterator> @@ -392,13 +392,6 @@ TEST(ElementsAreTest, AcceptsStringLiteral) { EXPECT_THAT(array, Not(ElementsAre("hi", "one", "too"))); } -#ifndef _MSC_VER - -// The following test passes a value of type const char[] to a -// function template that expects const T&. Some versions of MSVC -// generates a compiler error C2665 for that. We believe it's a bug -// in MSVC. Therefore this test is #if-ed out for MSVC. - // Declared here with the size unknown. Defined AFTER the following test. extern const char kHi[]; @@ -415,8 +408,6 @@ TEST(ElementsAreTest, AcceptsArrayWithUnknownSize) { const char kHi[] = "hi"; -#endif // _MSC_VER - TEST(ElementsAreTest, MakesCopyOfArguments) { int x = 1; int y = 2; @@ -773,9 +764,16 @@ MATCHER_P2(ReferencesAnyOf, variable1, variable2, "") { TEST(MatcherPnMacroTest, WorksWhenExplicitlyInstantiatedWithReferences) { UncopyableFoo foo1('1'), foo2('2'), foo3('3'); - const Matcher<const UncopyableFoo&> m = + const Matcher<const UncopyableFoo&> const_m = ReferencesAnyOf<const UncopyableFoo&, const UncopyableFoo&>(foo1, foo2); + EXPECT_TRUE(const_m.Matches(foo1)); + EXPECT_TRUE(const_m.Matches(foo2)); + EXPECT_FALSE(const_m.Matches(foo3)); + + const Matcher<UncopyableFoo&> m = + ReferencesAnyOf<UncopyableFoo&, UncopyableFoo&>(foo1, foo2); + EXPECT_TRUE(m.Matches(foo1)); EXPECT_TRUE(m.Matches(foo2)); EXPECT_FALSE(m.Matches(foo3)); diff --git a/googlemock/test/gmock-internal-utils_test.cc b/googlemock/test/gmock-internal-utils_test.cc index 19ba6fe5..8019f4a3 100644 --- a/googlemock/test/gmock-internal-utils_test.cc +++ b/googlemock/test/gmock-internal-utils_test.cc @@ -36,6 +36,7 @@ #include <stdlib.h> +#include <cstdint> #include <map> #include <memory> #include <sstream> @@ -172,9 +173,9 @@ TEST(KindOfTest, Integer) { EXPECT_EQ(kInteger, GMOCK_KIND_OF_(unsigned int)); // NOLINT EXPECT_EQ(kInteger, GMOCK_KIND_OF_(long)); // NOLINT EXPECT_EQ(kInteger, GMOCK_KIND_OF_(unsigned long)); // NOLINT + EXPECT_EQ(kInteger, GMOCK_KIND_OF_(long long)); // NOLINT + EXPECT_EQ(kInteger, GMOCK_KIND_OF_(unsigned long long)); // NOLINT EXPECT_EQ(kInteger, GMOCK_KIND_OF_(wchar_t)); // NOLINT - EXPECT_EQ(kInteger, GMOCK_KIND_OF_(Int64)); // NOLINT - EXPECT_EQ(kInteger, GMOCK_KIND_OF_(UInt64)); // NOLINT EXPECT_EQ(kInteger, GMOCK_KIND_OF_(size_t)); // NOLINT #if GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN // ssize_t is not defined on Windows and possibly some other OSes. @@ -222,11 +223,12 @@ TEST(LosslessArithmeticConvertibleTest, IntegerToInteger) { EXPECT_TRUE((LosslessArithmeticConvertible<unsigned char, int>::value)); // Unsigned => larger unsigned is fine. - EXPECT_TRUE( - (LosslessArithmeticConvertible<unsigned short, UInt64>::value)); // NOLINT + EXPECT_TRUE((LosslessArithmeticConvertible< + unsigned short, uint64_t>::value)); // NOLINT // Signed => unsigned is not fine. - EXPECT_FALSE((LosslessArithmeticConvertible<short, UInt64>::value)); // NOLINT + EXPECT_FALSE((LosslessArithmeticConvertible< + short, uint64_t>::value)); // NOLINT EXPECT_FALSE((LosslessArithmeticConvertible< signed char, unsigned int>::value)); // NOLINT @@ -242,12 +244,12 @@ TEST(LosslessArithmeticConvertibleTest, IntegerToInteger) { EXPECT_FALSE((LosslessArithmeticConvertible< unsigned char, signed char>::value)); EXPECT_FALSE((LosslessArithmeticConvertible<int, unsigned int>::value)); - EXPECT_FALSE((LosslessArithmeticConvertible<UInt64, Int64>::value)); + EXPECT_FALSE((LosslessArithmeticConvertible<uint64_t, int64_t>::value)); // Larger size => smaller size is not fine. EXPECT_FALSE((LosslessArithmeticConvertible<long, char>::value)); // NOLINT EXPECT_FALSE((LosslessArithmeticConvertible<int, signed char>::value)); - EXPECT_FALSE((LosslessArithmeticConvertible<Int64, unsigned int>::value)); + EXPECT_FALSE((LosslessArithmeticConvertible<int64_t, unsigned int>::value)); } TEST(LosslessArithmeticConvertibleTest, IntegerToFloatingPoint) { @@ -266,7 +268,7 @@ TEST(LosslessArithmeticConvertibleTest, FloatingPointToBool) { TEST(LosslessArithmeticConvertibleTest, FloatingPointToInteger) { EXPECT_FALSE((LosslessArithmeticConvertible<float, long>::value)); // NOLINT - EXPECT_FALSE((LosslessArithmeticConvertible<double, Int64>::value)); + EXPECT_FALSE((LosslessArithmeticConvertible<double, int64_t>::value)); EXPECT_FALSE((LosslessArithmeticConvertible<long double, int>::value)); } diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc index bc49cb62..186d8aae 100644 --- a/googlemock/test/gmock-matchers_test.cc +++ b/googlemock/test/gmock-matchers_test.cc @@ -46,6 +46,7 @@ #include <time.h> #include <array> +#include <cstdint> #include <deque> #include <forward_list> #include <functional> @@ -139,7 +140,7 @@ Matcher<int> GreaterThan(int n) { std::string OfType(const std::string& type_name) { #if GTEST_HAS_RTTI - return " (of type " + type_name + ")"; + return IsReadableTypeName(type_name) ? " (of type " + type_name + ")" : ""; #else return ""; #endif @@ -350,43 +351,43 @@ TEST(StringMatcherTest, CanBeImplicitlyConstructedFromString) { EXPECT_FALSE(m2.Matches("hello")); } -#if GTEST_HAS_ABSL +#if GTEST_INTERNAL_HAS_STRING_VIEW // Tests that a C-string literal can be implicitly converted to a -// Matcher<absl::string_view> or Matcher<const absl::string_view&>. +// Matcher<StringView> or Matcher<const StringView&>. TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) { - Matcher<absl::string_view> m1 = "cats"; + Matcher<internal::StringView> m1 = "cats"; EXPECT_TRUE(m1.Matches("cats")); EXPECT_FALSE(m1.Matches("dogs")); - Matcher<const absl::string_view&> m2 = "cats"; + Matcher<const internal::StringView&> m2 = "cats"; EXPECT_TRUE(m2.Matches("cats")); EXPECT_FALSE(m2.Matches("dogs")); } // Tests that a std::string object can be implicitly converted to a -// Matcher<absl::string_view> or Matcher<const absl::string_view&>. +// Matcher<StringView> or Matcher<const StringView&>. TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromString) { - Matcher<absl::string_view> m1 = std::string("cats"); + Matcher<internal::StringView> m1 = std::string("cats"); EXPECT_TRUE(m1.Matches("cats")); EXPECT_FALSE(m1.Matches("dogs")); - Matcher<const absl::string_view&> m2 = std::string("cats"); + Matcher<const internal::StringView&> m2 = std::string("cats"); EXPECT_TRUE(m2.Matches("cats")); EXPECT_FALSE(m2.Matches("dogs")); } -// Tests that a absl::string_view object can be implicitly converted to a -// Matcher<absl::string_view> or Matcher<const absl::string_view&>. +// Tests that a StringView object can be implicitly converted to a +// Matcher<StringView> or Matcher<const StringView&>. TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromStringView) { - Matcher<absl::string_view> m1 = absl::string_view("cats"); + Matcher<internal::StringView> m1 = internal::StringView("cats"); EXPECT_TRUE(m1.Matches("cats")); EXPECT_FALSE(m1.Matches("dogs")); - Matcher<const absl::string_view&> m2 = absl::string_view("cats"); + Matcher<const internal::StringView&> m2 = internal::StringView("cats"); EXPECT_TRUE(m2.Matches("cats")); EXPECT_FALSE(m2.Matches("dogs")); } -#endif // GTEST_HAS_ABSL +#endif // GTEST_INTERNAL_HAS_STRING_VIEW // Tests that a std::reference_wrapper<std::string> object can be implicitly // converted to a Matcher<std::string> or Matcher<const std::string&> via Eq(). @@ -764,10 +765,11 @@ TEST(SafeMatcherCastTest, FromConstReferenceToReference) { // Tests that MatcherCast<const T&>(m) works when m is a Matcher<T>. TEST(SafeMatcherCastTest, FromNonReferenceToConstReference) { - Matcher<int> m1 = Eq(0); - Matcher<const int&> m2 = SafeMatcherCast<const int&>(m1); - EXPECT_TRUE(m2.Matches(0)); - EXPECT_FALSE(m2.Matches(1)); + Matcher<std::unique_ptr<int>> m1 = IsNull(); + Matcher<const std::unique_ptr<int>&> m2 = + SafeMatcherCast<const std::unique_ptr<int>&>(m1); + EXPECT_TRUE(m2.Matches(std::unique_ptr<int>())); + EXPECT_FALSE(m2.Matches(std::unique_ptr<int>(new int))); } // Tests that SafeMatcherCast<T&>(m) works when m is a Matcher<T>. @@ -1234,17 +1236,17 @@ TEST(StrEqTest, MatchesEqualString) { EXPECT_TRUE(m2.Matches("Hello")); EXPECT_FALSE(m2.Matches("Hi")); -#if GTEST_HAS_ABSL - Matcher<const absl::string_view&> m3 = StrEq("Hello"); - EXPECT_TRUE(m3.Matches(absl::string_view("Hello"))); - EXPECT_FALSE(m3.Matches(absl::string_view("hello"))); - EXPECT_FALSE(m3.Matches(absl::string_view())); +#if GTEST_INTERNAL_HAS_STRING_VIEW + Matcher<const internal::StringView&> m3 = StrEq("Hello"); + EXPECT_TRUE(m3.Matches(internal::StringView("Hello"))); + EXPECT_FALSE(m3.Matches(internal::StringView("hello"))); + EXPECT_FALSE(m3.Matches(internal::StringView())); - Matcher<const absl::string_view&> m_empty = StrEq(""); - EXPECT_TRUE(m_empty.Matches(absl::string_view(""))); - EXPECT_TRUE(m_empty.Matches(absl::string_view())); - EXPECT_FALSE(m_empty.Matches(absl::string_view("hello"))); -#endif // GTEST_HAS_ABSL + Matcher<const internal::StringView&> m_empty = StrEq(""); + EXPECT_TRUE(m_empty.Matches(internal::StringView(""))); + EXPECT_TRUE(m_empty.Matches(internal::StringView())); + EXPECT_FALSE(m_empty.Matches(internal::StringView("hello"))); +#endif // GTEST_INTERNAL_HAS_STRING_VIEW } TEST(StrEqTest, CanDescribeSelf) { @@ -1271,12 +1273,12 @@ TEST(StrNeTest, MatchesUnequalString) { EXPECT_TRUE(m2.Matches("hello")); EXPECT_FALSE(m2.Matches("Hello")); -#if GTEST_HAS_ABSL - Matcher<const absl::string_view> m3 = StrNe("Hello"); - EXPECT_TRUE(m3.Matches(absl::string_view(""))); - EXPECT_TRUE(m3.Matches(absl::string_view())); - EXPECT_FALSE(m3.Matches(absl::string_view("Hello"))); -#endif // GTEST_HAS_ABSL +#if GTEST_INTERNAL_HAS_STRING_VIEW + Matcher<const internal::StringView> m3 = StrNe("Hello"); + EXPECT_TRUE(m3.Matches(internal::StringView(""))); + EXPECT_TRUE(m3.Matches(internal::StringView())); + EXPECT_FALSE(m3.Matches(internal::StringView("Hello"))); +#endif // GTEST_INTERNAL_HAS_STRING_VIEW } TEST(StrNeTest, CanDescribeSelf) { @@ -1295,13 +1297,13 @@ TEST(StrCaseEqTest, MatchesEqualStringIgnoringCase) { EXPECT_TRUE(m2.Matches("hello")); EXPECT_FALSE(m2.Matches("Hi")); -#if GTEST_HAS_ABSL - Matcher<const absl::string_view&> m3 = StrCaseEq(std::string("Hello")); - EXPECT_TRUE(m3.Matches(absl::string_view("Hello"))); - EXPECT_TRUE(m3.Matches(absl::string_view("hello"))); - EXPECT_FALSE(m3.Matches(absl::string_view("Hi"))); - EXPECT_FALSE(m3.Matches(absl::string_view())); -#endif // GTEST_HAS_ABSL +#if GTEST_INTERNAL_HAS_STRING_VIEW + Matcher<const internal::StringView&> m3 = StrCaseEq(std::string("Hello")); + EXPECT_TRUE(m3.Matches(internal::StringView("Hello"))); + EXPECT_TRUE(m3.Matches(internal::StringView("hello"))); + EXPECT_FALSE(m3.Matches(internal::StringView("Hi"))); + EXPECT_FALSE(m3.Matches(internal::StringView())); +#endif // GTEST_INTERNAL_HAS_STRING_VIEW } TEST(StrCaseEqTest, MatchesEqualStringWith0IgnoringCase) { @@ -1345,13 +1347,13 @@ TEST(StrCaseNeTest, MatchesUnequalStringIgnoringCase) { EXPECT_TRUE(m2.Matches("")); EXPECT_FALSE(m2.Matches("Hello")); -#if GTEST_HAS_ABSL - Matcher<const absl::string_view> m3 = StrCaseNe("Hello"); - EXPECT_TRUE(m3.Matches(absl::string_view("Hi"))); - EXPECT_TRUE(m3.Matches(absl::string_view())); - EXPECT_FALSE(m3.Matches(absl::string_view("Hello"))); - EXPECT_FALSE(m3.Matches(absl::string_view("hello"))); -#endif // GTEST_HAS_ABSL +#if GTEST_INTERNAL_HAS_STRING_VIEW + Matcher<const internal::StringView> m3 = StrCaseNe("Hello"); + EXPECT_TRUE(m3.Matches(internal::StringView("Hi"))); + EXPECT_TRUE(m3.Matches(internal::StringView())); + EXPECT_FALSE(m3.Matches(internal::StringView("Hello"))); + EXPECT_FALSE(m3.Matches(internal::StringView("hello"))); +#endif // GTEST_INTERNAL_HAS_STRING_VIEW } TEST(StrCaseNeTest, CanDescribeSelf) { @@ -1392,25 +1394,25 @@ TEST(HasSubstrTest, WorksForCStrings) { EXPECT_FALSE(m_empty.Matches(nullptr)); } -#if GTEST_HAS_ABSL -// Tests that HasSubstr() works for matching absl::string_view-typed values. +#if GTEST_INTERNAL_HAS_STRING_VIEW +// Tests that HasSubstr() works for matching StringView-typed values. TEST(HasSubstrTest, WorksForStringViewClasses) { - const Matcher<absl::string_view> m1 = HasSubstr("foo"); - EXPECT_TRUE(m1.Matches(absl::string_view("I love food."))); - EXPECT_FALSE(m1.Matches(absl::string_view("tofo"))); - EXPECT_FALSE(m1.Matches(absl::string_view())); + const Matcher<internal::StringView> m1 = HasSubstr("foo"); + EXPECT_TRUE(m1.Matches(internal::StringView("I love food."))); + EXPECT_FALSE(m1.Matches(internal::StringView("tofo"))); + EXPECT_FALSE(m1.Matches(internal::StringView())); - const Matcher<const absl::string_view&> m2 = HasSubstr("foo"); - EXPECT_TRUE(m2.Matches(absl::string_view("I love food."))); - EXPECT_FALSE(m2.Matches(absl::string_view("tofo"))); - EXPECT_FALSE(m2.Matches(absl::string_view())); + const Matcher<const internal::StringView&> m2 = HasSubstr("foo"); + EXPECT_TRUE(m2.Matches(internal::StringView("I love food."))); + EXPECT_FALSE(m2.Matches(internal::StringView("tofo"))); + EXPECT_FALSE(m2.Matches(internal::StringView())); - const Matcher<const absl::string_view&> m3 = HasSubstr(""); - EXPECT_TRUE(m3.Matches(absl::string_view("foo"))); - EXPECT_TRUE(m3.Matches(absl::string_view(""))); - EXPECT_TRUE(m3.Matches(absl::string_view())); + const Matcher<const internal::StringView&> m3 = HasSubstr(""); + EXPECT_TRUE(m3.Matches(internal::StringView("foo"))); + EXPECT_TRUE(m3.Matches(internal::StringView(""))); + EXPECT_TRUE(m3.Matches(internal::StringView())); } -#endif // GTEST_HAS_ABSL +#endif // GTEST_INTERNAL_HAS_STRING_VIEW // Tests that HasSubstr(s) describes itself properly. TEST(HasSubstrTest, CanDescribeSelf) { @@ -1647,12 +1649,12 @@ TEST(StartsWithTest, MatchesStringWithGivenPrefix) { EXPECT_FALSE(m2.Matches("H")); EXPECT_FALSE(m2.Matches(" Hi")); -#if GTEST_HAS_ABSL - const Matcher<absl::string_view> m_empty = StartsWith(""); - EXPECT_TRUE(m_empty.Matches(absl::string_view())); - EXPECT_TRUE(m_empty.Matches(absl::string_view(""))); - EXPECT_TRUE(m_empty.Matches(absl::string_view("not empty"))); -#endif // GTEST_HAS_ABSL +#if GTEST_INTERNAL_HAS_STRING_VIEW + const Matcher<internal::StringView> m_empty = StartsWith(""); + EXPECT_TRUE(m_empty.Matches(internal::StringView())); + EXPECT_TRUE(m_empty.Matches(internal::StringView(""))); + EXPECT_TRUE(m_empty.Matches(internal::StringView("not empty"))); +#endif // GTEST_INTERNAL_HAS_STRING_VIEW } TEST(StartsWithTest, CanDescribeSelf) { @@ -1675,13 +1677,13 @@ TEST(EndsWithTest, MatchesStringWithGivenSuffix) { EXPECT_FALSE(m2.Matches("i")); EXPECT_FALSE(m2.Matches("Hi ")); -#if GTEST_HAS_ABSL - const Matcher<const absl::string_view&> m4 = EndsWith(""); +#if GTEST_INTERNAL_HAS_STRING_VIEW + const Matcher<const internal::StringView&> m4 = EndsWith(""); EXPECT_TRUE(m4.Matches("Hi")); EXPECT_TRUE(m4.Matches("")); - EXPECT_TRUE(m4.Matches(absl::string_view())); - EXPECT_TRUE(m4.Matches(absl::string_view(""))); -#endif // GTEST_HAS_ABSL + EXPECT_TRUE(m4.Matches(internal::StringView())); + EXPECT_TRUE(m4.Matches(internal::StringView(""))); +#endif // GTEST_INTERNAL_HAS_STRING_VIEW } TEST(EndsWithTest, CanDescribeSelf) { @@ -1702,16 +1704,16 @@ TEST(MatchesRegexTest, MatchesStringMatchingGivenRegex) { EXPECT_FALSE(m2.Matches("az1")); EXPECT_FALSE(m2.Matches("1az")); -#if GTEST_HAS_ABSL - const Matcher<const absl::string_view&> m3 = MatchesRegex("a.*z"); - EXPECT_TRUE(m3.Matches(absl::string_view("az"))); - EXPECT_TRUE(m3.Matches(absl::string_view("abcz"))); - EXPECT_FALSE(m3.Matches(absl::string_view("1az"))); - EXPECT_FALSE(m3.Matches(absl::string_view())); - const Matcher<const absl::string_view&> m4 = MatchesRegex(""); - EXPECT_TRUE(m4.Matches(absl::string_view(""))); - EXPECT_TRUE(m4.Matches(absl::string_view())); -#endif // GTEST_HAS_ABSL +#if GTEST_INTERNAL_HAS_STRING_VIEW + const Matcher<const internal::StringView&> m3 = MatchesRegex("a.*z"); + EXPECT_TRUE(m3.Matches(internal::StringView("az"))); + EXPECT_TRUE(m3.Matches(internal::StringView("abcz"))); + EXPECT_FALSE(m3.Matches(internal::StringView("1az"))); + EXPECT_FALSE(m3.Matches(internal::StringView())); + const Matcher<const internal::StringView&> m4 = MatchesRegex(""); + EXPECT_TRUE(m4.Matches(internal::StringView(""))); + EXPECT_TRUE(m4.Matches(internal::StringView())); +#endif // GTEST_INTERNAL_HAS_STRING_VIEW } TEST(MatchesRegexTest, CanDescribeSelf) { @@ -1721,10 +1723,10 @@ TEST(MatchesRegexTest, CanDescribeSelf) { Matcher<const char*> m2 = MatchesRegex(new RE("a.*")); EXPECT_EQ("matches regular expression \"a.*\"", Describe(m2)); -#if GTEST_HAS_ABSL - Matcher<const absl::string_view> m3 = MatchesRegex(new RE("0.*")); +#if GTEST_INTERNAL_HAS_STRING_VIEW + Matcher<const internal::StringView> m3 = MatchesRegex(new RE("0.*")); EXPECT_EQ("matches regular expression \"0.*\"", Describe(m3)); -#endif // GTEST_HAS_ABSL +#endif // GTEST_INTERNAL_HAS_STRING_VIEW } // Tests ContainsRegex(). @@ -1740,16 +1742,17 @@ TEST(ContainsRegexTest, MatchesStringContainingGivenRegex) { EXPECT_TRUE(m2.Matches("az1")); EXPECT_FALSE(m2.Matches("1a")); -#if GTEST_HAS_ABSL - const Matcher<const absl::string_view&> m3 = ContainsRegex(new RE("a.*z")); - EXPECT_TRUE(m3.Matches(absl::string_view("azbz"))); - EXPECT_TRUE(m3.Matches(absl::string_view("az1"))); - EXPECT_FALSE(m3.Matches(absl::string_view("1a"))); - EXPECT_FALSE(m3.Matches(absl::string_view())); - const Matcher<const absl::string_view&> m4 = ContainsRegex(""); - EXPECT_TRUE(m4.Matches(absl::string_view(""))); - EXPECT_TRUE(m4.Matches(absl::string_view())); -#endif // GTEST_HAS_ABSL +#if GTEST_INTERNAL_HAS_STRING_VIEW + const Matcher<const internal::StringView&> m3 = + ContainsRegex(new RE("a.*z")); + EXPECT_TRUE(m3.Matches(internal::StringView("azbz"))); + EXPECT_TRUE(m3.Matches(internal::StringView("az1"))); + EXPECT_FALSE(m3.Matches(internal::StringView("1a"))); + EXPECT_FALSE(m3.Matches(internal::StringView())); + const Matcher<const internal::StringView&> m4 = ContainsRegex(""); + EXPECT_TRUE(m4.Matches(internal::StringView(""))); + EXPECT_TRUE(m4.Matches(internal::StringView())); +#endif // GTEST_INTERNAL_HAS_STRING_VIEW } TEST(ContainsRegexTest, CanDescribeSelf) { @@ -1759,10 +1762,10 @@ TEST(ContainsRegexTest, CanDescribeSelf) { Matcher<const char*> m2 = ContainsRegex(new RE("a.*")); EXPECT_EQ("contains regular expression \"a.*\"", Describe(m2)); -#if GTEST_HAS_ABSL - Matcher<const absl::string_view> m3 = ContainsRegex(new RE("0.*")); +#if GTEST_INTERNAL_HAS_STRING_VIEW + Matcher<const internal::StringView> m3 = ContainsRegex(new RE("0.*")); EXPECT_EQ("contains regular expression \"0.*\"", Describe(m3)); -#endif // GTEST_HAS_ABSL +#endif // GTEST_INTERNAL_HAS_STRING_VIEW } // Tests for wide strings. @@ -2874,6 +2877,33 @@ TEST(ExplainMatchResultTest, WorksWithMonomorphicMatcher) { EXPECT_EQ("", listener2.str()); } +MATCHER(ConstructNoArg, "") { return true; } +MATCHER_P(Construct1Arg, arg1, "") { return true; } +MATCHER_P2(Construct2Args, arg1, arg2, "") { return true; } + +TEST(MatcherConstruct, ExplicitVsImplicit) { + { + // No arg constructor can be constructed with empty brace. + ConstructNoArgMatcher m = {}; + (void)m; + // And with no args + ConstructNoArgMatcher m2; + (void)m2; + } + { + // The one arg constructor has an explicit constructor. + // This is to prevent the implicit conversion. + using M = Construct1ArgMatcherP<int>; + EXPECT_TRUE((std::is_constructible<M, int>::value)); + EXPECT_FALSE((std::is_convertible<int, M>::value)); + } + { + // Multiple arg matchers can be constructed with an implicit construction. + Construct2ArgsMatcherP2<int, double> m = {1, 2.2}; + (void)m; + } +} + MATCHER_P(Really, inner_matcher, "") { return ExplainMatchResult(inner_matcher, arg, result_listener); } @@ -2987,18 +3017,13 @@ TEST(MatcherAssertionTest, WorksWhenMatcherIsNotSatisfied) { static unsigned short n; // NOLINT n = 5; - // VC++ prior to version 8.0 SP1 has a bug where it will not see any - // functions declared in the namespace scope from within nested classes. - // EXPECT/ASSERT_(NON)FATAL_FAILURE macros use nested classes so that all - // namespace-level functions invoked inside them need to be explicitly - // resolved. - EXPECT_FATAL_FAILURE(ASSERT_THAT(n, ::testing::Gt(10)), + EXPECT_FATAL_FAILURE(ASSERT_THAT(n, Gt(10)), "Value of: n\n" "Expected: is > 10\n" " Actual: 5" + OfType("unsigned short")); n = 0; EXPECT_NONFATAL_FAILURE( - EXPECT_THAT(n, ::testing::AllOf(::testing::Le(7), ::testing::Ge(5))), + EXPECT_THAT(n, AllOf(Le(7), Ge(5))), "Value of: n\n" "Expected: (is <= 7) and (is >= 5)\n" " Actual: 0" + OfType("unsigned short")); @@ -3012,11 +3037,11 @@ TEST(MatcherAssertionTest, WorksForByRefArguments) { static int n; n = 0; EXPECT_THAT(n, AllOf(Le(7), Ref(n))); - EXPECT_FATAL_FAILURE(ASSERT_THAT(n, ::testing::Not(::testing::Ref(n))), + EXPECT_FATAL_FAILURE(ASSERT_THAT(n, Not(Ref(n))), "Value of: n\n" "Expected: does not reference the variable @"); // Tests the "Actual" part. - EXPECT_FATAL_FAILURE(ASSERT_THAT(n, ::testing::Not(::testing::Ref(n))), + EXPECT_FATAL_FAILURE(ASSERT_THAT(n, Not(Ref(n))), "Actual: 0" + OfType("int") + ", which is located @"); } @@ -4701,20 +4726,18 @@ TEST(SizeIsTest, ExplainsResult) { Matcher<vector<int> > m1 = SizeIs(2); Matcher<vector<int> > m2 = SizeIs(Lt(2u)); Matcher<vector<int> > m3 = SizeIs(AnyOf(0, 3)); - Matcher<vector<int> > m4 = SizeIs(GreaterThan(1)); + Matcher<vector<int> > m4 = SizeIs(Gt(1u)); vector<int> container; EXPECT_EQ("whose size 0 doesn't match", Explain(m1, container)); EXPECT_EQ("whose size 0 matches", Explain(m2, container)); EXPECT_EQ("whose size 0 matches", Explain(m3, container)); - EXPECT_EQ("whose size 0 doesn't match, which is 1 less than 1", - Explain(m4, container)); + EXPECT_EQ("whose size 0 doesn't match", Explain(m4, container)); container.push_back(0); container.push_back(0); EXPECT_EQ("whose size 2 matches", Explain(m1, container)); EXPECT_EQ("whose size 2 doesn't match", Explain(m2, container)); EXPECT_EQ("whose size 2 doesn't match", Explain(m3, container)); - EXPECT_EQ("whose size 2 matches, which is 1 more than 1", - Explain(m4, container)); + EXPECT_EQ("whose size 2 matches", Explain(m4, container)); } #if GTEST_HAS_TYPED_TEST @@ -6028,9 +6051,9 @@ TEST_P(BipartiteRandomTest, LargerNets) { int iters = GetParam().second; MatchMatrix graph(static_cast<size_t>(nodes), static_cast<size_t>(nodes)); - auto seed = static_cast<testing::internal::UInt32>(GTEST_FLAG(random_seed)); + auto seed = static_cast<uint32_t>(GTEST_FLAG(random_seed)); if (seed == 0) { - seed = static_cast<testing::internal::UInt32>(time(nullptr)); + seed = static_cast<uint32_t>(time(nullptr)); } for (; iters > 0; --iters, ++seed) { @@ -6889,7 +6912,8 @@ TEST_F(PredicateFormatterFromMatcherTest, NoShortCircuitOnFailure) { EXPECT_FALSE(result); // Implicit cast to bool. std::string expect = "Value of: dummy-name\nExpected: [DescribeTo]\n" - " Actual: 1, [MatchAndExplain]"; + " Actual: 1" + + OfType(internal::GetTypeName<Behavior>()) + ", [MatchAndExplain]"; EXPECT_EQ(expect, result.message()); } @@ -6900,7 +6924,8 @@ TEST_F(PredicateFormatterFromMatcherTest, DetectsFlakyShortCircuit) { "Value of: dummy-name\nExpected: [DescribeTo]\n" " The matcher failed on the initial attempt; but passed when rerun to " "generate the explanation.\n" - " Actual: 2, [MatchAndExplain]"; + " Actual: 2" + + OfType(internal::GetTypeName<Behavior>()) + ", [MatchAndExplain]"; EXPECT_EQ(expect, result.message()); } diff --git a/googlemock/test/gmock_all_test.cc b/googlemock/test/gmock_all_test.cc index b2b2027d..c53d0965 100644 --- a/googlemock/test/gmock_all_test.cc +++ b/googlemock/test/gmock_all_test.cc @@ -38,7 +38,6 @@ #include "test/gmock-actions_test.cc" #include "test/gmock-cardinalities_test.cc" #include "test/gmock-generated-actions_test.cc" -#include "test/gmock-generated-function-mockers_test.cc" #include "test/gmock-generated-matchers_test.cc" #include "test/gmock-internal-utils_test.cc" #include "test/gmock-matchers_test.cc" diff --git a/googletest/README.md b/googletest/README.md index 904048f4..8520549c 100644 --- a/googletest/README.md +++ b/googletest/README.md @@ -189,9 +189,9 @@ or When Google Test uses pthread, you may need to add flags to your compiler and/or linker to select the pthread library, or you'll get link errors. If you use the -CMake script or the deprecated Autotools script, this is taken care of for you. -If you use your own build script, you'll need to read your compiler and linker's -manual to figure out what flags to add. +CMake script, this is taken care of for you. If you use your own build script, +you'll need to read your compiler and linker's manual to figure out what flags +to add. ### As a Shared Library (DLL) diff --git a/googletest/cmake/gtest.pc.in b/googletest/cmake/gtest.pc.in index e7967ad5..b4148fae 100644 --- a/googletest/cmake/gtest.pc.in +++ b/googletest/cmake/gtest.pc.in @@ -6,4 +6,4 @@ Description: GoogleTest (without main() function) Version: @PROJECT_VERSION@ URL: https://github.com/google/googletest Libs: -L${libdir} -lgtest @CMAKE_THREAD_LIBS_INIT@ -Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ @CMAKE_THREAD_LIBS_INIT@ +Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ diff --git a/googletest/cmake/gtest_main.pc.in b/googletest/cmake/gtest_main.pc.in index fe25d9c7..1e01bd19 100644 --- a/googletest/cmake/gtest_main.pc.in +++ b/googletest/cmake/gtest_main.pc.in @@ -7,4 +7,4 @@ Version: @PROJECT_VERSION@ URL: https://github.com/google/googletest Requires: gtest Libs: -L${libdir} -lgtest_main @CMAKE_THREAD_LIBS_INIT@ -Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ @CMAKE_THREAD_LIBS_INIT@ +Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ diff --git a/googletest/docs/advanced.md b/googletest/docs/advanced.md index 217d527a..d65f1eff 100644 --- a/googletest/docs/advanced.md +++ b/googletest/docs/advanced.md @@ -106,7 +106,7 @@ assertion* to get the function arguments printed for free: | Fatal assertion | Nonfatal assertion | Verifies | | --------------------------------- | --------------------------------- | --------------------------- | | `ASSERT_PRED1(pred1, val1)` | `EXPECT_PRED1(pred1, val1)` | `pred1(val1)` is true | -| `ASSERT_PRED2(pred2, val1, val2)` | `EXPECT_PRED2(pred2, val1, val2)` | `pred1(val1, val2)` is true | +| `ASSERT_PRED2(pred2, val1, val2)` | `EXPECT_PRED2(pred2, val1, val2)` | `pred2(val1, val2)` is true | | `...` | `...` | `...` | <!-- mdformat on--> @@ -638,6 +638,7 @@ Fatal assertion | Nonfatal assertion ------------------------------------------------ | ------------------------------------------------ | -------- `ASSERT_DEATH(statement, matcher);` | `EXPECT_DEATH(statement, matcher);` | `statement` crashes with the given error `ASSERT_DEATH_IF_SUPPORTED(statement, matcher);` | `EXPECT_DEATH_IF_SUPPORTED(statement, matcher);` | if death tests are supported, verifies that `statement` crashes with the given error; otherwise verifies nothing +`ASSERT_DEBUG_DEATH(statement, matcher);` | `EXPECT_DEBUG_DEATH(statement, matcher);` | `statement` crashes with the given error **in debug mode**. When not in debug (i.e. `NDEBUG` is defined), this just executes `statement` `ASSERT_EXIT(statement, predicate, matcher);` | `EXPECT_EXIT(statement, predicate, matcher);` | `statement` exits with the given error, and its exit code matches `predicate` where `statement` is a statement that is expected to cause the process to die, @@ -955,7 +956,7 @@ path/to/foo_test.cc:11: Failure Value of: Bar(n) Expected: 1 Actual: 2 - Trace: +Google Test trace: path/to/foo_test.cc:17: A path/to/foo_test.cc:12: Failure @@ -1231,7 +1232,7 @@ environment, which knows how to set-up and tear-down: ```c++ class Environment : public ::testing::Environment { public: - virtual ~Environment() {} + ~Environment() override {} // Override this to define how to set up the environment. void SetUp() override {} @@ -1377,6 +1378,17 @@ function scope. NOTE: Don't forget this step! If you do your test will silently pass, but none of its suites will ever run! +There is work in progress to make omitting `INSTANTIATE_TEST_SUITE_P` show up +under the `GoogleTestVerification` test suite and to then make that an error. +If you have a test suite where that omission is not an error, for example it is +in a library that may be linked in for other reason or where the list of test +cases is dynamic and may be empty, then this check can be suppressed by tagging +the test suite: + +```c++ +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FooTest); +``` + To distinguish different instances of the pattern (yes, you can instantiate it more than once), the first argument to `INSTANTIATE_TEST_SUITE_P` is a prefix that will be added to the actual test suite name. Remember to pick unique @@ -2104,6 +2116,15 @@ For example: everything in test suite `FooTest` except `FooTest.Bar` and everything in test suite `BarTest` except `BarTest.Foo`. +#### Stop test execution upon first failure + +By default, a googletest program runs all tests the user has defined. In some +cases (e.g. iterative test development & execution) it may be desirable stop +test execution upon first failure (trading improved latency for completeness). +If `GTEST_FAIL_FAST` environment variable or `--gtest_fail_fast` flag is set, +the test runner will stop execution as soon as the first test failure is +found. + #### Temporarily Disabling Tests If you have a broken test that you cannot fix right away, you can add the diff --git a/googletest/docs/pkgconfig.md b/googletest/docs/pkgconfig.md index 117166cf..b9bef3fd 100644 --- a/googletest/docs/pkgconfig.md +++ b/googletest/docs/pkgconfig.md @@ -45,77 +45,6 @@ splitting the pkg-config `Cflags` variable into include dirs and macros for goes for using `_LDFLAGS` over the more commonplace `_LIBRARIES`, which happens to discard `-L` flags and `-pthread`. -### Autotools - -Finding GoogleTest in Autoconf and using it from Automake is also fairly easy: - -In your `configure.ac`: - -``` -AC_PREREQ([2.69]) -AC_INIT([my_gtest_pkgconfig], [0.0.1]) -AC_CONFIG_SRCDIR([samples/sample3_unittest.cc]) -AC_PROG_CXX - -PKG_CHECK_MODULES([GTEST], [gtest_main]) - -AM_INIT_AUTOMAKE([foreign subdir-objects]) -AC_CONFIG_FILES([Makefile]) -AC_OUTPUT -``` - -and in your `Makefile.am`: - -``` -check_PROGRAMS = testapp -TESTS = $(check_PROGRAMS) - -testapp_SOURCES = samples/sample3_unittest.cc -testapp_CXXFLAGS = $(GTEST_CFLAGS) -testapp_LDADD = $(GTEST_LIBS) -``` - -### Meson - -Meson natively uses pkgconfig to query dependencies: - -``` -project('my_gtest_pkgconfig', 'cpp', version : '0.0.1') - -gtest_dep = dependency('gtest_main') - -testapp = executable( - 'testapp', - files(['samples/sample3_unittest.cc']), - dependencies : gtest_dep, - install : false) - -test('first_and_only_test', testapp) -``` - -### Plain Makefiles - -Since `pkg-config` is a small Unix command-line utility, it can be used in -handwritten `Makefile`s too: - -```makefile -GTEST_CFLAGS = `pkg-config --cflags gtest_main` -GTEST_LIBS = `pkg-config --libs gtest_main` - -.PHONY: tests all - -tests: all - ./testapp - -all: testapp - -testapp: testapp.o - $(CXX) $(CXXFLAGS) $(LDFLAGS) $< -o $@ $(GTEST_LIBS) - -testapp.o: samples/sample3_unittest.cc - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $< -c -o $@ $(GTEST_CFLAGS) -``` - ### Help! pkg-config can't find GoogleTest! Let's say you have a `CMakeLists.txt` along the lines of the one in this diff --git a/googletest/docs/primer.md b/googletest/docs/primer.md index 63f05168..f581d77a 100644 --- a/googletest/docs/primer.md +++ b/googletest/docs/primer.md @@ -261,7 +261,7 @@ TEST(TestSuiteName, TestName) { `TEST()` arguments go from general to specific. The *first* argument is the name of the test suite, and the *second* argument is the test's name within the test -case. Both names must be valid C++ identifiers, and they should not contain +suite. Both names must be valid C++ identifiers, and they should not contain any underscores (`_`). A test's *full name* consists of its containing test suite and its individual name. Tests from different test suites can have the same individual name. diff --git a/googletest/include/gtest/gtest-matchers.h b/googletest/include/gtest/gtest-matchers.h index d9b28e08..a61cef40 100644 --- a/googletest/include/gtest/gtest-matchers.h +++ b/googletest/include/gtest/gtest-matchers.h @@ -384,18 +384,18 @@ class GTEST_API_ Matcher<std::string> Matcher(const char* s); // NOLINT }; -#if GTEST_HAS_ABSL +#if GTEST_INTERNAL_HAS_STRING_VIEW // The following two specializations allow the user to write str // instead of Eq(str) and "foo" instead of Eq("foo") when a absl::string_view // matcher is expected. template <> -class GTEST_API_ Matcher<const absl::string_view&> - : public internal::MatcherBase<const absl::string_view&> { +class GTEST_API_ Matcher<const internal::StringView&> + : public internal::MatcherBase<const internal::StringView&> { public: Matcher() {} - explicit Matcher(const MatcherInterface<const absl::string_view&>* impl) - : internal::MatcherBase<const absl::string_view&>(impl) {} + explicit Matcher(const MatcherInterface<const internal::StringView&>* impl) + : internal::MatcherBase<const internal::StringView&>(impl) {} // Allows the user to write str instead of Eq(str) sometimes, where // str is a std::string object. @@ -404,20 +404,20 @@ class GTEST_API_ Matcher<const absl::string_view&> // Allows the user to write "foo" instead of Eq("foo") sometimes. Matcher(const char* s); // NOLINT - // Allows the user to pass absl::string_views directly. - Matcher(absl::string_view s); // NOLINT + // Allows the user to pass absl::string_views or std::string_views directly. + Matcher(internal::StringView s); // NOLINT }; template <> -class GTEST_API_ Matcher<absl::string_view> - : public internal::MatcherBase<absl::string_view> { +class GTEST_API_ Matcher<internal::StringView> + : public internal::MatcherBase<internal::StringView> { public: Matcher() {} - explicit Matcher(const MatcherInterface<const absl::string_view&>* impl) - : internal::MatcherBase<absl::string_view>(impl) {} - explicit Matcher(const MatcherInterface<absl::string_view>* impl) - : internal::MatcherBase<absl::string_view>(impl) {} + explicit Matcher(const MatcherInterface<const internal::StringView&>* impl) + : internal::MatcherBase<internal::StringView>(impl) {} + explicit Matcher(const MatcherInterface<internal::StringView>* impl) + : internal::MatcherBase<internal::StringView>(impl) {} // Allows the user to write str instead of Eq(str) sometimes, where // str is a std::string object. @@ -426,10 +426,10 @@ class GTEST_API_ Matcher<absl::string_view> // Allows the user to write "foo" instead of Eq("foo") sometimes. Matcher(const char* s); // NOLINT - // Allows the user to pass absl::string_views directly. - Matcher(absl::string_view s); // NOLINT + // Allows the user to pass absl::string_views or std::string_views directly. + Matcher(internal::StringView s); // NOLINT }; -#endif // GTEST_HAS_ABSL +#endif // GTEST_INTERNAL_HAS_STRING_VIEW // Prints a matcher in a human-readable format. template <typename T> @@ -620,12 +620,12 @@ class MatchesRegexMatcher { MatchesRegexMatcher(const RE* regex, bool full_match) : regex_(regex), full_match_(full_match) {} -#if GTEST_HAS_ABSL - bool MatchAndExplain(const absl::string_view& s, +#if GTEST_INTERNAL_HAS_STRING_VIEW + bool MatchAndExplain(const internal::StringView& s, MatchResultListener* listener) const { return MatchAndExplain(std::string(s), listener); } -#endif // GTEST_HAS_ABSL +#endif // GTEST_INTERNAL_HAS_STRING_VIEW // Accepts pointer types, particularly: // const char* diff --git a/googletest/include/gtest/gtest-param-test.h b/googletest/include/gtest/gtest-param-test.h index f61e3c5d..5b039df9 100644 --- a/googletest/include/gtest/gtest-param-test.h +++ b/googletest/include/gtest/gtest-param-test.h @@ -58,9 +58,7 @@ class FooTest : public ::testing::TestWithParam<const char*> { // Then, use the TEST_P macro to define as many parameterized tests // for this fixture as you want. The _P suffix is for "parameterized" -// or "pattern", whichever you prefer to think. The arguments to the -// TEST_P macro are the test_suite_name and test_case (both which must be -// non-empty) that will form the test name. +// or "pattern", whichever you prefer to think. TEST_P(FooTest, DoesBlah) { // Inside a test, access the test parameter with the GetParam() method @@ -103,10 +101,10 @@ INSTANTIATE_TEST_SUITE_P(InstantiationName, // To distinguish different instances of the pattern, (yes, you // can instantiate it more than once) the first argument to the -// INSTANTIATE_TEST_SUITE_P macro is a prefix (which must be non-empty) that -// will be added to the actual test suite name. Remember to pick unique prefixes -// for different instantiations. The tests from the instantiation above will -// have these names: +// INSTANTIATE_TEST_SUITE_P macro is a prefix that will be added to the +// actual test suite name. Remember to pick unique prefixes for different +// instantiations. The tests from the instantiation above will have +// these names: // // * InstantiationName/FooTest.DoesBlah/0 for "meeny" // * InstantiationName/FooTest.DoesBlah/1 for "miny" @@ -414,10 +412,6 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) { } #define TEST_P(test_suite_name, test_name) \ - static_assert(sizeof(GTEST_STRINGIFY_(test_suite_name)) > 1, \ - "test_suite_name must not be empty"); \ - static_assert(sizeof(GTEST_STRINGIFY_(test_name)) > 1, \ - "test_name must not be empty"); \ class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \ : public test_suite_name { \ public: \ @@ -464,10 +458,6 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) { #define GTEST_GET_SECOND_(first, second, ...) second #define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...) \ - static_assert(sizeof(GTEST_STRINGIFY_(test_suite_name)) > 1, \ - "test_suite_name must not be empty"); \ - static_assert(sizeof(GTEST_STRINGIFY_(prefix)) > 1, \ - "prefix must not be empty"); \ static ::testing::internal::ParamGenerator<test_suite_name::ParamType> \ gtest_##prefix##test_suite_name##_EvalGenerator_() { \ return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_)); \ @@ -501,6 +491,13 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) { >est_##prefix##test_suite_name##_EvalGenerateName_, \ __FILE__, __LINE__) + +// Allow Marking a Parameterized test class as not needing to be instantiated. +#define GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(T) \ + namespace gtest_do_not_use_outside_namespace_scope {} \ + static const ::testing::internal::MarkAsIgnored gtest_allow_ignore_##T( \ + GTEST_STRINGIFY_(T)) + // Legacy API is deprecated but still available #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ #define INSTANTIATE_TEST_CASE_P \ diff --git a/googletest/include/gtest/gtest-printers.h b/googletest/include/gtest/gtest-printers.h index 56a05450..75e4422a 100644 --- a/googletest/include/gtest/gtest-printers.h +++ b/googletest/include/gtest/gtest-printers.h @@ -119,53 +119,126 @@ namespace testing { -// Definitions in the 'internal' and 'internal2' name spaces are -// subject to change without notice. DO NOT USE THEM IN USER CODE! -namespace internal2 { +// Definitions in the internal* namespaces are subject to change without notice. +// DO NOT USE THEM IN USER CODE! +namespace internal { -// Prints the given number of bytes in the given object to the given -// ostream. -GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes, - size_t count, - ::std::ostream* os); +template <typename T> +void UniversalPrint(const T& value, ::std::ostream* os); -// For selecting which printer to use when a given type has neither << -// nor PrintTo(). -enum TypeKind { - kProtobuf, // a protobuf type - kConvertibleToInteger, // a type implicitly convertible to BiggestInt - // (e.g. a named or unnamed enum type) -#if GTEST_HAS_ABSL - kConvertibleToStringView, // a type implicitly convertible to - // absl::string_view -#endif - kOtherType // anything else +// Used to print an STL-style container when the user doesn't define +// a PrintTo() for it. +struct ContainerPrinter { + template <typename T, + typename = typename std::enable_if< + (sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) && + !IsRecursiveContainer<T>::value>::type> + static void PrintValue(const T& container, std::ostream* os) { + const size_t kMaxCount = 32; // The maximum number of elements to print. + *os << '{'; + size_t count = 0; + for (auto&& elem : container) { + if (count > 0) { + *os << ','; + if (count == kMaxCount) { // Enough has been printed. + *os << " ..."; + break; + } + } + *os << ' '; + // We cannot call PrintTo(elem, os) here as PrintTo() doesn't + // handle `elem` being a native array. + internal::UniversalPrint(elem, os); + ++count; + } + + if (count > 0) { + *os << ' '; + } + *os << '}'; + } }; -// TypeWithoutFormatter<T, kTypeKind>::PrintValue(value, os) is called -// by the universal printer to print a value of type T when neither -// operator<< nor PrintTo() is defined for T, where kTypeKind is the -// "kind" of T as defined by enum TypeKind. -template <typename T, TypeKind kTypeKind> -class TypeWithoutFormatter { - public: - // This default version is called when kTypeKind is kOtherType. - static void PrintValue(const T& value, ::std::ostream* os) { - PrintBytesInObjectTo( - static_cast<const unsigned char*>( - reinterpret_cast<const void*>(std::addressof(value))), - sizeof(value), os); +// Used to print a pointer that is neither a char pointer nor a member +// pointer, when the user doesn't define PrintTo() for it. (A member +// variable pointer or member function pointer doesn't really point to +// a location in the address space. Their representation is +// implementation-defined. Therefore they will be printed as raw +// bytes.) +struct FunctionPointerPrinter { + template <typename T, typename = typename std::enable_if< + std::is_function<T>::value>::type> + static void PrintValue(T* p, ::std::ostream* os) { + if (p == nullptr) { + *os << "NULL"; + } else { + // T is a function type, so '*os << p' doesn't do what we want + // (it just prints p as bool). We want to print p as a const + // void*. + *os << reinterpret_cast<const void*>(p); + } + } +}; + +struct PointerPrinter { + template <typename T> + static void PrintValue(T* p, ::std::ostream* os) { + if (p == nullptr) { + *os << "NULL"; + } else { + // T is not a function type. We just call << to print p, + // relying on ADL to pick up user-defined << for their pointer + // types, if any. + *os << p; + } } }; -// We print a protobuf using its ShortDebugString() when the string -// doesn't exceed this many characters; otherwise we print it using -// DebugString() for better readability. -const size_t kProtobufOneLinerMaxLength = 50; +namespace internal_stream { +struct Sentinel; +template <typename Char, typename CharTraits, typename T> +Sentinel* operator<<(::std::basic_ostream<Char, CharTraits>& os, const T& x); + +// Check if the user has a user-defined operator<< for their type. +// +// We put this in its own namespace to inject a custom operator<< that allows us +// to probe the type's operator. +// +// Note that this operator<< takes a generic std::basic_ostream<Char, +// CharTraits> type instead of the more restricted std::ostream. If +// we define it to take an std::ostream instead, we'll get an +// "ambiguous overloads" compiler error when trying to print a type +// Foo that supports streaming to std::basic_ostream<Char, +// CharTraits>, as the compiler cannot tell whether +// operator<<(std::ostream&, const T&) or +// operator<<(std::basic_stream<Char, CharTraits>, const Foo&) is more +// specific. template <typename T> -class TypeWithoutFormatter<T, kProtobuf> { - public: +constexpr bool UseStreamOperator() { + return !std::is_same<decltype(std::declval<std::ostream&>() + << std::declval<const T&>()), + Sentinel*>::value; +} + +} // namespace internal_stream + +struct StreamPrinter { + template <typename T, typename = typename std::enable_if< + internal_stream::UseStreamOperator<T>()>::type> + static void PrintValue(const T& value, ::std::ostream* os) { + *os << value; + } +}; + +struct ProtobufPrinter { + // We print a protobuf using its ShortDebugString() when the string + // doesn't exceed this many characters; otherwise we print it using + // DebugString() for better readability. + static const size_t kProtobufOneLinerMaxLength = 50; + + template <typename T, typename = typename std::enable_if< + internal::IsAProtocolMessage<T>::value>::type> static void PrintValue(const T& value, ::std::ostream* os) { std::string pretty_str = value.ShortDebugString(); if (pretty_str.length() > kProtobufOneLinerMaxLength) { @@ -175,9 +248,7 @@ class TypeWithoutFormatter<T, kProtobuf> { } }; -template <typename T> -class TypeWithoutFormatter<T, kConvertibleToInteger> { - public: +struct ConvertibleToIntegerPrinter { // Since T has no << operator or PrintTo() but can be implicitly // converted to BiggestInt, we print it as a BiggestInt. // @@ -185,113 +256,64 @@ class TypeWithoutFormatter<T, kConvertibleToInteger> { // case printing it as an integer is the desired behavior. In case // T is not an enum, printing it as an integer is the best we can do // given that it has no user-defined printer. - static void PrintValue(const T& value, ::std::ostream* os) { - const internal::BiggestInt kBigInt = value; - *os << kBigInt; + static void PrintValue(internal::BiggestInt value, ::std::ostream* os) { + *os << value; } }; -#if GTEST_HAS_ABSL -template <typename T> -class TypeWithoutFormatter<T, kConvertibleToStringView> { - public: - // Since T has neither operator<< nor PrintTo() but can be implicitly - // converted to absl::string_view, we print it as a absl::string_view. - // - // Note: the implementation is further below, as it depends on - // internal::PrintTo symbol which is defined later in the file. - static void PrintValue(const T& value, ::std::ostream* os); -}; +struct ConvertibleToStringViewPrinter { +#if GTEST_INTERNAL_HAS_STRING_VIEW + static void PrintValue(internal::StringView value, ::std::ostream* os) { + internal::UniversalPrint(value, os); + } #endif +}; -// Prints the given value to the given ostream. If the value is a -// protocol message, its debug string is printed; if it's an enum or -// of a type implicitly convertible to BiggestInt, it's printed as an -// integer; otherwise the bytes in the value are printed. This is -// what UniversalPrinter<T>::Print() does when it knows nothing about -// type T and T has neither << operator nor PrintTo(). -// -// A user can override this behavior for a class type Foo by defining -// a << operator in the namespace where Foo is defined. -// -// We put this operator in namespace 'internal2' instead of 'internal' -// to simplify the implementation, as much code in 'internal' needs to -// use << in STL, which would conflict with our own << were it defined -// in 'internal'. -// -// Note that this operator<< takes a generic std::basic_ostream<Char, -// CharTraits> type instead of the more restricted std::ostream. If -// we define it to take an std::ostream instead, we'll get an -// "ambiguous overloads" compiler error when trying to print a type -// Foo that supports streaming to std::basic_ostream<Char, -// CharTraits>, as the compiler cannot tell whether -// operator<<(std::ostream&, const T&) or -// operator<<(std::basic_stream<Char, CharTraits>, const Foo&) is more -// specific. -template <typename Char, typename CharTraits, typename T> -::std::basic_ostream<Char, CharTraits>& operator<<( - ::std::basic_ostream<Char, CharTraits>& os, const T& x) { - TypeWithoutFormatter<T, (internal::IsAProtocolMessage<T>::value - ? kProtobuf - : std::is_convertible< - const T&, internal::BiggestInt>::value - ? kConvertibleToInteger - : -#if GTEST_HAS_ABSL - std::is_convertible< - const T&, absl::string_view>::value - ? kConvertibleToStringView - : -#endif - kOtherType)>::PrintValue(x, &os); - return os; -} -} // namespace internal2 -} // namespace testing +// Prints the given number of bytes in the given object to the given +// ostream. +GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes, + size_t count, + ::std::ostream* os); +struct FallbackPrinter { + template <typename T> + static void PrintValue(const T& value, ::std::ostream* os) { + PrintBytesInObjectTo( + static_cast<const unsigned char*>( + reinterpret_cast<const void*>(std::addressof(value))), + sizeof(value), os); + } +}; -// This namespace MUST NOT BE NESTED IN ::testing, or the name look-up -// magic needed for implementing UniversalPrinter won't work. -namespace testing_internal { +// Try every printer in order and return the first one that works. +template <typename T, typename E, typename Printer, typename... Printers> +struct FindFirstPrinter : FindFirstPrinter<T, E, Printers...> {}; -// Used to print a value that is not an STL-style container when the -// user doesn't define PrintTo() for it. -template <typename T> -void DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) { - // With the following statement, during unqualified name lookup, - // testing::internal2::operator<< appears as if it was declared in - // the nearest enclosing namespace that contains both - // ::testing_internal and ::testing::internal2, i.e. the global - // namespace. For more details, refer to the C++ Standard section - // 7.3.4-1 [namespace.udir]. This allows us to fall back onto - // testing::internal2::operator<< in case T doesn't come with a << - // operator. - // - // We cannot write 'using ::testing::internal2::operator<<;', which - // gcc 3.3 fails to compile due to a compiler bug. - using namespace ::testing::internal2; // NOLINT +template <typename T, typename Printer, typename... Printers> +struct FindFirstPrinter< + T, decltype(Printer::PrintValue(std::declval<const T&>(), nullptr)), + Printer, Printers...> { + using type = Printer; +}; - // Assuming T is defined in namespace foo, in the next statement, - // the compiler will consider all of: - // - // 1. foo::operator<< (thanks to Koenig look-up), - // 2. ::operator<< (as the current namespace is enclosed in ::), - // 3. testing::internal2::operator<< (thanks to the using statement above). - // - // The operator<< whose type matches T best will be picked. - // - // We deliberately allow #2 to be a candidate, as sometimes it's - // impossible to define #1 (e.g. when foo is ::std, defining - // anything in it is undefined behavior unless you are a compiler - // vendor.). - *os << value; +// Select the best printer in the following order: +// - Print containers (they have begin/end/etc). +// - Print function pointers. +// - Print object pointers. +// - Use the stream operator, if available. +// - Print protocol buffers. +// - Print types convertible to BiggestInt. +// - Print types convertible to StringView, if available. +// - Fallback to printing the raw bytes of the object. +template <typename T> +void PrintWithFallback(const T& value, ::std::ostream* os) { + using Printer = typename FindFirstPrinter< + T, void, ContainerPrinter, FunctionPointerPrinter, PointerPrinter, + StreamPrinter, ProtobufPrinter, ConvertibleToIntegerPrinter, + ConvertibleToStringViewPrinter, FallbackPrinter>::type; + Printer::PrintValue(value, os); } -} // namespace testing_internal - -namespace testing { -namespace internal { - // FormatForComparison<ToPrint, OtherOperand>::Format(value) formats a // value of type ToPrint that is an operand of a comparison assertion // (e.g. ASSERT_EQ). OtherOperand is the type of the other operand in @@ -389,85 +411,6 @@ std::string FormatForComparisonFailureMessage( template <typename T> class UniversalPrinter; -template <typename T> -void UniversalPrint(const T& value, ::std::ostream* os); - -enum DefaultPrinterType { - kPrintContainer, - kPrintPointer, - kPrintFunctionPointer, - kPrintOther, -}; -template <DefaultPrinterType type> struct WrapPrinterType {}; - -// Used to print an STL-style container when the user doesn't define -// a PrintTo() for it. -template <typename C> -void DefaultPrintTo(WrapPrinterType<kPrintContainer> /* dummy */, - const C& container, ::std::ostream* os) { - const size_t kMaxCount = 32; // The maximum number of elements to print. - *os << '{'; - size_t count = 0; - for (typename C::const_iterator it = container.begin(); - it != container.end(); ++it, ++count) { - if (count > 0) { - *os << ','; - if (count == kMaxCount) { // Enough has been printed. - *os << " ..."; - break; - } - } - *os << ' '; - // We cannot call PrintTo(*it, os) here as PrintTo() doesn't - // handle *it being a native array. - internal::UniversalPrint(*it, os); - } - - if (count > 0) { - *os << ' '; - } - *os << '}'; -} - -// Used to print a pointer that is neither a char pointer nor a member -// pointer, when the user doesn't define PrintTo() for it. (A member -// variable pointer or member function pointer doesn't really point to -// a location in the address space. Their representation is -// implementation-defined. Therefore they will be printed as raw -// bytes.) -template <typename T> -void DefaultPrintTo(WrapPrinterType<kPrintPointer> /* dummy */, - T* p, ::std::ostream* os) { - if (p == nullptr) { - *os << "NULL"; - } else { - // T is not a function type. We just call << to print p, - // relying on ADL to pick up user-defined << for their pointer - // types, if any. - *os << p; - } -} -template <typename T> -void DefaultPrintTo(WrapPrinterType<kPrintFunctionPointer> /* dummy */, - T* p, ::std::ostream* os) { - if (p == nullptr) { - *os << "NULL"; - } else { - // T is a function type, so '*os << p' doesn't do what we want - // (it just prints p as bool). We want to print p as a const - // void*. - *os << reinterpret_cast<const void*>(p); - } -} - -// Used to print a non-container, non-pointer value when the user -// doesn't define PrintTo() for it. -template <typename T> -void DefaultPrintTo(WrapPrinterType<kPrintOther> /* dummy */, - const T& value, ::std::ostream* os) { - ::testing_internal::DefaultPrintNonContainerTo(value, os); -} - // Prints the given value using the << operator if it has one; // otherwise prints the bytes in it. This is what // UniversalPrinter<T>::Print() does when PrintTo() is not specialized @@ -481,36 +424,7 @@ void DefaultPrintTo(WrapPrinterType<kPrintOther> /* dummy */, // wants). template <typename T> void PrintTo(const T& value, ::std::ostream* os) { - // DefaultPrintTo() is overloaded. The type of its first argument - // determines which version will be picked. - // - // Note that we check for container types here, prior to we check - // for protocol message types in our operator<<. The rationale is: - // - // For protocol messages, we want to give people a chance to - // override Google Mock's format by defining a PrintTo() or - // operator<<. For STL containers, other formats can be - // incompatible with Google Mock's format for the container - // elements; therefore we check for container types here to ensure - // that our format is used. - // - // Note that MSVC and clang-cl do allow an implicit conversion from - // pointer-to-function to pointer-to-object, but clang-cl warns on it. - // So don't use ImplicitlyConvertible if it can be helped since it will - // cause this warning, and use a separate overload of DefaultPrintTo for - // function pointers so that the `*os << p` in the object pointer overload - // doesn't cause that warning either. - DefaultPrintTo( - WrapPrinterType < - (sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) && - !IsRecursiveContainer<T>::value - ? kPrintContainer - : !std::is_pointer<T>::value - ? kPrintOther - : std::is_function<typename std::remove_pointer<T>::type>::value - ? kPrintFunctionPointer - : kPrintPointer > (), - value, os); + internal::PrintWithFallback(value, os); } // The following list of PrintTo() overloads tells @@ -603,12 +517,12 @@ inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) { } #endif // GTEST_HAS_STD_WSTRING -#if GTEST_HAS_ABSL -// Overload for absl::string_view. -inline void PrintTo(absl::string_view sp, ::std::ostream* os) { +#if GTEST_INTERNAL_HAS_STRING_VIEW +// Overload for internal::StringView. +inline void PrintTo(internal::StringView sp, ::std::ostream* os) { PrintTo(::std::string(sp), os); } -#endif // GTEST_HAS_ABSL +#endif // GTEST_INTERNAL_HAS_STRING_VIEW inline void PrintTo(std::nullptr_t, ::std::ostream* os) { *os << "(nullptr)"; } @@ -901,16 +815,6 @@ Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) { } // namespace internal -#if GTEST_HAS_ABSL -namespace internal2 { -template <typename T> -void TypeWithoutFormatter<T, kConvertibleToStringView>::PrintValue( - const T& value, ::std::ostream* os) { - internal::PrintTo(absl::string_view(value), os); -} -} // namespace internal2 -#endif - template <typename T> ::std::string PrintToString(const T& value) { ::std::stringstream ss; diff --git a/googletest/include/gtest/gtest-typed-test.h b/googletest/include/gtest/gtest-typed-test.h index 151fc8f7..3ffa50b7 100644 --- a/googletest/include/gtest/gtest-typed-test.h +++ b/googletest/include/gtest/gtest-typed-test.h @@ -169,6 +169,7 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes); #endif // 0 +#include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-type-util.h" @@ -194,6 +195,8 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes); GTEST_NAME_GENERATOR_(CaseName) #define TYPED_TEST(CaseName, TestName) \ + static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1, \ + "test-name must not be empty"); \ template <typename gtest_TypeParam_> \ class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ : public CaseName<gtest_TypeParam_> { \ @@ -211,7 +214,8 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes); CaseName)>::Register("", \ ::testing::internal::CodeLocation( \ __FILE__, __LINE__), \ - #CaseName, #TestName, 0, \ + GTEST_STRINGIFY_(CaseName), \ + GTEST_STRINGIFY_(TestName), 0, \ ::testing::internal::GenerateNames< \ GTEST_NAME_GENERATOR_(CaseName), \ GTEST_TYPE_PARAMS_(CaseName)>()); \ @@ -278,12 +282,14 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes); }; \ static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \ GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \ - __FILE__, __LINE__, #SuiteName, #TestName); \ + __FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \ + GTEST_STRINGIFY_(TestName)); \ } \ template <typename gtest_TypeParam_> \ void GTEST_SUITE_NAMESPACE_( \ SuiteName)::TestName<gtest_TypeParam_>::TestBody() +// Note: this won't work correctly if the trailing arguments are macros. #define REGISTER_TYPED_TEST_SUITE_P(SuiteName, ...) \ namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \ typedef ::testing::internal::Templates<__VA_ARGS__> gtest_AllTests_; \ @@ -291,7 +297,7 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes); static const char* const GTEST_REGISTERED_TEST_NAMES_( \ SuiteName) GTEST_ATTRIBUTE_UNUSED_ = \ GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \ - __FILE__, __LINE__, #__VA_ARGS__) + GTEST_STRINGIFY_(SuiteName), __FILE__, __LINE__, #__VA_ARGS__) // Legacy API is deprecated but still available #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ @@ -302,13 +308,16 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes); #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ #define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \ + static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \ + "test-suit-prefix must not be empty"); \ static bool gtest_##Prefix##_##SuiteName GTEST_ATTRIBUTE_UNUSED_ = \ ::testing::internal::TypeParameterizedTestSuite< \ SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \ ::testing::internal::GenerateTypeList<Types>::type>:: \ - Register(#Prefix, \ + Register(GTEST_STRINGIFY_(Prefix), \ ::testing::internal::CodeLocation(__FILE__, __LINE__), \ - >EST_TYPED_TEST_SUITE_P_STATE_(SuiteName), #SuiteName, \ + >EST_TYPED_TEST_SUITE_P_STATE_(SuiteName), \ + GTEST_STRINGIFY_(SuiteName), \ GTEST_REGISTERED_TEST_NAMES_(SuiteName), \ ::testing::internal::GenerateNames< \ ::testing::internal::NameGeneratorSelector< \ diff --git a/googletest/include/gtest/gtest.h b/googletest/include/gtest/gtest.h index 8eda6eac..deacb279 100644 --- a/googletest/include/gtest/gtest.h +++ b/googletest/include/gtest/gtest.h @@ -101,6 +101,10 @@ GTEST_DECLARE_bool_(catch_exceptions); // to let Google Test decide. GTEST_DECLARE_string_(color); +// This flag controls whether the test runner should continue execution past +// first failure. +GTEST_DECLARE_bool_(fail_fast); + // This flag sets up the filter to select by name using a glob pattern // the tests to run. If the filter is not given all tests are executed. GTEST_DECLARE_string_(filter); @@ -177,6 +181,7 @@ class FuchsiaDeathTest; class UnitTestImpl* GetUnitTestImpl(); void ReportFailureInUnknownLocation(TestPartResult::Type result_type, const std::string& message); +std::set<std::string>* GetIgnoredParameterizedTestSuites(); } // namespace internal @@ -278,7 +283,11 @@ class GTEST_API_ AssertionResult { // Used in EXPECT_TRUE/FALSE(assertion_result). AssertionResult(const AssertionResult& other); -#if defined(_MSC_VER) && _MSC_VER < 1910 +// C4800 is a level 3 warning in Visual Studio 2015 and earlier. +// This warning is not emitted in Visual Studio 2017. +// This warning is off by default starting in Visual Studio 2019 but can be +// enabled with command-line options. +#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920) GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */) #endif @@ -298,7 +307,7 @@ class GTEST_API_ AssertionResult { = nullptr) : success_(success) {} -#if defined(_MSC_VER) && _MSC_VER < 1910 +#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920) GTEST_DISABLE_MSC_WARNINGS_POP_() #endif @@ -412,8 +421,6 @@ class GTEST_API_ Test { // test in test case Foo. Hence a sub-class can define its own // SetUpTestSuite() method to shadow the one defined in the super // class. - // Failures that happen during SetUpTestSuite are logged but otherwise - // ignored. static void SetUpTestSuite() {} // Tears down the stuff shared by all tests in this test suite. @@ -422,8 +429,6 @@ class GTEST_API_ Test { // test in test case Foo. Hence a sub-class can define its own // TearDownTestSuite() method to shadow the one defined in the super // class. - // Failures that happen during TearDownTestSuite are logged but otherwise - // ignored. static void TearDownTestSuite() {} // Legacy API is deprecated but still available @@ -794,6 +799,9 @@ class GTEST_API_ TestInfo { // deletes it. void Run(); + // Skip and records the test result for this object. + void Skip(); + static void ClearTestResult(TestInfo* test_info) { test_info->result_.Clear(); } @@ -889,7 +897,9 @@ class GTEST_API_ TestSuite { bool Passed() const { return !Failed(); } // Returns true if and only if the test suite failed. - bool Failed() const { return failed_test_count() > 0; } + bool Failed() const { + return failed_test_count() > 0 || ad_hoc_test_result().Failed(); + } // Returns the elapsed time, in milliseconds. TimeInMillis elapsed_time() const { return elapsed_time_; } @@ -940,6 +950,9 @@ class GTEST_API_ TestSuite { // Runs every test in this TestSuite. void Run(); + // Skips the execution of tests under this TestSuite + void Skip(); + // Runs SetUpTestSuite() for this TestSuite. This wrapper is needed // for catching exceptions thrown from SetUpTestSuite(). void RunSetUpTestSuite() { @@ -1420,6 +1433,7 @@ class GTEST_API_ UnitTest { friend class internal::StreamingListenerTest; friend class internal::UnitTestRecordPropertyTestHelper; friend Environment* AddGlobalTestEnvironment(Environment* env); + friend std::set<std::string>* internal::GetIgnoredParameterizedTestSuites(); friend internal::UnitTestImpl* internal::GetUnitTestImpl(); friend void internal::ReportFailureInUnknownLocation( TestPartResult::Type result_type, @@ -1803,12 +1817,6 @@ class GTEST_API_ AssertHelper { GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper); }; -enum GTestColor { COLOR_DEFAULT, COLOR_RED, COLOR_GREEN, COLOR_YELLOW }; - -GTEST_API_ GTEST_ATTRIBUTE_PRINTF_(2, 3) void ColoredPrintf(GTestColor color, - const char* fmt, - ...); - } // namespace internal // The pure interface class that all value-parameterized tests inherit from. @@ -2364,9 +2372,11 @@ constexpr bool StaticAssertTypeEq() noexcept { // } // // GOOGLETEST_CM0011 DO NOT DELETE +#if !GTEST_DONT_DEFINE_TEST #define TEST_F(test_fixture, test_name)\ GTEST_TEST_(test_fixture, test_name, test_fixture, \ ::testing::internal::GetTypeId<test_fixture>()) +#endif // !GTEST_DONT_DEFINE_TEST // Returns a path to temporary directory. // Tries to determine an appropriate directory for the platform. diff --git a/googletest/include/gtest/internal/gtest-internal.h b/googletest/include/gtest/internal/gtest-internal.h index f9da4899..7f1a5b00 100644 --- a/googletest/include/gtest/internal/gtest-internal.h +++ b/googletest/include/gtest/internal/gtest-internal.h @@ -53,6 +53,7 @@ #include <ctype.h> #include <float.h> #include <string.h> +#include <cstdint> #include <iomanip> #include <limits> #include <map> @@ -78,9 +79,20 @@ #define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar // Stringifies its argument. -#define GTEST_STRINGIFY_(name) #name +// Work around a bug in visual studio which doesn't accept code like this: +// +// #define GTEST_STRINGIFY_(name) #name +// #define MACRO(a, b, c) ... GTEST_STRINGIFY_(a) ... +// MACRO(, x, y) +// +// Complaining about the argument to GTEST_STRINGIFY_ being empty. +// This is allowed by the spec. +#define GTEST_STRINGIFY_HELPER_(name, ...) #name +#define GTEST_STRINGIFY_(...) GTEST_STRINGIFY_HELPER_(__VA_ARGS__, ) -namespace proto2 { class Message; } +namespace proto2 { +class MessageLite; +} namespace testing { @@ -607,8 +619,9 @@ class GTEST_API_ TypedTestSuitePState { // Verifies that registered_tests match the test names in // defined_test_names_; returns registered_tests if successful, or // aborts the program otherwise. - const char* VerifyRegisteredTestNames( - const char* file, int line, const char* registered_tests); + const char* VerifyRegisteredTestNames(const char* test_suite_name, + const char* file, int line, + const char* registered_tests); private: typedef ::std::map<std::string, CodeLocation> RegisteredTestsMap; @@ -740,6 +753,11 @@ class TypeParameterizedTest<Fixture, TestSel, internal::None> { } }; +GTEST_API_ void RegisterTypeParameterizedTestSuite(const char* test_suite_name, + CodeLocation code_location); +GTEST_API_ void RegisterTypeParameterizedTestSuiteInstantiation( + const char* case_name); + // TypeParameterizedTestSuite<Fixture, Tests, Types>::Register() // registers *all combinations* of 'Tests' and 'Types' with Google // Test. The return value is insignificant - we just need to return @@ -752,6 +770,7 @@ class TypeParameterizedTestSuite { const char* test_names, const std::vector<std::string>& type_names = GenerateNames<DefaultNameGenerator, Types>()) { + RegisterTypeParameterizedTestSuiteInstantiation(case_name); std::string test_name = StripTrailingSpaces( GetPrefixUntilComma(test_names)); if (!state->TestExists(test_name)) { @@ -827,7 +846,7 @@ struct GTEST_API_ ConstCharPtr { // Helper for declaring std::string within 'if' statement // in pre C++17 build environment. -struct GTEST_API_ TrueWithString { +struct TrueWithString { TrueWithString() = default; explicit TrueWithString(const char* str) : value(str) {} explicit TrueWithString(const std::string& str) : value(str) {} @@ -842,18 +861,18 @@ struct GTEST_API_ TrueWithString { // but it's good enough for our purposes. class GTEST_API_ Random { public: - static const UInt32 kMaxRange = 1u << 31; + static const uint32_t kMaxRange = 1u << 31; - explicit Random(UInt32 seed) : state_(seed) {} + explicit Random(uint32_t seed) : state_(seed) {} - void Reseed(UInt32 seed) { state_ = seed; } + void Reseed(uint32_t seed) { state_ = seed; } // Generates a random number from [0, range). Crashes if 'range' is // 0 or greater than kMaxRange. - UInt32 Generate(UInt32 range); + uint32_t Generate(uint32_t range); private: - UInt32 state_; + uint32_t state_; GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); }; @@ -862,10 +881,10 @@ class GTEST_API_ Random { typename std::remove_const<typename std::remove_reference<T>::type>::type // IsAProtocolMessage<T>::value is a compile-time bool constant that's -// true if and only if T is type proto2::Message or a subclass of it. +// true if and only if T is type proto2::MessageLite or a subclass of it. template <typename T> struct IsAProtocolMessage - : public std::is_convertible<const T*, const ::proto2::Message*> {}; + : public std::is_convertible<const T*, const ::proto2::MessageLite*> {}; // When the compiler sees expression IsContainerTest<C>(0), if C is an // STL-style container class, the first overload of IsContainerTest @@ -1185,7 +1204,7 @@ struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>> // Analog to std::tuple but with different tradeoffs. // This class minimizes the template instantiation depth, thus allowing more -// elements that std::tuple would. std::tuple has been seen to require an +// elements than std::tuple would. std::tuple has been seen to require an // instantiation depth of more than 10x the number of elements in some // implementations. // FlatTuple and ElemFromList are not recursive and have a fixed depth @@ -1196,7 +1215,8 @@ template <typename... T> class FlatTuple : private FlatTupleBase<FlatTuple<T...>, typename MakeIndexSequence<sizeof...(T)>::type> { - using Indices = typename FlatTuple::FlatTupleBase::Indices; + using Indices = typename FlatTupleBase< + FlatTuple<T...>, typename MakeIndexSequence<sizeof...(T)>::type>::Indices; public: FlatTuple() = default; @@ -1387,12 +1407,15 @@ constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; } : public parent_class { \ public: \ GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \ + ~GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() override = default; \ + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \ + test_name)); \ + GTEST_DISALLOW_MOVE_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \ + test_name)); \ \ private: \ void TestBody() override; \ static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_; \ - GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \ - test_name)); \ }; \ \ ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \ diff --git a/googletest/include/gtest/internal/gtest-param-util.h b/googletest/include/gtest/internal/gtest-param-util.h index e900b3ff..7f7a13bf 100644 --- a/googletest/include/gtest/internal/gtest-param-util.h +++ b/googletest/include/gtest/internal/gtest-param-util.h @@ -42,12 +42,14 @@ #include <memory> #include <set> #include <tuple> +#include <type_traits> #include <utility> #include <vector> #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-port.h" #include "gtest/gtest-printers.h" +#include "gtest/gtest-test-part.h" namespace testing { // Input to a parameterized test name generator, describing a test parameter. @@ -474,6 +476,17 @@ class ParameterizedTestSuiteInfoBase { // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // +// Report a the name of a test_suit as safe to ignore +// as the side effect of construction of this type. +struct MarkAsIgnored { + explicit MarkAsIgnored(const char* test_suite); +}; + +GTEST_API_ void InsertSyntheticTestCase(const std::string& name, + CodeLocation location, bool has_test_p); + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// // ParameterizedTestSuiteInfo accumulates tests obtained from TEST_P // macro invocations for a particular test suite and generators // obtained from INSTANTIATE_TEST_SUITE_P macro invocations for that @@ -522,11 +535,13 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { return 0; // Return value used only to run this method in namespace scope. } // UnitTest class invokes this method to register tests in this test suite - // test suites right before running tests in RUN_ALL_TESTS macro. + // right before running tests in RUN_ALL_TESTS macro. // This method should not be called more than once on any single // instance of a ParameterizedTestSuiteInfoBase derived class. // UnitTest has a guard to prevent from calling this method more than once. void RegisterTests() override { + bool generated_instantiations = false; + for (typename TestInfoContainer::iterator test_it = tests_.begin(); test_it != tests_.end(); ++test_it) { std::shared_ptr<TestInfo> test_info = *test_it; @@ -549,6 +564,8 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { for (typename ParamGenerator<ParamType>::iterator param_it = generator.begin(); param_it != generator.end(); ++param_it, ++i) { + generated_instantiations = true; + Message test_name_stream; std::string param_name = name_func( @@ -565,7 +582,10 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { test_param_names.insert(param_name); - test_name_stream << test_info->test_base_name << "/" << param_name; + if (!test_info->test_base_name.empty()) { + test_name_stream << test_info->test_base_name << "/"; + } + test_name_stream << param_name; MakeAndRegisterTestInfo( test_suite_name.c_str(), test_name_stream.GetString().c_str(), nullptr, // No type parameter. @@ -577,6 +597,12 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { } // for param_it } // for gen_it } // for test_it + + if (!generated_instantiations) { + // There are no generaotrs, or they all generate nothing ... + InsertSyntheticTestCase(GetTestSuiteName(), code_location_, + !tests_.empty()); + } } // RegisterTests private: @@ -714,6 +740,34 @@ class ParameterizedTestSuiteRegistry { GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteRegistry); }; +// Keep track of what type-parameterized test suite are defined and +// where as well as which are intatiated. This allows susequently +// identifying suits that are defined but never used. +class TypeParameterizedTestSuiteRegistry { + public: + // Add a suite definition + void RegisterTestSuite(const char* test_suite_name, + CodeLocation code_location); + + // Add an instantiation of a suit. + void RegisterInstantiation(const char* test_suite_name); + + // For each suit repored as defined but not reported as instantiation, + // emit a test that reports that fact (configurably, as an error). + void CheckForInstantiations(); + + private: + struct TypeParameterizedTestSuiteInfo { + explicit TypeParameterizedTestSuiteInfo(CodeLocation c) + : code_location(c), instantiated(false) {} + + CodeLocation code_location; + bool instantiated; + }; + + std::map<std::string, TypeParameterizedTestSuiteInfo> suites_; +}; + } // namespace internal // Forward declarations of ValuesIn(), which is implemented in diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h index 90be25e2..21fcf822 100644 --- a/googletest/include/gtest/internal/gtest-port.h +++ b/googletest/include/gtest/internal/gtest-port.h @@ -190,13 +190,18 @@ // GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning. // GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a // variable don't have to be used. -// GTEST_DISALLOW_ASSIGN_ - disables operator=. +// GTEST_DISALLOW_ASSIGN_ - disables copy operator=. // GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=. +// GTEST_DISALLOW_MOVE_ASSIGN_ - disables move operator=. +// GTEST_DISALLOW_MOVE_AND_ASSIGN_ - disables move ctor and operator=. // GTEST_MUST_USE_RESULT_ - declares that a function's result must be used. // GTEST_INTENTIONAL_CONST_COND_PUSH_ - start code section where MSVC C4127 is // suppressed (constant conditional). // GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127 // is suppressed. +// GTEST_INTERNAL_HAS_STRING_VIEW - for enabling Matcher<std::string_view> or +// Matcher<absl::string_view> +// specializations. // // Synchronization: // Mutex, MutexLock, ThreadLocal, GetThreadCount() @@ -223,8 +228,7 @@ // // Integer types: // TypeWithSize - maps an integer to a int type. -// Int32, UInt32, Int64, UInt64, TimeInMillis -// - integers of known sizes. +// TimeInMillis - integers of known sizes. // BiggestInt - the biggest signed integer type. // // Command-line utilities: @@ -235,7 +239,7 @@ // Environment variable utilities: // GetEnv() - gets the value of an environment variable. // BoolFromGTestEnv() - parses a bool environment variable. -// Int32FromGTestEnv() - parses an Int32 environment variable. +// Int32FromGTestEnv() - parses an int32_t environment variable. // StringFromGTestEnv() - parses a string environment variable. // // Deprecation warnings: @@ -248,6 +252,10 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> + +#include <cerrno> +#include <cstdint> +#include <limits> #include <type_traits> #ifndef _WIN32_WCE @@ -665,10 +673,10 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; #endif -// A macro to disallow operator= +// A macro to disallow copy operator= // This should be used in the private: declarations for a class. #define GTEST_DISALLOW_ASSIGN_(type) \ - void operator=(type const &) = delete + type& operator=(type const &) = delete // A macro to disallow copy constructor and operator= // This should be used in the private: declarations for a class. @@ -676,6 +684,17 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; type(type const &) = delete; \ GTEST_DISALLOW_ASSIGN_(type) +// A macro to disallow move operator= +// This should be used in the private: declarations for a class. +#define GTEST_DISALLOW_MOVE_ASSIGN_(type) \ + type& operator=(type &&) noexcept = delete + +// A macro to disallow move constructor and operator= +// This should be used in the private: declarations for a class. +#define GTEST_DISALLOW_MOVE_AND_ASSIGN_(type) \ + type(type &&) noexcept = delete; \ + GTEST_DISALLOW_MOVE_ASSIGN_(type) + // Tell the compiler to warn about unused return values for functions declared // with this macro. The macro should be used on function declarations // following the argument list: @@ -1876,12 +1895,9 @@ GTEST_API_ size_t GetThreadCount(); #if GTEST_OS_WINDOWS # define GTEST_PATH_SEP_ "\\" # define GTEST_HAS_ALT_PATH_SEP_ 1 -// The biggest signed integer type the compiler supports. -typedef __int64 BiggestInt; #else # define GTEST_PATH_SEP_ "/" # define GTEST_HAS_ALT_PATH_SEP_ 0 -typedef long long BiggestInt; // NOLINT #endif // GTEST_OS_WINDOWS // Utilities for char. @@ -1946,16 +1962,16 @@ namespace posix { typedef struct _stat StatStruct; # ifdef __BORLANDC__ -inline int IsATTY(int fd) { return isatty(fd); } +inline int DoIsATTY(int fd) { return isatty(fd); } inline int StrCaseCmp(const char* s1, const char* s2) { return stricmp(s1, s2); } inline char* StrDup(const char* src) { return strdup(src); } # else // !__BORLANDC__ # if GTEST_OS_WINDOWS_MOBILE -inline int IsATTY(int /* fd */) { return 0; } +inline int DoIsATTY(int /* fd */) { return 0; } # else -inline int IsATTY(int fd) { return _isatty(fd); } +inline int DoIsATTY(int fd) { return _isatty(fd); } # endif // GTEST_OS_WINDOWS_MOBILE inline int StrCaseCmp(const char* s1, const char* s2) { return _stricmp(s1, s2); @@ -1980,7 +1996,7 @@ inline bool IsDir(const StatStruct& st) { typedef struct stat StatStruct; inline int FileNo(FILE* file) { return fileno(file); } -inline int IsATTY(int fd) { return isatty(fd); } +inline int DoIsATTY(int fd) { return isatty(fd); } inline int Stat(const char* path, StatStruct* buf) { // stat function not implemented on ESP8266 return 0; @@ -1997,7 +2013,7 @@ inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } typedef struct stat StatStruct; inline int FileNo(FILE* file) { return fileno(file); } -inline int IsATTY(int fd) { return isatty(fd); } +inline int DoIsATTY(int fd) { return isatty(fd); } inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); } inline int StrCaseCmp(const char* s1, const char* s2) { return strcasecmp(s1, s2); @@ -2008,6 +2024,17 @@ inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } #endif // GTEST_OS_WINDOWS +inline int IsATTY(int fd) { + // DoIsATTY might change errno (for example ENOTTY in case you redirect stdout + // to a file on Linux), which is unexpected, so save the previous value, and + // restore it after the call. + int savedErrno = errno; + int isAttyValue = DoIsATTY(fd); + errno = savedErrno; + + return isAttyValue; +} + // Functions deprecated by MSVC 8.0. GTEST_DISABLE_MSC_DEPRECATED_PUSH_() @@ -2084,15 +2111,13 @@ GTEST_DISABLE_MSC_DEPRECATED_POP_() # define GTEST_SNPRINTF_ snprintf #endif -// The maximum number a BiggestInt can represent. This definition -// works no matter BiggestInt is represented in one's complement or -// two's complement. +// The biggest signed integer type the compiler supports. // -// We cannot rely on numeric_limits in STL, as __int64 and long long -// are not part of standard C++ and numeric_limits doesn't need to be -// defined for them. -const BiggestInt kMaxBiggestInt = - ~(static_cast<BiggestInt>(1) << (8*sizeof(BiggestInt) - 1)); +// long long is guaranteed to be at least 64-bits in C++11. +using BiggestInt = long long; // NOLINT + +// The maximum number a BiggestInt can represent. +constexpr BiggestInt kMaxBiggestInt = (std::numeric_limits<BiggestInt>::max)(); // This template class serves as a compile-time function from size to // type. It maps a size in bytes to a primitive type with that @@ -2117,40 +2142,27 @@ class TypeWithSize { public: // This prevents the user from using TypeWithSize<N> with incorrect // values of N. - typedef void UInt; + using UInt = void; }; // The specialization for size 4. template <> class TypeWithSize<4> { public: - // unsigned int has size 4 in both gcc and MSVC. - // - // As base/basictypes.h doesn't compile on Windows, we cannot use - // uint32, uint64, and etc here. - typedef int Int; - typedef unsigned int UInt; + using Int = std::int32_t; + using UInt = std::uint32_t; }; // The specialization for size 8. template <> class TypeWithSize<8> { public: -#if GTEST_OS_WINDOWS - typedef __int64 Int; - typedef unsigned __int64 UInt; -#else - typedef long long Int; // NOLINT - typedef unsigned long long UInt; // NOLINT -#endif // GTEST_OS_WINDOWS + using Int = std::int64_t; + using UInt = std::uint64_t; }; // Integer types of known sizes. -typedef TypeWithSize<4>::Int Int32; -typedef TypeWithSize<4>::UInt UInt32; -typedef TypeWithSize<8>::Int Int64; -typedef TypeWithSize<8>::UInt UInt64; -typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. +using TimeInMillis = int64_t; // Represents time in milliseconds. // Utilities for command line flags and environment variables. @@ -2169,7 +2181,7 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. // Macros for declaring flags. # define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name) # define GTEST_DECLARE_int32_(name) \ - GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name) + GTEST_API_ extern std::int32_t GTEST_FLAG(name) # define GTEST_DECLARE_string_(name) \ GTEST_API_ extern ::std::string GTEST_FLAG(name) @@ -2177,7 +2189,7 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. # define GTEST_DEFINE_bool_(name, default_val, doc) \ GTEST_API_ bool GTEST_FLAG(name) = (default_val) # define GTEST_DEFINE_int32_(name, default_val, doc) \ - GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) + GTEST_API_ std::int32_t GTEST_FLAG(name) = (default_val) # define GTEST_DEFINE_string_(name, default_val, doc) \ GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val) @@ -2192,12 +2204,12 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. // Parses 'str' for a 32-bit signed integer. If successful, writes the result // to *value and returns true; otherwise leaves *value unchanged and returns // false. -bool ParseInt32(const Message& src_text, const char* str, Int32* value); +bool ParseInt32(const Message& src_text, const char* str, int32_t* value); -// Parses a bool/Int32/string from the environment variable +// Parses a bool/int32_t/string from the environment variable // corresponding to the given Google Test flag. bool BoolFromGTestEnv(const char* flag, bool default_val); -GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val); +GTEST_API_ int32_t Int32FromGTestEnv(const char* flag, int32_t default_val); std::string OutputFlagAlsoCheckEnvVar(); const char* StringFromGTestEnv(const char* flag, const char* default_val); @@ -2224,4 +2236,32 @@ const char* StringFromGTestEnv(const char* flag, const char* default_val); #endif // !defined(GTEST_INTERNAL_DEPRECATED) +#if GTEST_HAS_ABSL +// Always use absl::string_view for Matcher<> specializations if googletest +// is built with absl support. +# define GTEST_INTERNAL_HAS_STRING_VIEW 1 +#include "absl/strings/string_view.h" +namespace testing { +namespace internal { +using StringView = ::absl::string_view; +} // namespace internal +} // namespace testing +#else +# ifdef __has_include +# if __has_include(<string_view>) && __cplusplus >= 201703L +// Otherwise for C++17 and higher use std::string_view for Matcher<> +// specializations. +# define GTEST_INTERNAL_HAS_STRING_VIEW 1 +#include <string_view> +namespace testing { +namespace internal { +using StringView = ::std::string_view; +} // namespace internal +} // namespace testing +// The case where absl is configured NOT to alias std::string_view is not +// supported. +# endif // __has_include(<string_view>) && __cplusplus >= 201703L +# endif // __has_include +#endif // GTEST_HAS_ABSL + #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ diff --git a/googletest/include/gtest/internal/gtest-string.h b/googletest/include/gtest/internal/gtest-string.h index 82aaa63b..0b2a91a5 100644 --- a/googletest/include/gtest/internal/gtest-string.h +++ b/googletest/include/gtest/internal/gtest-string.h @@ -47,6 +47,7 @@ #endif #include <string.h> +#include <cstdint> #include <string> #include "gtest/internal/gtest-port.h" @@ -152,7 +153,7 @@ class GTEST_API_ String { static std::string FormatHexInt(int value); // Formats an int value as "%X". - static std::string FormatHexUInt32(UInt32 value); + static std::string FormatHexUInt32(uint32_t value); // Formats a byte as "%02X". static std::string FormatByte(unsigned char value); diff --git a/googletest/samples/prime_tables.h b/googletest/samples/prime_tables.h index 72539bf1..34002f3d 100644 --- a/googletest/samples/prime_tables.h +++ b/googletest/samples/prime_tables.h @@ -66,11 +66,11 @@ class OnTheFlyPrimeTable : public PrimeTable { } int GetNextPrime(int p) const override { - for (int n = p + 1; n > 0; n++) { + if (p < 0) return -1; + + for (int n = p + 1;; n++) { if (IsPrime(n)) return n; } - - return -1; } }; diff --git a/googletest/scripts/gen_gtest_pred_impl.py b/googletest/scripts/gen_gtest_pred_impl.py index 72942779..e09a6e01 100755 --- a/googletest/scripts/gen_gtest_pred_impl.py +++ b/googletest/scripts/gen_gtest_pred_impl.py @@ -78,7 +78,7 @@ def HeaderPreamble(n): } return ( -"""// Copyright 2006, Google Inc. + """// Copyright 2006, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -337,7 +337,7 @@ def UnitTestPreamble(): } return ( -"""// Copyright 2006, Google Inc. + """// Copyright 2006, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -431,7 +431,7 @@ def TestsForArity(n): } tests = ( -"""// Sample functions/functors for testing %(arity)s predicate assertions. + """// Sample functions/functors for testing %(arity)s predicate assertions. // A %(arity)s predicate function. template <%(types)s> @@ -439,9 +439,8 @@ bool PredFunction%(n)s(%(tvs)s) { return %(v_sum)s > 0; } -// The following two functions are needed to circumvent a bug in -// gcc 2.95.3, which sometimes has problem with the above template -// function. +// The following two functions are needed because a compiler doesn't have +// a context yet to know which template function must be instantiated. bool PredFunction%(n)sInt(%(int_vs)s) { return %(v_sum)s > 0; } @@ -544,10 +543,10 @@ class Predicate%(n)sTest : public testing::Test { } } - // true iff the test function is expected to run to finish. + // true if and only if the test function is expected to run to finish. static bool expected_to_finish_; - // true iff the test function did run to finish. + // true if and only if the test function did run to finish. static bool finished_; """ % DEFS @@ -576,12 +575,12 @@ typedef Predicate%(n)sTest ASSERT_PRED%(n)sTest; """Returns the test for a predicate assertion macro. Args: - use_format: true iff the assertion is a *_PRED_FORMAT*. - use_assert: true iff the assertion is a ASSERT_*. - expect_failure: true iff the assertion is expected to fail. - use_functor: true iff the first argument of the assertion is + use_format: true if and only if the assertion is a *_PRED_FORMAT*. + use_assert: true if and only if the assertion is a ASSERT_*. + expect_failure: true if and only if the assertion is expected to fail. + use_functor: true if and only if the first argument of the assertion is a functor (as opposed to a function) - use_user_type: true iff the predicate functor/function takes + use_user_type: true if and only if the predicate functor/function takes argument(s) of a user-defined type. Example: diff --git a/googletest/src/gtest-death-test.cc b/googletest/src/gtest-death-test.cc index da09a1cf..5d1031be 100644 --- a/googletest/src/gtest-death-test.cc +++ b/googletest/src/gtest-death-test.cc @@ -1364,7 +1364,7 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { if (!use_fork) { static const bool stack_grows_down = StackGrowsDown(); - const auto stack_size = static_cast<size_t>(getpagesize()); + const auto stack_size = static_cast<size_t>(getpagesize() * 2); // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. void* const stack = mmap(nullptr, stack_size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); diff --git a/googletest/src/gtest-internal-inl.h b/googletest/src/gtest-internal-inl.h index 8ed70daa..75ec3524 100644 --- a/googletest/src/gtest-internal-inl.h +++ b/googletest/src/gtest-internal-inl.h @@ -42,6 +42,7 @@ #include <string.h> // For memmove. #include <algorithm> +#include <cstdint> #include <memory> #include <string> #include <vector> @@ -83,6 +84,7 @@ const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests"; const char kBreakOnFailureFlag[] = "break_on_failure"; const char kCatchExceptionsFlag[] = "catch_exceptions"; const char kColorFlag[] = "color"; +const char kFailFast[] = "fail_fast"; const char kFilterFlag[] = "filter"; const char kListTestsFlag[] = "list_tests"; const char kOutputFlag[] = "output"; @@ -123,11 +125,11 @@ GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms); // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. GTEST_API_ bool ParseInt32Flag( - const char* str, const char* flag, Int32* value); + const char* str, const char* flag, int32_t* value); // Returns a random seed in range [1, kMaxRandomSeed] based on the // given --gtest_random_seed flag value. -inline int GetRandomSeedFromFlag(Int32 random_seed_flag) { +inline int GetRandomSeedFromFlag(int32_t random_seed_flag) { const unsigned int raw_seed = (random_seed_flag == 0) ? static_cast<unsigned int>(GetTimeInMillis()) : static_cast<unsigned int>(random_seed_flag); @@ -163,6 +165,7 @@ class GTestFlagSaver { color_ = GTEST_FLAG(color); death_test_style_ = GTEST_FLAG(death_test_style); death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); + fail_fast_ = GTEST_FLAG(fail_fast); filter_ = GTEST_FLAG(filter); internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); list_tests_ = GTEST_FLAG(list_tests); @@ -186,6 +189,7 @@ class GTestFlagSaver { GTEST_FLAG(death_test_style) = death_test_style_; GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; GTEST_FLAG(filter) = filter_; + GTEST_FLAG(fail_fast) = fail_fast_; GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; GTEST_FLAG(list_tests) = list_tests_; GTEST_FLAG(output) = output_; @@ -207,16 +211,17 @@ class GTestFlagSaver { std::string color_; std::string death_test_style_; bool death_test_use_fork_; + bool fail_fast_; std::string filter_; std::string internal_run_death_test_; bool list_tests_; std::string output_; bool print_time_; bool print_utf8_; - internal::Int32 random_seed_; - internal::Int32 repeat_; + int32_t random_seed_; + int32_t repeat_; bool shuffle_; - internal::Int32 stack_trace_depth_; + int32_t stack_trace_depth_; std::string stream_result_to_; bool throw_on_failure_; } GTEST_ATTRIBUTE_UNUSED_; @@ -227,7 +232,7 @@ class GTestFlagSaver { // If the code_point is not a valid Unicode code point // (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted // to "(Invalid Unicode 0xXXXXXXXX)". -GTEST_API_ std::string CodePointToUtf8(UInt32 code_point); +GTEST_API_ std::string CodePointToUtf8(uint32_t code_point); // Converts a wide string to a narrow string in UTF-8 encoding. // The wide string is assumed to have the following encoding: @@ -260,10 +265,10 @@ GTEST_API_ bool ShouldShard(const char* total_shards_str, const char* shard_index_str, bool in_subprocess_for_death_test); -// Parses the environment variable var as an Int32. If it is unset, -// returns default_val. If it is not an Int32, prints an error and +// Parses the environment variable var as a 32-bit integer. If it is unset, +// returns default_val. If it is not a 32-bit integer, prints an error and // and aborts. -GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); +GTEST_API_ int32_t Int32FromEnvOrDie(const char* env_var, int32_t default_val); // Given the total number of shards, the shard index, and the test id, // returns true if and only if the test should be run on this shard. The test id @@ -323,7 +328,7 @@ void ShuffleRange(internal::Random* random, int begin, int end, const int last_in_range = begin + range_width - 1; const int selected = begin + - static_cast<int>(random->Generate(static_cast<UInt32>(range_width))); + static_cast<int>(random->Generate(static_cast<uint32_t>(range_width))); std::swap((*v)[static_cast<size_t>(selected)], (*v)[static_cast<size_t>(last_in_range)]); } @@ -697,6 +702,17 @@ class GTEST_API_ UnitTestImpl { return parameterized_test_registry_; } + std::set<std::string>* ignored_parameterized_test_suites() { + return &ignored_parameterized_test_suites_; + } + + // Returns TypeParameterizedTestSuiteRegistry object used to keep track of + // type-parameterized tests and instantiations of them. + internal::TypeParameterizedTestSuiteRegistry& + type_parameterized_test_registry() { + return type_parameterized_test_registry_; + } + // Sets the TestSuite object for the test that's currently running. void set_current_test_suite(TestSuite* a_current_test_suite) { current_test_suite_ = a_current_test_suite; @@ -873,6 +889,12 @@ class GTEST_API_ UnitTestImpl { // ParameterizedTestRegistry object used to register value-parameterized // tests. internal::ParameterizedTestSuiteRegistry parameterized_test_registry_; + internal::TypeParameterizedTestSuiteRegistry + type_parameterized_test_registry_; + + // The set holding the name of parameterized + // test suites that may go uninstantiated. + std::set<std::string> ignored_parameterized_test_suites_; // Indicates whether RegisterParameterizedTests() has been called already. bool parameterized_tests_registered_; @@ -999,20 +1021,9 @@ bool ParseNaturalNumber(const ::std::string& str, Integer* number) { char* end; // BiggestConvertible is the largest integer type that system-provided // string-to-number conversion routines can return. + using BiggestConvertible = unsigned long long; // NOLINT -# if GTEST_OS_WINDOWS && !defined(__GNUC__) - - // MSVC and C++ Builder define __int64 instead of the standard long long. - typedef unsigned __int64 BiggestConvertible; - const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); - -# else - - typedef unsigned long long BiggestConvertible; // NOLINT - const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); - -# endif // GTEST_OS_WINDOWS && !defined(__GNUC__) - + const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); // NOLINT const bool parse_success = *end == '\0' && errno == 0; GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); diff --git a/googletest/src/gtest-matchers.cc b/googletest/src/gtest-matchers.cc index 7d2fb685..65104eba 100644 --- a/googletest/src/gtest-matchers.cc +++ b/googletest/src/gtest-matchers.cc @@ -58,40 +58,40 @@ Matcher<std::string>::Matcher(const std::string& s) { *this = Eq(s); } // s. Matcher<std::string>::Matcher(const char* s) { *this = Eq(std::string(s)); } -#if GTEST_HAS_ABSL -// Constructs a matcher that matches a const absl::string_view& whose value is +#if GTEST_INTERNAL_HAS_STRING_VIEW +// Constructs a matcher that matches a const StringView& whose value is // equal to s. -Matcher<const absl::string_view&>::Matcher(const std::string& s) { +Matcher<const internal::StringView&>::Matcher(const std::string& s) { *this = Eq(s); } -// Constructs a matcher that matches a const absl::string_view& whose value is +// Constructs a matcher that matches a const StringView& whose value is // equal to s. -Matcher<const absl::string_view&>::Matcher(const char* s) { +Matcher<const internal::StringView&>::Matcher(const char* s) { *this = Eq(std::string(s)); } -// Constructs a matcher that matches a const absl::string_view& whose value is +// Constructs a matcher that matches a const StringView& whose value is // equal to s. -Matcher<const absl::string_view&>::Matcher(absl::string_view s) { +Matcher<const internal::StringView&>::Matcher(internal::StringView s) { *this = Eq(std::string(s)); } -// Constructs a matcher that matches a absl::string_view whose value is equal to +// Constructs a matcher that matches a StringView whose value is equal to // s. -Matcher<absl::string_view>::Matcher(const std::string& s) { *this = Eq(s); } +Matcher<internal::StringView>::Matcher(const std::string& s) { *this = Eq(s); } -// Constructs a matcher that matches a absl::string_view whose value is equal to +// Constructs a matcher that matches a StringView whose value is equal to // s. -Matcher<absl::string_view>::Matcher(const char* s) { +Matcher<internal::StringView>::Matcher(const char* s) { *this = Eq(std::string(s)); } -// Constructs a matcher that matches a absl::string_view whose value is equal to +// Constructs a matcher that matches a StringView whose value is equal to // s. -Matcher<absl::string_view>::Matcher(absl::string_view s) { +Matcher<internal::StringView>::Matcher(internal::StringView s) { *this = Eq(std::string(s)); } -#endif // GTEST_HAS_ABSL +#endif // GTEST_INTERNAL_HAS_STRING_VIEW } // namespace testing diff --git a/googletest/src/gtest-port.cc b/googletest/src/gtest-port.cc index fc5ba6be..a05c50a3 100644 --- a/googletest/src/gtest-port.cc +++ b/googletest/src/gtest-port.cc @@ -34,6 +34,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <cstdint> #include <fstream> #include <memory> @@ -536,6 +537,9 @@ class ThreadLocalRegistryImpl { // Returns a value that can be used to identify the thread from other threads. static ThreadLocalValueHolderBase* GetValueOnCurrentThread( const ThreadLocalBase* thread_local_instance) { +#ifdef _MSC_VER + MemoryIsNotDeallocated memory_is_not_deallocated; +#endif // _MSC_VER DWORD current_thread = ::GetCurrentThreadId(); MutexLock lock(&mutex_); ThreadIdToThreadLocals* const thread_to_thread_locals = @@ -1286,7 +1290,7 @@ static std::string FlagToEnvVar(const char* flag) { // Parses 'str' for a 32-bit signed integer. If successful, writes // the result to *value and returns true; otherwise leaves *value // unchanged and returns false. -bool ParseInt32(const Message& src_text, const char* str, Int32* value) { +bool ParseInt32(const Message& src_text, const char* str, int32_t* value) { // Parses the environment variable as a decimal integer. char* end = nullptr; const long long_value = strtol(str, &end, 10); // NOLINT @@ -1303,13 +1307,13 @@ bool ParseInt32(const Message& src_text, const char* str, Int32* value) { return false; } - // Is the parsed value in the range of an Int32? - const Int32 result = static_cast<Int32>(long_value); + // Is the parsed value in the range of an int32_t? + const auto result = static_cast<int32_t>(long_value); if (long_value == LONG_MAX || long_value == LONG_MIN || // The parsed value overflows as a long. (strtol() returns // LONG_MAX or LONG_MIN when the input overflows.) result != long_value - // The parsed value overflows as an Int32. + // The parsed value overflows as an int32_t. ) { Message msg; msg << "WARNING: " << src_text @@ -1342,7 +1346,7 @@ bool BoolFromGTestEnv(const char* flag, bool default_value) { // Reads and returns a 32-bit integer stored in the environment // variable corresponding to the given flag; if it isn't set or // doesn't represent a valid 32-bit integer, returns default_value. -Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { +int32_t Int32FromGTestEnv(const char* flag, int32_t default_value) { #if defined(GTEST_GET_INT32_FROM_ENV_) return GTEST_GET_INT32_FROM_ENV_(flag, default_value); #else @@ -1353,7 +1357,7 @@ Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { return default_value; } - Int32 result = default_value; + int32_t result = default_value; if (!ParseInt32(Message() << "Environment variable " << env_var, string_value, &result)) { printf("The default value %s is used.\n", diff --git a/googletest/src/gtest-printers.cc b/googletest/src/gtest-printers.cc index 3337be31..4e1ccad8 100644 --- a/googletest/src/gtest-printers.cc +++ b/googletest/src/gtest-printers.cc @@ -104,7 +104,7 @@ void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, } // namespace -namespace internal2 { +namespace internal { // Delegates to PrintBytesInObjectToImpl() to print the bytes in the // given object. The delegation simplifies the implementation, which @@ -116,10 +116,6 @@ void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, PrintBytesInObjectToImpl(obj_bytes, count, os); } -} // namespace internal2 - -namespace internal { - // Depending on the value of a char (or wchar_t), we print it in one // of three formats: // - as is if it's a printable ASCII (e.g. 'a', '2', ' '), diff --git a/googletest/src/gtest-typed-test.cc b/googletest/src/gtest-typed-test.cc index 8677caf7..1b1cfb0d 100644 --- a/googletest/src/gtest-typed-test.cc +++ b/googletest/src/gtest-typed-test.cc @@ -58,7 +58,10 @@ static std::vector<std::string> SplitIntoTestNames(const char* src) { // registered_tests_; returns registered_tests if successful, or // aborts the program otherwise. const char* TypedTestSuitePState::VerifyRegisteredTestNames( - const char* file, int line, const char* registered_tests) { + const char* test_suite_name, const char* file, int line, + const char* registered_tests) { + RegisterTypeParameterizedTestSuite(test_suite_name, CodeLocation(file, line)); + typedef RegisteredTestsMap::const_iterator RegisteredTestIter; registered_ = true; diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index 8afb070d..4c8b42f9 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -44,6 +44,7 @@ #include <wctype.h> #include <algorithm> +#include <cstdint> #include <iomanip> #include <limits> #include <list> @@ -83,8 +84,11 @@ # include <windows.h> // NOLINT # undef min +#ifdef _MSC_VER # include <crtdbg.h> // NOLINT # include <debugapi.h> // NOLINT +#endif + # include <io.h> // NOLINT # include <sys/timeb.h> // NOLINT # include <sys/types.h> // NOLINT @@ -209,6 +213,21 @@ static const char* GetDefaultFilter() { return kUniversalFilter; } +// Bazel passes in the argument to '--test_runner_fail_fast' via the +// TESTBRIDGE_TEST_RUNNER_FAIL_FAST environment variable. +static bool GetDefaultFailFast() { + const char* const testbridge_test_runner_fail_fast = + internal::posix::GetEnv("TESTBRIDGE_TEST_RUNNER_FAIL_FAST"); + if (testbridge_test_runner_fail_fast != nullptr) { + return strcmp(testbridge_test_runner_fail_fast, "1") == 0; + } + return false; +} + +GTEST_DEFINE_bool_( + fail_fast, internal::BoolFromGTestEnv("fail_fast", GetDefaultFailFast()), + "True if and only if a test failure should stop further test execution."); + GTEST_DEFINE_bool_( also_run_disabled_tests, internal::BoolFromGTestEnv("also_run_disabled_tests", false), @@ -330,10 +349,10 @@ namespace internal { // Generates a random number from [0, range), using a Linear // Congruential Generator (LCG). Crashes if 'range' is 0 or greater // than kMaxRange. -UInt32 Random::Generate(UInt32 range) { +uint32_t Random::Generate(uint32_t range) { // These constants are the same as are used in glibc's rand(3). // Use wider types than necessary to prevent unsigned overflow diagnostics. - state_ = static_cast<UInt32>(1103515245ULL*state_ + 12345U) % kMaxRange; + state_ = static_cast<uint32_t>(1103515245ULL*state_ + 12345U) % kMaxRange; GTEST_CHECK_(range > 0) << "Cannot generate a number in the range [0, 0)."; @@ -403,6 +422,162 @@ void AssertHelper::operator=(const Message& message) const { ); // NOLINT } +namespace { + +// When TEST_P is found without a matching INSTANTIATE_TEST_SUITE_P +// to creates test cases for it, a syntetic test case is +// inserted to report ether an error or a log message. +// +// This configuration bit will likely be removed at some point. +constexpr bool kErrorOnUninstantiatedParameterizedTest = false; +constexpr bool kErrorOnUninstantiatedTypeParameterizedTest = false; + +// A test that fails at a given file/line location with a given message. +class FailureTest : public Test { + public: + explicit FailureTest(const CodeLocation& loc, std::string error_message, + bool as_error) + : loc_(loc), + error_message_(std::move(error_message)), + as_error_(as_error) {} + + void TestBody() override { + if (as_error_) { + AssertHelper(TestPartResult::kNonFatalFailure, loc_.file.c_str(), + loc_.line, "") = Message() << error_message_; + } else { + std::cout << error_message_ << std::endl; + } + } + + private: + const CodeLocation loc_; + const std::string error_message_; + const bool as_error_; +}; + + +} // namespace + +std::set<std::string>* GetIgnoredParameterizedTestSuites() { + return UnitTest::GetInstance()->impl()->ignored_parameterized_test_suites(); +} + +// Add a given test_suit to the list of them allow to go un-instantiated. +MarkAsIgnored::MarkAsIgnored(const char* test_suite) { + GetIgnoredParameterizedTestSuites()->insert(test_suite); +} + +// If this parameterized test suite has no instantiations (and that +// has not been marked as okay), emit a test case reporting that. +void InsertSyntheticTestCase(const std::string& name, CodeLocation location, + bool has_test_p) { + const auto& ignored = *GetIgnoredParameterizedTestSuites(); + if (ignored.find(name) != ignored.end()) return; + + const char kMissingInstantiation[] = // + " is defined via TEST_P, but never instantiated. None of the test cases " + "will run. Either no INSTANTIATE_TEST_SUITE_P is provided or the only " + "ones provided expand to nothing." + "\n\n" + "Ideally, TEST_P definitions should only ever be included as part of " + "binaries that intend to use them. (As opposed to, for example, being " + "placed in a library that may be linked in to get other utilities.)"; + + const char kMissingTestCase[] = // + " is instantiated via INSTANTIATE_TEST_SUITE_P, but no tests are " + "defined via TEST_P . No test cases will run." + "\n\n" + "Ideally, INSTANTIATE_TEST_SUITE_P should only ever be invoked from " + "code that always depend on code that provides TEST_P. Failing to do " + "so is often an indication of dead code, e.g. the last TEST_P was " + "removed but the rest got left behind."; + + std::string message = + "Paramaterized test suite " + name + + (has_test_p ? kMissingInstantiation : kMissingTestCase) + + "\n\n" + "To suppress this error for this test suite, insert the following line " + "(in a non-header) in the namespace it is defined in:" + "\n\n" + "GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(" + name + ");"; + + std::string full_name = "UninstantiatedParamaterizedTestSuite<" + name + ">"; + RegisterTest( // + "GoogleTestVerification", full_name.c_str(), + nullptr, // No type parameter. + nullptr, // No value parameter. + location.file.c_str(), location.line, [message, location] { + return new FailureTest(location, message, + kErrorOnUninstantiatedParameterizedTest); + }); +} + +void RegisterTypeParameterizedTestSuite(const char* test_suite_name, + CodeLocation code_location) { + GetUnitTestImpl()->type_parameterized_test_registry().RegisterTestSuite( + test_suite_name, code_location); +} + +void RegisterTypeParameterizedTestSuiteInstantiation(const char* case_name) { + GetUnitTestImpl() + ->type_parameterized_test_registry() + .RegisterInstantiation(case_name); +} + +void TypeParameterizedTestSuiteRegistry::RegisterTestSuite( + const char* test_suite_name, CodeLocation code_location) { + suites_.emplace(std::string(test_suite_name), + TypeParameterizedTestSuiteInfo(code_location)); +} + +void TypeParameterizedTestSuiteRegistry::RegisterInstantiation( + const char* test_suite_name) { + auto it = suites_.find(std::string(test_suite_name)); + if (it != suites_.end()) { + it->second.instantiated = true; + } else { + GTEST_LOG_(ERROR) << "Unknown type parameterized test suit '" + << test_suite_name << "'"; + } +} + +void TypeParameterizedTestSuiteRegistry::CheckForInstantiations() { + const auto& ignored = *GetIgnoredParameterizedTestSuites(); + for (const auto& testcase : suites_) { + if (testcase.second.instantiated) continue; + if (ignored.find(testcase.first) != ignored.end()) continue; + + std::string message = + "Type paramaterized test suite " + testcase.first + + " is defined via REGISTER_TYPED_TEST_SUITE_P, but never instantiated " + "via INSTANTIATE_TYPED_TEST_SUITE_P. None of the test cases will run." + "\n\n" + "Ideally, TYPED_TEST_P definitions should only ever be included as " + "part of binaries that intend to use them. (As opposed to, for " + "example, being placed in a library that may be linked in to get other " + "utilities.)" + "\n\n" + "To suppress this error for this test suite, insert the following line " + "(in a non-header) in the namespace it is definedin in:" + "\n\n" + "GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(" + + testcase.first + ");"; + + std::string full_name = + "UninstantiatedTypeParamaterizedTestSuite<" + testcase.first + ">"; + RegisterTest( // + "GoogleTestVerification", full_name.c_str(), + nullptr, // No type parameter. + nullptr, // No value parameter. + testcase.second.code_location.file.c_str(), + testcase.second.code_location.line, [message, testcase] { + return new FailureTest(testcase.second.code_location, message, + kErrorOnUninstantiatedTypeParameterizedTest); + }); + } +} + // A copy of all command line arguments. Set by InitGoogleTest(). static ::std::vector<std::string> g_argvs; @@ -1735,33 +1910,33 @@ AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT // 17 - 21 bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx // The maximum code-point a one-byte UTF-8 sequence can represent. -const UInt32 kMaxCodePoint1 = (static_cast<UInt32>(1) << 7) - 1; +constexpr uint32_t kMaxCodePoint1 = (static_cast<uint32_t>(1) << 7) - 1; // The maximum code-point a two-byte UTF-8 sequence can represent. -const UInt32 kMaxCodePoint2 = (static_cast<UInt32>(1) << (5 + 6)) - 1; +constexpr uint32_t kMaxCodePoint2 = (static_cast<uint32_t>(1) << (5 + 6)) - 1; // The maximum code-point a three-byte UTF-8 sequence can represent. -const UInt32 kMaxCodePoint3 = (static_cast<UInt32>(1) << (4 + 2*6)) - 1; +constexpr uint32_t kMaxCodePoint3 = (static_cast<uint32_t>(1) << (4 + 2*6)) - 1; // The maximum code-point a four-byte UTF-8 sequence can represent. -const UInt32 kMaxCodePoint4 = (static_cast<UInt32>(1) << (3 + 3*6)) - 1; +constexpr uint32_t kMaxCodePoint4 = (static_cast<uint32_t>(1) << (3 + 3*6)) - 1; // Chops off the n lowest bits from a bit pattern. Returns the n // lowest bits. As a side effect, the original bit pattern will be // shifted to the right by n bits. -inline UInt32 ChopLowBits(UInt32* bits, int n) { - const UInt32 low_bits = *bits & ((static_cast<UInt32>(1) << n) - 1); +inline uint32_t ChopLowBits(uint32_t* bits, int n) { + const uint32_t low_bits = *bits & ((static_cast<uint32_t>(1) << n) - 1); *bits >>= n; return low_bits; } // Converts a Unicode code point to a narrow string in UTF-8 encoding. -// code_point parameter is of type UInt32 because wchar_t may not be +// code_point parameter is of type uint32_t because wchar_t may not be // wide enough to contain a code point. // If the code_point is not a valid Unicode code point // (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted // to "(Invalid Unicode 0xXXXXXXXX)". -std::string CodePointToUtf8(UInt32 code_point) { +std::string CodePointToUtf8(uint32_t code_point) { if (code_point > kMaxCodePoint4) { return "(Invalid Unicode 0x" + String::FormatHexUInt32(code_point) + ")"; } @@ -1802,11 +1977,11 @@ inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) { } // Creates a Unicode code point from UTF16 surrogate pair. -inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first, - wchar_t second) { - const auto first_u = static_cast<UInt32>(first); - const auto second_u = static_cast<UInt32>(second); - const UInt32 mask = (1 << 10) - 1; +inline uint32_t CreateCodePointFromUtf16SurrogatePair(wchar_t first, + wchar_t second) { + const auto first_u = static_cast<uint32_t>(first); + const auto second_u = static_cast<uint32_t>(second); + const uint32_t mask = (1 << 10) - 1; return (sizeof(wchar_t) == 2) ? (((first_u & mask) << 10) | (second_u & mask)) + 0x10000 : @@ -1834,7 +2009,7 @@ std::string WideStringToUtf8(const wchar_t* str, int num_chars) { ::std::stringstream stream; for (int i = 0; i < num_chars; ++i) { - UInt32 unicode_code_point; + uint32_t unicode_code_point; if (str[i] == L'\0') { break; @@ -1843,7 +2018,7 @@ std::string WideStringToUtf8(const wchar_t* str, int num_chars) { str[i + 1]); i++; } else { - unicode_code_point = static_cast<UInt32>(str[i]); + unicode_code_point = static_cast<uint32_t>(str[i]); } stream << CodePointToUtf8(unicode_code_point); @@ -1969,7 +2144,7 @@ std::string String::FormatIntWidth2(int value) { } // Formats an int value as "%X". -std::string String::FormatHexUInt32(UInt32 value) { +std::string String::FormatHexUInt32(uint32_t value) { std::stringstream ss; ss << std::hex << std::uppercase << value; return ss.str(); @@ -1977,7 +2152,7 @@ std::string String::FormatHexUInt32(UInt32 value) { // Formats an int value as "%X". std::string String::FormatHexInt(int value) { - return FormatHexUInt32(static_cast<UInt32>(value)); + return FormatHexUInt32(static_cast<uint32_t>(value)); } // Formats a byte as "%02X". @@ -2108,7 +2283,7 @@ static const char* const kReservedOutputTestCaseAttributes[] = { "classname", "name", "status", "time", "type_param", "value_param", "file", "line", "result", "timestamp"}; -template <int kSize> +template <size_t kSize> std::vector<std::string> ArrayAsVector(const char* const (&array)[kSize]) { return std::vector<std::string>(array, array + kSize); } @@ -2646,6 +2821,7 @@ namespace internal { void UnitTestImpl::RegisterParameterizedTests() { if (!parameterized_tests_registered_) { parameterized_test_registry_.RegisterTests(); + type_parameterized_test_registry_.CheckForInstantiations(); parameterized_tests_registered_ = true; } } @@ -2702,6 +2878,28 @@ void TestInfo::Run() { impl->set_current_test_info(nullptr); } +// Skip and records a skipped test result for this object. +void TestInfo::Skip() { + if (!should_run_) return; + + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_info(this); + + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + // Notifies the unit test event listeners that a test is about to start. + repeater->OnTestStart(*this); + + const TestPartResult test_part_result = + TestPartResult(TestPartResult::kSkip, this->file(), this->line(), ""); + impl->GetTestPartResultReporterForCurrentThread()->ReportTestPartResult( + test_part_result); + + // Notifies the unit test event listener that a test has just finished. + repeater->OnTestEnd(*this); + impl->set_current_test_info(nullptr); +} + // class TestSuite // Gets the number of successful tests in this test suite. @@ -2814,6 +3012,12 @@ void TestSuite::Run() { start_timestamp_ = internal::GetTimeInMillis(); for (int i = 0; i < total_test_count(); i++) { GetMutableTestInfo(i)->Run(); + if (GTEST_FLAG(fail_fast) && GetMutableTestInfo(i)->result()->Failed()) { + for (int j = i + 1; j < total_test_count(); j++) { + GetMutableTestInfo(j)->Skip(); + } + break; + } } elapsed_time_ = internal::GetTimeInMillis() - start_timestamp_; @@ -2831,6 +3035,36 @@ void TestSuite::Run() { impl->set_current_test_suite(nullptr); } +// Skips all tests under this TestSuite. +void TestSuite::Skip() { + if (!should_run_) return; + + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_suite(this); + + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + // Call both legacy and the new API + repeater->OnTestSuiteStart(*this); +// Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI + repeater->OnTestCaseStart(*this); +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI + + for (int i = 0; i < total_test_count(); i++) { + GetMutableTestInfo(i)->Skip(); + } + + // Call both legacy and the new API + repeater->OnTestSuiteEnd(*this); + // Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI + repeater->OnTestCaseEnd(*this); +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI + + impl->set_current_test_suite(nullptr); +} + // Clears the results of all tests in this test suite. void TestSuite::ClearResult() { ad_hoc_test_result_.Clear(); @@ -2895,6 +3129,9 @@ static const char * TestPartResultTypeToString(TestPartResult::Type type) { } namespace internal { +namespace { +enum class GTestColor { kDefault, kRed, kGreen, kYellow }; +} // namespace // Prints a TestPartResult to an std::string. static std::string PrintTestPartResultToString( @@ -2932,9 +3169,12 @@ static void PrintTestPartResult(const TestPartResult& test_part_result) { // Returns the character attribute for the given color. static WORD GetColorAttribute(GTestColor color) { switch (color) { - case COLOR_RED: return FOREGROUND_RED; - case COLOR_GREEN: return FOREGROUND_GREEN; - case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; + case GTestColor::kRed: + return FOREGROUND_RED; + case GTestColor::kGreen: + return FOREGROUND_GREEN; + case GTestColor::kYellow: + return FOREGROUND_RED | FOREGROUND_GREEN; default: return 0; } } @@ -2972,13 +3212,16 @@ static WORD GetNewColor(GTestColor color, WORD old_color_attrs) { #else -// Returns the ANSI color code for the given color. COLOR_DEFAULT is +// Returns the ANSI color code for the given color. GTestColor::kDefault is // an invalid input. static const char* GetAnsiColorCode(GTestColor color) { switch (color) { - case COLOR_RED: return "1"; - case COLOR_GREEN: return "2"; - case COLOR_YELLOW: return "3"; + case GTestColor::kRed: + return "1"; + case GTestColor::kGreen: + return "2"; + case GTestColor::kYellow: + return "3"; default: return nullptr; } @@ -3027,6 +3270,7 @@ bool ShouldUseColor(bool stdout_is_tty) { // cannot simply emit special characters and have the terminal change colors. // This routine must actually emit the characters rather than return a string // that would be colored when printed, as can be done on Linux. + void ColoredPrintf(GTestColor color, const char* fmt, ...) { va_list args; va_start(args, fmt); @@ -3037,7 +3281,7 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) { #else static const bool in_color_mode = ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); - const bool use_color = in_color_mode && (color != COLOR_DEFAULT); + const bool use_color = in_color_mode && (color != GTestColor::kDefault); #endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_ZOS if (!use_color) { @@ -3134,6 +3378,7 @@ class PrettyUnitTestResultPrinter : public TestEventListener { private: static void PrintFailedTests(const UnitTest& unit_test); + static void PrintFailedTestSuites(const UnitTest& unit_test); static void PrintSkippedTests(const UnitTest& unit_test); }; @@ -3148,25 +3393,24 @@ void PrettyUnitTestResultPrinter::OnTestIterationStart( // Prints the filter if it's not *. This reminds the user that some // tests may be skipped. if (!String::CStringEquals(filter, kUniversalFilter)) { - ColoredPrintf(COLOR_YELLOW, - "Note: %s filter = %s\n", GTEST_NAME_, filter); + ColoredPrintf(GTestColor::kYellow, "Note: %s filter = %s\n", GTEST_NAME_, + filter); } if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { - const Int32 shard_index = Int32FromEnvOrDie(kTestShardIndex, -1); - ColoredPrintf(COLOR_YELLOW, - "Note: This is test shard %d of %s.\n", + const int32_t shard_index = Int32FromEnvOrDie(kTestShardIndex, -1); + ColoredPrintf(GTestColor::kYellow, "Note: This is test shard %d of %s.\n", static_cast<int>(shard_index) + 1, internal::posix::GetEnv(kTestTotalShards)); } if (GTEST_FLAG(shuffle)) { - ColoredPrintf(COLOR_YELLOW, + ColoredPrintf(GTestColor::kYellow, "Note: Randomizing tests' orders with a seed of %d .\n", unit_test.random_seed()); } - ColoredPrintf(COLOR_GREEN, "[==========] "); + ColoredPrintf(GTestColor::kGreen, "[==========] "); printf("Running %s from %s.\n", FormatTestCount(unit_test.test_to_run_count()).c_str(), FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str()); @@ -3175,7 +3419,7 @@ void PrettyUnitTestResultPrinter::OnTestIterationStart( void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( const UnitTest& /*unit_test*/) { - ColoredPrintf(COLOR_GREEN, "[----------] "); + ColoredPrintf(GTestColor::kGreen, "[----------] "); printf("Global test environment set-up.\n"); fflush(stdout); } @@ -3184,7 +3428,7 @@ void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { const std::string counts = FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); - ColoredPrintf(COLOR_GREEN, "[----------] "); + ColoredPrintf(GTestColor::kGreen, "[----------] "); printf("%s from %s", counts.c_str(), test_case.name()); if (test_case.type_param() == nullptr) { printf("\n"); @@ -3198,7 +3442,7 @@ void PrettyUnitTestResultPrinter::OnTestSuiteStart( const TestSuite& test_suite) { const std::string counts = FormatCountableNoun(test_suite.test_to_run_count(), "test", "tests"); - ColoredPrintf(COLOR_GREEN, "[----------] "); + ColoredPrintf(GTestColor::kGreen, "[----------] "); printf("%s from %s", counts.c_str(), test_suite.name()); if (test_suite.type_param() == nullptr) { printf("\n"); @@ -3210,7 +3454,7 @@ void PrettyUnitTestResultPrinter::OnTestSuiteStart( #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { - ColoredPrintf(COLOR_GREEN, "[ RUN ] "); + ColoredPrintf(GTestColor::kGreen, "[ RUN ] "); PrintTestName(test_info.test_suite_name(), test_info.name()); printf("\n"); fflush(stdout); @@ -3233,11 +3477,11 @@ void PrettyUnitTestResultPrinter::OnTestPartResult( void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { if (test_info.result()->Passed()) { - ColoredPrintf(COLOR_GREEN, "[ OK ] "); + ColoredPrintf(GTestColor::kGreen, "[ OK ] "); } else if (test_info.result()->Skipped()) { - ColoredPrintf(COLOR_GREEN, "[ SKIPPED ] "); + ColoredPrintf(GTestColor::kGreen, "[ SKIPPED ] "); } else { - ColoredPrintf(COLOR_RED, "[ FAILED ] "); + ColoredPrintf(GTestColor::kRed, "[ FAILED ] "); } PrintTestName(test_info.test_suite_name(), test_info.name()); if (test_info.result()->Failed()) @@ -3258,7 +3502,7 @@ void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { const std::string counts = FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); - ColoredPrintf(COLOR_GREEN, "[----------] "); + ColoredPrintf(GTestColor::kGreen, "[----------] "); printf("%s from %s (%s ms total)\n\n", counts.c_str(), test_case.name(), internal::StreamableToString(test_case.elapsed_time()).c_str()); fflush(stdout); @@ -3269,7 +3513,7 @@ void PrettyUnitTestResultPrinter::OnTestSuiteEnd(const TestSuite& test_suite) { const std::string counts = FormatCountableNoun(test_suite.test_to_run_count(), "test", "tests"); - ColoredPrintf(COLOR_GREEN, "[----------] "); + ColoredPrintf(GTestColor::kGreen, "[----------] "); printf("%s from %s (%s ms total)\n\n", counts.c_str(), test_suite.name(), internal::StreamableToString(test_suite.elapsed_time()).c_str()); fflush(stdout); @@ -3278,7 +3522,7 @@ void PrettyUnitTestResultPrinter::OnTestSuiteEnd(const TestSuite& test_suite) { void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( const UnitTest& /*unit_test*/) { - ColoredPrintf(COLOR_GREEN, "[----------] "); + ColoredPrintf(GTestColor::kGreen, "[----------] "); printf("Global test environment tear-down\n"); fflush(stdout); } @@ -3286,9 +3530,8 @@ void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( // Internal helper for printing the list of failed tests. void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { const int failed_test_count = unit_test.failed_test_count(); - if (failed_test_count == 0) { - return; - } + ColoredPrintf(GTestColor::kRed, "[ FAILED ] "); + printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); for (int i = 0; i < unit_test.total_test_suite_count(); ++i) { const TestSuite& test_suite = *unit_test.GetTestSuite(i); @@ -3300,12 +3543,36 @@ void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { if (!test_info.should_run() || !test_info.result()->Failed()) { continue; } - ColoredPrintf(COLOR_RED, "[ FAILED ] "); + ColoredPrintf(GTestColor::kRed, "[ FAILED ] "); printf("%s.%s", test_suite.name(), test_info.name()); PrintFullTestCommentIfPresent(test_info); printf("\n"); } } + printf("\n%2d FAILED %s\n", failed_test_count, + failed_test_count == 1 ? "TEST" : "TESTS"); +} + +// Internal helper for printing the list of test suite failures not covered by +// PrintFailedTests. +void PrettyUnitTestResultPrinter::PrintFailedTestSuites( + const UnitTest& unit_test) { + int suite_failure_count = 0; + for (int i = 0; i < unit_test.total_test_suite_count(); ++i) { + const TestSuite& test_suite = *unit_test.GetTestSuite(i); + if (!test_suite.should_run()) { + continue; + } + if (test_suite.ad_hoc_test_result().Failed()) { + ColoredPrintf(GTestColor::kRed, "[ FAILED ] "); + printf("%s: SetUpTestSuite or TearDownTestSuite\n", test_suite.name()); + ++suite_failure_count; + } + } + if (suite_failure_count > 0) { + printf("\n%2d FAILED TEST %s\n", suite_failure_count, + suite_failure_count == 1 ? "SUITE" : "SUITES"); + } } // Internal helper for printing the list of skipped tests. @@ -3325,7 +3592,7 @@ void PrettyUnitTestResultPrinter::PrintSkippedTests(const UnitTest& unit_test) { if (!test_info.should_run() || !test_info.result()->Skipped()) { continue; } - ColoredPrintf(COLOR_GREEN, "[ SKIPPED ] "); + ColoredPrintf(GTestColor::kGreen, "[ SKIPPED ] "); printf("%s.%s", test_suite.name(), test_info.name()); printf("\n"); } @@ -3334,7 +3601,7 @@ void PrettyUnitTestResultPrinter::PrintSkippedTests(const UnitTest& unit_test) { void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, int /*iteration*/) { - ColoredPrintf(COLOR_GREEN, "[==========] "); + ColoredPrintf(GTestColor::kGreen, "[==========] "); printf("%s from %s ran.", FormatTestCount(unit_test.test_to_run_count()).c_str(), FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str()); @@ -3343,35 +3610,28 @@ void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, internal::StreamableToString(unit_test.elapsed_time()).c_str()); } printf("\n"); - ColoredPrintf(COLOR_GREEN, "[ PASSED ] "); + ColoredPrintf(GTestColor::kGreen, "[ PASSED ] "); printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); const int skipped_test_count = unit_test.skipped_test_count(); if (skipped_test_count > 0) { - ColoredPrintf(COLOR_GREEN, "[ SKIPPED ] "); + ColoredPrintf(GTestColor::kGreen, "[ SKIPPED ] "); printf("%s, listed below:\n", FormatTestCount(skipped_test_count).c_str()); PrintSkippedTests(unit_test); } - int num_failures = unit_test.failed_test_count(); if (!unit_test.Passed()) { - const int failed_test_count = unit_test.failed_test_count(); - ColoredPrintf(COLOR_RED, "[ FAILED ] "); - printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); PrintFailedTests(unit_test); - printf("\n%2d FAILED %s\n", num_failures, - num_failures == 1 ? "TEST" : "TESTS"); + PrintFailedTestSuites(unit_test); } int num_disabled = unit_test.reportable_disabled_test_count(); if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) { - if (!num_failures) { + if (unit_test.Passed()) { printf("\n"); // Add a spacer if no FAILURE banner is displayed. } - ColoredPrintf(COLOR_YELLOW, - " YOU HAVE %d DISABLED %s\n\n", - num_disabled, - num_disabled == 1 ? "TEST" : "TESTS"); + ColoredPrintf(GTestColor::kYellow, " YOU HAVE %d DISABLED %s\n\n", + num_disabled, num_disabled == 1 ? "TEST" : "TESTS"); } // Ensure that Google Test output is printed before, e.g., heapchecker output. fflush(stdout); @@ -4908,7 +5168,6 @@ int UnitTest::Run() { _set_abort_behavior( 0x0, // Clear the following flags: _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. -# endif // In debug mode, the Windows CRT can crash with an assertion over invalid // input (e.g. passing an invalid file descriptor). The default handling @@ -4919,6 +5178,7 @@ int UnitTest::Run() { _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); (void)_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); } +# endif } #endif // GTEST_OS_WINDOWS @@ -5299,7 +5559,7 @@ bool UnitTestImpl::RunAllTests() { // Shuffles test suites and tests if requested. if (has_tests_to_run && GTEST_FLAG(shuffle)) { - random()->Reseed(static_cast<UInt32>(random_seed_)); + random()->Reseed(static_cast<uint32_t>(random_seed_)); // This should be done before calling OnTestIterationStart(), // such that a test event listener can see the actual test order // in the event. @@ -5336,6 +5596,13 @@ bool UnitTestImpl::RunAllTests() { for (int test_index = 0; test_index < total_test_suite_count(); test_index++) { GetMutableSuiteCase(test_index)->Run(); + if (GTEST_FLAG(fail_fast) && + GetMutableSuiteCase(test_index)->Failed()) { + for (int j = test_index + 1; j < total_test_suite_count(); j++) { + GetMutableSuiteCase(j)->Skip(); + } + break; + } } } @@ -5374,14 +5641,14 @@ bool UnitTestImpl::RunAllTests() { if (!gtest_is_initialized_before_run_all_tests) { ColoredPrintf( - COLOR_RED, + GTestColor::kRed, "\nIMPORTANT NOTICE - DO NOT IGNORE:\n" "This test program did NOT call " GTEST_INIT_GOOGLE_TEST_NAME_ "() before calling RUN_ALL_TESTS(). This is INVALID. Soon " GTEST_NAME_ " will start to enforce the valid usage. " "Please fix it ASAP, or IT WILL START TO FAIL.\n"); // NOLINT #if GTEST_FOR_GOOGLE_ - ColoredPrintf(COLOR_RED, + ColoredPrintf(GTestColor::kRed, "For more details, see http://wiki/Main/ValidGUnitMain.\n"); #endif // GTEST_FOR_GOOGLE_ } @@ -5398,7 +5665,7 @@ void WriteToShardStatusFileIfNeeded() { if (test_shard_file != nullptr) { FILE* const file = posix::FOpen(test_shard_file, "w"); if (file == nullptr) { - ColoredPrintf(COLOR_RED, + ColoredPrintf(GTestColor::kRed, "Could not write to the test shard status file \"%s\" " "specified by the %s environment variable.\n", test_shard_file, kTestShardStatusFile); @@ -5422,8 +5689,8 @@ bool ShouldShard(const char* total_shards_env, return false; } - const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1); - const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1); + const int32_t total_shards = Int32FromEnvOrDie(total_shards_env, -1); + const int32_t shard_index = Int32FromEnvOrDie(shard_index_env, -1); if (total_shards == -1 && shard_index == -1) { return false; @@ -5432,7 +5699,7 @@ bool ShouldShard(const char* total_shards_env, << "Invalid environment variables: you have " << kTestShardIndex << " = " << shard_index << ", but have left " << kTestTotalShards << " unset.\n"; - ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str()); + ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str()); fflush(stdout); exit(EXIT_FAILURE); } else if (total_shards != -1 && shard_index == -1) { @@ -5440,7 +5707,7 @@ bool ShouldShard(const char* total_shards_env, << "Invalid environment variables: you have " << kTestTotalShards << " = " << total_shards << ", but have left " << kTestShardIndex << " unset.\n"; - ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str()); + ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str()); fflush(stdout); exit(EXIT_FAILURE); } else if (shard_index < 0 || shard_index >= total_shards) { @@ -5449,7 +5716,7 @@ bool ShouldShard(const char* total_shards_env, << kTestShardIndex << " < " << kTestTotalShards << ", but you have " << kTestShardIndex << "=" << shard_index << ", " << kTestTotalShards << "=" << total_shards << ".\n"; - ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str()); + ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str()); fflush(stdout); exit(EXIT_FAILURE); } @@ -5460,13 +5727,13 @@ bool ShouldShard(const char* total_shards_env, // Parses the environment variable var as an Int32. If it is unset, // returns default_val. If it is not an Int32, prints an error // and aborts. -Int32 Int32FromEnvOrDie(const char* var, Int32 default_val) { +int32_t Int32FromEnvOrDie(const char* var, int32_t default_val) { const char* str_val = posix::GetEnv(var); if (str_val == nullptr) { return default_val; } - Int32 result; + int32_t result; if (!ParseInt32(Message() << "The value of environment variable " << var, str_val, &result)) { exit(EXIT_FAILURE); @@ -5490,9 +5757,9 @@ bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { // https://github.com/google/googletest/blob/master/googletest/docs/advanced.md // . Returns the number of tests that should run. int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { - const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? + const int32_t total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? Int32FromEnvOrDie(kTestTotalShards, -1) : -1; - const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? + const int32_t shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? Int32FromEnvOrDie(kTestShardIndex, -1) : -1; // num_runnable_tests are the number of tests that will @@ -5781,12 +6048,11 @@ static bool ParseBoolFlag(const char* str, const char* flag, bool* value) { return true; } -// Parses a string for an Int32 flag, in the form of -// "--flag=value". +// Parses a string for an int32_t flag, in the form of "--flag=value". // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. -bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { +bool ParseInt32Flag(const char* str, const char* flag, int32_t* value) { // Gets the value of the flag as a string. const char* const value_str = ParseFlagValue(str, flag, false); @@ -5798,8 +6064,7 @@ bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { value_str, value); } -// Parses a string for a string flag, in the form of -// "--flag=value". +// Parses a string for a string flag, in the form of "--flag=value". // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. @@ -5841,7 +6106,7 @@ static bool HasGoogleTestFlagPrefix(const char* str) { // @D changes to the default terminal text color. // static void PrintColorEncoded(const char* str) { - GTestColor color = COLOR_DEFAULT; // The current color. + GTestColor color = GTestColor::kDefault; // The current color. // Conceptually, we split the string into segments divided by escape // sequences. Then we print one segment at a time. At the end of @@ -5861,13 +6126,13 @@ static void PrintColorEncoded(const char* str) { if (ch == '@') { ColoredPrintf(color, "@"); } else if (ch == 'D') { - color = COLOR_DEFAULT; + color = GTestColor::kDefault; } else if (ch == 'R') { - color = COLOR_RED; + color = GTestColor::kRed; } else if (ch == 'G') { - color = COLOR_GREEN; + color = GTestColor::kGreen; } else if (ch == 'Y') { - color = COLOR_YELLOW; + color = GTestColor::kYellow; } else { --str; } @@ -5942,31 +6207,31 @@ static const char kColorEncodedHelpMessage[] = static bool ParseGoogleTestFlag(const char* const arg) { return ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, >EST_FLAG(also_run_disabled_tests)) || - ParseBoolFlag(arg, kBreakOnFailureFlag, - >EST_FLAG(break_on_failure)) || - ParseBoolFlag(arg, kCatchExceptionsFlag, - >EST_FLAG(catch_exceptions)) || - ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || - ParseStringFlag(arg, kDeathTestStyleFlag, - >EST_FLAG(death_test_style)) || - ParseBoolFlag(arg, kDeathTestUseFork, - >EST_FLAG(death_test_use_fork)) || - ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || - ParseStringFlag(arg, kInternalRunDeathTestFlag, - >EST_FLAG(internal_run_death_test)) || - ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || - ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || - ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || - ParseBoolFlag(arg, kPrintUTF8Flag, >EST_FLAG(print_utf8)) || - ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || - ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || - ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || - ParseInt32Flag(arg, kStackTraceDepthFlag, - >EST_FLAG(stack_trace_depth)) || - ParseStringFlag(arg, kStreamResultToFlag, - >EST_FLAG(stream_result_to)) || - ParseBoolFlag(arg, kThrowOnFailureFlag, - >EST_FLAG(throw_on_failure)); + ParseBoolFlag(arg, kBreakOnFailureFlag, + >EST_FLAG(break_on_failure)) || + ParseBoolFlag(arg, kCatchExceptionsFlag, + >EST_FLAG(catch_exceptions)) || + ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || + ParseStringFlag(arg, kDeathTestStyleFlag, + >EST_FLAG(death_test_style)) || + ParseBoolFlag(arg, kDeathTestUseFork, + >EST_FLAG(death_test_use_fork)) || + ParseBoolFlag(arg, kFailFast, >EST_FLAG(fail_fast)) || + ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || + ParseStringFlag(arg, kInternalRunDeathTestFlag, + >EST_FLAG(internal_run_death_test)) || + ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || + ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || + ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || + ParseBoolFlag(arg, kPrintUTF8Flag, >EST_FLAG(print_utf8)) || + ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || + ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || + ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || + ParseInt32Flag(arg, kStackTraceDepthFlag, + >EST_FLAG(stack_trace_depth)) || + ParseStringFlag(arg, kStreamResultToFlag, + >EST_FLAG(stream_result_to)) || + ParseBoolFlag(arg, kThrowOnFailureFlag, >EST_FLAG(throw_on_failure)); } #if GTEST_USE_OWN_FLAGFILE_FLAG_ @@ -6149,7 +6414,11 @@ std::string TempDir() { else return std::string(temp_dir) + "\\"; #elif GTEST_OS_LINUX_ANDROID - return "/sdcard/"; + const char* temp_dir = internal::posix::GetEnv("TEST_TMPDIR"); + if (temp_dir == nullptr || temp_dir[0] == '\0') + return "/data/local/tmp/"; + else + return temp_dir; #else return "/tmp/"; #endif // GTEST_OS_WINDOWS_MOBILE diff --git a/googletest/test/BUILD.bazel b/googletest/test/BUILD.bazel index 224e6e6e..e24f5f22 100644 --- a/googletest/test/BUILD.bazel +++ b/googletest/test/BUILD.bazel @@ -28,8 +28,6 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -# Author: misterg@google.com (Gennadiy Civil) -# # Bazel BUILD for The Google C++ Testing Framework (Google Test) load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test") @@ -56,15 +54,18 @@ cc_test( "gtest-listener_test.cc", "gtest-unittest-api_test.cc", "googletest-param-test-test.cc", + "googletest-param-test2-test.cc", "googletest-catch-exceptions-test_.cc", "googletest-color-test_.cc", "googletest-env-var-test_.cc", + "googletest-failfast-unittest_.cc", "googletest-filter-unittest_.cc", "googletest-break-on-failure-unittest_.cc", "googletest-listener-test.cc", "googletest-output-test_.cc", "googletest-list-tests-unittest_.cc", "googletest-shuffle-test_.cc", + "googletest-setuptestsuite-test_.cc", "googletest-uninitialized-test_.cc", "googletest-death-test_ex_test.cc", "googletest-param-test-test", @@ -223,6 +224,21 @@ py_test( ) cc_binary( + name = "googletest-failfast-unittest_", + testonly = 1, + srcs = ["googletest-failfast-unittest_.cc"], + deps = ["//:gtest"], +) + +py_test( + name = "googletest-failfast-unittest", + size = "medium", + srcs = ["googletest-failfast-unittest.py"], + data = [":googletest-failfast-unittest_"], + deps = [":gtest_test_utils"], +) + +cc_binary( name = "googletest-filter-unittest_", testonly = 1, srcs = ["googletest-filter-unittest_.cc"], @@ -424,6 +440,21 @@ py_test( ) cc_binary( + name = "googletest-setuptestsuite-test_", + testonly = 1, + srcs = ["googletest-setuptestsuite-test_.cc"], + deps = ["//:gtest_main"], +) + +py_test( + name = "googletest-setuptestsuite-test", + size = "medium", + srcs = ["googletest-setuptestsuite-test.py"], + data = [":googletest-setuptestsuite-test_"], + deps = [":gtest_test_utils"], +) + +cc_binary( name = "googletest-uninitialized-test_", testonly = 1, srcs = ["googletest-uninitialized-test_.cc"], diff --git a/googletest/test/googletest-death-test-test.cc b/googletest/test/googletest-death-test-test.cc index cba906cc..b0dda27f 100644 --- a/googletest/test/googletest-death-test-test.cc +++ b/googletest/test/googletest-death-test-test.cc @@ -391,17 +391,19 @@ void SigprofAction(int, siginfo_t*, void*) { /* no op */ } // Sets SIGPROF action and ITIMER_PROF timer (interval: 1ms). void SetSigprofActionAndTimer() { - struct itimerval timer; - timer.it_interval.tv_sec = 0; - timer.it_interval.tv_usec = 1; - timer.it_value = timer.it_interval; - ASSERT_EQ(0, setitimer(ITIMER_PROF, &timer, nullptr)); struct sigaction signal_action; memset(&signal_action, 0, sizeof(signal_action)); sigemptyset(&signal_action.sa_mask); signal_action.sa_sigaction = SigprofAction; signal_action.sa_flags = SA_RESTART | SA_SIGINFO; ASSERT_EQ(0, sigaction(SIGPROF, &signal_action, nullptr)); + // timer comes second, to avoid SIGPROF premature delivery, as suggested at + // https://www.gnu.org/software/libc/manual/html_node/Setting-an-Alarm.html + struct itimerval timer; + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = 1; + timer.it_value = timer.it_interval; + ASSERT_EQ(0, setitimer(ITIMER_PROF, &timer, nullptr)); } // Disables ITIMER_PROF timer and ignores SIGPROF signal. diff --git a/googletest/test/googletest-env-var-test.py b/googletest/test/googletest-env-var-test.py index 2f0e406a..ce4d2a04 100755 --- a/googletest/test/googletest-env-var-test.py +++ b/googletest/test/googletest-env-var-test.py @@ -85,6 +85,8 @@ class GTestEnvVarTest(gtest_test_utils.TestCase): TestFlag('break_on_failure', '1', '0') TestFlag('color', 'yes', 'auto') + SetEnvVar('TESTBRIDGE_TEST_RUNNER_FAIL_FAST', None) # For 'fail_fast' test + TestFlag('fail_fast', '1', '0') TestFlag('filter', 'FooTest.Bar', '*') SetEnvVar('XML_OUTPUT_FILE', None) # For 'output' test TestFlag('output', 'xml:tmp/foo.xml', '') diff --git a/googletest/test/googletest-env-var-test_.cc b/googletest/test/googletest-env-var-test_.cc index fd2aa82f..66d18712 100644 --- a/googletest/test/googletest-env-var-test_.cc +++ b/googletest/test/googletest-env-var-test_.cc @@ -72,6 +72,11 @@ void PrintFlag(const char* flag) { return; } + if (strcmp(flag, "fail_fast") == 0) { + cout << GTEST_FLAG(fail_fast); + return; + } + if (strcmp(flag, "filter") == 0) { cout << GTEST_FLAG(filter); return; diff --git a/googletest/test/googletest-failfast-unittest.py b/googletest/test/googletest-failfast-unittest.py new file mode 100755 index 00000000..3aeb2dff --- /dev/null +++ b/googletest/test/googletest-failfast-unittest.py @@ -0,0 +1,410 @@ +#!/usr/bin/env python +# +# Copyright 2020 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. + +"""Unit test for Google Test fail_fast. + +A user can specify if a Google Test program should continue test execution +after a test failure via the GTEST_FAIL_FAST environment variable or the +--gtest_fail_fast flag. The default value of the flag can also be changed +by Bazel fail fast environment variable TESTBRIDGE_TEST_RUNNER_FAIL_FAST. + +This script tests such functionality by invoking googletest-failfast-unittest_ +(a program written with Google Test) with different environments and command +line flags. +""" + +import os +import gtest_test_utils + +# Constants. + +# Bazel testbridge environment variable for fail fast +BAZEL_FAIL_FAST_ENV_VAR = 'TESTBRIDGE_TEST_RUNNER_FAIL_FAST' + +# The environment variable for specifying fail fast. +FAIL_FAST_ENV_VAR = 'GTEST_FAIL_FAST' + +# The command line flag for specifying fail fast. +FAIL_FAST_FLAG = 'gtest_fail_fast' + +# The command line flag to run disabled tests. +RUN_DISABLED_FLAG = 'gtest_also_run_disabled_tests' + +# The command line flag for specifying a filter. +FILTER_FLAG = 'gtest_filter' + +# Command to run the googletest-failfast-unittest_ program. +COMMAND = gtest_test_utils.GetTestExecutablePath( + 'googletest-failfast-unittest_') + +# The command line flag to tell Google Test to output the list of tests it +# will run. +LIST_TESTS_FLAG = '--gtest_list_tests' + +# Indicates whether Google Test supports death tests. +SUPPORTS_DEATH_TESTS = 'HasDeathTest' in gtest_test_utils.Subprocess( + [COMMAND, LIST_TESTS_FLAG]).output + +# Utilities. + +environ = os.environ.copy() + + +def SetEnvVar(env_var, value): + """Sets the env variable to 'value'; unsets it when 'value' is None.""" + + if value is not None: + environ[env_var] = value + elif env_var in environ: + del environ[env_var] + + +def RunAndReturnOutput(test_suite=None, fail_fast=None, run_disabled=False): + """Runs the test program and returns its output.""" + + args = [] + xml_path = os.path.join(gtest_test_utils.GetTempDir(), + '.GTestFailFastUnitTest.xml') + args += ['--gtest_output=xml:' + xml_path] + if fail_fast is not None: + if isinstance(fail_fast, str): + args += ['--%s=%s' % (FAIL_FAST_FLAG, fail_fast)] + elif fail_fast: + args += ['--%s' % FAIL_FAST_FLAG] + else: + args += ['--no%s' % FAIL_FAST_FLAG] + if test_suite: + args += ['--%s=%s.*' % (FILTER_FLAG, test_suite)] + if run_disabled: + args += ['--%s' % RUN_DISABLED_FLAG] + txt_out = gtest_test_utils.Subprocess([COMMAND] + args, env=environ).output + with open(xml_path) as xml_file: + return txt_out, xml_file.read() + + +# The unit test. +class GTestFailFastUnitTest(gtest_test_utils.TestCase): + """Tests the env variable or the command line flag for fail_fast.""" + + def testDefaultBehavior(self): + """Tests the behavior of not specifying the fail_fast.""" + + txt, _ = RunAndReturnOutput() + self.assertIn('22 FAILED TEST', txt) + + def testGoogletestFlag(self): + txt, _ = RunAndReturnOutput(test_suite='HasSimpleTest', fail_fast=True) + self.assertIn('1 FAILED TEST', txt) + self.assertIn('[ SKIPPED ] 3 tests', txt) + + txt, _ = RunAndReturnOutput(test_suite='HasSimpleTest', fail_fast=False) + self.assertIn('4 FAILED TEST', txt) + self.assertNotIn('[ SKIPPED ]', txt) + + def testGoogletestEnvVar(self): + """Tests the behavior of specifying fail_fast via Googletest env var.""" + + try: + SetEnvVar(FAIL_FAST_ENV_VAR, '1') + txt, _ = RunAndReturnOutput('HasSimpleTest') + self.assertIn('1 FAILED TEST', txt) + self.assertIn('[ SKIPPED ] 3 tests', txt) + + SetEnvVar(FAIL_FAST_ENV_VAR, '0') + txt, _ = RunAndReturnOutput('HasSimpleTest') + self.assertIn('4 FAILED TEST', txt) + self.assertNotIn('[ SKIPPED ]', txt) + finally: + SetEnvVar(FAIL_FAST_ENV_VAR, None) + + def testBazelEnvVar(self): + """Tests the behavior of specifying fail_fast via Bazel testbridge.""" + + try: + SetEnvVar(BAZEL_FAIL_FAST_ENV_VAR, '1') + txt, _ = RunAndReturnOutput('HasSimpleTest') + self.assertIn('1 FAILED TEST', txt) + self.assertIn('[ SKIPPED ] 3 tests', txt) + + SetEnvVar(BAZEL_FAIL_FAST_ENV_VAR, '0') + txt, _ = RunAndReturnOutput('HasSimpleTest') + self.assertIn('4 FAILED TEST', txt) + self.assertNotIn('[ SKIPPED ]', txt) + finally: + SetEnvVar(BAZEL_FAIL_FAST_ENV_VAR, None) + + def testFlagOverridesEnvVar(self): + """Tests precedence of flag over env var.""" + + try: + SetEnvVar(FAIL_FAST_ENV_VAR, '0') + txt, _ = RunAndReturnOutput('HasSimpleTest', True) + self.assertIn('1 FAILED TEST', txt) + self.assertIn('[ SKIPPED ] 3 tests', txt) + finally: + SetEnvVar(FAIL_FAST_ENV_VAR, None) + + def testGoogletestEnvVarOverridesBazelEnvVar(self): + """Tests that the Googletest native env var over Bazel testbridge.""" + + try: + SetEnvVar(BAZEL_FAIL_FAST_ENV_VAR, '0') + SetEnvVar(FAIL_FAST_ENV_VAR, '1') + txt, _ = RunAndReturnOutput('HasSimpleTest') + self.assertIn('1 FAILED TEST', txt) + self.assertIn('[ SKIPPED ] 3 tests', txt) + finally: + SetEnvVar(FAIL_FAST_ENV_VAR, None) + SetEnvVar(BAZEL_FAIL_FAST_ENV_VAR, None) + + def testEventListener(self): + txt, _ = RunAndReturnOutput(test_suite='HasSkipTest', fail_fast=True) + self.assertIn('1 FAILED TEST', txt) + self.assertIn('[ SKIPPED ] 3 tests', txt) + for expected_count, callback in [(1, 'OnTestSuiteStart'), + (5, 'OnTestStart'), + (5, 'OnTestEnd'), + (5, 'OnTestPartResult'), + (1, 'OnTestSuiteEnd')]: + self.assertEqual( + expected_count, txt.count(callback), + 'Expected %d calls to callback %s match count on output: %s ' % + (expected_count, callback, txt)) + + txt, _ = RunAndReturnOutput(test_suite='HasSkipTest', fail_fast=False) + self.assertIn('3 FAILED TEST', txt) + self.assertIn('[ SKIPPED ] 1 test', txt) + for expected_count, callback in [(1, 'OnTestSuiteStart'), + (5, 'OnTestStart'), + (5, 'OnTestEnd'), + (5, 'OnTestPartResult'), + (1, 'OnTestSuiteEnd')]: + self.assertEqual( + expected_count, txt.count(callback), + 'Expected %d calls to callback %s match count on output: %s ' % + (expected_count, callback, txt)) + + def assertXmlResultCount(self, result, count, xml): + self.assertEqual( + count, xml.count('result="%s"' % result), + 'Expected \'result="%s"\' match count of %s: %s ' % + (result, count, xml)) + + def assertXmlStatusCount(self, status, count, xml): + self.assertEqual( + count, xml.count('status="%s"' % status), + 'Expected \'status="%s"\' match count of %s: %s ' % + (status, count, xml)) + + def assertFailFastXmlAndTxtOutput(self, + fail_fast, + test_suite, + passed_count, + failure_count, + skipped_count, + suppressed_count, + run_disabled=False): + """Assert XML and text output of a test execution.""" + + txt, xml = RunAndReturnOutput(test_suite, fail_fast, run_disabled) + if failure_count > 0: + self.assertIn('%s FAILED TEST' % failure_count, txt) + if suppressed_count > 0: + self.assertIn('%s DISABLED TEST' % suppressed_count, txt) + if skipped_count > 0: + self.assertIn('[ SKIPPED ] %s tests' % skipped_count, txt) + self.assertXmlStatusCount('run', + passed_count + failure_count + skipped_count, xml) + self.assertXmlStatusCount('notrun', suppressed_count, xml) + self.assertXmlResultCount('completed', passed_count + failure_count, xml) + self.assertXmlResultCount('skipped', skipped_count, xml) + self.assertXmlResultCount('suppressed', suppressed_count, xml) + + def assertFailFastBehavior(self, + test_suite, + passed_count, + failure_count, + skipped_count, + suppressed_count, + run_disabled=False): + """Assert --fail_fast via flag.""" + + for fail_fast in ('true', '1', 't', True): + self.assertFailFastXmlAndTxtOutput(fail_fast, test_suite, passed_count, + failure_count, skipped_count, + suppressed_count, run_disabled) + + def assertNotFailFastBehavior(self, + test_suite, + passed_count, + failure_count, + skipped_count, + suppressed_count, + run_disabled=False): + """Assert --nofail_fast via flag.""" + + for fail_fast in ('false', '0', 'f', False): + self.assertFailFastXmlAndTxtOutput(fail_fast, test_suite, passed_count, + failure_count, skipped_count, + suppressed_count, run_disabled) + + def testFlag_HasFixtureTest(self): + """Tests the behavior of fail_fast and TEST_F.""" + self.assertFailFastBehavior( + test_suite='HasFixtureTest', + passed_count=1, + failure_count=1, + skipped_count=3, + suppressed_count=0) + self.assertNotFailFastBehavior( + test_suite='HasFixtureTest', + passed_count=1, + failure_count=4, + skipped_count=0, + suppressed_count=0) + + def testFlag_HasSimpleTest(self): + """Tests the behavior of fail_fast and TEST.""" + self.assertFailFastBehavior( + test_suite='HasSimpleTest', + passed_count=1, + failure_count=1, + skipped_count=3, + suppressed_count=0) + self.assertNotFailFastBehavior( + test_suite='HasSimpleTest', + passed_count=1, + failure_count=4, + skipped_count=0, + suppressed_count=0) + + def testFlag_HasParametersTest(self): + """Tests the behavior of fail_fast and TEST_P.""" + self.assertFailFastBehavior( + test_suite='HasParametersSuite/HasParametersTest', + passed_count=0, + failure_count=1, + skipped_count=3, + suppressed_count=0) + self.assertNotFailFastBehavior( + test_suite='HasParametersSuite/HasParametersTest', + passed_count=0, + failure_count=4, + skipped_count=0, + suppressed_count=0) + + def testFlag_HasDisabledTest(self): + """Tests the behavior of fail_fast and Disabled test cases.""" + self.assertFailFastBehavior( + test_suite='HasDisabledTest', + passed_count=1, + failure_count=1, + skipped_count=2, + suppressed_count=1, + run_disabled=False) + self.assertNotFailFastBehavior( + test_suite='HasDisabledTest', + passed_count=1, + failure_count=3, + skipped_count=0, + suppressed_count=1, + run_disabled=False) + + def testFlag_HasDisabledRunDisabledTest(self): + """Tests the behavior of fail_fast and Disabled test cases enabled.""" + self.assertFailFastBehavior( + test_suite='HasDisabledTest', + passed_count=1, + failure_count=1, + skipped_count=3, + suppressed_count=0, + run_disabled=True) + self.assertNotFailFastBehavior( + test_suite='HasDisabledTest', + passed_count=1, + failure_count=4, + skipped_count=0, + suppressed_count=0, + run_disabled=True) + + def testFlag_HasDisabledSuiteTest(self): + """Tests the behavior of fail_fast and Disabled test suites.""" + self.assertFailFastBehavior( + test_suite='DISABLED_HasDisabledSuite', + passed_count=0, + failure_count=0, + skipped_count=0, + suppressed_count=5, + run_disabled=False) + self.assertNotFailFastBehavior( + test_suite='DISABLED_HasDisabledSuite', + passed_count=0, + failure_count=0, + skipped_count=0, + suppressed_count=5, + run_disabled=False) + + def testFlag_HasDisabledSuiteRunDisabledTest(self): + """Tests the behavior of fail_fast and Disabled test suites enabled.""" + self.assertFailFastBehavior( + test_suite='DISABLED_HasDisabledSuite', + passed_count=1, + failure_count=1, + skipped_count=3, + suppressed_count=0, + run_disabled=True) + self.assertNotFailFastBehavior( + test_suite='DISABLED_HasDisabledSuite', + passed_count=1, + failure_count=4, + skipped_count=0, + suppressed_count=0, + run_disabled=True) + + if SUPPORTS_DEATH_TESTS: + + def testFlag_HasDeathTest(self): + """Tests the behavior of fail_fast and death tests.""" + self.assertFailFastBehavior( + test_suite='HasDeathTest', + passed_count=1, + failure_count=1, + skipped_count=3, + suppressed_count=0) + self.assertNotFailFastBehavior( + test_suite='HasDeathTest', + passed_count=1, + failure_count=4, + skipped_count=0, + suppressed_count=0) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/googletest/test/googletest-failfast-unittest_.cc b/googletest/test/googletest-failfast-unittest_.cc new file mode 100644 index 00000000..0b2c951b --- /dev/null +++ b/googletest/test/googletest-failfast-unittest_.cc @@ -0,0 +1,167 @@ +// Copyright 2005, 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. + + +// Unit test for Google Test test filters. +// +// A user can specify which test(s) in a Google Test program to run via +// either the GTEST_FILTER environment variable or the --gtest_filter +// flag. This is used for testing such functionality. +// +// The program will be invoked from a Python unit test. Don't run it +// directly. + +#include "gtest/gtest.h" + +namespace { + +// Test HasFixtureTest. + +class HasFixtureTest : public testing::Test {}; + +TEST_F(HasFixtureTest, Test0) {} + +TEST_F(HasFixtureTest, Test1) { FAIL() << "Expected failure."; } + +TEST_F(HasFixtureTest, Test2) { FAIL() << "Expected failure."; } + +TEST_F(HasFixtureTest, Test3) { FAIL() << "Expected failure."; } + +TEST_F(HasFixtureTest, Test4) { FAIL() << "Expected failure."; } + +// Test HasSimpleTest. + +TEST(HasSimpleTest, Test0) {} + +TEST(HasSimpleTest, Test1) { FAIL() << "Expected failure."; } + +TEST(HasSimpleTest, Test2) { FAIL() << "Expected failure."; } + +TEST(HasSimpleTest, Test3) { FAIL() << "Expected failure."; } + +TEST(HasSimpleTest, Test4) { FAIL() << "Expected failure."; } + +// Test HasDisabledTest. + +TEST(HasDisabledTest, Test0) {} + +TEST(HasDisabledTest, DISABLED_Test1) { FAIL() << "Expected failure."; } + +TEST(HasDisabledTest, Test2) { FAIL() << "Expected failure."; } + +TEST(HasDisabledTest, Test3) { FAIL() << "Expected failure."; } + +TEST(HasDisabledTest, Test4) { FAIL() << "Expected failure."; } + +// Test HasDeathTest + +TEST(HasDeathTest, Test0) { EXPECT_DEATH_IF_SUPPORTED(exit(1), ".*"); } + +TEST(HasDeathTest, Test1) { + EXPECT_DEATH_IF_SUPPORTED(FAIL() << "Expected failure.", ".*"); +} + +TEST(HasDeathTest, Test2) { + EXPECT_DEATH_IF_SUPPORTED(FAIL() << "Expected failure.", ".*"); +} + +TEST(HasDeathTest, Test3) { + EXPECT_DEATH_IF_SUPPORTED(FAIL() << "Expected failure.", ".*"); +} + +TEST(HasDeathTest, Test4) { + EXPECT_DEATH_IF_SUPPORTED(FAIL() << "Expected failure.", ".*"); +} + +// Test DISABLED_HasDisabledSuite + +TEST(DISABLED_HasDisabledSuite, Test0) {} + +TEST(DISABLED_HasDisabledSuite, Test1) { FAIL() << "Expected failure."; } + +TEST(DISABLED_HasDisabledSuite, Test2) { FAIL() << "Expected failure."; } + +TEST(DISABLED_HasDisabledSuite, Test3) { FAIL() << "Expected failure."; } + +TEST(DISABLED_HasDisabledSuite, Test4) { FAIL() << "Expected failure."; } + +// Test HasParametersTest + +class HasParametersTest : public testing::TestWithParam<int> {}; + +TEST_P(HasParametersTest, Test1) { FAIL() << "Expected failure."; } + +TEST_P(HasParametersTest, Test2) { FAIL() << "Expected failure."; } + +INSTANTIATE_TEST_SUITE_P(HasParametersSuite, HasParametersTest, + testing::Values(1, 2)); + +class MyTestListener : public ::testing::EmptyTestEventListener { + void OnTestSuiteStart(const ::testing::TestSuite& test_suite) override { + printf("We are in OnTestSuiteStart of %s.\n", test_suite.name()); + } + + void OnTestStart(const ::testing::TestInfo& test_info) override { + printf("We are in OnTestStart of %s.%s.\n", test_info.test_suite_name(), + test_info.name()); + } + + void OnTestPartResult( + const ::testing::TestPartResult& test_part_result) override { + printf("We are in OnTestPartResult %s:%d.\n", test_part_result.file_name(), + test_part_result.line_number()); + } + + void OnTestEnd(const ::testing::TestInfo& test_info) override { + printf("We are in OnTestEnd of %s.%s.\n", test_info.test_suite_name(), + test_info.name()); + } + + void OnTestSuiteEnd(const ::testing::TestSuite& test_suite) override { + printf("We are in OnTestSuiteEnd of %s.\n", test_suite.name()); + } +}; + +TEST(HasSkipTest, Test0) { SUCCEED() << "Expected success."; } + +TEST(HasSkipTest, Test1) { GTEST_SKIP() << "Expected skip."; } + +TEST(HasSkipTest, Test2) { FAIL() << "Expected failure."; } + +TEST(HasSkipTest, Test3) { FAIL() << "Expected failure."; } + +TEST(HasSkipTest, Test4) { FAIL() << "Expected failure."; } + +} // namespace + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + ::testing::UnitTest::GetInstance()->listeners().Append(new MyTestListener()); + return RUN_ALL_TESTS(); +} diff --git a/googletest/test/googletest-output-test-golden-lin.txt b/googletest/test/googletest-output-test-golden-lin.txt index 270b15ae..8bc45800 100644 --- a/googletest/test/googletest-output-test-golden-lin.txt +++ b/googletest/test/googletest-output-test-golden-lin.txt @@ -12,7 +12,7 @@ Expected equality of these values: 3 Stack trace: (omitted) -[0;32m[==========] [mRunning 84 tests from 39 test suites. +[0;32m[==========] [mRunning 88 tests from 41 test suites. [0;32m[----------] [mGlobal test environment set-up. FooEnvironment::SetUp() called. BarEnvironment::SetUp() called. @@ -966,6 +966,9 @@ Expected equality of these values: Stack trace: (omitted) [0;31m[ FAILED ] [mPrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 +[0;32m[----------] [m1 test from EmptyBasenameParamInst +[0;32m[ RUN ] [mEmptyBasenameParamInst.Passes/0 +[0;32m[ OK ] [mEmptyBasenameParamInst.Passes/0 [0;32m[----------] [m2 tests from PrintingStrings/ParamTest [0;32m[ RUN ] [mPrintingStrings/ParamTest.Success/a [0;32m[ OK ] [mPrintingStrings/ParamTest.Success/a @@ -979,6 +982,34 @@ Expected failure Stack trace: (omitted) [0;31m[ FAILED ] [mPrintingStrings/ParamTest.Failure/a, where GetParam() = "a" +[0;32m[----------] [m3 tests from GoogleTestVerification +[0;32m[ RUN ] [mGoogleTestVerification.UninstantiatedParamaterizedTestSuite<NoTests> +Paramaterized test suite NoTests is instantiated via INSTANTIATE_TEST_SUITE_P, but no tests are defined via TEST_P . No test cases will run. + +Ideally, INSTANTIATE_TEST_SUITE_P should only ever be invoked from code that always depend on code that provides TEST_P. Failing to do so is often an indication of dead code, e.g. the last TEST_P was removed but the rest got left behind. + +To suppress this error for this test suite, insert the following line (in a non-header) in the namespace it is defined in: + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(NoTests); +[0;32m[ OK ] [mGoogleTestVerification.UninstantiatedParamaterizedTestSuite<NoTests> +[0;32m[ RUN ] [mGoogleTestVerification.UninstantiatedParamaterizedTestSuite<DetectNotInstantiatedTest> +Paramaterized test suite DetectNotInstantiatedTest is defined via TEST_P, but never instantiated. None of the test cases will run. Either no INSTANTIATE_TEST_SUITE_P is provided or the only ones provided expand to nothing. + +Ideally, TEST_P definitions should only ever be included as part of binaries that intend to use them. (As opposed to, for example, being placed in a library that may be linked in to get other utilities.) + +To suppress this error for this test suite, insert the following line (in a non-header) in the namespace it is defined in: + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DetectNotInstantiatedTest); +[0;32m[ OK ] [mGoogleTestVerification.UninstantiatedParamaterizedTestSuite<DetectNotInstantiatedTest> +[0;32m[ RUN ] [mGoogleTestVerification.UninstantiatedTypeParamaterizedTestSuite<DetectNotInstantiatedTypesTest> +Type paramaterized test suite DetectNotInstantiatedTypesTest is defined via REGISTER_TYPED_TEST_SUITE_P, but never instantiated via INSTANTIATE_TYPED_TEST_SUITE_P. None of the test cases will run. + +Ideally, TYPED_TEST_P definitions should only ever be included as part of binaries that intend to use them. (As opposed to, for example, being placed in a library that may be linked in to get other utilities.) + +To suppress this error for this test suite, insert the following line (in a non-header) in the namespace it is definedin in: + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DetectNotInstantiatedTypesTest); +[0;32m[ OK ] [mGoogleTestVerification.UninstantiatedTypeParamaterizedTestSuite<DetectNotInstantiatedTypesTest> [0;32m[----------] [mGlobal test environment tear-down BarEnvironment::TearDown() called. googletest-output-test_.cc:#: Failure @@ -992,8 +1023,8 @@ Failed Expected fatal failure. Stack trace: (omitted) -[0;32m[==========] [m84 tests from 39 test suites ran. -[0;32m[ PASSED ] [m30 tests. +[0;32m[==========] [m88 tests from 41 test suites ran. +[0;32m[ PASSED ] [m34 tests. [0;31m[ FAILED ] [m54 tests, listed below: [0;31m[ FAILED ] [mNonfatalFailureTest.EscapesStringOperands [0;31m[ FAILED ] [mNonfatalFailureTest.DiffForLongStrings diff --git a/googletest/test/googletest-output-test.py b/googletest/test/googletest-output-test.py index c727f17a..09028f66 100755 --- a/googletest/test/googletest-output-test.py +++ b/googletest/test/googletest-output-test.py @@ -29,7 +29,7 @@ # (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 the text output of Google C++ Testing and Mocking Framework. +r"""Tests the text output of Google C++ Testing and Mocking Framework. To update the golden file: googletest_output_test.py --build_dir=BUILD/DIR --gengolden @@ -331,7 +331,7 @@ if __name__ == '__main__': if CAN_GENERATE_GOLDEN_FILE: output = GetOutputOfAllCommands() golden_file = open(GOLDEN_PATH, 'wb') - golden_file.write(output) + golden_file.write(output.encode()) golden_file.close() else: message = ( diff --git a/googletest/test/googletest-output-test_.cc b/googletest/test/googletest-output-test_.cc index f724cca9..b32b8f3c 100644 --- a/googletest/test/googletest-output-test_.cc +++ b/googletest/test/googletest-output-test_.cc @@ -96,6 +96,14 @@ INSTANTIATE_TEST_SUITE_P(PrintingFailingParams, FailingParamTest, testing::Values(2)); +// Tests that an empty value for the test suite basename yields just +// the test name without any prior / +class EmptyBasenameParamInst : public testing::TestWithParam<int> {}; + +TEST_P(EmptyBasenameParamInst, Passes) { EXPECT_EQ(1, GetParam()); } + +INSTANTIATE_TEST_SUITE_P(, EmptyBasenameParamInst, testing::Values(1)); + static const char kGoldenString[] = "\"Line\0 1\"\nLine 2"; TEST(NonfatalFailureTest, EscapesStringOperands) { @@ -468,63 +476,6 @@ TEST(GtestFailAtTest, MessageContainsSpecifiedFileAndLineNumber) { GTEST_FAIL_AT("foo.cc", 42) << "Expected fatal failure in foo.cc"; } -#if GTEST_IS_THREADSAFE - -// A unary function that may die. -void DieIf(bool should_die) { - GTEST_CHECK_(!should_die) << " - death inside DieIf()."; -} - -// Tests running death tests in a multi-threaded context. - -// Used for coordination between the main and the spawn thread. -struct SpawnThreadNotifications { - SpawnThreadNotifications() {} - - Notification spawn_thread_started; - Notification spawn_thread_ok_to_terminate; - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(SpawnThreadNotifications); -}; - -// The function to be executed in the thread spawn by the -// MultipleThreads test (below). -static void ThreadRoutine(SpawnThreadNotifications* notifications) { - // Signals the main thread that this thread has started. - notifications->spawn_thread_started.Notify(); - - // Waits for permission to finish from the main thread. - notifications->spawn_thread_ok_to_terminate.WaitForNotification(); -} - -// This is a death-test test, but it's not named with a DeathTest -// suffix. It starts threads which might interfere with later -// death tests, so it must run after all other death tests. -class DeathTestAndMultiThreadsTest : public testing::Test { - protected: - // Starts a thread and waits for it to begin. - void SetUp() override { - thread_.reset(new ThreadWithParam<SpawnThreadNotifications*>( - &ThreadRoutine, ¬ifications_, nullptr)); - notifications_.spawn_thread_started.WaitForNotification(); - } - // Tells the thread to finish, and reaps it. - // Depending on the version of the thread library in use, - // a manager thread might still be left running that will interfere - // with later death tests. This is unfortunate, but this class - // cleans up after itself as best it can. - void TearDown() override { - notifications_.spawn_thread_ok_to_terminate.Notify(); - } - - private: - SpawnThreadNotifications notifications_; - std::unique_ptr<ThreadWithParam<SpawnThreadNotifications*> > thread_; -}; - -#endif // GTEST_IS_THREADSAFE - // The MixedUpTestSuiteTest test case verifies that Google Test will fail a // test if it uses a different fixture class than what other tests in // the same test case use. It deliberately contains two fixture @@ -782,6 +733,17 @@ INSTANTIATE_TEST_SUITE_P(PrintingStrings, testing::Values(std::string("a")), ParamNameFunc); +// The case where a suite has INSTANTIATE_TEST_SUITE_P but not TEST_P. +using NoTests = ParamTest; +INSTANTIATE_TEST_SUITE_P(ThisIsOdd, NoTests, ::testing::Values("Hello")); + +// fails under kErrorOnUninstantiatedParameterizedTest=true +class DetectNotInstantiatedTest : public testing::TestWithParam<int> {}; +TEST_P(DetectNotInstantiatedTest, Used) { } + +// This would make the test failure from the above go away. +// INSTANTIATE_TEST_SUITE_P(Fix, DetectNotInstantiatedTest, testing::Values(1)); + // This #ifdef block tests the output of typed tests. #if GTEST_HAS_TYPED_TEST @@ -861,6 +823,21 @@ class TypedTestPNames { INSTANTIATE_TYPED_TEST_SUITE_P(UnsignedCustomName, TypedTestP, UnsignedTypes, TypedTestPNames); +template <typename T> +class DetectNotInstantiatedTypesTest : public testing::Test {}; +TYPED_TEST_SUITE_P(DetectNotInstantiatedTypesTest); +TYPED_TEST_P(DetectNotInstantiatedTypesTest, Used) { + TypeParam instantiate; + (void)instantiate; +} +REGISTER_TYPED_TEST_SUITE_P(DetectNotInstantiatedTypesTest, Used); + +// kErrorOnUninstantiatedTypeParameterizedTest=true would make the above fail. +// Adding the following would make that test failure go away. +// +// typedef ::testing::Types<char, int, unsigned int> MyTypes; +// INSTANTIATE_TYPED_TEST_SUITE_P(All, DetectNotInstantiatedTypesTest, MyTypes); + #endif // GTEST_HAS_TYPED_TEST_P #if GTEST_HAS_DEATH_TEST diff --git a/googletest/test/googletest-param-test-test.cc b/googletest/test/googletest-param-test-test.cc index 2740aaab..6ba89654 100644 --- a/googletest/test/googletest-param-test-test.cc +++ b/googletest/test/googletest-param-test-test.cc @@ -1068,6 +1068,38 @@ TEST_P(MyEnumTest, ChecksParamMoreThanZero) { EXPECT_GE(10, GetParam()); } INSTANTIATE_TEST_SUITE_P(MyEnumTests, MyEnumTest, ::testing::Values(ENUM1, ENUM2, 0)); +namespace works_here { +// Never used not instantiated, this should work. +class NotUsedTest : public testing::TestWithParam<int> {}; + +/////// +// Never used not instantiated, this should work. +template <typename T> +class NotUsedTypeTest : public testing::Test {}; +TYPED_TEST_SUITE_P(NotUsedTypeTest); + +// Used but not instantiated, this would fail. but... +class NotInstantiatedTest : public testing::TestWithParam<int> {}; +// ... we mark is as allowed. +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(NotInstantiatedTest); + +TEST_P(NotInstantiatedTest, Used) { } + +using OtherName = NotInstantiatedTest; +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OtherName); +TEST_P(OtherName, Used) { } + +// Used but not instantiated, this would fail. but... +template <typename T> +class NotInstantiatedTypeTest : public testing::Test {}; +TYPED_TEST_SUITE_P(NotInstantiatedTypeTest); +// ... we mark is as allowed. +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(NotInstantiatedTypeTest); + +TYPED_TEST_P(NotInstantiatedTypeTest, Used) { } +REGISTER_TYPED_TEST_SUITE_P(NotInstantiatedTypeTest, Used); +} // namespace works_here + int main(int argc, char **argv) { // Used in TestGenerationTest test suite. AddGlobalTestEnvironment(TestGenerationTest::Environment::Instance()); diff --git a/googletest/test/googletest-printers-test.cc b/googletest/test/googletest-printers-test.cc index 58be7d1c..ddf2c0e1 100644 --- a/googletest/test/googletest-printers-test.cc +++ b/googletest/test/googletest-printers-test.cc @@ -33,11 +33,12 @@ // This file tests the universal value printer. #include <ctype.h> -#include <limits.h> #include <string.h> #include <algorithm> +#include <cstdint> #include <deque> #include <forward_list> +#include <limits> #include <list> #include <map> #include <set> @@ -339,23 +340,25 @@ TEST(PrintBuiltInTypeTest, Wchar_t) { EXPECT_EQ("L'\\xC74D' (51021)", Print(static_cast<wchar_t>(0xC74D))); } -// Test that Int64 provides more storage than wchar_t. +// Test that int64_t provides more storage than wchar_t. TEST(PrintTypeSizeTest, Wchar_t) { - EXPECT_LT(sizeof(wchar_t), sizeof(testing::internal::Int64)); + EXPECT_LT(sizeof(wchar_t), sizeof(int64_t)); } // Various integer types. TEST(PrintBuiltInTypeTest, Integer) { EXPECT_EQ("'\\xFF' (255)", Print(static_cast<unsigned char>(255))); // uint8 EXPECT_EQ("'\\x80' (-128)", Print(static_cast<signed char>(-128))); // int8 - EXPECT_EQ("65535", Print(USHRT_MAX)); // uint16 - EXPECT_EQ("-32768", Print(SHRT_MIN)); // int16 - EXPECT_EQ("4294967295", Print(UINT_MAX)); // uint32 - EXPECT_EQ("-2147483648", Print(INT_MIN)); // int32 + EXPECT_EQ("65535", Print(std::numeric_limits<uint16_t>::max())); // uint16 + EXPECT_EQ("-32768", Print(std::numeric_limits<int16_t>::min())); // int16 + EXPECT_EQ("4294967295", + Print(std::numeric_limits<uint32_t>::max())); // uint32 + EXPECT_EQ("-2147483648", + Print(std::numeric_limits<int32_t>::min())); // int32 EXPECT_EQ("18446744073709551615", - Print(static_cast<testing::internal::UInt64>(-1))); // uint64 + Print(std::numeric_limits<uint64_t>::max())); // uint64 EXPECT_EQ("-9223372036854775808", - Print(static_cast<testing::internal::Int64>(1) << 63)); // int64 + Print(std::numeric_limits<int64_t>::min())); // int64 } // Size types. @@ -757,22 +760,22 @@ TEST(PrintTypeWithGenericStreamingTest, TypeImplicitlyConvertible) { EXPECT_EQ("AllowsGenericStreamingAndImplicitConversionTemplate", Print(a)); } -#if GTEST_HAS_ABSL +#if GTEST_INTERNAL_HAS_STRING_VIEW -// Tests printing ::absl::string_view. +// Tests printing internal::StringView. TEST(PrintStringViewTest, SimpleStringView) { - const ::absl::string_view sp = "Hello"; + const internal::StringView sp = "Hello"; EXPECT_EQ("\"Hello\"", Print(sp)); } TEST(PrintStringViewTest, UnprintableCharacters) { const char str[] = "NUL (\0) and \r\t"; - const ::absl::string_view sp(str, sizeof(str) - 1); + const internal::StringView sp(str, sizeof(str) - 1); EXPECT_EQ("\"NUL (\\0) and \\r\\t\"", Print(sp)); } -#endif // GTEST_HAS_ABSL +#endif // GTEST_INTERNAL_HAS_STRING_VIEW // Tests printing STL containers. @@ -977,9 +980,8 @@ TEST(PrintStdTupleTest, VariousSizes) { EXPECT_EQ("(false, 2, 3, 4)", Print(t4)); const char* const str = "8"; - ::std::tuple<bool, char, short, testing::internal::Int32, // NOLINT - testing::internal::Int64, float, double, const char*, void*, - std::string> + ::std::tuple<bool, char, short, int32_t, int64_t, float, double, // NOLINT + const char*, void*, std::string> t10(false, 'a', static_cast<short>(3), 4, 5, 1.5F, -2.5, str, // NOLINT nullptr, "10"); EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) + diff --git a/googletest/test/googletest-setuptestsuite-test.py b/googletest/test/googletest-setuptestsuite-test.py new file mode 100755 index 00000000..c82162fc --- /dev/null +++ b/googletest/test/googletest-setuptestsuite-test.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python +# +# Copyright 2019, 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. + +"""Verifies that SetUpTestSuite and TearDownTestSuite errors are noticed.""" + +import gtest_test_utils + +COMMAND = gtest_test_utils.GetTestExecutablePath( + 'googletest-setuptestsuite-test_') + + +class GTestSetUpTestSuiteTest(gtest_test_utils.TestCase): + + def testSetupErrorAndTearDownError(self): + p = gtest_test_utils.Subprocess(COMMAND) + self.assertNotEqual(p.exit_code, 0, msg=p.output) + + self.assertIn( + '[ FAILED ] SetupFailTest: SetUpTestSuite or TearDownTestSuite\n' + '[ FAILED ] TearDownFailTest: SetUpTestSuite or TearDownTestSuite\n' + '\n' + ' 2 FAILED TEST SUITES\n', + p.output) + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/googletest/test/googletest-test2_test.cc b/googletest/test/googletest-setuptestsuite-test_.cc index 2e425dae..a4bc4ef4 100644 --- a/googletest/test/googletest-test2_test.cc +++ b/googletest/test/googletest-setuptestsuite-test_.cc @@ -27,35 +27,23 @@ // (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 Google Test itself. This verifies that the basic constructs of -// Google Test work. #include "gtest/gtest.h" -#include "googletest-param-test-test.h" - -using ::testing::Values; -using ::testing::internal::ParamGenerator; -// Tests that generators defined in a different translation unit -// are functional. The test using extern_gen_2 is defined -// in googletest-param-test-test.cc. -ParamGenerator<int> extern_gen_2 = Values(33); +class SetupFailTest : public ::testing::Test { + protected: + static void SetUpTestSuite() { + ASSERT_EQ("", "SET_UP_FAIL"); + } +}; -// Tests that a parameterized test case can be defined in one translation unit -// and instantiated in another. The test is defined in -// googletest-param-test-test.cc and ExternalInstantiationTest fixture class is -// defined in gtest-param-test_test.h. -INSTANTIATE_TEST_SUITE_P(MultiplesOf33, - ExternalInstantiationTest, - Values(33, 66)); +TEST_F(SetupFailTest, NoopPassingTest) {} -// Tests that a parameterized test case can be instantiated -// in multiple translation units. Another instantiation is defined -// in googletest-param-test-test.cc and -// InstantiationInMultipleTranslationUnitsTest fixture is defined in -// gtest-param-test_test.h -INSTANTIATE_TEST_SUITE_P(Sequence2, - InstantiationInMultipleTranslationUnitsTest, - Values(42*3, 42*4, 42*5)); +class TearDownFailTest : public ::testing::Test { + protected: + static void TearDownTestSuite() { + ASSERT_EQ("", "TEAR_DOWN_FAIL"); + } +}; +TEST_F(TearDownFailTest, NoopPassingTest) {} diff --git a/googletest/test/gtest-typed-test_test.cc b/googletest/test/gtest-typed-test_test.cc index 5411832a..0c1f660f 100644 --- a/googletest/test/gtest-typed-test_test.cc +++ b/googletest/test/gtest-typed-test_test.cc @@ -228,7 +228,7 @@ class TypedTestSuitePStateTest : public Test { TEST_F(TypedTestSuitePStateTest, SucceedsForMatchingList) { const char* tests = "A, B, C"; EXPECT_EQ(tests, - state_.VerifyRegisteredTestNames("foo.cc", 1, tests)); + state_.VerifyRegisteredTestNames("Suite", "foo.cc", 1, tests)); } // Makes sure that the order of the tests and spaces around the names @@ -236,33 +236,33 @@ TEST_F(TypedTestSuitePStateTest, SucceedsForMatchingList) { TEST_F(TypedTestSuitePStateTest, IgnoresOrderAndSpaces) { const char* tests = "A,C, B"; EXPECT_EQ(tests, - state_.VerifyRegisteredTestNames("foo.cc", 1, tests)); + state_.VerifyRegisteredTestNames("Suite", "foo.cc", 1, tests)); } using TypedTestSuitePStateDeathTest = TypedTestSuitePStateTest; TEST_F(TypedTestSuitePStateDeathTest, DetectsDuplicates) { EXPECT_DEATH_IF_SUPPORTED( - state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, A, C"), + state_.VerifyRegisteredTestNames("Suite", "foo.cc", 1, "A, B, A, C"), "foo\\.cc.1.?: Test A is listed more than once\\."); } TEST_F(TypedTestSuitePStateDeathTest, DetectsExtraTest) { EXPECT_DEATH_IF_SUPPORTED( - state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C, D"), + state_.VerifyRegisteredTestNames("Suite", "foo.cc", 1, "A, B, C, D"), "foo\\.cc.1.?: No test named D can be found in this test suite\\."); } TEST_F(TypedTestSuitePStateDeathTest, DetectsMissedTest) { EXPECT_DEATH_IF_SUPPORTED( - state_.VerifyRegisteredTestNames("foo.cc", 1, "A, C"), + state_.VerifyRegisteredTestNames("Suite", "foo.cc", 1, "A, C"), "foo\\.cc.1.?: You forgot to list test B\\."); } // Tests that defining a test for a parameterized test case generates // a run-time error if the test case has been registered. TEST_F(TypedTestSuitePStateDeathTest, DetectsTestAfterRegistration) { - state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C"); + state_.VerifyRegisteredTestNames("Suite", "foo.cc", 1, "A, B, C"); EXPECT_DEATH_IF_SUPPORTED( state_.AddTestName("foo.cc", 2, "FooTest", "D"), "foo\\.cc.2.?: Test D must be defined before REGISTER_TYPED_TEST_SUITE_P" diff --git a/googletest/test/gtest_pred_impl_unittest.cc b/googletest/test/gtest_pred_impl_unittest.cc index 1afe5e2d..bbef9947 100644 --- a/googletest/test/gtest_pred_impl_unittest.cc +++ b/googletest/test/gtest_pred_impl_unittest.cc @@ -27,7 +27,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// This file is AUTOMATICALLY GENERATED on 01/02/2019 by command +// This file is AUTOMATICALLY GENERATED on 11/05/2019 by command // 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! // Regression test for gtest_pred_impl.h @@ -78,9 +78,8 @@ bool PredFunction1(T1 v1) { return v1 > 0; } -// The following two functions are needed to circumvent a bug in -// gcc 2.95.3, which sometimes has problem with the above template -// function. +// The following two functions are needed because a compiler doesn't have +// a context yet to know which template function must be instantiated. bool PredFunction1Int(int v1) { return v1 > 0; } @@ -465,9 +464,8 @@ bool PredFunction2(T1 v1, T2 v2) { return v1 + v2 > 0; } -// The following two functions are needed to circumvent a bug in -// gcc 2.95.3, which sometimes has problem with the above template -// function. +// The following two functions are needed because a compiler doesn't have +// a context yet to know which template function must be instantiated. bool PredFunction2Int(int v1, int v2) { return v1 + v2 > 0; } @@ -894,9 +892,8 @@ bool PredFunction3(T1 v1, T2 v2, T3 v3) { return v1 + v2 + v3 > 0; } -// The following two functions are needed to circumvent a bug in -// gcc 2.95.3, which sometimes has problem with the above template -// function. +// The following two functions are needed because a compiler doesn't have +// a context yet to know which template function must be instantiated. bool PredFunction3Int(int v1, int v2, int v3) { return v1 + v2 + v3 > 0; } @@ -1365,9 +1362,8 @@ bool PredFunction4(T1 v1, T2 v2, T3 v3, T4 v4) { return v1 + v2 + v3 + v4 > 0; } -// The following two functions are needed to circumvent a bug in -// gcc 2.95.3, which sometimes has problem with the above template -// function. +// The following two functions are needed because a compiler doesn't have +// a context yet to know which template function must be instantiated. bool PredFunction4Int(int v1, int v2, int v3, int v4) { return v1 + v2 + v3 + v4 > 0; } @@ -1878,9 +1874,8 @@ bool PredFunction5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) { return v1 + v2 + v3 + v4 + v5 > 0; } -// The following two functions are needed to circumvent a bug in -// gcc 2.95.3, which sometimes has problem with the above template -// function. +// The following two functions are needed because a compiler doesn't have +// a context yet to know which template function must be instantiated. bool PredFunction5Int(int v1, int v2, int v3, int v4, int v5) { return v1 + v2 + v3 + v4 + v5 > 0; } diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc index 74379abc..005a2d40 100644 --- a/googletest/test/gtest_unittest.cc +++ b/googletest/test/gtest_unittest.cc @@ -37,21 +37,22 @@ // code once "gtest.h" has been #included. // Do not move it after other gtest #includes. TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { - bool dummy = testing::GTEST_FLAG(also_run_disabled_tests) - || testing::GTEST_FLAG(break_on_failure) - || testing::GTEST_FLAG(catch_exceptions) - || testing::GTEST_FLAG(color) != "unknown" - || testing::GTEST_FLAG(filter) != "unknown" - || testing::GTEST_FLAG(list_tests) - || testing::GTEST_FLAG(output) != "unknown" - || testing::GTEST_FLAG(print_time) - || testing::GTEST_FLAG(random_seed) - || testing::GTEST_FLAG(repeat) > 0 - || testing::GTEST_FLAG(show_internal_stack_frames) - || testing::GTEST_FLAG(shuffle) - || testing::GTEST_FLAG(stack_trace_depth) > 0 - || testing::GTEST_FLAG(stream_result_to) != "unknown" - || testing::GTEST_FLAG(throw_on_failure); + bool dummy = testing::GTEST_FLAG(also_run_disabled_tests) || + testing::GTEST_FLAG(break_on_failure) || + testing::GTEST_FLAG(catch_exceptions) || + testing::GTEST_FLAG(color) != "unknown" || + testing::GTEST_FLAG(fail_fast) || + testing::GTEST_FLAG(filter) != "unknown" || + testing::GTEST_FLAG(list_tests) || + testing::GTEST_FLAG(output) != "unknown" || + testing::GTEST_FLAG(print_time) || + testing::GTEST_FLAG(random_seed) || + testing::GTEST_FLAG(repeat) > 0 || + testing::GTEST_FLAG(show_internal_stack_frames) || + testing::GTEST_FLAG(shuffle) || + testing::GTEST_FLAG(stack_trace_depth) > 0 || + testing::GTEST_FLAG(stream_result_to) != "unknown" || + testing::GTEST_FLAG(throw_on_failure); EXPECT_TRUE(dummy || !dummy); // Suppresses warning that dummy is unused. } @@ -60,6 +61,7 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { #include <string.h> #include <time.h> +#include <cstdint> #include <map> #include <ostream> #include <type_traits> @@ -201,6 +203,7 @@ using testing::GTEST_FLAG(break_on_failure); using testing::GTEST_FLAG(catch_exceptions); using testing::GTEST_FLAG(color); using testing::GTEST_FLAG(death_test_use_fork); +using testing::GTEST_FLAG(fail_fast); using testing::GTEST_FLAG(filter); using testing::GTEST_FLAG(list_tests); using testing::GTEST_FLAG(output); @@ -249,7 +252,6 @@ using testing::internal::GetTestTypeId; using testing::internal::GetTimeInMillis; using testing::internal::GetTypeId; using testing::internal::GetUnitTestImpl; -using testing::internal::Int32; using testing::internal::Int32FromEnvOrDie; using testing::internal::IsAProtocolMessage; using testing::internal::IsContainer; @@ -271,7 +273,6 @@ using testing::internal::StreamableToString; using testing::internal::String; using testing::internal::TestEventListenersAccessor; using testing::internal::TestResultAccessor; -using testing::internal::UInt32; using testing::internal::UnitTestImpl; using testing::internal::WideStringToUtf8; using testing::internal::edit_distance::CalculateOptimalEdits; @@ -788,7 +789,7 @@ TEST(RandomDeathTest, GeneratesCrashesOnInvalidRange) { } TEST(RandomTest, GeneratesNumbersWithinRange) { - const UInt32 kRange = 10000; + constexpr uint32_t kRange = 10000; testing::internal::Random random(12345); for (int i = 0; i < 10; i++) { EXPECT_LT(random.Generate(kRange), kRange) << " for iteration " << i; @@ -801,10 +802,10 @@ TEST(RandomTest, GeneratesNumbersWithinRange) { } TEST(RandomTest, RepeatsWhenReseeded) { - const int kSeed = 123; - const int kArraySize = 10; - const UInt32 kRange = 10000; - UInt32 values[kArraySize]; + constexpr int kSeed = 123; + constexpr int kArraySize = 10; + constexpr uint32_t kRange = 10000; + uint32_t values[kArraySize]; testing::internal::Random random(kSeed); for (int i = 0; i < kArraySize; i++) { @@ -1599,6 +1600,7 @@ class GTestFlagSaverTest : public Test { GTEST_FLAG(catch_exceptions) = false; GTEST_FLAG(death_test_use_fork) = false; GTEST_FLAG(color) = "auto"; + GTEST_FLAG(fail_fast) = false; GTEST_FLAG(filter) = ""; GTEST_FLAG(list_tests) = false; GTEST_FLAG(output) = ""; @@ -1626,6 +1628,7 @@ class GTestFlagSaverTest : public Test { EXPECT_FALSE(GTEST_FLAG(catch_exceptions)); EXPECT_STREQ("auto", GTEST_FLAG(color).c_str()); EXPECT_FALSE(GTEST_FLAG(death_test_use_fork)); + EXPECT_FALSE(GTEST_FLAG(fail_fast)); EXPECT_STREQ("", GTEST_FLAG(filter).c_str()); EXPECT_FALSE(GTEST_FLAG(list_tests)); EXPECT_STREQ("", GTEST_FLAG(output).c_str()); @@ -1642,6 +1645,7 @@ class GTestFlagSaverTest : public Test { GTEST_FLAG(catch_exceptions) = true; GTEST_FLAG(color) = "no"; GTEST_FLAG(death_test_use_fork) = true; + GTEST_FLAG(fail_fast) = true; GTEST_FLAG(filter) = "abc"; GTEST_FLAG(list_tests) = true; GTEST_FLAG(output) = "xml:foo.xml"; @@ -1772,7 +1776,7 @@ TEST(Int32FromGTestEnvTest, ParsesAndReturnsValidValue) { // Tests that ParseInt32Flag() returns false and doesn't change the // output value when the flag has wrong format TEST(ParseInt32FlagTest, ReturnsFalseForInvalidFlag) { - Int32 value = 123; + int32_t value = 123; EXPECT_FALSE(ParseInt32Flag("--a=100", "b", &value)); EXPECT_EQ(123, value); @@ -1785,7 +1789,7 @@ TEST(ParseInt32FlagTest, ReturnsFalseForInvalidFlag) { TEST(ParseInt32FlagTest, ReturnsDefaultWhenValueOverflows) { printf("(expecting 2 warnings)\n"); - Int32 value = 123; + int32_t value = 123; EXPECT_FALSE(ParseInt32Flag("--abc=12345678987654321", "abc", &value)); EXPECT_EQ(123, value); @@ -1799,7 +1803,7 @@ TEST(ParseInt32FlagTest, ReturnsDefaultWhenValueOverflows) { TEST(ParseInt32FlagTest, ReturnsDefaultWhenValueIsInvalid) { printf("(expecting 2 warnings)\n"); - Int32 value = 123; + int32_t value = 123; EXPECT_FALSE(ParseInt32Flag("--abc=A1", "abc", &value)); EXPECT_EQ(123, value); @@ -1811,7 +1815,7 @@ TEST(ParseInt32FlagTest, ReturnsDefaultWhenValueIsInvalid) { // returns true when the flag represents a valid decimal integer in // the range of an Int32. TEST(ParseInt32FlagTest, ParsesAndReturnsValidValue) { - Int32 value = 123; + int32_t value = 123; EXPECT_TRUE(ParseInt32Flag("--" GTEST_FLAG_PREFIX_ "abc=456", "abc", &value)); EXPECT_EQ(456, value); @@ -1834,7 +1838,7 @@ TEST(Int32FromEnvOrDieTest, ParsesAndReturnsValidValue) { #endif // !GTEST_OS_WINDOWS_MOBILE // Tests that Int32FromEnvOrDie() aborts with an error message -// if the variable is not an Int32. +// if the variable is not an int32_t. TEST(Int32FromEnvOrDieDeathTest, AbortsOnFailure) { SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "xxx"); EXPECT_DEATH_IF_SUPPORTED( @@ -1843,7 +1847,7 @@ TEST(Int32FromEnvOrDieDeathTest, AbortsOnFailure) { } // Tests that Int32FromEnvOrDie() aborts with an error message -// if the variable cannot be represented by an Int32. +// if the variable cannot be represented by an int32_t. TEST(Int32FromEnvOrDieDeathTest, AbortsOnInt32Overflow) { SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "1234567891234567891234"); EXPECT_DEATH_IF_SUPPORTED( @@ -2924,22 +2928,18 @@ TEST_F(FloatTest, Commutative) { TEST_F(FloatTest, EXPECT_NEAR) { EXPECT_NEAR(-1.0f, -1.1f, 0.2f); EXPECT_NEAR(2.0f, 3.0f, 1.0f); - EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0f,1.5f, 0.25f), // NOLINT + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0f, 1.5f, 0.25f), // NOLINT "The difference between 1.0f and 1.5f is 0.5, " "which exceeds 0.25f"); - // To work around a bug in gcc 2.95.0, there is intentionally no - // space after the first comma in the previous line. } // Tests ASSERT_NEAR. TEST_F(FloatTest, ASSERT_NEAR) { ASSERT_NEAR(-1.0f, -1.1f, 0.2f); ASSERT_NEAR(2.0f, 3.0f, 1.0f); - EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0f,1.5f, 0.25f), // NOLINT + EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0f, 1.5f, 0.25f), // NOLINT "The difference between 1.0f and 1.5f is 0.5, " "which exceeds 0.25f"); - // To work around a bug in gcc 2.95.0, there is intentionally no - // space after the first comma in the previous line. } // Tests the cases where FloatLE() should succeed. @@ -3080,8 +3080,6 @@ TEST_F(DoubleTest, EXPECT_NEAR) { EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0, 1.5, 0.25), // NOLINT "The difference between 1.0 and 1.5 is 0.5, " "which exceeds 0.25"); - // To work around a bug in gcc 2.95.0, there is intentionally no - // space after the first comma in the previous statement. } // Tests ASSERT_NEAR. @@ -3091,8 +3089,6 @@ TEST_F(DoubleTest, ASSERT_NEAR) { EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0, 1.5, 0.25), // NOLINT "The difference between 1.0 and 1.5 is 0.5, " "which exceeds 0.25"); - // To work around a bug in gcc 2.95.0, there is intentionally no - // space after the first comma in the previous statement. } // Tests the cases where DoubleLE() should succeed. @@ -3737,10 +3733,6 @@ TEST(AssertionTest, ASSERT_EQ) { TEST(AssertionTest, ASSERT_EQ_NULL) { // A success. const char* p = nullptr; - // Some older GCC versions may issue a spurious warning in this or the next - // assertion statement. This warning should not be suppressed with - // static_cast since the test verifies the ability to use bare NULL as the - // expected parameter to the macro. ASSERT_EQ(nullptr, p); // A failure. @@ -4322,10 +4314,8 @@ TEST(AssertionWithMessageTest, ASSERT_STR) { TEST(AssertionWithMessageTest, ASSERT_FLOATING) { ASSERT_FLOAT_EQ(1, 1) << "This should succeed."; ASSERT_DOUBLE_EQ(1, 1) << "This should succeed."; - EXPECT_FATAL_FAILURE(ASSERT_NEAR(1,1.2, 0.1) << "Expect failure.", // NOLINT + EXPECT_FATAL_FAILURE(ASSERT_NEAR(1, 1.2, 0.1) << "Expect failure.", // NOLINT "Expect failure."); - // To work around a bug in gcc 2.95.0, there is intentionally no - // space after the first comma in the previous statement. } // Tests using ASSERT_FALSE with a streamed message. @@ -4466,10 +4456,6 @@ TEST(ExpectTest, EXPECT_EQ_Double) { TEST(ExpectTest, EXPECT_EQ_NULL) { // A success. const char* p = nullptr; - // Some older GCC versions may issue a spurious warning in this or the next - // assertion statement. This warning should not be suppressed with - // static_cast since the test verifies the ability to use bare NULL as the - // expected parameter to the macro. EXPECT_EQ(nullptr, p); // A failure. @@ -5356,7 +5342,7 @@ TEST_P(CodeLocationForTESTP, Verify) { VERIFY_CODE_LOCATION; } -INSTANTIATE_TEST_SUITE_P(All, CodeLocationForTESTP, Values(0)); +INSTANTIATE_TEST_SUITE_P(, CodeLocationForTESTP, Values(0)); template <typename T> class CodeLocationForTYPEDTEST : public Test { @@ -5514,20 +5500,22 @@ TEST_F(SetUpTestSuiteTest, TestSetupTestSuite2) { // The Flags struct stores a copy of all Google Test flags. struct Flags { // Constructs a Flags struct where each flag has its default value. - Flags() : also_run_disabled_tests(false), - break_on_failure(false), - catch_exceptions(false), - death_test_use_fork(false), - filter(""), - list_tests(false), - output(""), - print_time(true), - random_seed(0), - repeat(1), - shuffle(false), - stack_trace_depth(kMaxStackTraceDepth), - stream_result_to(""), - throw_on_failure(false) {} + Flags() + : also_run_disabled_tests(false), + break_on_failure(false), + catch_exceptions(false), + death_test_use_fork(false), + fail_fast(false), + filter(""), + list_tests(false), + output(""), + print_time(true), + random_seed(0), + repeat(1), + shuffle(false), + stack_trace_depth(kMaxStackTraceDepth), + stream_result_to(""), + throw_on_failure(false) {} // Factory methods. @@ -5563,6 +5551,14 @@ struct Flags { return flags; } + // Creates a Flags struct where the gtest_fail_fast flag has + // the given value. + static Flags FailFast(bool fail_fast) { + Flags flags; + flags.fail_fast = fail_fast; + return flags; + } + // Creates a Flags struct where the gtest_filter flag has the given // value. static Flags Filter(const char* filter) { @@ -5597,7 +5593,7 @@ struct Flags { // Creates a Flags struct where the gtest_random_seed flag has the given // value. - static Flags RandomSeed(Int32 random_seed) { + static Flags RandomSeed(int32_t random_seed) { Flags flags; flags.random_seed = random_seed; return flags; @@ -5605,7 +5601,7 @@ struct Flags { // Creates a Flags struct where the gtest_repeat flag has the given // value. - static Flags Repeat(Int32 repeat) { + static Flags Repeat(int32_t repeat) { Flags flags; flags.repeat = repeat; return flags; @@ -5621,7 +5617,7 @@ struct Flags { // Creates a Flags struct where the GTEST_FLAG(stack_trace_depth) flag has // the given value. - static Flags StackTraceDepth(Int32 stack_trace_depth) { + static Flags StackTraceDepth(int32_t stack_trace_depth) { Flags flags; flags.stack_trace_depth = stack_trace_depth; return flags; @@ -5648,14 +5644,15 @@ struct Flags { bool break_on_failure; bool catch_exceptions; bool death_test_use_fork; + bool fail_fast; const char* filter; bool list_tests; const char* output; bool print_time; - Int32 random_seed; - Int32 repeat; + int32_t random_seed; + int32_t repeat; bool shuffle; - Int32 stack_trace_depth; + int32_t stack_trace_depth; const char* stream_result_to; bool throw_on_failure; }; @@ -5669,6 +5666,7 @@ class ParseFlagsTest : public Test { GTEST_FLAG(break_on_failure) = false; GTEST_FLAG(catch_exceptions) = false; GTEST_FLAG(death_test_use_fork) = false; + GTEST_FLAG(fail_fast) = false; GTEST_FLAG(filter) = ""; GTEST_FLAG(list_tests) = false; GTEST_FLAG(output) = ""; @@ -5699,6 +5697,7 @@ class ParseFlagsTest : public Test { EXPECT_EQ(expected.break_on_failure, GTEST_FLAG(break_on_failure)); EXPECT_EQ(expected.catch_exceptions, GTEST_FLAG(catch_exceptions)); EXPECT_EQ(expected.death_test_use_fork, GTEST_FLAG(death_test_use_fork)); + EXPECT_EQ(expected.fail_fast, GTEST_FLAG(fail_fast)); EXPECT_STREQ(expected.filter, GTEST_FLAG(filter).c_str()); EXPECT_EQ(expected.list_tests, GTEST_FLAG(list_tests)); EXPECT_STREQ(expected.output, GTEST_FLAG(output).c_str()); @@ -5785,6 +5784,15 @@ TEST_F(ParseFlagsTest, NoFlag) { GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), false); } +// Tests parsing --gtest_fail_fast. +TEST_F(ParseFlagsTest, FailFast) { + const char* argv[] = {"foo.exe", "--gtest_fail_fast", nullptr}; + + const char* argv2[] = {"foo.exe", nullptr}; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::FailFast(true), false); +} + // Tests parsing a bad --gtest_filter flag. TEST_F(ParseFlagsTest, FilterBad) { const char* argv[] = {"foo.exe", "--gtest_filter", nullptr}; @@ -7096,7 +7104,7 @@ class ConversionHelperDerived : public ConversionHelperBase {}; // Tests that IsAProtocolMessage<T>::value is a compile-time constant. TEST(IsAProtocolMessageTest, ValueIsCompileTimeConstant) { - GTEST_COMPILE_ASSERT_(IsAProtocolMessage<::proto2::Message>::value, + GTEST_COMPILE_ASSERT_(IsAProtocolMessage<::proto2::MessageLite>::value, const_true); GTEST_COMPILE_ASSERT_(!IsAProtocolMessage<int>::value, const_false); } @@ -7104,7 +7112,7 @@ TEST(IsAProtocolMessageTest, ValueIsCompileTimeConstant) { // Tests that IsAProtocolMessage<T>::value is true when T is // proto2::Message or a sub-class of it. TEST(IsAProtocolMessageTest, ValueIsTrueWhenTypeIsAProtocolMessage) { - EXPECT_TRUE(IsAProtocolMessage< ::proto2::Message>::value); + EXPECT_TRUE(IsAProtocolMessage<::proto2::MessageLite>::value); } // Tests that IsAProtocolMessage<T>::value is false when T is neither @@ -7447,22 +7455,7 @@ TEST(SkipPrefixTest, DoesNotSkipWhenPrefixDoesNotMatch) { } // Tests ad_hoc_test_result(). - -class AdHocTestResultTest : public testing::Test { - protected: - static void SetUpTestSuite() { - FAIL() << "A failure happened inside SetUpTestSuite()."; - } -}; - -TEST_F(AdHocTestResultTest, AdHocTestResultForTestSuiteShowsFailure) { - const testing::TestResult& test_result = testing::UnitTest::GetInstance() - ->current_test_suite() - ->ad_hoc_test_result(); - EXPECT_TRUE(test_result.Failed()); -} - -TEST_F(AdHocTestResultTest, AdHocTestResultTestForUnitTestDoesNotShowFailure) { +TEST(AdHocTestResultTest, AdHocTestResultForUnitTestDoesNotShowFailure) { const testing::TestResult& test_result = testing::UnitTest::GetInstance()->ad_hoc_test_result(); EXPECT_FALSE(test_result.Failed()); diff --git a/library.json b/library.json index 91169b7f..f61bf003 100644 --- a/library.json +++ b/library.json @@ -25,14 +25,10 @@ "ci", "googlemock/cmake", "googlemock/scripts", - "googlemock/src/gmock-all.cc", - "googlemock/src/gmock_main.cc", "googlemock/test", "googlemock/CMakeLists.txt", "googletest/cmake", "googletest/scripts", - "googletest/src/gtest-all.cc", - "googletest/src/gtest_main.cc", "googletest/test", "googletest/CMakeLists.txt" ] |