diff options
author | Conor Burgess <Burgess.Conor@gmail.com> | 2018-08-17 17:15:32 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-17 17:15:32 +0100 |
commit | 687964c84f798ce331fc60f6b8f212410ef46b3c (patch) | |
tree | 20ed743afd555c46b91361cf864c76643f1d89b2 /googlemock | |
parent | f11a8f9131584cf4009eca8af8a66e920c1b7391 (diff) | |
parent | 02a8ca87735601466d8c564344f9be493da84708 (diff) | |
download | googletest-687964c84f798ce331fc60f6b8f212410ef46b3c.tar.gz googletest-687964c84f798ce331fc60f6b8f212410ef46b3c.tar.bz2 googletest-687964c84f798ce331fc60f6b8f212410ef46b3c.zip |
Merge branch 'master' into fix-argc
Diffstat (limited to 'googlemock')
64 files changed, 5193 insertions, 1943 deletions
diff --git a/googlemock/CMakeLists.txt b/googlemock/CMakeLists.txt index bac2e3bf..07b6ad28 100644 --- a/googlemock/CMakeLists.txt +++ b/googlemock/CMakeLists.txt @@ -5,10 +5,6 @@ # ctest. You can select which tests to run using 'ctest -R regex'. # For more options, run 'ctest --help'. -# BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to -# make it prominent in the GUI. -option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF) - option(gmock_build_tests "Build all of Google Mock's own tests." OFF) # A directory to find Google Test sources. @@ -55,6 +51,20 @@ endif() # if they are the same (the default). add_subdirectory("${gtest_dir}" "${gmock_BINARY_DIR}/gtest") + +# These commands only run if this is the main project +if(CMAKE_PROJECT_NAME STREQUAL "gmock" OR CMAKE_PROJECT_NAME STREQUAL "googletest-distribution") + + # BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to + # make it prominent in the GUI. + option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF) + +else() + + mark_as_advanced(gmock_build_tests) + +endif() + # Although Google Test's CMakeLists.txt calls this function, the # changes there don't affect the current scope. Therefore we have to # call it again here. @@ -128,13 +138,13 @@ if(INSTALL_GMOCK) # configure and install pkgconfig files configure_file( cmake/gmock.pc.in - "${CMAKE_BINARY_DIR}/gmock.pc" + "${gmock_BINARY_DIR}/gmock.pc" @ONLY) configure_file( cmake/gmock_main.pc.in - "${CMAKE_BINARY_DIR}/gmock_main.pc" + "${gmock_BINARY_DIR}/gmock_main.pc" @ONLY) - install(FILES "${CMAKE_BINARY_DIR}/gmock.pc" "${CMAKE_BINARY_DIR}/gmock_main.pc" + install(FILES "${gmock_BINARY_DIR}/gmock.pc" "${gmock_BINARY_DIR}/gmock_main.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") endif() diff --git a/googlemock/README.md b/googlemock/README.md index 1170cfab..ad374dea 100644 --- a/googlemock/README.md +++ b/googlemock/README.md @@ -53,7 +53,7 @@ the Apache License, which is different from Google Mock's license. If you are new to the project, we suggest that you read the user documentation in the following order: - * Learn the [basics](../../master/googletest/docs/Primer.md) of + * Learn the [basics](../../master/googletest/docs/primer.md) of Google Test, if you choose to use Google Mock with it (recommended). * Read [Google Mock for Dummies](../../master/googlemock/docs/ForDummies.md). * Read the instructions below on how to build Google Mock. @@ -129,20 +129,20 @@ build Google Mock and its tests, which has further requirements: If you have CMake available, it is recommended that you follow the [build instructions][gtest_cmakebuild] -as described for Google Test. +as described for Google Test. If are using Google Mock with an existing CMake project, the section [Incorporating Into An Existing CMake Project][gtest_incorpcmake] -may be of particular interest. -To make it work for Google Mock you will need to change +may be of particular interest. +To make it work for Google Mock you will need to change target_link_libraries(example gtest_main) -to +to target_link_libraries(example gmock_main) - + This works because `gmock_main` library is compiled with Google Test. However, it does not automatically add Google Test includes. Therefore you will also have to change @@ -161,8 +161,8 @@ to "${gtest_SOURCE_DIR}/include" "${gmock_SOURCE_DIR}/include") endif() -This will addtionally mark Google Mock includes as system, which will -silence compiler warnings when compiling your tests using clang with +This will addtionally mark Google Mock includes as system, which will +silence compiler warnings when compiling your tests using clang with `-Wpedantic -Wall -Wextra -Wconversion`. diff --git a/googlemock/docs/CheatSheet.md b/googlemock/docs/CheatSheet.md index c6367fdd..d54dd16a 100644 --- a/googlemock/docs/CheatSheet.md +++ b/googlemock/docs/CheatSheet.md @@ -178,6 +178,8 @@ divided into several categories: |`Ne(value)` |`argument != value`| |`IsNull()` |`argument` is a `NULL` pointer (raw or smart).| |`NotNull()` |`argument` is a non-null pointer (raw or smart).| +|`VariantWith<T>(m)` |`argument` is `variant<>` that holds the alternative of +type T with a value matching `m`.| |`Ref(variable)` |`argument` is a reference to `variable`.| |`TypedEq<type>(value)`|`argument` has type `type` and is equal to `value`. You may need to use this instead of `Eq(value)` when the mock function is overloaded.| @@ -227,7 +229,7 @@ The `argument` can be either a C string or a C++ string object: `ContainsRegex()` and `MatchesRegex()` use the regular expression syntax defined -[here](../../googletest/docs/AdvancedGuide.md#regular-expression-syntax). +[here](../../googletest/docs/advanced.md#regular-expression-syntax). `StrCaseEq()`, `StrCaseNe()`, `StrEq()`, and `StrNe()` work for wide strings as well. @@ -347,7 +349,7 @@ You can make a matcher from one or more other matchers: ## Matchers as Test Assertions ## -|`ASSERT_THAT(expression, m)`|Generates a [fatal failure](../../googletest/docs/Primer.md#assertions) if the value of `expression` doesn't match matcher `m`.| +|`ASSERT_THAT(expression, m)`|Generates a [fatal failure](../../googletest/docs/primer.md#assertions) if the value of `expression` doesn't match matcher `m`.| |:---------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------| |`EXPECT_THAT(expression, m)`|Generates a non-fatal failure if the value of `expression` doesn't match matcher `m`. | diff --git a/googlemock/docs/CookBook.md b/googlemock/docs/CookBook.md index c2565f1e..8809b0e7 100644 --- a/googlemock/docs/CookBook.md +++ b/googlemock/docs/CookBook.md @@ -2229,77 +2229,71 @@ versus ## Mocking Methods That Use Move-Only Types ## -C++11 introduced <em>move-only types</em>. A move-only-typed value can be moved from one object to another, but cannot be copied. `std::unique_ptr<T>` is probably the most commonly used move-only type. +C++11 introduced *move-only types*. A move-only-typed value can be moved from +one object to another, but cannot be copied. `std::unique_ptr<T>` is +probably the most commonly used move-only type. -Mocking a method that takes and/or returns move-only types presents some challenges, but nothing insurmountable. This recipe shows you how you can do it. +Mocking a method that takes and/or returns move-only types presents some +challenges, but nothing insurmountable. This recipe shows you how you can do it. +Note that the support for move-only method arguments was only introduced to +gMock in April 2017; in older code, you may find more complex +[workarounds](#LegacyMoveOnly) for lack of this feature. -Let’s say we are working on a fictional project that lets one post and share snippets called “buzzes”. Your code uses these types: +Let’s say we are working on a fictional project that lets one post and share +snippets called “buzzes”. Your code uses these types: -``` +```cpp enum class AccessLevel { kInternal, kPublic }; class Buzz { public: - explicit Buzz(AccessLevel access) { … } + explicit Buzz(AccessLevel access) { ... } ... }; class Buzzer { public: virtual ~Buzzer() {} - virtual std::unique_ptr<Buzz> MakeBuzz(const std::string& text) = 0; - virtual bool ShareBuzz(std::unique_ptr<Buzz> buzz, Time timestamp) = 0; + virtual std::unique_ptr<Buzz> MakeBuzz(StringPiece text) = 0; + virtual bool ShareBuzz(std::unique_ptr<Buzz> buzz, int64_t timestamp) = 0; ... }; ``` -A `Buzz` object represents a snippet being posted. A class that implements the `Buzzer` interface is capable of creating and sharing `Buzz`. Methods in `Buzzer` may return a `unique_ptr<Buzz>` or take a `unique_ptr<Buzz>`. Now we need to mock `Buzzer` in our tests. - -To mock a method that returns a move-only type, you just use the familiar `MOCK_METHOD` syntax as usual: - -``` -class MockBuzzer : public Buzzer { - public: - MOCK_METHOD1(MakeBuzz, std::unique_ptr<Buzz>(const std::string& text)); - … -}; -``` - -However, if you attempt to use the same `MOCK_METHOD` pattern to mock a method that takes a move-only parameter, you’ll get a compiler error currently: - -``` - // Does NOT compile! - MOCK_METHOD2(ShareBuzz, bool(std::unique_ptr<Buzz> buzz, Time timestamp)); -``` - -While it’s highly desirable to make this syntax just work, it’s not trivial and the work hasn’t been done yet. Fortunately, there is a trick you can apply today to get something that works nearly as well as this. +A `Buzz` object represents a snippet being posted. A class that implements the +`Buzzer` interface is capable of creating and sharing `Buzz`es. Methods in +`Buzzer` may return a `unique_ptr<Buzz>` or take a +`unique_ptr<Buzz>`. Now we need to mock `Buzzer` in our tests. -The trick, is to delegate the `ShareBuzz()` method to a mock method (let’s call it `DoShareBuzz()`) that does not take move-only parameters: +To mock a method that accepts or returns move-only types, you just use the +familiar `MOCK_METHOD` syntax as usual: -``` +```cpp class MockBuzzer : public Buzzer { public: - MOCK_METHOD1(MakeBuzz, std::unique_ptr<Buzz>(const std::string& text)); - MOCK_METHOD2(DoShareBuzz, bool(Buzz* buzz, Time timestamp)); - bool ShareBuzz(std::unique_ptr<Buzz> buzz, Time timestamp) { - return DoShareBuzz(buzz.get(), timestamp); - } + MOCK_METHOD1(MakeBuzz, std::unique_ptr<Buzz>(StringPiece text)); + MOCK_METHOD2(ShareBuzz, bool(std::unique_ptr<Buzz> buzz, int64_t timestamp)); }; ``` -Note that there's no need to define or declare `DoShareBuzz()` in a base class. You only need to define it as a `MOCK_METHOD` in the mock class. - -Now that we have the mock class defined, we can use it in tests. In the following code examples, we assume that we have defined a `MockBuzzer` object named `mock_buzzer_`: +Now that we have the mock class defined, we can use it in tests. In the +following code examples, we assume that we have defined a `MockBuzzer` object +named `mock_buzzer_`: -``` +```cpp MockBuzzer mock_buzzer_; ``` -First let’s see how we can set expectations on the `MakeBuzz()` method, which returns a `unique_ptr<Buzz>`. +First let’s see how we can set expectations on the `MakeBuzz()` method, which +returns a `unique_ptr<Buzz>`. -As usual, if you set an expectation without an action (i.e. the `.WillOnce()` or `.WillRepeated()` clause), when that expectation fires, the default action for that method will be taken. Since `unique_ptr<>` has a default constructor that returns a null `unique_ptr`, that’s what you’ll get if you don’t specify an action: +As usual, if you set an expectation without an action (i.e. the `.WillOnce()` or +`.WillRepeated()` clause), when that expectation fires, the default action for +that method will be taken. Since `unique_ptr<>` has a default constructor +that returns a null `unique_ptr`, that’s what you’ll get if you don’t specify an +action: -``` +```cpp // Use the default action. EXPECT_CALL(mock_buzzer_, MakeBuzz("hello")); @@ -2307,32 +2301,13 @@ As usual, if you set an expectation without an action (i.e. the `.WillOnce()` or EXPECT_EQ(nullptr, mock_buzzer_.MakeBuzz("hello")); ``` -If you are not happy with the default action, you can tweak it. Depending on what you need, you may either tweak the default action for a specific (mock object, mock method) combination using `ON_CALL()`, or you may tweak the default action for all mock methods that return a specific type. The usage of `ON_CALL()` is similar to `EXPECT_CALL()`, so we’ll skip it and just explain how to do the latter (tweaking the default action for a specific return type). You do this via the `DefaultValue<>::SetFactory()` and `DefaultValue<>::Clear()` API: - -``` - // Sets the default action for return type std::unique_ptr<Buzz> to - // creating a new Buzz every time. - DefaultValue<std::unique_ptr<Buzz>>::SetFactory( - [] { return MakeUnique<Buzz>(AccessLevel::kInternal); }); - - // When this fires, the default action of MakeBuzz() will run, which - // will return a new Buzz object. - EXPECT_CALL(mock_buzzer_, MakeBuzz("hello")).Times(AnyNumber()); +If you are not happy with the default action, you can tweak it as usual; see +[Setting Default Actions](#OnCall). - auto buzz1 = mock_buzzer_.MakeBuzz("hello"); - auto buzz2 = mock_buzzer_.MakeBuzz("hello"); - EXPECT_NE(nullptr, buzz1); - EXPECT_NE(nullptr, buzz2); - EXPECT_NE(buzz1, buzz2); +If you just need to return a pre-defined move-only value, you can use the +`Return(ByMove(...))` action: - // Resets the default action for return type std::unique_ptr<Buzz>, - // to avoid interfere with other tests. - DefaultValue<std::unique_ptr<Buzz>>::Clear(); -``` - -What if you want the method to do something other than the default action? If you just need to return a pre-defined move-only value, you can use the `Return(ByMove(...))` action: - -``` +```cpp // When this fires, the unique_ptr<> specified by ByMove(...) will // be returned. EXPECT_CALL(mock_buzzer_, MakeBuzz("world")) @@ -2343,81 +2318,87 @@ What if you want the method to do something other than the default action? If y Note that `ByMove()` is essential here - if you drop it, the code won’t compile. -Quiz time! What do you think will happen if a `Return(ByMove(...))` action is performed more than once (e.g. you write `….WillRepeatedly(Return(ByMove(...)));`)? Come think of it, after the first time the action runs, the source value will be consumed (since it’s a move-only value), so the next time around, there’s no value to move from -- you’ll get a run-time error that `Return(ByMove(...))` can only be run once. +Quiz time! What do you think will happen if a `Return(ByMove(...))` action is +performed more than once (e.g. you write +`.WillRepeatedly(Return(ByMove(...)));`)? Come think of it, after the first +time the action runs, the source value will be consumed (since it’s a move-only +value), so the next time around, there’s no value to move from -- you’ll get a +run-time error that `Return(ByMove(...))` can only be run once. -If you need your mock method to do more than just moving a pre-defined value, remember that you can always use `Invoke()` to call a lambda or a callable object, which can do pretty much anything you want: +If you need your mock method to do more than just moving a pre-defined value, +remember that you can always use a lambda or a callable object, which can do +pretty much anything you want: -``` +```cpp EXPECT_CALL(mock_buzzer_, MakeBuzz("x")) - .WillRepeatedly(Invoke([](const std::string& text) { - return std::make_unique<Buzz>(AccessLevel::kInternal); - })); + .WillRepeatedly([](StringPiece text) { + return MakeUnique<Buzz>(AccessLevel::kInternal); + }); EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("x")); EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("x")); ``` -Every time this `EXPECT_CALL` fires, a new `unique_ptr<Buzz>` will be created and returned. You cannot do this with `Return(ByMove(...))`. +Every time this `EXPECT_CALL` fires, a new `unique_ptr<Buzz>` will be +created and returned. You cannot do this with `Return(ByMove(...))`. -Now there’s one topic we haven’t covered: how do you set expectations on `ShareBuzz()`, which takes a move-only-typed parameter? The answer is you don’t. Instead, you set expectations on the `DoShareBuzz()` mock method (remember that we defined a `MOCK_METHOD` for `DoShareBuzz()`, not `ShareBuzz()`): +That covers returning move-only values; but how do we work with methods +accepting move-only arguments? The answer is that they work normally, although +some actions will not compile when any of method's arguments are move-only. You +can always use `Return`, or a [lambda or functor](#FunctionsAsActions): -``` - EXPECT_CALL(mock_buzzer_, DoShareBuzz(NotNull(), _)); +```cpp + using ::testing::Unused; - // When one calls ShareBuzz() on the MockBuzzer like this, the call is - // forwarded to DoShareBuzz(), which is mocked. Therefore this statement - // will trigger the above EXPECT_CALL. - mock_buzzer_.ShareBuzz(MakeUnique<Buzz>(AccessLevel::kInternal), - ::base::Now()); + EXPECT_CALL(mock_buzzer_, ShareBuzz(NotNull(), _)) .WillOnce(Return(true)); + EXPECT_TRUE(mock_buzzer_.ShareBuzz(MakeUnique<Buzz>(AccessLevel::kInternal)), + 0); + + EXPECT_CALL(mock_buzzer_, ShareBuzz(_, _)) .WillOnce( + [](std::unique_ptr<Buzz> buzz, Unused) { return buzz != nullptr; }); + EXPECT_FALSE(mock_buzzer_.ShareBuzz(nullptr, 0)); ``` -Some of you may have spotted one problem with this approach: the `DoShareBuzz()` mock method differs from the real `ShareBuzz()` method in that it cannot take ownership of the buzz parameter - `ShareBuzz()` will always delete buzz after `DoShareBuzz()` returns. What if you need to save the buzz object somewhere for later use when `ShareBuzz()` is called? Indeed, you'd be stuck. +Many built-in actions (`WithArgs`, `WithoutArgs`,`DeleteArg`, `SaveArg`, ...) +could in principle support move-only arguments, but the support for this is not +implemented yet. If this is blocking you, please file a bug. -Another problem with the `DoShareBuzz()` we had is that it can surprise people reading or maintaining the test, as one would expect that `DoShareBuzz()` has (logically) the same contract as `ShareBuzz()`. +A few actions (e.g. `DoAll`) copy their arguments internally, so they can never +work with non-copyable objects; you'll have to use functors instead. -Fortunately, these problems can be fixed with a bit more code. Let's try to get it right this time: +##### Legacy workarounds for move-only types {#LegacyMoveOnly} -``` +Support for move-only function arguments was only introduced to gMock in April +2017. In older code, you may encounter the following workaround for the lack of +this feature (it is no longer necessary - we're including it just for +reference): + +```cpp class MockBuzzer : public Buzzer { public: - MockBuzzer() { - // Since DoShareBuzz(buzz, time) is supposed to take ownership of - // buzz, define a default behavior for DoShareBuzz(buzz, time) to - // delete buzz. - ON_CALL(*this, DoShareBuzz(_, _)) - .WillByDefault(Invoke([](Buzz* buzz, Time timestamp) { - delete buzz; - return true; - })); - } - - MOCK_METHOD1(MakeBuzz, std::unique_ptr<Buzz>(const std::string& text)); - - // Takes ownership of buzz. MOCK_METHOD2(DoShareBuzz, bool(Buzz* buzz, Time timestamp)); - bool ShareBuzz(std::unique_ptr<Buzz> buzz, Time timestamp) { - return DoShareBuzz(buzz.release(), timestamp); + bool ShareBuzz(std::unique_ptr<Buzz> buzz, Time timestamp) override { + return DoShareBuzz(buzz.get(), timestamp); } }; ``` -Now, the mock `DoShareBuzz()` method is free to save the buzz argument for later use if this is what you want: +The trick is to delegate the `ShareBuzz()` method to a mock method (let’s call +it `DoShareBuzz()`) that does not take move-only parameters. Then, instead of +setting expectations on `ShareBuzz()`, you set them on the `DoShareBuzz()` mock +method: -``` - std::unique_ptr<Buzz> intercepted_buzz; - EXPECT_CALL(mock_buzzer_, DoShareBuzz(NotNull(), _)) - .WillOnce(Invoke([&intercepted_buzz](Buzz* buzz, Time timestamp) { - // Save buzz in intercepted_buzz for analysis later. - intercepted_buzz.reset(buzz); - return false; - })); +```cpp + MockBuzzer mock_buzzer_; + EXPECT_CALL(mock_buzzer_, DoShareBuzz(NotNull(), _)); - mock_buzzer_.ShareBuzz(std::make_unique<Buzz>(AccessLevel::kInternal), - Now()); - EXPECT_NE(nullptr, intercepted_buzz); + // When one calls ShareBuzz() on the MockBuzzer like this, the call is + // forwarded to DoShareBuzz(), which is mocked. Therefore this statement + // will trigger the above EXPECT_CALL. + mock_buzzer_.ShareBuzz(MakeUnique<Buzz>(AccessLevel::kInternal), 0); ``` -Using the tricks covered in this recipe, you are now able to mock methods that take and/or return move-only types. Put your newly-acquired power to good use - when you design a new API, you can now feel comfortable using `unique_ptrs` as appropriate, without fearing that doing so will compromise your tests. + ## Making the Compilation Faster ## @@ -3674,6 +3655,6 @@ This printer knows how to print built-in C++ types, native arrays, STL containers, and any type that supports the `<<` operator. For other types, it prints the raw bytes in the value and hopes that you the user can figure it out. -[Google Test's advanced guide](../../googletest/docs/AdvancedGuide.md#teaching-google-test-how-to-print-your-values) +[Google Test's advanced guide](../../googletest/docs/advanced.md#teaching-google-test-how-to-print-your-values) explains how to extend the printer to do a better job at printing your particular type than to dump the bytes. diff --git a/googlemock/docs/ForDummies.md b/googlemock/docs/ForDummies.md index 76910569..566a34e5 100644 --- a/googlemock/docs/ForDummies.md +++ b/googlemock/docs/ForDummies.md @@ -170,7 +170,7 @@ Admittedly, this test is contrived and doesn't do much. You can easily achieve t ## Using Google Mock with Any Testing Framework ## If you want to use something other than Google Test (e.g. [CppUnit](http://sourceforge.net/projects/cppunit/) or -[CxxTest](http://cxxtest.tigris.org/)) as your testing framework, just change the `main()` function in the previous section to: +[CxxTest](https://cxxtest.com/)) as your testing framework, just change the `main()` function in the previous section to: ``` int main(int argc, char** argv) { // The following line causes Google Mock to throw an exception on failure, @@ -187,7 +187,7 @@ sometimes causes the test program to crash. You'll still be able to notice that the test has failed, but it's not a graceful failure. A better solution is to use Google Test's -[event listener API](../../googletest/docs/AdvancedGuide.md#extending-google-test-by-handling-test-events) +[event listener API](../../googletest/docs/advanced.md#extending-google-test-by-handling-test-events) to report a test failure to your testing framework properly. You'll need to implement the `OnTestPartResult()` method of the event listener interface, but it should be straightforward. diff --git a/googlemock/docs/FrequentlyAskedQuestions.md b/googlemock/docs/FrequentlyAskedQuestions.md index ccaa3d7a..9008c637 100644 --- a/googlemock/docs/FrequentlyAskedQuestions.md +++ b/googlemock/docs/FrequentlyAskedQuestions.md @@ -528,7 +528,7 @@ interface, which then can be easily mocked. It's a bit of work initially, but usually pays for itself quickly. This Google Testing Blog -[post](http://googletesting.blogspot.com/2008/06/defeat-static-cling.html) +[post](https://testing.googleblog.com/2008/06/defeat-static-cling.html) says it excellently. Check it out. ## My mock object needs to do complex stuff. It's a lot of pain to specify the actions. Google Mock sucks! ## @@ -607,7 +607,6 @@ See this [recipe](CookBook.md#mocking_side_effects) for more details and an exam If you cannot find the answer to your question in this FAQ, there are some other resources you can use: - 1. read other [documentation](Documentation.md), 1. search the mailing list [archive](http://groups.google.com/group/googlemock/topics), 1. ask it on [googlemock@googlegroups.com](mailto:googlemock@googlegroups.com) and someone will answer it (to prevent spam, we require you to join the [discussion group](http://groups.google.com/group/googlemock) before you can post.). diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h index 845c8232..b82313d5 100644 --- a/googlemock/include/gmock/gmock-actions.h +++ b/googlemock/include/gmock/gmock-actions.h @@ -26,13 +26,14 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // // This file implements some commonly used actions. +// GOOGLETEST_CM0002 DO NOT DELETE + #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ @@ -46,9 +47,10 @@ #include "gmock/internal/gmock-internal-utils.h" #include "gmock/internal/gmock-port.h" -#if GTEST_HAS_STD_TYPE_TRAITS_ // Defined by gtest-port.h via gmock-port.h. +#if GTEST_LANG_CXX11 // Defined by gtest-port.h via gmock-port.h. +#include <functional> #include <type_traits> -#endif +#endif // GTEST_LANG_CXX11 namespace testing { @@ -96,7 +98,7 @@ struct BuiltInDefaultValueGetter<T, false> { template <typename T> class BuiltInDefaultValue { public: -#if GTEST_HAS_STD_TYPE_TRAITS_ +#if GTEST_LANG_CXX11 // This function returns true iff type T has a built-in default value. static bool Exists() { return ::std::is_default_constructible<T>::value; @@ -107,7 +109,7 @@ class BuiltInDefaultValue { T, ::std::is_default_constructible<T>::value>::Get(); } -#else // GTEST_HAS_STD_TYPE_TRAITS_ +#else // GTEST_LANG_CXX11 // This function returns true iff type T has a built-in default value. static bool Exists() { return false; @@ -117,7 +119,7 @@ class BuiltInDefaultValue { return BuiltInDefaultValueGetter<T, false>::Get(); } -#endif // GTEST_HAS_STD_TYPE_TRAITS_ +#endif // GTEST_LANG_CXX11 }; // This partial specialization says that we use the same built-in @@ -359,14 +361,20 @@ class Action { // Constructs a null Action. Needed for storing Action objects in // STL containers. - Action() : impl_(NULL) {} + Action() {} - // Constructs an Action from its implementation. A NULL impl is - // used to represent the "do-default" action. - explicit Action(ActionInterface<F>* impl) : impl_(impl) {} +#if GTEST_LANG_CXX11 + // Construct an Action from a specified callable. + // 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 +#endif - // Copy constructor. - Action(const Action& action) : impl_(action.impl_) {} + // Constructs an Action from its implementation. + explicit Action(ActionInterface<F>* impl) : impl_(impl) {} // This constructor allows us to turn an Action<Func> object into an // Action<F>, as long as F's arguments can be implicitly converted @@ -376,7 +384,13 @@ class Action { explicit Action(const Action<Func>& action); // Returns true iff this is the DoDefault() action. - bool IsDoDefault() const { return impl_.get() == NULL; } + bool IsDoDefault() const { +#if GTEST_LANG_CXX11 + return impl_ == nullptr && fun_ == nullptr; +#else + return impl_ == NULL; +#endif + } // Performs the action. Note that this method is const even though // the corresponding method in ActionInterface is not. The reason @@ -384,14 +398,15 @@ class Action { // another concrete action, not that the concrete action it binds to // cannot change state. (Think of the difference between a const // pointer and a pointer to const.) - Result Perform(const ArgumentTuple& args) const { - internal::Assert( - !IsDoDefault(), __FILE__, __LINE__, - "You are using DoDefault() inside a composite action like " - "DoAll() or WithArgs(). This is not supported for technical " - "reasons. Please instead spell out the default action, or " - "assign the default action to an Action variable and use " - "the variable in various places."); + Result Perform(ArgumentTuple args) const { + if (IsDoDefault()) { + internal::IllegalDoDefault(__FILE__, __LINE__); + } +#if GTEST_LANG_CXX11 + if (fun_ != nullptr) { + return internal::Apply(fun_, ::std::move(args)); + } +#endif return impl_->Perform(args); } @@ -399,6 +414,18 @@ class Action { template <typename F1, typename F2> friend class internal::ActionAdaptor; + template <typename G> + friend class Action; + + // In C++11, Action can be implemented either as a generic functor (through + // std::function), or legacy ActionInterface. In C++98, only ActionInterface + // is available. The invariants are as follows: + // * in C++98, impl_ is null iff this is the default action + // * in C++11, at most one of fun_ & impl_ may be nonnull; both are null iff + // this is the default action +#if GTEST_LANG_CXX11 + ::std::function<F> fun_; +#endif internal::linked_ptr<ActionInterface<F> > impl_; }; @@ -530,6 +557,9 @@ struct ByMoveWrapper { // statement, and conversion of the result of Return to Action<T(U)> is a // good place for that. // +// The real life example of the above scenario happens when an invocation +// of gtl::Container() is passed into Return. +// template <typename R> class ReturnAction { public: @@ -749,7 +779,7 @@ class DoDefaultAction { // This template type conversion operator allows DoDefault() to be // used in any function. template <typename F> - operator Action<F>() const { return Action<F>(NULL); } + operator Action<F>() const { return Action<F>(); } // NOLINT }; // Implements the Assign action to set a given pointer referent to a @@ -885,6 +915,28 @@ class InvokeMethodWithoutArgsAction { GTEST_DISALLOW_ASSIGN_(InvokeMethodWithoutArgsAction); }; +// Implements the InvokeWithoutArgs(callback) action. +template <typename CallbackType> +class InvokeCallbackWithoutArgsAction { + public: + // The c'tor takes ownership of the callback. + explicit InvokeCallbackWithoutArgsAction(CallbackType* callback) + : callback_(callback) { + callback->CheckIsRepeatable(); // Makes sure the callback is permanent. + } + + // This type conversion operator template allows Invoke(callback) to + // be used wherever the callback's return type can be implicitly + // converted to that of the mock function. + template <typename Result, typename ArgumentTuple> + Result Perform(const ArgumentTuple&) const { return callback_->Run(); } + + private: + const internal::linked_ptr<CallbackType> callback_; + + GTEST_DISALLOW_ASSIGN_(InvokeCallbackWithoutArgsAction); +}; + // Implements the IgnoreResult(action) action. template <typename A> class IgnoreResultAction { @@ -1052,7 +1104,13 @@ typedef internal::IgnoredValue Unused; template <typename To> template <typename From> Action<To>::Action(const Action<From>& from) - : impl_(new internal::ActionAdaptor<To, From>(from)) {} + : +#if GTEST_LANG_CXX11 + fun_(from.fun_), +#endif + impl_(from.impl_ == NULL ? NULL + : new internal::ActionAdaptor<To, From>(from)) { +} // Creates an action that returns 'value'. 'value' is passed by value // instead of const reference - otherwise Return("string literal") diff --git a/googlemock/include/gmock/gmock-cardinalities.h b/googlemock/include/gmock/gmock-cardinalities.h index fc315f92..bf3ae557 100644 --- a/googlemock/include/gmock/gmock-cardinalities.h +++ b/googlemock/include/gmock/gmock-cardinalities.h @@ -26,8 +26,7 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // @@ -35,6 +34,8 @@ // cardinalities can be defined by the user implementing the // CardinalityInterface interface if necessary. +// GOOGLETEST_CM0002 DO NOT DELETE + #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ diff --git a/googlemock/include/gmock/gmock-generated-actions.h b/googlemock/include/gmock/gmock-generated-actions.h index be4ebe4f..260036da 100644 --- a/googlemock/include/gmock/gmock-generated-actions.h +++ b/googlemock/include/gmock/gmock-generated-actions.h @@ -1,4 +1,6 @@ -// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! +// This file was GENERATED by command: +// pump.py gmock-generated-actions.h.pump +// DO NOT EDIT BY HAND!!! // Copyright 2007, Google Inc. // All rights reserved. @@ -28,13 +30,14 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // // This file implements some commonly used variadic actions. +// GOOGLETEST_CM0002 DO NOT DELETE + #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ @@ -45,8 +48,8 @@ namespace testing { namespace internal { // InvokeHelper<F> knows how to unpack an N-tuple and invoke an N-ary -// function or method with the unpacked values, where F is a function -// type that takes N arguments. +// function, method, or callback with the unpacked values, where F is +// a function type that takes N arguments. template <typename Result, typename ArgumentTuple> class InvokeHelper; @@ -64,6 +67,12 @@ class InvokeHelper<R, ::testing::tuple<> > { const ::testing::tuple<>&) { return (obj_ptr->*method_ptr)(); } + + template <typename CallbackType> + static R InvokeCallback(CallbackType* callback, + const ::testing::tuple<>&) { + return callback->Run(); + } }; template <typename R, typename A1> @@ -80,6 +89,12 @@ class InvokeHelper<R, ::testing::tuple<A1> > { const ::testing::tuple<A1>& args) { return (obj_ptr->*method_ptr)(get<0>(args)); } + + template <typename CallbackType> + static R InvokeCallback(CallbackType* callback, + const ::testing::tuple<A1>& args) { + return callback->Run(get<0>(args)); + } }; template <typename R, typename A1, typename A2> @@ -96,6 +111,12 @@ class InvokeHelper<R, ::testing::tuple<A1, A2> > { const ::testing::tuple<A1, A2>& args) { return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args)); } + + template <typename CallbackType> + static R InvokeCallback(CallbackType* callback, + const ::testing::tuple<A1, A2>& args) { + return callback->Run(get<0>(args), get<1>(args)); + } }; template <typename R, typename A1, typename A2, typename A3> @@ -113,6 +134,12 @@ class InvokeHelper<R, ::testing::tuple<A1, A2, A3> > { return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), get<2>(args)); } + + template <typename CallbackType> + static R InvokeCallback(CallbackType* callback, + const ::testing::tuple<A1, A2, A3>& args) { + return callback->Run(get<0>(args), get<1>(args), get<2>(args)); + } }; template <typename R, typename A1, typename A2, typename A3, typename A4> @@ -132,6 +159,13 @@ class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4> > { return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), get<2>(args), get<3>(args)); } + + template <typename CallbackType> + static R InvokeCallback(CallbackType* callback, + const ::testing::tuple<A1, A2, A3, A4>& args) { + return callback->Run(get<0>(args), get<1>(args), get<2>(args), + get<3>(args)); + } }; template <typename R, typename A1, typename A2, typename A3, typename A4, @@ -152,6 +186,13 @@ class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5> > { return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args)); } + + template <typename CallbackType> + static R InvokeCallback(CallbackType* callback, + const ::testing::tuple<A1, A2, A3, A4, A5>& args) { + return callback->Run(get<0>(args), get<1>(args), get<2>(args), + get<3>(args), get<4>(args)); + } }; template <typename R, typename A1, typename A2, typename A3, typename A4, @@ -172,6 +213,8 @@ class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6> > { return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args), get<5>(args)); } + + // There is no InvokeCallback() for 6-tuples }; template <typename R, typename A1, typename A2, typename A3, typename A4, @@ -194,6 +237,8 @@ class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6, A7> > { get<2>(args), get<3>(args), get<4>(args), get<5>(args), get<6>(args)); } + + // There is no InvokeCallback() for 7-tuples }; template <typename R, typename A1, typename A2, typename A3, typename A4, @@ -217,6 +262,8 @@ class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8> > { get<2>(args), get<3>(args), get<4>(args), get<5>(args), get<6>(args), get<7>(args)); } + + // There is no InvokeCallback() for 8-tuples }; template <typename R, typename A1, typename A2, typename A3, typename A4, @@ -240,6 +287,8 @@ class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> > { get<2>(args), get<3>(args), get<4>(args), get<5>(args), get<6>(args), get<7>(args), get<8>(args)); } + + // There is no InvokeCallback() for 9-tuples }; template <typename R, typename A1, typename A2, typename A3, typename A4, @@ -265,6 +314,33 @@ class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9, get<2>(args), get<3>(args), get<4>(args), get<5>(args), get<6>(args), get<7>(args), get<8>(args), get<9>(args)); } + + // There is no InvokeCallback() for 10-tuples +}; + +// Implements the Invoke(callback) action. +template <typename CallbackType> +class InvokeCallbackAction { + public: + // The c'tor takes ownership of the callback. + explicit InvokeCallbackAction(CallbackType* callback) + : callback_(callback) { + callback->CheckIsRepeatable(); // Makes sure the callback is permanent. + } + + // This type conversion operator template allows Invoke(callback) to + // be used wherever the callback's type is compatible with that of + // the mock function, i.e. if the mock function's arguments can be + // implicitly converted to the callback's arguments and the + // callback's result can be implicitly converted to the mock + // function's result. + template <typename Result, typename ArgumentTuple> + Result Perform(const ArgumentTuple& args) const { + return InvokeHelper<Result, ArgumentTuple>::InvokeCallback( + callback_.get(), args); + } + private: + const linked_ptr<CallbackType> callback_; }; // An INTERNAL macro for extracting the type of a tuple field. It's @@ -1073,52 +1149,90 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, #define GMOCK_INTERNAL_INIT_AND_0_VALUE_PARAMS()\ () #define GMOCK_INTERNAL_INIT_AND_1_VALUE_PARAMS(p0)\ - (p0##_type gmock_p0) : p0(gmock_p0) + (p0##_type gmock_p0) : p0(::testing::internal::move(gmock_p0)) #define GMOCK_INTERNAL_INIT_AND_2_VALUE_PARAMS(p0, p1)\ - (p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), p1(gmock_p1) + (p0##_type gmock_p0, \ + p1##_type gmock_p1) : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)) #define GMOCK_INTERNAL_INIT_AND_3_VALUE_PARAMS(p0, p1, p2)\ (p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) + p2##_type gmock_p2) : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)), \ + p2(::testing::internal::move(gmock_p2)) #define GMOCK_INTERNAL_INIT_AND_4_VALUE_PARAMS(p0, p1, p2, p3)\ (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3) + p3##_type gmock_p3) : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)), \ + p2(::testing::internal::move(gmock_p2)), \ + p3(::testing::internal::move(gmock_p3)) #define GMOCK_INTERNAL_INIT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)\ (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4) : p0(gmock_p0), p1(gmock_p1), \ - p2(gmock_p2), p3(gmock_p3), p4(gmock_p4) + p3##_type gmock_p3, \ + p4##_type gmock_p4) : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)), \ + p2(::testing::internal::move(gmock_p2)), \ + p3(::testing::internal::move(gmock_p3)), \ + p4(::testing::internal::move(gmock_p4)) #define GMOCK_INTERNAL_INIT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)\ (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(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) + p5##_type gmock_p5) : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)), \ + p2(::testing::internal::move(gmock_p2)), \ + p3(::testing::internal::move(gmock_p3)), \ + p4(::testing::internal::move(gmock_p4)), \ + p5(::testing::internal::move(gmock_p5)) #define GMOCK_INTERNAL_INIT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)\ (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(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6) + p6##_type gmock_p6) : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)), \ + p2(::testing::internal::move(gmock_p2)), \ + p3(::testing::internal::move(gmock_p3)), \ + p4(::testing::internal::move(gmock_p4)), \ + p5(::testing::internal::move(gmock_p5)), \ + p6(::testing::internal::move(gmock_p6)) #define GMOCK_INTERNAL_INIT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)\ (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(gmock_p0), p1(gmock_p1), \ - p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \ - p7(gmock_p7) + p6##_type gmock_p6, \ + p7##_type gmock_p7) : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)), \ + p2(::testing::internal::move(gmock_p2)), \ + p3(::testing::internal::move(gmock_p3)), \ + p4(::testing::internal::move(gmock_p4)), \ + p5(::testing::internal::move(gmock_p5)), \ + p6(::testing::internal::move(gmock_p6)), \ + p7(::testing::internal::move(gmock_p7)) #define GMOCK_INTERNAL_INIT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ p7, p8)\ (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(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \ - p8(gmock_p8) + p8##_type gmock_p8) : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)), \ + p2(::testing::internal::move(gmock_p2)), \ + p3(::testing::internal::move(gmock_p3)), \ + p4(::testing::internal::move(gmock_p4)), \ + p5(::testing::internal::move(gmock_p5)), \ + p6(::testing::internal::move(gmock_p6)), \ + p7(::testing::internal::move(gmock_p7)), \ + p8(::testing::internal::move(gmock_p8)) #define GMOCK_INTERNAL_INIT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ p7, p8, p9)\ (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(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \ - p8(gmock_p8), p9(gmock_p9) + p9##_type gmock_p9) : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)), \ + p2(::testing::internal::move(gmock_p2)), \ + p3(::testing::internal::move(gmock_p3)), \ + p4(::testing::internal::move(gmock_p4)), \ + p5(::testing::internal::move(gmock_p5)), \ + p6(::testing::internal::move(gmock_p6)), \ + p7(::testing::internal::move(gmock_p7)), \ + p8(::testing::internal::move(gmock_p8)), \ + p9(::testing::internal::move(gmock_p9)) // Declares the fields for storing the value parameters. #define GMOCK_INTERNAL_DEFN_AND_0_VALUE_PARAMS() @@ -1354,7 +1468,8 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, template <typename p0##_type>\ class name##ActionP {\ public:\ - explicit name##ActionP(p0##_type gmock_p0) : p0(gmock_p0) {}\ + explicit name##ActionP(p0##_type gmock_p0) : \ + p0(::testing::internal::forward<p0##_type>(gmock_p0)) {}\ template <typename F>\ class gmock_Impl : public ::testing::ActionInterface<F> {\ public:\ @@ -1362,7 +1477,8 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, 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(gmock_p0) {}\ + explicit gmock_Impl(p0##_type gmock_p0) : \ + p0(::testing::internal::forward<p0##_type>(gmock_p0)) {}\ virtual return_type Perform(const args_type& args) {\ return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ Perform(this, args);\ @@ -1404,8 +1520,9 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, template <typename p0##_type, typename p1##_type>\ class name##ActionP2 {\ public:\ - name##ActionP2(p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), \ - p1(gmock_p1) {}\ + name##ActionP2(p0##_type gmock_p0, \ + p1##_type gmock_p1) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ + p1(::testing::internal::forward<p1##_type>(gmock_p1)) {}\ template <typename F>\ class gmock_Impl : public ::testing::ActionInterface<F> {\ public:\ @@ -1413,8 +1530,9 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, 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(gmock_p0), \ - p1(gmock_p1) {}\ + gmock_Impl(p0##_type gmock_p0, \ + p1##_type gmock_p1) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ + p1(::testing::internal::forward<p1##_type>(gmock_p1)) {}\ virtual return_type Perform(const args_type& args) {\ return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ Perform(this, args);\ @@ -1460,7 +1578,9 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, class name##ActionP3 {\ public:\ name##ActionP3(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {}\ + p2##_type gmock_p2) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ + p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ + p2(::testing::internal::forward<p2##_type>(gmock_p2)) {}\ template <typename F>\ class gmock_Impl : public ::testing::ActionInterface<F> {\ public:\ @@ -1469,7 +1589,9 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, typedef typename ::testing::internal::Function<F>::ArgumentTuple\ args_type;\ gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {}\ + p2##_type gmock_p2) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ + p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ + p2(::testing::internal::forward<p2##_type>(gmock_p2)) {}\ virtual return_type Perform(const args_type& args) {\ return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ Perform(this, args);\ @@ -1519,8 +1641,11 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, class name##ActionP4 {\ public:\ name##ActionP4(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), \ - p2(gmock_p2), p3(gmock_p3) {}\ + p2##_type gmock_p2, \ + p3##_type gmock_p3) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ + p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ + p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ + p3(::testing::internal::forward<p3##_type>(gmock_p3)) {}\ template <typename F>\ class gmock_Impl : public ::testing::ActionInterface<F> {\ public:\ @@ -1529,8 +1654,10 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, 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(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3) {}\ + p3##_type gmock_p3) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ + p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ + p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ + p3(::testing::internal::forward<p3##_type>(gmock_p3)) {}\ virtual return_type Perform(const args_type& args) {\ return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ Perform(this, args);\ @@ -1587,8 +1714,11 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, public:\ name##ActionP5(p0##_type gmock_p0, p1##_type gmock_p1, \ p2##_type gmock_p2, p3##_type gmock_p3, \ - p4##_type gmock_p4) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4) {}\ + p4##_type gmock_p4) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ + p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ + p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ + p3(::testing::internal::forward<p3##_type>(gmock_p3)), \ + p4(::testing::internal::forward<p4##_type>(gmock_p4)) {}\ template <typename F>\ class gmock_Impl : public ::testing::ActionInterface<F> {\ public:\ @@ -1597,8 +1727,12 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, 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(gmock_p0), \ - p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), p4(gmock_p4) {}\ + p3##_type gmock_p3, \ + p4##_type gmock_p4) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ + p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ + p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ + p3(::testing::internal::forward<p3##_type>(gmock_p3)), \ + p4(::testing::internal::forward<p4##_type>(gmock_p4)) {}\ virtual return_type Perform(const args_type& args) {\ return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ Perform(this, args);\ @@ -1657,8 +1791,12 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, 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(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) {}\ + p5##_type gmock_p5) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ + p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ + p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ + p3(::testing::internal::forward<p3##_type>(gmock_p3)), \ + p4(::testing::internal::forward<p4##_type>(gmock_p4)), \ + p5(::testing::internal::forward<p5##_type>(gmock_p5)) {}\ template <typename F>\ class gmock_Impl : public ::testing::ActionInterface<F> {\ public:\ @@ -1668,8 +1806,12 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, 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(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) {}\ + p5##_type gmock_p5) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ + p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ + p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ + p3(::testing::internal::forward<p3##_type>(gmock_p3)), \ + p4(::testing::internal::forward<p4##_type>(gmock_p4)), \ + p5(::testing::internal::forward<p5##_type>(gmock_p5)) {}\ virtual return_type Perform(const args_type& args) {\ return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ Perform(this, args);\ @@ -1731,9 +1873,14 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, 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(gmock_p0), p1(gmock_p1), \ - p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), \ - p6(gmock_p6) {}\ + p5##_type gmock_p5, \ + p6##_type gmock_p6) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ + p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ + p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ + p3(::testing::internal::forward<p3##_type>(gmock_p3)), \ + p4(::testing::internal::forward<p4##_type>(gmock_p4)), \ + p5(::testing::internal::forward<p5##_type>(gmock_p5)), \ + p6(::testing::internal::forward<p6##_type>(gmock_p6)) {}\ template <typename F>\ class gmock_Impl : public ::testing::ActionInterface<F> {\ public:\ @@ -1743,8 +1890,13 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, 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(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6) {}\ + p6##_type gmock_p6) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ + p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ + p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ + p3(::testing::internal::forward<p3##_type>(gmock_p3)), \ + p4(::testing::internal::forward<p4##_type>(gmock_p4)), \ + p5(::testing::internal::forward<p5##_type>(gmock_p5)), \ + p6(::testing::internal::forward<p6##_type>(gmock_p6)) {}\ virtual return_type Perform(const args_type& args) {\ return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ Perform(this, args);\ @@ -1813,9 +1965,14 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, 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(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \ - p7(gmock_p7) {}\ + p7##_type gmock_p7) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ + p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ + p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ + p3(::testing::internal::forward<p3##_type>(gmock_p3)), \ + p4(::testing::internal::forward<p4##_type>(gmock_p4)), \ + p5(::testing::internal::forward<p5##_type>(gmock_p5)), \ + p6(::testing::internal::forward<p6##_type>(gmock_p6)), \ + p7(::testing::internal::forward<p7##_type>(gmock_p7)) {}\ template <typename F>\ class gmock_Impl : public ::testing::ActionInterface<F> {\ public:\ @@ -1825,9 +1982,15 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, 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(gmock_p0), \ - p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), \ - p5(gmock_p5), p6(gmock_p6), p7(gmock_p7) {}\ + p6##_type gmock_p6, \ + p7##_type gmock_p7) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ + p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ + p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ + p3(::testing::internal::forward<p3##_type>(gmock_p3)), \ + p4(::testing::internal::forward<p4##_type>(gmock_p4)), \ + p5(::testing::internal::forward<p5##_type>(gmock_p5)), \ + p6(::testing::internal::forward<p6##_type>(gmock_p6)), \ + p7(::testing::internal::forward<p7##_type>(gmock_p7)) {}\ virtual return_type Perform(const args_type& args) {\ return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ Perform(this, args);\ @@ -1900,9 +2063,15 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, 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(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \ - p8(gmock_p8) {}\ + p8##_type gmock_p8) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ + p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ + p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ + p3(::testing::internal::forward<p3##_type>(gmock_p3)), \ + p4(::testing::internal::forward<p4##_type>(gmock_p4)), \ + p5(::testing::internal::forward<p5##_type>(gmock_p5)), \ + p6(::testing::internal::forward<p6##_type>(gmock_p6)), \ + p7(::testing::internal::forward<p7##_type>(gmock_p7)), \ + p8(::testing::internal::forward<p8##_type>(gmock_p8)) {}\ template <typename F>\ class gmock_Impl : public ::testing::ActionInterface<F> {\ public:\ @@ -1913,9 +2082,15 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, 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(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \ - p7(gmock_p7), p8(gmock_p8) {}\ + p8##_type gmock_p8) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ + p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ + p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ + p3(::testing::internal::forward<p3##_type>(gmock_p3)), \ + p4(::testing::internal::forward<p4##_type>(gmock_p4)), \ + p5(::testing::internal::forward<p5##_type>(gmock_p5)), \ + p6(::testing::internal::forward<p6##_type>(gmock_p6)), \ + p7(::testing::internal::forward<p7##_type>(gmock_p7)), \ + p8(::testing::internal::forward<p8##_type>(gmock_p8)) {}\ virtual return_type Perform(const args_type& args) {\ return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ Perform(this, args);\ @@ -1992,9 +2167,17 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, 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(gmock_p0), p1(gmock_p1), \ - p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \ - p7(gmock_p7), p8(gmock_p8), p9(gmock_p9) {}\ + p8##_type gmock_p8, \ + p9##_type gmock_p9) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ + p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ + p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ + p3(::testing::internal::forward<p3##_type>(gmock_p3)), \ + p4(::testing::internal::forward<p4##_type>(gmock_p4)), \ + p5(::testing::internal::forward<p5##_type>(gmock_p5)), \ + p6(::testing::internal::forward<p6##_type>(gmock_p6)), \ + p7(::testing::internal::forward<p7##_type>(gmock_p7)), \ + p8(::testing::internal::forward<p8##_type>(gmock_p8)), \ + p9(::testing::internal::forward<p9##_type>(gmock_p9)) {}\ template <typename F>\ class gmock_Impl : public ::testing::ActionInterface<F> {\ public:\ @@ -2005,9 +2188,16 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, 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(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \ - p7(gmock_p7), p8(gmock_p8), p9(gmock_p9) {}\ + p9##_type gmock_p9) : p0(::testing::internal::forward<p0##_type>(gmock_p0)), \ + p1(::testing::internal::forward<p1##_type>(gmock_p1)), \ + p2(::testing::internal::forward<p2##_type>(gmock_p2)), \ + p3(::testing::internal::forward<p3##_type>(gmock_p3)), \ + p4(::testing::internal::forward<p4##_type>(gmock_p4)), \ + p5(::testing::internal::forward<p5##_type>(gmock_p5)), \ + p6(::testing::internal::forward<p6##_type>(gmock_p6)), \ + p7(::testing::internal::forward<p7##_type>(gmock_p7)), \ + p8(::testing::internal::forward<p8##_type>(gmock_p8)), \ + p9(::testing::internal::forward<p9##_type>(gmock_p9)) {}\ virtual return_type Perform(const args_type& args) {\ return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\ Perform(this, args);\ @@ -2369,7 +2559,7 @@ ACTION_TEMPLATE(ReturnNew, } // namespace testing -// Include any custom actions added by the local installation. +// Include any custom callback actions added by the local installation. // We must include this header at the end to make sure it can use the // declarations from this file. #include "gmock/internal/custom/gmock-generated-actions.h" diff --git a/googlemock/include/gmock/gmock-generated-actions.h.pump b/googlemock/include/gmock/gmock-generated-actions.h.pump index 712f65d6..f1ee4a61 100644 --- a/googlemock/include/gmock/gmock-generated-actions.h.pump +++ b/googlemock/include/gmock/gmock-generated-actions.h.pump @@ -1,5 +1,5 @@ $$ -*- mode: c++; -*- -$$ This is a Pump source file. Please use Pump to convert it to +$$ This is a Pump source file. Please use Pump to convert it to $$ gmock-generated-actions.h. $$ $var n = 10 $$ The maximum arity we support. @@ -32,13 +32,14 @@ $$}} This meta comment fixes auto-indentation in editors. // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // // This file implements some commonly used variadic actions. +// GOOGLETEST_CM0002 DO NOT DELETE + #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ @@ -49,12 +50,13 @@ namespace testing { namespace internal { // InvokeHelper<F> knows how to unpack an N-tuple and invoke an N-ary -// function or method with the unpacked values, where F is a function -// type that takes N arguments. +// function, method, or callback with the unpacked values, where F is +// a function type that takes N arguments. template <typename Result, typename ArgumentTuple> class InvokeHelper; +$var max_callback_arity = 5 $range i 0..n $for i [[ $range j 1..i @@ -76,10 +78,47 @@ class InvokeHelper<R, ::testing::tuple<$as> > { const ::testing::tuple<$as>&$args) { return (obj_ptr->*method_ptr)($gets); } + + +$if i <= max_callback_arity [[ + template <typename CallbackType> + static R InvokeCallback(CallbackType* callback, + const ::testing::tuple<$as>&$args) { + return callback->Run($gets); + } +]] $else [[ + // There is no InvokeCallback() for $i-tuples +]] + }; ]] +// Implements the Invoke(callback) action. +template <typename CallbackType> +class InvokeCallbackAction { + public: + // The c'tor takes ownership of the callback. + explicit InvokeCallbackAction(CallbackType* callback) + : callback_(callback) { + callback->CheckIsRepeatable(); // Makes sure the callback is permanent. + } + + // This type conversion operator template allows Invoke(callback) to + // be used wherever the callback's type is compatible with that of + // the mock function, i.e. if the mock function's arguments can be + // implicitly converted to the callback's arguments and the + // callback's result can be implicitly converted to the mock + // function's result. + template <typename Result, typename ArgumentTuple> + Result Perform(const ArgumentTuple& args) const { + return InvokeHelper<Result, ArgumentTuple>::InvokeCallback( + callback_.get(), args); + } + private: + const linked_ptr<CallbackType> callback_; +}; + // An INTERNAL macro for extracting the type of a tuple field. It's // subject to change without notice - DO NOT USE IN USER CODE! #define GMOCK_FIELD_(Tuple, N) \ @@ -486,7 +525,7 @@ _VALUE_PARAMS($for j, [[p$j]]) $for j [[, typename p$j##_type]] $for i [[ $range j 0..i-1 #define GMOCK_INTERNAL_INIT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])\ - ($for j, [[p$j##_type gmock_p$j]])$if i>0 [[ : ]]$for j, [[p$j(gmock_p$j)]] + ($for j, [[p$j##_type gmock_p$j]])$if i>0 [[ : ]]$for j, [[p$j(::testing::internal::move(gmock_p$j))]] ]] @@ -619,7 +658,7 @@ $var class_name = [[name##Action[[$if i==0 [[]] $elif i==1 [[P]] $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(gmock_p$j)]]]]]] +$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::testing::internal::forward<p$j##_type>(gmock_p$j))]]]]]] $var param_field_decls = [[$for j [[ diff --git a/googlemock/include/gmock/gmock-generated-function-mockers.h b/googlemock/include/gmock/gmock-generated-function-mockers.h index 4fa5ca94..5792d3d5 100644 --- a/googlemock/include/gmock/gmock-generated-function-mockers.h +++ b/googlemock/include/gmock/gmock-generated-function-mockers.h @@ -30,13 +30,14 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // 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_ @@ -68,8 +69,8 @@ class FunctionMocker<R()> : public typedef R F(); typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - MockSpec<F>& With() { - return this->current_spec(); + MockSpec<F> With() { + return MockSpec<F>(this, ::testing::make_tuple()); } R Invoke() { @@ -88,9 +89,8 @@ class FunctionMocker<R(A1)> : public typedef R F(A1); typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - MockSpec<F>& With(const Matcher<A1>& m1) { - this->current_spec().SetMatchers(::testing::make_tuple(m1)); - return this->current_spec(); + MockSpec<F> With(const Matcher<A1>& m1) { + return MockSpec<F>(this, ::testing::make_tuple(m1)); } R Invoke(A1 a1) { @@ -98,7 +98,7 @@ class FunctionMocker<R(A1)> : public // by the C++ standard [14.6.4] here, as the base class type is // dependent on the template argument (and thus shouldn't be // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(a1)); + return this->InvokeWith(ArgumentTuple(internal::forward<A1>(a1))); } }; @@ -109,9 +109,8 @@ class FunctionMocker<R(A1, A2)> : public typedef R F(A1, A2); typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2) { - this->current_spec().SetMatchers(::testing::make_tuple(m1, m2)); - return this->current_spec(); + MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2) { + return MockSpec<F>(this, ::testing::make_tuple(m1, m2)); } R Invoke(A1 a1, A2 a2) { @@ -119,7 +118,8 @@ class FunctionMocker<R(A1, A2)> : public // by the C++ standard [14.6.4] here, as the base class type is // dependent on the template argument (and thus shouldn't be // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(a1, a2)); + return this->InvokeWith(ArgumentTuple(internal::forward<A1>(a1), + internal::forward<A2>(a2))); } }; @@ -130,10 +130,9 @@ class FunctionMocker<R(A1, A2, A3)> : public typedef R F(A1, A2, A3); typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2, + MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2, const Matcher<A3>& m3) { - this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3)); - return this->current_spec(); + return MockSpec<F>(this, ::testing::make_tuple(m1, m2, m3)); } R Invoke(A1 a1, A2 a2, A3 a3) { @@ -141,7 +140,8 @@ class FunctionMocker<R(A1, A2, A3)> : public // by the C++ standard [14.6.4] here, as the base class type is // dependent on the template argument (and thus shouldn't be // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(a1, a2, a3)); + return this->InvokeWith(ArgumentTuple(internal::forward<A1>(a1), + internal::forward<A2>(a2), internal::forward<A3>(a3))); } }; @@ -152,10 +152,9 @@ class FunctionMocker<R(A1, A2, A3, A4)> : public typedef R F(A1, A2, A3, A4); typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2, + MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2, const Matcher<A3>& m3, const Matcher<A4>& m4) { - this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4)); - return this->current_spec(); + return MockSpec<F>(this, ::testing::make_tuple(m1, m2, m3, m4)); } R Invoke(A1 a1, A2 a2, A3 a3, A4 a4) { @@ -163,7 +162,9 @@ class FunctionMocker<R(A1, A2, A3, A4)> : public // by the C++ standard [14.6.4] here, as the base class type is // dependent on the template argument (and thus shouldn't be // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4)); + return this->InvokeWith(ArgumentTuple(internal::forward<A1>(a1), + internal::forward<A2>(a2), internal::forward<A3>(a3), + internal::forward<A4>(a4))); } }; @@ -175,10 +176,9 @@ class FunctionMocker<R(A1, A2, A3, A4, A5)> : public typedef R F(A1, A2, A3, A4, A5); typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2, + MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2, const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5) { - this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5)); - return this->current_spec(); + return MockSpec<F>(this, ::testing::make_tuple(m1, m2, m3, m4, m5)); } R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { @@ -186,7 +186,9 @@ class FunctionMocker<R(A1, A2, A3, A4, A5)> : public // by the C++ standard [14.6.4] here, as the base class type is // dependent on the template argument (and thus shouldn't be // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5)); + return this->InvokeWith(ArgumentTuple(internal::forward<A1>(a1), + internal::forward<A2>(a2), internal::forward<A3>(a3), + internal::forward<A4>(a4), internal::forward<A5>(a5))); } }; @@ -198,12 +200,10 @@ class FunctionMocker<R(A1, A2, A3, A4, A5, A6)> : public typedef R F(A1, A2, A3, A4, A5, A6); typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2, + MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2, const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5, const Matcher<A6>& m6) { - this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5, - m6)); - return this->current_spec(); + return MockSpec<F>(this, ::testing::make_tuple(m1, m2, m3, m4, m5, m6)); } R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) { @@ -211,7 +211,10 @@ class FunctionMocker<R(A1, A2, A3, A4, A5, A6)> : public // by the C++ standard [14.6.4] here, as the base class type is // dependent on the template argument (and thus shouldn't be // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6)); + return this->InvokeWith(ArgumentTuple(internal::forward<A1>(a1), + internal::forward<A2>(a2), internal::forward<A3>(a3), + internal::forward<A4>(a4), internal::forward<A5>(a5), + internal::forward<A6>(a6))); } }; @@ -223,12 +226,10 @@ class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7)> : public typedef R F(A1, A2, A3, A4, A5, A6, A7); typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2, + MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2, const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5, const Matcher<A6>& m6, const Matcher<A7>& m7) { - this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5, - m6, m7)); - return this->current_spec(); + return MockSpec<F>(this, ::testing::make_tuple(m1, m2, m3, m4, m5, m6, m7)); } R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) { @@ -236,7 +237,10 @@ class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7)> : public // by the C++ standard [14.6.4] here, as the base class type is // dependent on the template argument (and thus shouldn't be // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7)); + return this->InvokeWith(ArgumentTuple(internal::forward<A1>(a1), + internal::forward<A2>(a2), internal::forward<A3>(a3), + internal::forward<A4>(a4), internal::forward<A5>(a5), + internal::forward<A6>(a6), internal::forward<A7>(a7))); } }; @@ -248,12 +252,11 @@ class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8)> : public typedef R F(A1, A2, A3, A4, A5, A6, A7, A8); typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2, + MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2, const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5, const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8) { - this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5, - m6, m7, m8)); - return this->current_spec(); + return MockSpec<F>(this, ::testing::make_tuple(m1, m2, m3, m4, m5, m6, m7, + m8)); } R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) { @@ -261,7 +264,11 @@ class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8)> : public // by the C++ standard [14.6.4] here, as the base class type is // dependent on the template argument (and thus shouldn't be // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8)); + return this->InvokeWith(ArgumentTuple(internal::forward<A1>(a1), + internal::forward<A2>(a2), internal::forward<A3>(a3), + internal::forward<A4>(a4), internal::forward<A5>(a5), + internal::forward<A6>(a6), internal::forward<A7>(a7), + internal::forward<A8>(a8))); } }; @@ -273,13 +280,12 @@ class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> : public typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9); typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2, + MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2, const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5, const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8, const Matcher<A9>& m9) { - this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5, - m6, m7, m8, m9)); - return this->current_spec(); + return MockSpec<F>(this, ::testing::make_tuple(m1, m2, m3, m4, m5, m6, m7, + m8, m9)); } R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) { @@ -287,7 +293,11 @@ class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> : public // by the C++ standard [14.6.4] here, as the base class type is // dependent on the template argument (and thus shouldn't be // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8, a9)); + return this->InvokeWith(ArgumentTuple(internal::forward<A1>(a1), + internal::forward<A2>(a2), internal::forward<A3>(a3), + internal::forward<A4>(a4), internal::forward<A5>(a5), + internal::forward<A6>(a6), internal::forward<A7>(a7), + internal::forward<A8>(a8), internal::forward<A9>(a9))); } }; @@ -300,13 +310,12 @@ class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> : public typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2, + MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2, const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5, const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8, const Matcher<A9>& m9, const Matcher<A10>& m10) { - this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5, - m6, m7, m8, m9, m10)); - return this->current_spec(); + return MockSpec<F>(this, ::testing::make_tuple(m1, m2, m3, m4, m5, m6, m7, + m8, m9, m10)); } R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, @@ -315,11 +324,67 @@ class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> : public // by the C++ standard [14.6.4] here, as the base class type is // dependent on the template argument (and thus shouldn't be // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8, a9, - a10)); + return this->InvokeWith(ArgumentTuple(internal::forward<A1>(a1), + internal::forward<A2>(a2), internal::forward<A3>(a3), + internal::forward<A4>(a4), internal::forward<A5>(a5), + internal::forward<A6>(a6), internal::forward<A7>(a7), + internal::forward<A8>(a8), internal::forward<A9>(a9), + internal::forward<A10>(a10))); } }; +// 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 @@ -353,324 +418,534 @@ using internal::FunctionMocker; GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__) // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD0_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - ) constness { \ - GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ - tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ - == 0), \ - this_method_does_not_take_0_arguments); \ - 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(); \ - } \ +#define GMOCK_METHOD0_(tn, constness, ct, Method, ...) \ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method() constness { \ + GTEST_COMPILE_ASSERT_( \ + (::testing::tuple_size<tn ::testing::internal::Function< \ + __VA_ARGS__>::ArgumentTuple>::value == 0), \ + this_method_does_not_take_0_arguments); \ + 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) + Method) // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD1_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1) constness { \ - GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ - tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ - == 1), \ - this_method_does_not_take_1_argument); \ - GMOCK_MOCKER_(1, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(1, constness, Method).Invoke(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); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(1, constness, \ - Method) +#define GMOCK_METHOD1_(tn, constness, ct, Method, ...) \ + GMOCK_RESULT_(tn, __VA_ARGS__) \ + ct Method(GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1) constness { \ + GTEST_COMPILE_ASSERT_( \ + (::testing::tuple_size<tn ::testing::internal::Function< \ + __VA_ARGS__>::ArgumentTuple>::value == 1), \ + this_method_does_not_take_1_argument); \ + GMOCK_MOCKER_(1, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(1, constness, Method) \ + .Invoke(::testing::internal::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, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2) constness { \ - GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ - tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ - == 2), \ - this_method_does_not_take_2_arguments); \ - GMOCK_MOCKER_(2, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(2, constness, Method).Invoke(gmock_a1, 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); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(2, constness, \ - Method) +#define GMOCK_METHOD2_(tn, constness, ct, Method, ...) \ + GMOCK_RESULT_(tn, __VA_ARGS__) \ + ct Method(GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2) constness { \ + GTEST_COMPILE_ASSERT_( \ + (::testing::tuple_size<tn ::testing::internal::Function< \ + __VA_ARGS__>::ArgumentTuple>::value == 2), \ + this_method_does_not_take_2_arguments); \ + GMOCK_MOCKER_(2, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(2, constness, Method) \ + .Invoke(::testing::internal::forward<GMOCK_ARG_(tn, 1, __VA_ARGS__)>( \ + gmock_a1), \ + ::testing::internal::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, ...) \ - 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 { \ - GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ - tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ - == 3), \ - this_method_does_not_take_3_arguments); \ - GMOCK_MOCKER_(3, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(3, constness, Method).Invoke(gmock_a1, gmock_a2, \ - 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); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(3, constness, \ - Method) +#define GMOCK_METHOD3_(tn, constness, ct, Method, ...) \ + 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 { \ + GTEST_COMPILE_ASSERT_( \ + (::testing::tuple_size<tn ::testing::internal::Function< \ + __VA_ARGS__>::ArgumentTuple>::value == 3), \ + this_method_does_not_take_3_arguments); \ + GMOCK_MOCKER_(3, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(3, constness, Method) \ + .Invoke(::testing::internal::forward<GMOCK_ARG_(tn, 1, __VA_ARGS__)>( \ + gmock_a1), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>( \ + gmock_a2), \ + ::testing::internal::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, ...) \ - 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 { \ - GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ - tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ - == 4), \ - this_method_does_not_take_4_arguments); \ - GMOCK_MOCKER_(4, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(4, constness, Method).Invoke(gmock_a1, gmock_a2, \ - gmock_a3, 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); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(4, constness, \ - Method) +#define GMOCK_METHOD4_(tn, constness, ct, Method, ...) \ + 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 { \ + GTEST_COMPILE_ASSERT_( \ + (::testing::tuple_size<tn ::testing::internal::Function< \ + __VA_ARGS__>::ArgumentTuple>::value == 4), \ + this_method_does_not_take_4_arguments); \ + GMOCK_MOCKER_(4, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(4, constness, Method) \ + .Invoke(::testing::internal::forward<GMOCK_ARG_(tn, 1, __VA_ARGS__)>( \ + gmock_a1), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>( \ + gmock_a2), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>( \ + gmock_a3), \ + ::testing::internal::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, ...) \ - 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 { \ - GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ - tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ - == 5), \ - this_method_does_not_take_5_arguments); \ - GMOCK_MOCKER_(5, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(5, constness, Method).Invoke(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4, 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); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(5, constness, \ - Method) +#define GMOCK_METHOD5_(tn, constness, ct, Method, ...) \ + 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 { \ + GTEST_COMPILE_ASSERT_( \ + (::testing::tuple_size<tn ::testing::internal::Function< \ + __VA_ARGS__>::ArgumentTuple>::value == 5), \ + this_method_does_not_take_5_arguments); \ + GMOCK_MOCKER_(5, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(5, constness, Method) \ + .Invoke(::testing::internal::forward<GMOCK_ARG_(tn, 1, __VA_ARGS__)>( \ + gmock_a1), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>( \ + gmock_a2), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>( \ + gmock_a3), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>( \ + gmock_a4), \ + ::testing::internal::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, ...) \ - 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 { \ - GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ - tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ - == 6), \ - this_method_does_not_take_6_arguments); \ - GMOCK_MOCKER_(6, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(6, constness, Method).Invoke(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4, gmock_a5, 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); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(6, constness, \ - Method) +#define GMOCK_METHOD6_(tn, constness, ct, Method, ...) \ + 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 { \ + GTEST_COMPILE_ASSERT_( \ + (::testing::tuple_size<tn ::testing::internal::Function< \ + __VA_ARGS__>::ArgumentTuple>::value == 6), \ + this_method_does_not_take_6_arguments); \ + GMOCK_MOCKER_(6, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(6, constness, Method) \ + .Invoke(::testing::internal::forward<GMOCK_ARG_(tn, 1, __VA_ARGS__)>( \ + gmock_a1), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>( \ + gmock_a2), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>( \ + gmock_a3), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>( \ + gmock_a4), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>( \ + gmock_a5), \ + ::testing::internal::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, ...) \ - 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 { \ - GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ - tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ - == 7), \ - this_method_does_not_take_7_arguments); \ - GMOCK_MOCKER_(7, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(7, constness, Method).Invoke(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4, gmock_a5, gmock_a6, 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); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(7, constness, \ - Method) +#define GMOCK_METHOD7_(tn, constness, ct, Method, ...) \ + 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 { \ + GTEST_COMPILE_ASSERT_( \ + (::testing::tuple_size<tn ::testing::internal::Function< \ + __VA_ARGS__>::ArgumentTuple>::value == 7), \ + this_method_does_not_take_7_arguments); \ + GMOCK_MOCKER_(7, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(7, constness, Method) \ + .Invoke(::testing::internal::forward<GMOCK_ARG_(tn, 1, __VA_ARGS__)>( \ + gmock_a1), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>( \ + gmock_a2), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>( \ + gmock_a3), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>( \ + gmock_a4), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>( \ + gmock_a5), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>( \ + gmock_a6), \ + ::testing::internal::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, ...) \ - 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 { \ - GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ - tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ - == 8), \ - this_method_does_not_take_8_arguments); \ - GMOCK_MOCKER_(8, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(8, constness, Method).Invoke(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, 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); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(8, constness, \ - Method) +#define GMOCK_METHOD8_(tn, constness, ct, Method, ...) \ + 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 { \ + GTEST_COMPILE_ASSERT_( \ + (::testing::tuple_size<tn ::testing::internal::Function< \ + __VA_ARGS__>::ArgumentTuple>::value == 8), \ + this_method_does_not_take_8_arguments); \ + GMOCK_MOCKER_(8, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(8, constness, Method) \ + .Invoke(::testing::internal::forward<GMOCK_ARG_(tn, 1, __VA_ARGS__)>( \ + gmock_a1), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>( \ + gmock_a2), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>( \ + gmock_a3), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>( \ + gmock_a4), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>( \ + gmock_a5), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>( \ + gmock_a6), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>( \ + gmock_a7), \ + ::testing::internal::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, ...) \ - 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 { \ - GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ - tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ - == 9), \ - this_method_does_not_take_9_arguments); \ - GMOCK_MOCKER_(9, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(9, constness, Method).Invoke(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \ - 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); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(9, constness, \ - Method) +#define GMOCK_METHOD9_(tn, constness, ct, Method, ...) \ + 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 { \ + GTEST_COMPILE_ASSERT_( \ + (::testing::tuple_size<tn ::testing::internal::Function< \ + __VA_ARGS__>::ArgumentTuple>::value == 9), \ + this_method_does_not_take_9_arguments); \ + GMOCK_MOCKER_(9, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(9, constness, Method) \ + .Invoke(::testing::internal::forward<GMOCK_ARG_(tn, 1, __VA_ARGS__)>( \ + gmock_a1), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>( \ + gmock_a2), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>( \ + gmock_a3), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>( \ + gmock_a4), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>( \ + gmock_a5), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>( \ + gmock_a6), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>( \ + gmock_a7), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 8, __VA_ARGS__)>( \ + gmock_a8), \ + ::testing::internal::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, ...) \ - 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 { \ - GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ - tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ - == 10), \ - this_method_does_not_take_10_arguments); \ - GMOCK_MOCKER_(10, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(10, constness, Method).Invoke(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(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); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(10, constness, \ - Method) +#define GMOCK_METHOD10_(tn, constness, ct, Method, ...) \ + 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 { \ + GTEST_COMPILE_ASSERT_( \ + (::testing::tuple_size<tn ::testing::internal::Function< \ + __VA_ARGS__>::ArgumentTuple>::value == 10), \ + this_method_does_not_take_10_arguments); \ + GMOCK_MOCKER_(10, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(10, constness, Method) \ + .Invoke(::testing::internal::forward<GMOCK_ARG_(tn, 1, __VA_ARGS__)>( \ + gmock_a1), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>( \ + gmock_a2), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>( \ + gmock_a3), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>( \ + gmock_a4), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>( \ + gmock_a5), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>( \ + gmock_a6), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>( \ + gmock_a7), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 8, __VA_ARGS__)>( \ + gmock_a8), \ + ::testing::internal::forward<GMOCK_ARG_(tn, 9, __VA_ARGS__)>( \ + gmock_a9), \ + ::testing::internal::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__) @@ -880,7 +1155,7 @@ class MockFunction<R()> { MOCK_METHOD0_T(Call, R()); #if GTEST_HAS_STD_FUNCTION_ - std::function<R()> AsStdFunction() { + ::std::function<R()> AsStdFunction() { return [this]() -> R { return this->Call(); }; @@ -899,9 +1174,9 @@ class MockFunction<R(A0)> { MOCK_METHOD1_T(Call, R(A0)); #if GTEST_HAS_STD_FUNCTION_ - std::function<R(A0)> AsStdFunction() { + ::std::function<R(A0)> AsStdFunction() { return [this](A0 a0) -> R { - return this->Call(a0); + return this->Call(::std::move(a0)); }; } #endif // GTEST_HAS_STD_FUNCTION_ @@ -918,9 +1193,9 @@ class MockFunction<R(A0, A1)> { MOCK_METHOD2_T(Call, R(A0, A1)); #if GTEST_HAS_STD_FUNCTION_ - std::function<R(A0, A1)> AsStdFunction() { + ::std::function<R(A0, A1)> AsStdFunction() { return [this](A0 a0, A1 a1) -> R { - return this->Call(a0, a1); + return this->Call(::std::move(a0), ::std::move(a1)); }; } #endif // GTEST_HAS_STD_FUNCTION_ @@ -937,9 +1212,9 @@ class MockFunction<R(A0, A1, A2)> { MOCK_METHOD3_T(Call, R(A0, A1, A2)); #if GTEST_HAS_STD_FUNCTION_ - std::function<R(A0, A1, A2)> AsStdFunction() { + ::std::function<R(A0, A1, A2)> AsStdFunction() { return [this](A0 a0, A1 a1, A2 a2) -> R { - return this->Call(a0, a1, a2); + return this->Call(::std::move(a0), ::std::move(a1), ::std::move(a2)); }; } #endif // GTEST_HAS_STD_FUNCTION_ @@ -956,9 +1231,10 @@ class MockFunction<R(A0, A1, A2, A3)> { MOCK_METHOD4_T(Call, R(A0, A1, A2, A3)); #if GTEST_HAS_STD_FUNCTION_ - std::function<R(A0, A1, A2, A3)> AsStdFunction() { + ::std::function<R(A0, A1, A2, A3)> AsStdFunction() { return [this](A0 a0, A1 a1, A2 a2, A3 a3) -> R { - return this->Call(a0, a1, a2, a3); + return this->Call(::std::move(a0), ::std::move(a1), ::std::move(a2), + ::std::move(a3)); }; } #endif // GTEST_HAS_STD_FUNCTION_ @@ -976,9 +1252,10 @@ class MockFunction<R(A0, A1, A2, A3, A4)> { MOCK_METHOD5_T(Call, R(A0, A1, A2, A3, A4)); #if GTEST_HAS_STD_FUNCTION_ - std::function<R(A0, A1, A2, A3, A4)> AsStdFunction() { + ::std::function<R(A0, A1, A2, A3, A4)> AsStdFunction() { return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) -> R { - return this->Call(a0, a1, a2, a3, a4); + return this->Call(::std::move(a0), ::std::move(a1), ::std::move(a2), + ::std::move(a3), ::std::move(a4)); }; } #endif // GTEST_HAS_STD_FUNCTION_ @@ -996,9 +1273,10 @@ class MockFunction<R(A0, A1, A2, A3, A4, A5)> { MOCK_METHOD6_T(Call, R(A0, A1, A2, A3, A4, A5)); #if GTEST_HAS_STD_FUNCTION_ - std::function<R(A0, A1, A2, A3, A4, A5)> AsStdFunction() { + ::std::function<R(A0, A1, A2, A3, A4, A5)> AsStdFunction() { return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) -> R { - return this->Call(a0, a1, a2, a3, a4, a5); + return this->Call(::std::move(a0), ::std::move(a1), ::std::move(a2), + ::std::move(a3), ::std::move(a4), ::std::move(a5)); }; } #endif // GTEST_HAS_STD_FUNCTION_ @@ -1016,9 +1294,10 @@ class MockFunction<R(A0, A1, A2, A3, A4, A5, A6)> { MOCK_METHOD7_T(Call, R(A0, A1, A2, A3, A4, A5, A6)); #if GTEST_HAS_STD_FUNCTION_ - std::function<R(A0, A1, A2, A3, A4, A5, A6)> AsStdFunction() { + ::std::function<R(A0, A1, A2, A3, A4, A5, A6)> AsStdFunction() { return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) -> R { - return this->Call(a0, a1, a2, a3, a4, a5, a6); + return this->Call(::std::move(a0), ::std::move(a1), ::std::move(a2), + ::std::move(a3), ::std::move(a4), ::std::move(a5), ::std::move(a6)); }; } #endif // GTEST_HAS_STD_FUNCTION_ @@ -1036,9 +1315,11 @@ class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7)> { MOCK_METHOD8_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7)); #if GTEST_HAS_STD_FUNCTION_ - std::function<R(A0, A1, A2, A3, A4, A5, A6, A7)> AsStdFunction() { + ::std::function<R(A0, A1, A2, A3, A4, A5, A6, A7)> AsStdFunction() { return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) -> R { - return this->Call(a0, a1, a2, a3, a4, a5, a6, a7); + return this->Call(::std::move(a0), ::std::move(a1), ::std::move(a2), + ::std::move(a3), ::std::move(a4), ::std::move(a5), ::std::move(a6), + ::std::move(a7)); }; } #endif // GTEST_HAS_STD_FUNCTION_ @@ -1056,10 +1337,12 @@ class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7, A8)> { MOCK_METHOD9_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8)); #if GTEST_HAS_STD_FUNCTION_ - std::function<R(A0, A1, A2, A3, A4, A5, A6, A7, A8)> AsStdFunction() { + ::std::function<R(A0, A1, A2, A3, A4, A5, A6, A7, A8)> AsStdFunction() { return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) -> R { - return this->Call(a0, a1, a2, a3, a4, a5, a6, a7, a8); + return this->Call(::std::move(a0), ::std::move(a1), ::std::move(a2), + ::std::move(a3), ::std::move(a4), ::std::move(a5), ::std::move(a6), + ::std::move(a7), ::std::move(a8)); }; } #endif // GTEST_HAS_STD_FUNCTION_ @@ -1078,10 +1361,12 @@ class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)> { MOCK_METHOD10_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)); #if GTEST_HAS_STD_FUNCTION_ - std::function<R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)> AsStdFunction() { + ::std::function<R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)> AsStdFunction() { return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) -> R { - return this->Call(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); + return this->Call(::std::move(a0), ::std::move(a1), ::std::move(a2), + ::std::move(a3), ::std::move(a4), ::std::move(a5), ::std::move(a6), + ::std::move(a7), ::std::move(a8), ::std::move(a9)); }; } #endif // GTEST_HAS_STD_FUNCTION_ diff --git a/googlemock/include/gmock/gmock-generated-function-mockers.h.pump b/googlemock/include/gmock/gmock-generated-function-mockers.h.pump index 811502d0..82f9512f 100644 --- a/googlemock/include/gmock/gmock-generated-function-mockers.h.pump +++ b/googlemock/include/gmock/gmock-generated-function-mockers.h.pump @@ -1,6 +1,6 @@ $$ -*- mode: c++; -*- -$$ This is a Pump source file. Please use Pump to convert it to -$$ gmock-generated-function-mockers.h. +$$ 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. @@ -31,13 +31,14 @@ $var n = 10 $$ The maximum arity we support. // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // 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_ @@ -68,7 +69,7 @@ $for i [[ $range j 1..i $var typename_As = [[$for j [[, typename A$j]]]] $var As = [[$for j, [[A$j]]]] -$var as = [[$for j, [[a$j]]]] +$var as = [[$for j, [[internal::forward<A$j>(a$j)]]]] $var Aas = [[$for j, [[A$j a$j]]]] $var ms = [[$for j, [[m$j]]]] $var matchers = [[$for j, [[const Matcher<A$j>& m$j]]]] @@ -79,13 +80,8 @@ class FunctionMocker<R($As)> : public typedef R F($As); typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; - MockSpec<F>& With($matchers) { - -$if i >= 1 [[ - this->current_spec().SetMatchers(::testing::make_tuple($ms)); - -]] - return this->current_spec(); + MockSpec<F> With($matchers) { + return MockSpec<F>(this, ::testing::make_tuple($ms)); } R Invoke($Aas) { @@ -99,6 +95,58 @@ $if i >= 1 [[ ]] +// 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 @@ -134,11 +182,14 @@ using internal::FunctionMocker; $for i [[ $range j 1..i -$var arg_as = [[$for j, \ - [[GMOCK_ARG_(tn, $j, __VA_ARGS__) gmock_a$j]]]] -$var as = [[$for j, [[gmock_a$j]]]] -$var matcher_as = [[$for j, \ +$var arg_as = [[$for j, [[GMOCK_ARG_(tn, $j, __VA_ARGS__) gmock_a$j]]]] +$var as = [[$for j, \ + [[::testing::internal::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, ...) \ GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ @@ -149,11 +200,17 @@ $var matcher_as = [[$for j, \ GMOCK_MOCKER_($i, constness, Method).SetOwnerAndName(this, #Method); \ return GMOCK_MOCKER_($i, constness, Method).Invoke($as); \ } \ - ::testing::MockSpec<__VA_ARGS__>& \ - gmock_##Method($matcher_as) constness { \ + ::testing::MockSpec<__VA_ARGS__> \ + gmock_##Method($matcher_arg_as) constness { \ GMOCK_MOCKER_($i, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_($i, constness, Method).With($as); \ + 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) @@ -263,7 +320,7 @@ class MockFunction; $for i [[ $range j 0..i-1 $var ArgTypes = [[$for j, [[A$j]]]] -$var ArgNames = [[$for j, [[a$j]]]] +$var ArgValues = [[$for j, [[::std::move(a$j)]]]] $var ArgDecls = [[$for j, [[A$j a$j]]]] template <typename R$for j [[, typename A$j]]> class MockFunction<R($ArgTypes)> { @@ -273,9 +330,9 @@ class MockFunction<R($ArgTypes)> { MOCK_METHOD$i[[]]_T(Call, R($ArgTypes)); #if GTEST_HAS_STD_FUNCTION_ - std::function<R($ArgTypes)> AsStdFunction() { + ::std::function<R($ArgTypes)> AsStdFunction() { return [this]($ArgDecls) -> R { - return this->Call($ArgNames); + return this->Call($ArgValues); }; } #endif // GTEST_HAS_STD_FUNCTION_ diff --git a/googlemock/include/gmock/gmock-generated-matchers.h b/googlemock/include/gmock/gmock-generated-matchers.h index 1655bcd3..0d46d23b 100644 --- a/googlemock/include/gmock/gmock-generated-matchers.h +++ b/googlemock/include/gmock/gmock-generated-matchers.h @@ -35,6 +35,8 @@ // // 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_ @@ -779,6 +781,9 @@ ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, // UnorderedElementsAre(e_1, e_2, ..., e_n) is an ElementsAre extension // that matches n elements in any order. We support up to n=10 arguments. +// +// If you have >10 elements, consider UnorderedElementsAreArray() or +// UnorderedPointwise() instead. inline internal::UnorderedElementsAreMatcher< ::testing::tuple<> > @@ -1268,7 +1273,7 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { // using testing::PrintToString; // // MATCHER_P2(InClosedRange, low, hi, -// string(negation ? "is not" : "is") + " in range [" + +// std::string(negation ? "is not" : "is") + " in range [" + // PrintToString(low) + ", " + PrintToString(hi) + "]") { // return low <= arg && arg <= hi; // } @@ -1383,12 +1388,14 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { class name##Matcher {\ public:\ template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ public:\ gmock_Impl()\ {}\ virtual bool MatchAndExplain(\ - arg_type arg, ::testing::MatchResultListener* result_listener) const;\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const;\ virtual void DescribeTo(::std::ostream* gmock_os) const {\ *gmock_os << FormatDescription(false);\ }\ @@ -1396,17 +1403,15 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { *gmock_os << FormatDescription(true);\ }\ private:\ - ::testing::internal::string FormatDescription(bool negation) const {\ - const ::testing::internal::string gmock_description = (description);\ - if (!gmock_description.empty()) {\ + ::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(\ ::testing::tuple<>()));\ }\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ };\ template <typename arg_type>\ operator ::testing::Matcher<arg_type>() const {\ @@ -1416,14 +1421,13 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { name##Matcher() {\ }\ private:\ - GTEST_DISALLOW_ASSIGN_(name##Matcher);\ };\ inline name##Matcher name() {\ return name##Matcher();\ }\ template <typename arg_type>\ bool name##Matcher::gmock_Impl<arg_type>::MatchAndExplain(\ - arg_type arg, \ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ const @@ -1432,42 +1436,42 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { class name##MatcherP {\ public:\ template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ public:\ explicit gmock_Impl(p0##_type gmock_p0)\ - : p0(gmock_p0) {}\ + : p0(::testing::internal::move(gmock_p0)) {}\ virtual bool MatchAndExplain(\ - arg_type arg, ::testing::MatchResultListener* result_listener) const;\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const;\ virtual void DescribeTo(::std::ostream* gmock_os) const {\ *gmock_os << FormatDescription(false);\ }\ virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ *gmock_os << FormatDescription(true);\ }\ - p0##_type p0;\ + p0##_type const p0;\ private:\ - ::testing::internal::string FormatDescription(bool negation) const {\ - const ::testing::internal::string gmock_description = (description);\ - if (!gmock_description.empty()) {\ + ::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(\ ::testing::tuple<p0##_type>(p0)));\ }\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ };\ 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(gmock_p0) {\ + explicit name##MatcherP(p0##_type gmock_p0) : \ + p0(::testing::internal::move(gmock_p0)) {\ }\ - p0##_type p0;\ + p0##_type const p0;\ private:\ - GTEST_DISALLOW_ASSIGN_(name##MatcherP);\ };\ template <typename p0##_type>\ inline name##MatcherP<p0##_type> name(p0##_type p0) {\ @@ -1476,7 +1480,7 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { template <typename p0##_type>\ template <typename arg_type>\ bool name##MatcherP<p0##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - arg_type arg, \ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ const @@ -1485,45 +1489,46 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { class name##MatcherP2 {\ public:\ template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<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(gmock_p0), p1(gmock_p1) {}\ + : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)) {}\ virtual bool MatchAndExplain(\ - arg_type arg, ::testing::MatchResultListener* result_listener) const;\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const;\ virtual void DescribeTo(::std::ostream* gmock_os) const {\ *gmock_os << FormatDescription(false);\ }\ virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ *gmock_os << FormatDescription(true);\ }\ - p0##_type p0;\ - p1##_type p1;\ + p0##_type const p0;\ + p1##_type const p1;\ private:\ - ::testing::internal::string FormatDescription(bool negation) const {\ - const ::testing::internal::string gmock_description = (description);\ - if (!gmock_description.empty()) {\ + ::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(\ ::testing::tuple<p0##_type, p1##_type>(p0, p1)));\ }\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ };\ 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(gmock_p0), \ - p1(gmock_p1) {\ + name##MatcherP2(p0##_type gmock_p0, \ + p1##_type gmock_p1) : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)) {\ }\ - p0##_type p0;\ - p1##_type p1;\ + p0##_type const p0;\ + p1##_type const p1;\ private:\ - GTEST_DISALLOW_ASSIGN_(name##MatcherP2);\ };\ template <typename p0##_type, typename p1##_type>\ inline name##MatcherP2<p0##_type, p1##_type> name(p0##_type p0, \ @@ -1534,7 +1539,7 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { template <typename arg_type>\ bool name##MatcherP2<p0##_type, \ p1##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - arg_type arg, \ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ const @@ -1543,34 +1548,36 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { class name##MatcherP3 {\ public:\ template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<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(gmock_p0), p1(gmock_p1), p2(gmock_p2) {}\ + : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)), \ + p2(::testing::internal::move(gmock_p2)) {}\ virtual bool MatchAndExplain(\ - arg_type arg, ::testing::MatchResultListener* result_listener) const;\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const;\ virtual void DescribeTo(::std::ostream* gmock_os) const {\ *gmock_os << FormatDescription(false);\ }\ virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ *gmock_os << FormatDescription(true);\ }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ private:\ - ::testing::internal::string FormatDescription(bool negation) const {\ - const ::testing::internal::string gmock_description = (description);\ - if (!gmock_description.empty()) {\ + ::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(\ ::testing::tuple<p0##_type, p1##_type, p2##_type>(p0, p1, \ p2)));\ }\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ };\ template <typename arg_type>\ operator ::testing::Matcher<arg_type>() const {\ @@ -1578,13 +1585,14 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { new gmock_Impl<arg_type>(p0, p1, p2));\ }\ name##MatcherP3(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {\ + p2##_type gmock_p2) : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)), \ + p2(::testing::internal::move(gmock_p2)) {\ }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ private:\ - GTEST_DISALLOW_ASSIGN_(name##MatcherP3);\ };\ template <typename p0##_type, typename p1##_type, typename p2##_type>\ inline name##MatcherP3<p0##_type, p1##_type, p2##_type> name(p0##_type p0, \ @@ -1595,7 +1603,7 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { template <typename arg_type>\ bool name##MatcherP3<p0##_type, p1##_type, \ p2##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - arg_type arg, \ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ const @@ -1605,36 +1613,39 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { class name##MatcherP4 {\ public:\ template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<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(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3) {}\ + : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)), \ + p2(::testing::internal::move(gmock_p2)), \ + p3(::testing::internal::move(gmock_p3)) {}\ virtual bool MatchAndExplain(\ - arg_type arg, ::testing::MatchResultListener* result_listener) const;\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const;\ virtual void DescribeTo(::std::ostream* gmock_os) const {\ *gmock_os << FormatDescription(false);\ }\ virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ *gmock_os << FormatDescription(true);\ }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ private:\ - ::testing::internal::string FormatDescription(bool negation) const {\ - const ::testing::internal::string gmock_description = (description);\ - if (!gmock_description.empty()) {\ + ::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(\ ::testing::tuple<p0##_type, p1##_type, p2##_type, \ p3##_type>(p0, p1, p2, p3)));\ }\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ };\ template <typename arg_type>\ operator ::testing::Matcher<arg_type>() const {\ @@ -1642,15 +1653,17 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { 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(gmock_p0), p1(gmock_p1), \ - p2(gmock_p2), p3(gmock_p3) {\ + p2##_type gmock_p2, \ + p3##_type gmock_p3) : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)), \ + p2(::testing::internal::move(gmock_p2)), \ + p3(::testing::internal::move(gmock_p3)) {\ }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ private:\ - GTEST_DISALLOW_ASSIGN_(name##MatcherP4);\ };\ template <typename p0##_type, typename p1##_type, typename p2##_type, \ typename p3##_type>\ @@ -1665,7 +1678,7 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { template <typename arg_type>\ bool name##MatcherP4<p0##_type, p1##_type, p2##_type, \ p3##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - arg_type arg, \ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ const @@ -1675,38 +1688,41 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { class name##MatcherP5 {\ public:\ template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<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(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \ - p4(gmock_p4) {}\ + : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)), \ + p2(::testing::internal::move(gmock_p2)), \ + p3(::testing::internal::move(gmock_p3)), \ + p4(::testing::internal::move(gmock_p4)) {}\ virtual bool MatchAndExplain(\ - arg_type arg, ::testing::MatchResultListener* result_listener) const;\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const;\ virtual void DescribeTo(::std::ostream* gmock_os) const {\ *gmock_os << FormatDescription(false);\ }\ virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ *gmock_os << FormatDescription(true);\ }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ private:\ - ::testing::internal::string FormatDescription(bool negation) const {\ - const ::testing::internal::string gmock_description = (description);\ - if (!gmock_description.empty()) {\ + ::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(\ ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ p4##_type>(p0, p1, p2, p3, p4)));\ }\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ };\ template <typename arg_type>\ operator ::testing::Matcher<arg_type>() const {\ @@ -1715,16 +1731,18 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { }\ name##MatcherP5(p0##_type gmock_p0, p1##_type gmock_p1, \ p2##_type gmock_p2, p3##_type gmock_p3, \ - p4##_type gmock_p4) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4) {\ + p4##_type gmock_p4) : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)), \ + p2(::testing::internal::move(gmock_p2)), \ + p3(::testing::internal::move(gmock_p3)), \ + p4(::testing::internal::move(gmock_p4)) {\ }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ private:\ - GTEST_DISALLOW_ASSIGN_(name##MatcherP5);\ };\ template <typename p0##_type, typename p1##_type, typename p2##_type, \ typename p3##_type, typename p4##_type>\ @@ -1739,7 +1757,7 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { template <typename arg_type>\ bool name##MatcherP5<p0##_type, p1##_type, p2##_type, p3##_type, \ p4##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - arg_type arg, \ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ const @@ -1749,39 +1767,43 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { class name##MatcherP6 {\ public:\ template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<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(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \ - p4(gmock_p4), p5(gmock_p5) {}\ + : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)), \ + p2(::testing::internal::move(gmock_p2)), \ + p3(::testing::internal::move(gmock_p3)), \ + p4(::testing::internal::move(gmock_p4)), \ + p5(::testing::internal::move(gmock_p5)) {}\ virtual bool MatchAndExplain(\ - arg_type arg, ::testing::MatchResultListener* result_listener) const;\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const;\ virtual void DescribeTo(::std::ostream* gmock_os) const {\ *gmock_os << FormatDescription(false);\ }\ virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ *gmock_os << FormatDescription(true);\ }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type 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:\ - ::testing::internal::string FormatDescription(bool negation) const {\ - const ::testing::internal::string gmock_description = (description);\ - if (!gmock_description.empty()) {\ + ::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(\ ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ p4##_type, p5##_type>(p0, p1, p2, p3, p4, p5)));\ }\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ };\ template <typename arg_type>\ operator ::testing::Matcher<arg_type>() const {\ @@ -1790,17 +1812,20 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { }\ 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(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) {\ + p5##_type gmock_p5) : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)), \ + p2(::testing::internal::move(gmock_p2)), \ + p3(::testing::internal::move(gmock_p3)), \ + p4(::testing::internal::move(gmock_p4)), \ + p5(::testing::internal::move(gmock_p5)) {\ }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type 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:\ - GTEST_DISALLOW_ASSIGN_(name##MatcherP6);\ };\ template <typename p0##_type, typename p1##_type, typename p2##_type, \ typename p3##_type, typename p4##_type, typename p5##_type>\ @@ -1815,7 +1840,7 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { template <typename arg_type>\ bool name##MatcherP6<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ p5##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - arg_type arg, \ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ const @@ -1826,34 +1851,40 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { class name##MatcherP7 {\ public:\ template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<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(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \ - p4(gmock_p4), p5(gmock_p5), p6(gmock_p6) {}\ + : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)), \ + p2(::testing::internal::move(gmock_p2)), \ + p3(::testing::internal::move(gmock_p3)), \ + p4(::testing::internal::move(gmock_p4)), \ + p5(::testing::internal::move(gmock_p5)), \ + p6(::testing::internal::move(gmock_p6)) {}\ virtual bool MatchAndExplain(\ - arg_type arg, ::testing::MatchResultListener* result_listener) const;\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const;\ virtual void DescribeTo(::std::ostream* gmock_os) const {\ *gmock_os << FormatDescription(false);\ }\ virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ *gmock_os << FormatDescription(true);\ }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type 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:\ - ::testing::internal::string FormatDescription(bool negation) const {\ - const ::testing::internal::string gmock_description = (description);\ - if (!gmock_description.empty()) {\ + ::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(\ @@ -1861,7 +1892,6 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { p4##_type, p5##_type, p6##_type>(p0, p1, p2, p3, p4, p5, \ p6)));\ }\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ };\ template <typename arg_type>\ operator ::testing::Matcher<arg_type>() const {\ @@ -1870,19 +1900,23 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { }\ 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(gmock_p0), p1(gmock_p1), \ - p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), \ - p6(gmock_p6) {\ + p5##_type gmock_p5, \ + p6##_type gmock_p6) : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)), \ + p2(::testing::internal::move(gmock_p2)), \ + p3(::testing::internal::move(gmock_p3)), \ + p4(::testing::internal::move(gmock_p4)), \ + p5(::testing::internal::move(gmock_p5)), \ + p6(::testing::internal::move(gmock_p6)) {\ }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type 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:\ - GTEST_DISALLOW_ASSIGN_(name##MatcherP7);\ };\ template <typename p0##_type, typename p1##_type, typename p2##_type, \ typename p3##_type, typename p4##_type, typename p5##_type, \ @@ -1900,7 +1934,7 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { 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(\ - arg_type arg, \ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ const @@ -1911,35 +1945,42 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { class name##MatcherP8 {\ public:\ template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<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(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \ - p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7) {}\ + : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)), \ + p2(::testing::internal::move(gmock_p2)), \ + p3(::testing::internal::move(gmock_p3)), \ + p4(::testing::internal::move(gmock_p4)), \ + p5(::testing::internal::move(gmock_p5)), \ + p6(::testing::internal::move(gmock_p6)), \ + p7(::testing::internal::move(gmock_p7)) {}\ virtual bool MatchAndExplain(\ - arg_type arg, ::testing::MatchResultListener* result_listener) const;\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const;\ virtual void DescribeTo(::std::ostream* gmock_os) const {\ *gmock_os << FormatDescription(false);\ }\ virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ *gmock_os << FormatDescription(true);\ }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - p7##_type 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:\ - ::testing::internal::string FormatDescription(bool negation) const {\ - const ::testing::internal::string gmock_description = (description);\ - if (!gmock_description.empty()) {\ + ::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(\ @@ -1947,7 +1988,6 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { p4##_type, p5##_type, p6##_type, p7##_type>(p0, p1, p2, \ p3, p4, p5, p6, p7)));\ }\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ };\ template <typename arg_type>\ operator ::testing::Matcher<arg_type>() const {\ @@ -1957,20 +1997,24 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { 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(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \ - p7(gmock_p7) {\ + p7##_type gmock_p7) : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)), \ + p2(::testing::internal::move(gmock_p2)), \ + p3(::testing::internal::move(gmock_p3)), \ + p4(::testing::internal::move(gmock_p4)), \ + p5(::testing::internal::move(gmock_p5)), \ + p6(::testing::internal::move(gmock_p6)), \ + p7(::testing::internal::move(gmock_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;\ + 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:\ - GTEST_DISALLOW_ASSIGN_(name##MatcherP8);\ };\ template <typename p0##_type, typename p1##_type, typename p2##_type, \ typename p3##_type, typename p4##_type, typename p5##_type, \ @@ -1990,7 +2034,7 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { bool name##MatcherP8<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ p5##_type, p6##_type, \ p7##_type>::gmock_Impl<arg_type>::MatchAndExplain(\ - arg_type arg, \ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ const @@ -2001,37 +2045,44 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { class name##MatcherP9 {\ public:\ template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<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(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \ - p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \ - p8(gmock_p8) {}\ + : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)), \ + p2(::testing::internal::move(gmock_p2)), \ + p3(::testing::internal::move(gmock_p3)), \ + p4(::testing::internal::move(gmock_p4)), \ + p5(::testing::internal::move(gmock_p5)), \ + p6(::testing::internal::move(gmock_p6)), \ + p7(::testing::internal::move(gmock_p7)), \ + p8(::testing::internal::move(gmock_p8)) {}\ virtual bool MatchAndExplain(\ - arg_type arg, ::testing::MatchResultListener* result_listener) const;\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const;\ virtual void DescribeTo(::std::ostream* gmock_os) const {\ *gmock_os << FormatDescription(false);\ }\ virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ *gmock_os << FormatDescription(true);\ }\ - 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;\ + 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:\ - ::testing::internal::string FormatDescription(bool negation) const {\ - const ::testing::internal::string gmock_description = (description);\ - if (!gmock_description.empty()) {\ + ::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(\ @@ -2039,7 +2090,6 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { p4##_type, p5##_type, p6##_type, p7##_type, \ p8##_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8)));\ }\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ };\ template <typename arg_type>\ operator ::testing::Matcher<arg_type>() const {\ @@ -2049,21 +2099,26 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { 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(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \ - p8(gmock_p8) {\ + p8##_type gmock_p8) : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)), \ + p2(::testing::internal::move(gmock_p2)), \ + p3(::testing::internal::move(gmock_p3)), \ + p4(::testing::internal::move(gmock_p4)), \ + p5(::testing::internal::move(gmock_p5)), \ + p6(::testing::internal::move(gmock_p6)), \ + p7(::testing::internal::move(gmock_p7)), \ + p8(::testing::internal::move(gmock_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;\ + 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:\ - GTEST_DISALLOW_ASSIGN_(name##MatcherP9);\ };\ template <typename p0##_type, typename p1##_type, typename p2##_type, \ typename p3##_type, typename p4##_type, typename p5##_type, \ @@ -2084,7 +2139,7 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { 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(\ - arg_type arg, \ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ const @@ -2096,39 +2151,47 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { class name##MatcherP10 {\ public:\ template <typename arg_type>\ - class gmock_Impl : public ::testing::MatcherInterface<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(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \ - p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \ - p8(gmock_p8), p9(gmock_p9) {}\ + : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)), \ + p2(::testing::internal::move(gmock_p2)), \ + p3(::testing::internal::move(gmock_p3)), \ + p4(::testing::internal::move(gmock_p4)), \ + p5(::testing::internal::move(gmock_p5)), \ + p6(::testing::internal::move(gmock_p6)), \ + p7(::testing::internal::move(gmock_p7)), \ + p8(::testing::internal::move(gmock_p8)), \ + p9(::testing::internal::move(gmock_p9)) {}\ virtual bool MatchAndExplain(\ - arg_type arg, ::testing::MatchResultListener* result_listener) const;\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const;\ virtual void DescribeTo(::std::ostream* gmock_os) const {\ *gmock_os << FormatDescription(false);\ }\ virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ *gmock_os << FormatDescription(true);\ }\ - 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;\ + 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:\ - ::testing::internal::string FormatDescription(bool negation) const {\ - const ::testing::internal::string gmock_description = (description);\ - if (!gmock_description.empty()) {\ + ::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(\ @@ -2136,7 +2199,6 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, \ p9##_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)));\ }\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ };\ template <typename arg_type>\ operator ::testing::Matcher<arg_type>() const {\ @@ -2146,22 +2208,29 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { 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(gmock_p0), p1(gmock_p1), \ - p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \ - p7(gmock_p7), p8(gmock_p8), p9(gmock_p9) {\ + p8##_type gmock_p8, \ + p9##_type gmock_p9) : p0(::testing::internal::move(gmock_p0)), \ + p1(::testing::internal::move(gmock_p1)), \ + p2(::testing::internal::move(gmock_p2)), \ + p3(::testing::internal::move(gmock_p3)), \ + p4(::testing::internal::move(gmock_p4)), \ + p5(::testing::internal::move(gmock_p5)), \ + p6(::testing::internal::move(gmock_p6)), \ + p7(::testing::internal::move(gmock_p7)), \ + p8(::testing::internal::move(gmock_p8)), \ + p9(::testing::internal::move(gmock_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;\ + 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:\ - GTEST_DISALLOW_ASSIGN_(name##MatcherP10);\ };\ template <typename p0##_type, typename p1##_type, typename p2##_type, \ typename p3##_type, typename p4##_type, typename p5##_type, \ @@ -2184,7 +2253,7 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { 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(\ - arg_type arg, \ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ const diff --git a/googlemock/include/gmock/gmock-generated-matchers.h.pump b/googlemock/include/gmock/gmock-generated-matchers.h.pump index 25d2da99..9fe0fd7a 100644 --- a/googlemock/include/gmock/gmock-generated-matchers.h.pump +++ b/googlemock/include/gmock/gmock-generated-matchers.h.pump @@ -1,6 +1,6 @@ $$ -*- mode: c++; -*- -$$ This is a Pump source file. Please use Pump to convert it to -$$ gmock-generated-actions.h. +$$ 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. @@ -37,6 +37,8 @@ $$ }} This line fixes auto-indentation of the following code in Emacs. // // 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_ @@ -303,6 +305,9 @@ $for j, [[ // UnorderedElementsAre(e_1, e_2, ..., e_n) is an ElementsAre extension // that matches n elements in any order. We support up to n=$n arguments. +// +// If you have >$n elements, consider UnorderedElementsAreArray() or +// UnorderedPointwise() instead. $range i 0..n $for i [[ @@ -479,7 +484,7 @@ $$ // show up in the generated code. // using testing::PrintToString; // // MATCHER_P2(InClosedRange, low, hi, -// string(negation ? "is not" : "is") + " in range [" + +// std::string(negation ? "is not" : "is") + " in range [" + // PrintToString(low) + ", " + PrintToString(hi) + "]") { // return low <= arg && arg <= hi; // } @@ -604,32 +609,34 @@ $var template = [[$if i==0 [[]] $else [[ ]]]] $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(gmock_p$j)]]]]]] -$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]] +$var impl_inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::testing::internal::move(gmock_p$j))]]]]]] +$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::testing::internal::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 p$j;\ + p$j##_type const p$j;\ ]]]] $var param_field_decls2 = [[$for j [[ - p$j##_type p$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<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 {}\ virtual bool MatchAndExplain(\ - arg_type arg, ::testing::MatchResultListener* result_listener) const;\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const;\ virtual void DescribeTo(::std::ostream* gmock_os) const {\ *gmock_os << FormatDescription(false);\ }\ @@ -637,17 +644,15 @@ $var param_field_decls2 = [[$for j *gmock_os << FormatDescription(true);\ }\$param_field_decls private:\ - ::testing::internal::string FormatDescription(bool negation) const {\ - const ::testing::internal::string gmock_description = (description);\ - if (!gmock_description.empty()) {\ + ::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(\ ::testing::tuple<$for j, [[p$j##_type]]>($for j, [[p$j]])));\ }\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ };\ template <typename arg_type>\ operator ::testing::Matcher<arg_type>() const {\ @@ -657,14 +662,13 @@ $var param_field_decls2 = [[$for j [[$if i==1 [[explicit ]]]]$class_name($ctor_param_list)$inits {\ }\$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 arg_type>\ bool $class_name$param_types::gmock_Impl<arg_type>::MatchAndExplain(\ - arg_type arg, \ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ const ]] diff --git a/googlemock/include/gmock/gmock-generated-nice-strict.h b/googlemock/include/gmock/gmock-generated-nice-strict.h index 4095f4d5..91ba1d9b 100644 --- a/googlemock/include/gmock/gmock-generated-nice-strict.h +++ b/googlemock/include/gmock/gmock-generated-nice-strict.h @@ -30,8 +30,7 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Implements class templates NiceMock, NaggyMock, and StrictMock. // @@ -51,10 +50,9 @@ // NiceMock<MockFoo>. // // NiceMock, NaggyMock, and StrictMock "inherit" the constructors of -// their respective base class, with up-to 10 arguments. Therefore -// you can write NiceMock<MockFoo>(5, "a") to construct a nice mock -// where MockFoo has a constructor that accepts (int, const char*), -// for example. +// their respective base class. Therefore you can write +// NiceMock<MockFoo>(5, "a") to construct a nice mock where MockFoo +// has a constructor that accepts (int, const char*), for example. // // A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>, // and StrictMock<MockFoo> only works for mock methods defined using @@ -63,10 +61,8 @@ // or "strict" modifier may not affect it, depending on the compiler. // In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT // supported. -// -// Another known limitation is that the constructors of the base mock -// cannot have arguments passed by non-const reference, which are -// banned by the Google C++ style guide anyway. + +// GOOGLETEST_CM0002 DO NOT DELETE #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ @@ -79,15 +75,35 @@ namespace testing { template <class MockClass> class NiceMock : public MockClass { public: - // We don't factor out the constructor body to a common method, as - // we have to avoid a possible clash with members of MockClass. - NiceMock() { + NiceMock() : MockClass() { + ::testing::Mock::AllowUninterestingCalls( + internal::ImplicitCast_<MockClass*>(this)); + } + +#if GTEST_LANG_CXX11 + // Ideally, we would inherit base class's constructors through a using + // declaration, which would preserve their visibility. However, many existing + // tests rely on the fact that current implementation reexports protected + // constructors as public. These tests would need to be cleaned up first. + + // Single argument constructor is special-cased so that it can be + // made explicit. + template <typename A> + explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) { ::testing::Mock::AllowUninterestingCalls( internal::ImplicitCast_<MockClass*>(this)); } - // C++ doesn't (yet) allow inheritance of constructors, so we have - // to define it for each arity. + template <typename A1, typename A2, typename... An> + NiceMock(A1&& arg1, A2&& arg2, An&&... args) + : MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2), + std::forward<An>(args)...) { + ::testing::Mock::AllowUninterestingCalls( + internal::ImplicitCast_<MockClass*>(this)); + } +#else + // C++98 doesn't have variadic templates, so we have to define one + // for each arity. template <typename A1> explicit NiceMock(const A1& a1) : MockClass(a1) { ::testing::Mock::AllowUninterestingCalls( @@ -163,7 +179,9 @@ class NiceMock : public MockClass { internal::ImplicitCast_<MockClass*>(this)); } - virtual ~NiceMock() { +#endif // GTEST_LANG_CXX11 + + ~NiceMock() { ::testing::Mock::UnregisterCallReaction( internal::ImplicitCast_<MockClass*>(this)); } @@ -175,15 +193,35 @@ class NiceMock : public MockClass { template <class MockClass> class NaggyMock : public MockClass { public: - // We don't factor out the constructor body to a common method, as - // we have to avoid a possible clash with members of MockClass. - NaggyMock() { + NaggyMock() : MockClass() { ::testing::Mock::WarnUninterestingCalls( internal::ImplicitCast_<MockClass*>(this)); } - // C++ doesn't (yet) allow inheritance of constructors, so we have - // to define it for each arity. +#if GTEST_LANG_CXX11 + // Ideally, we would inherit base class's constructors through a using + // declaration, which would preserve their visibility. However, many existing + // tests rely on the fact that current implementation reexports protected + // constructors as public. These tests would need to be cleaned up first. + + // Single argument constructor is special-cased so that it can be + // made explicit. + template <typename A> + explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) { + ::testing::Mock::WarnUninterestingCalls( + internal::ImplicitCast_<MockClass*>(this)); + } + + template <typename A1, typename A2, typename... An> + NaggyMock(A1&& arg1, A2&& arg2, An&&... args) + : MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2), + std::forward<An>(args)...) { + ::testing::Mock::WarnUninterestingCalls( + internal::ImplicitCast_<MockClass*>(this)); + } +#else + // C++98 doesn't have variadic templates, so we have to define one + // for each arity. template <typename A1> explicit NaggyMock(const A1& a1) : MockClass(a1) { ::testing::Mock::WarnUninterestingCalls( @@ -259,7 +297,9 @@ class NaggyMock : public MockClass { internal::ImplicitCast_<MockClass*>(this)); } - virtual ~NaggyMock() { +#endif // GTEST_LANG_CXX11 + + ~NaggyMock() { ::testing::Mock::UnregisterCallReaction( internal::ImplicitCast_<MockClass*>(this)); } @@ -271,15 +311,35 @@ class NaggyMock : public MockClass { template <class MockClass> class StrictMock : public MockClass { public: - // We don't factor out the constructor body to a common method, as - // we have to avoid a possible clash with members of MockClass. - StrictMock() { + StrictMock() : MockClass() { ::testing::Mock::FailUninterestingCalls( internal::ImplicitCast_<MockClass*>(this)); } - // C++ doesn't (yet) allow inheritance of constructors, so we have - // to define it for each arity. +#if GTEST_LANG_CXX11 + // Ideally, we would inherit base class's constructors through a using + // declaration, which would preserve their visibility. However, many existing + // tests rely on the fact that current implementation reexports protected + // constructors as public. These tests would need to be cleaned up first. + + // Single argument constructor is special-cased so that it can be + // made explicit. + template <typename A> + explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) { + ::testing::Mock::FailUninterestingCalls( + internal::ImplicitCast_<MockClass*>(this)); + } + + template <typename A1, typename A2, typename... An> + StrictMock(A1&& arg1, A2&& arg2, An&&... args) + : MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2), + std::forward<An>(args)...) { + ::testing::Mock::FailUninterestingCalls( + internal::ImplicitCast_<MockClass*>(this)); + } +#else + // C++98 doesn't have variadic templates, so we have to define one + // for each arity. template <typename A1> explicit StrictMock(const A1& a1) : MockClass(a1) { ::testing::Mock::FailUninterestingCalls( @@ -355,7 +415,9 @@ class StrictMock : public MockClass { internal::ImplicitCast_<MockClass*>(this)); } - virtual ~StrictMock() { +#endif // GTEST_LANG_CXX11 + + ~StrictMock() { ::testing::Mock::UnregisterCallReaction( internal::ImplicitCast_<MockClass*>(this)); } diff --git a/googlemock/include/gmock/gmock-generated-nice-strict.h.pump b/googlemock/include/gmock/gmock-generated-nice-strict.h.pump index 3ee1ce7f..ed49f4ab 100644 --- a/googlemock/include/gmock/gmock-generated-nice-strict.h.pump +++ b/googlemock/include/gmock/gmock-generated-nice-strict.h.pump @@ -1,6 +1,6 @@ $$ -*- mode: c++; -*- -$$ This is a Pump source file. Please use Pump to convert it to -$$ gmock-generated-nice-strict.h. +$$ This is a Pump source file. Please use Pump to convert +$$ it to gmock-generated-nice-strict.h. $$ $var n = 10 $$ The maximum arity we support. // Copyright 2008, Google Inc. @@ -31,8 +31,7 @@ $var n = 10 $$ The maximum arity we support. // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Implements class templates NiceMock, NaggyMock, and StrictMock. // @@ -52,10 +51,9 @@ $var n = 10 $$ The maximum arity we support. // NiceMock<MockFoo>. // // NiceMock, NaggyMock, and StrictMock "inherit" the constructors of -// their respective base class, with up-to $n arguments. Therefore -// you can write NiceMock<MockFoo>(5, "a") to construct a nice mock -// where MockFoo has a constructor that accepts (int, const char*), -// for example. +// their respective base class. Therefore you can write +// NiceMock<MockFoo>(5, "a") to construct a nice mock where MockFoo +// has a constructor that accepts (int, const char*), for example. // // A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>, // and StrictMock<MockFoo> only works for mock methods defined using @@ -64,10 +62,8 @@ $var n = 10 $$ The maximum arity we support. // or "strict" modifier may not affect it, depending on the compiler. // In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT // supported. -// -// Another known limitation is that the constructors of the base mock -// cannot have arguments passed by non-const reference, which are -// banned by the Google C++ style guide anyway. + +// GOOGLETEST_CM0002 DO NOT DELETE #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ @@ -91,15 +87,35 @@ $var method=[[$if kind==0 [[AllowUninterestingCalls]] template <class MockClass> class $clazz : public MockClass { public: - // We don't factor out the constructor body to a common method, as - // we have to avoid a possible clash with members of MockClass. - $clazz() { + $clazz() : MockClass() { ::testing::Mock::$method( internal::ImplicitCast_<MockClass*>(this)); } - // C++ doesn't (yet) allow inheritance of constructors, so we have - // to define it for each arity. +#if GTEST_LANG_CXX11 + // Ideally, we would inherit base class's constructors through a using + // declaration, which would preserve their visibility. However, many existing + // tests rely on the fact that current implementation reexports protected + // constructors as public. These tests would need to be cleaned up first. + + // Single argument constructor is special-cased so that it can be + // made explicit. + template <typename A> + explicit $clazz(A&& arg) : MockClass(std::forward<A>(arg)) { + ::testing::Mock::$method( + internal::ImplicitCast_<MockClass*>(this)); + } + + template <typename A1, typename A2, typename... An> + $clazz(A1&& arg1, A2&& arg2, An&&... args) + : MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2), + std::forward<An>(args)...) { + ::testing::Mock::$method( + internal::ImplicitCast_<MockClass*>(this)); + } +#else + // C++98 doesn't have variadic templates, so we have to define one + // for each arity. template <typename A1> explicit $clazz(const A1& a1) : MockClass(a1) { ::testing::Mock::$method( @@ -117,7 +133,9 @@ $range j 1..i ]] - virtual ~$clazz() { +#endif // GTEST_LANG_CXX11 + + ~$clazz() { ::testing::Mock::UnregisterCallReaction( internal::ImplicitCast_<MockClass*>(this)); } diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index 94c23d38..a0018505 100644 --- a/googlemock/include/gmock/gmock-matchers.h +++ b/googlemock/include/gmock/gmock-matchers.h @@ -26,8 +26,7 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // @@ -35,6 +34,8 @@ // matchers can be defined by the user implementing the // MatcherInterface<T> interface if necessary. +// GOOGLETEST_CM0002 DO NOT DELETE + #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ @@ -72,7 +73,7 @@ namespace testing { // MatchResultListener is an abstract class. Its << operator can be // used by a matcher to explain why a value matches or doesn't match. // -// TODO(wan@google.com): add method +// FIXME: add method // bool InterestedInWhy(bool result) const; // to indicate whether the listener is interested in why the match // result is 'result'. @@ -179,6 +180,35 @@ class MatcherInterface : public MatcherDescriberInterface { // virtual void DescribeNegationTo(::std::ostream* os) const; }; +namespace internal { + +// Converts a MatcherInterface<T> to a MatcherInterface<const T&>. +template <typename T> +class MatcherInterfaceAdapter : public MatcherInterface<const T&> { + public: + explicit MatcherInterfaceAdapter(const MatcherInterface<T>* impl) + : impl_(impl) {} + virtual ~MatcherInterfaceAdapter() { delete impl_; } + + virtual void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); } + + virtual void DescribeNegationTo(::std::ostream* os) const { + impl_->DescribeNegationTo(os); + } + + virtual bool MatchAndExplain(const T& x, + MatchResultListener* listener) const { + return impl_->MatchAndExplain(x, listener); + } + + private: + const MatcherInterface<T>* const impl_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(MatcherInterfaceAdapter); +}; + +} // namespace internal + // A match result listener that stores the explanation in a string. class StringMatchResultListener : public MatchResultListener { public: @@ -252,12 +282,13 @@ class MatcherBase { public: // Returns true iff the matcher matches x; also explains the match // result to 'listener'. - bool MatchAndExplain(T x, MatchResultListener* listener) const { + bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) x, + MatchResultListener* listener) const { return impl_->MatchAndExplain(x, listener); } // Returns true iff this matcher matches x. - bool Matches(T x) const { + bool Matches(GTEST_REFERENCE_TO_CONST_(T) x) const { DummyMatchResultListener dummy; return MatchAndExplain(x, &dummy); } @@ -271,7 +302,8 @@ class MatcherBase { } // Explains why x matches, or doesn't match, the matcher. - void ExplainMatchResultTo(T x, ::std::ostream* os) const { + void ExplainMatchResultTo(GTEST_REFERENCE_TO_CONST_(T) x, + ::std::ostream* os) const { StreamMatchResultListener listener(os); MatchAndExplain(x, &listener); } @@ -287,9 +319,18 @@ class MatcherBase { MatcherBase() {} // Constructs a matcher from its implementation. - explicit MatcherBase(const MatcherInterface<T>* impl) + explicit MatcherBase( + const MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)>* impl) : impl_(impl) {} + template <typename U> + explicit MatcherBase( + const MatcherInterface<U>* impl, + typename internal::EnableIf< + !internal::IsSame<U, GTEST_REFERENCE_TO_CONST_(U)>::value>::type* = + NULL) + : impl_(new internal::MatcherInterfaceAdapter<U>(impl)) {} + virtual ~MatcherBase() {} private: @@ -304,7 +345,9 @@ class MatcherBase { // // If performance becomes a problem, we should see if using // shared_ptr helps. - ::testing::internal::linked_ptr<const MatcherInterface<T> > impl_; + ::testing::internal::linked_ptr< + const MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)> > + impl_; }; } // namespace internal @@ -323,7 +366,13 @@ class Matcher : public internal::MatcherBase<T> { explicit Matcher() {} // NOLINT // Constructs a matcher from its implementation. - explicit Matcher(const MatcherInterface<T>* impl) + explicit Matcher(const MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)>* impl) + : internal::MatcherBase<T>(impl) {} + + template <typename U> + explicit Matcher(const MatcherInterface<U>* impl, + typename internal::EnableIf<!internal::IsSame< + U, GTEST_REFERENCE_TO_CONST_(U)>::value>::type* = NULL) : internal::MatcherBase<T>(impl) {} // Implicit constructor here allows people to write @@ -332,86 +381,170 @@ class Matcher : public internal::MatcherBase<T> { }; // The following two specializations allow the user to write str -// instead of Eq(str) and "foo" instead of Eq("foo") when a string +// instead of Eq(str) and "foo" instead of Eq("foo") when a std::string // matcher is expected. template <> -class GTEST_API_ Matcher<const internal::string&> - : public internal::MatcherBase<const internal::string&> { +class GTEST_API_ Matcher<const std::string&> + : public internal::MatcherBase<const std::string&> { public: Matcher() {} - explicit Matcher(const MatcherInterface<const internal::string&>* impl) - : internal::MatcherBase<const internal::string&>(impl) {} + explicit Matcher(const MatcherInterface<const std::string&>* impl) + : internal::MatcherBase<const std::string&>(impl) {} // Allows the user to write str instead of Eq(str) sometimes, where - // str is a string object. - Matcher(const internal::string& s); // NOLINT + // str is a std::string object. + Matcher(const std::string& s); // NOLINT + +#if GTEST_HAS_GLOBAL_STRING + // Allows the user to write str instead of Eq(str) sometimes, where + // str is a ::string object. + Matcher(const ::string& s); // NOLINT +#endif // GTEST_HAS_GLOBAL_STRING // Allows the user to write "foo" instead of Eq("foo") sometimes. Matcher(const char* s); // NOLINT }; template <> -class GTEST_API_ Matcher<internal::string> - : public internal::MatcherBase<internal::string> { +class GTEST_API_ Matcher<std::string> + : public internal::MatcherBase<std::string> { public: Matcher() {} - explicit Matcher(const MatcherInterface<internal::string>* impl) - : internal::MatcherBase<internal::string>(impl) {} + explicit Matcher(const MatcherInterface<const std::string&>* impl) + : internal::MatcherBase<std::string>(impl) {} + explicit Matcher(const MatcherInterface<std::string>* impl) + : internal::MatcherBase<std::string>(impl) {} // Allows the user to write str instead of Eq(str) sometimes, where // str is a string object. - Matcher(const internal::string& s); // NOLINT + Matcher(const std::string& s); // NOLINT + +#if GTEST_HAS_GLOBAL_STRING + // Allows the user to write str instead of Eq(str) sometimes, where + // str is a ::string object. + Matcher(const ::string& s); // NOLINT +#endif // GTEST_HAS_GLOBAL_STRING // Allows the user to write "foo" instead of Eq("foo") sometimes. Matcher(const char* s); // NOLINT }; -#if GTEST_HAS_STRING_PIECE_ +#if GTEST_HAS_GLOBAL_STRING // The following two specializations allow the user to write str -// instead of Eq(str) and "foo" instead of Eq("foo") when a StringPiece +// instead of Eq(str) and "foo" instead of Eq("foo") when a ::string // matcher is expected. template <> -class GTEST_API_ Matcher<const StringPiece&> - : public internal::MatcherBase<const StringPiece&> { +class GTEST_API_ Matcher<const ::string&> + : public internal::MatcherBase<const ::string&> { public: Matcher() {} - explicit Matcher(const MatcherInterface<const StringPiece&>* impl) - : internal::MatcherBase<const StringPiece&>(impl) {} + explicit Matcher(const MatcherInterface<const ::string&>* impl) + : internal::MatcherBase<const ::string&>(impl) {} // Allows the user to write str instead of Eq(str) sometimes, where - // str is a string object. - Matcher(const internal::string& s); // NOLINT + // str is a std::string object. + Matcher(const std::string& s); // NOLINT + + // Allows the user to write str instead of Eq(str) sometimes, where + // str is a ::string object. + Matcher(const ::string& s); // NOLINT // Allows the user to write "foo" instead of Eq("foo") sometimes. Matcher(const char* s); // NOLINT +}; + +template <> +class GTEST_API_ Matcher< ::string> + : public internal::MatcherBase< ::string> { + public: + Matcher() {} + + explicit Matcher(const MatcherInterface<const ::string&>* impl) + : internal::MatcherBase< ::string>(impl) {} + explicit Matcher(const MatcherInterface< ::string>* impl) + : internal::MatcherBase< ::string>(impl) {} + + // Allows the user to write str instead of Eq(str) sometimes, where + // str is a std::string object. + Matcher(const std::string& s); // NOLINT - // Allows the user to pass StringPieces directly. - Matcher(StringPiece s); // NOLINT + // Allows the user to write str instead of Eq(str) sometimes, where + // str is a ::string object. + Matcher(const ::string& s); // NOLINT + + // Allows the user to write "foo" instead of Eq("foo") sometimes. + Matcher(const char* s); // NOLINT }; +#endif // GTEST_HAS_GLOBAL_STRING +#if GTEST_HAS_ABSL +// 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<StringPiece> - : public internal::MatcherBase<StringPiece> { +class GTEST_API_ Matcher<const absl::string_view&> + : public internal::MatcherBase<const absl::string_view&> { public: Matcher() {} - explicit Matcher(const MatcherInterface<StringPiece>* impl) - : internal::MatcherBase<StringPiece>(impl) {} + explicit Matcher(const MatcherInterface<const absl::string_view&>* impl) + : internal::MatcherBase<const absl::string_view&>(impl) {} // Allows the user to write str instead of Eq(str) sometimes, where - // str is a string object. - Matcher(const internal::string& s); // NOLINT + // str is a std::string object. + Matcher(const std::string& s); // NOLINT + +#if GTEST_HAS_GLOBAL_STRING + // Allows the user to write str instead of Eq(str) sometimes, where + // str is a ::string object. + Matcher(const ::string& s); // NOLINT +#endif // GTEST_HAS_GLOBAL_STRING // Allows the user to write "foo" instead of Eq("foo") sometimes. Matcher(const char* s); // NOLINT - // Allows the user to pass StringPieces directly. - Matcher(StringPiece s); // NOLINT + // Allows the user to pass absl::string_views directly. + Matcher(absl::string_view s); // NOLINT }; -#endif // GTEST_HAS_STRING_PIECE_ + +template <> +class GTEST_API_ Matcher<absl::string_view> + : public internal::MatcherBase<absl::string_view> { + 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) {} + + // Allows the user to write str instead of Eq(str) sometimes, where + // str is a std::string object. + Matcher(const std::string& s); // NOLINT + +#if GTEST_HAS_GLOBAL_STRING + // Allows the user to write str instead of Eq(str) sometimes, where + // str is a ::string object. + Matcher(const ::string& s); // NOLINT +#endif // GTEST_HAS_GLOBAL_STRING + + // 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 +}; +#endif // GTEST_HAS_ABSL + +// Prints a matcher in a human-readable format. +template <typename T> +std::ostream& operator<<(std::ostream& os, const Matcher<T>& matcher) { + matcher.DescribeTo(&os); + return os; +} // The PolymorphicMatcher class template makes it easy to implement a // polymorphic matcher (i.e. a matcher that can match values of more @@ -440,7 +573,7 @@ class PolymorphicMatcher { template <typename T> operator Matcher<T>() const { - return Matcher<T>(new MonomorphicImpl<T>(impl_)); + return Matcher<T>(new MonomorphicImpl<GTEST_REFERENCE_TO_CONST_(T)>(impl_)); } private: @@ -514,7 +647,7 @@ template <typename T, typename M> class MatcherCastImpl { public: static Matcher<T> Cast(const M& polymorphic_matcher_or_value) { - // M can be a polymorhic matcher, in which case we want to use + // M can be a polymorphic matcher, in which case we want to use // its conversion operator to create Matcher<T>. Or it can be a value // that should be passed to the Matcher<T>'s constructor. // @@ -530,21 +663,18 @@ class MatcherCastImpl { return CastImpl( polymorphic_matcher_or_value, BooleanConstant< - internal::ImplicitlyConvertible<M, Matcher<T> >::value>()); + internal::ImplicitlyConvertible<M, Matcher<T> >::value>(), + BooleanConstant< + internal::ImplicitlyConvertible<M, T>::value>()); } private: - static Matcher<T> CastImpl(const M& value, BooleanConstant<false>) { - // M can't be implicitly converted to Matcher<T>, so M isn't a polymorphic - // matcher. It must be a value then. Use direct initialization to create - // a matcher. - return Matcher<T>(ImplicitCast_<T>(value)); - } - + template <bool Ignore> static Matcher<T> CastImpl(const M& polymorphic_matcher_or_value, - BooleanConstant<true>) { + BooleanConstant<true> /* convertible_to_matcher */, + BooleanConstant<Ignore>) { // M is implicitly convertible to Matcher<T>, which means that either - // M is a polymorhpic matcher or Matcher<T> has an implicit constructor + // M is a polymorphic matcher or Matcher<T> has an implicit constructor // from M. In both cases using the implicit conversion will produce a // matcher. // @@ -553,6 +683,29 @@ class MatcherCastImpl { // (first to create T from M and then to create Matcher<T> from T). return polymorphic_matcher_or_value; } + + // M can't be implicitly converted to Matcher<T>, so M isn't a polymorphic + // matcher. It's a value of a type implicitly convertible to T. Use direct + // initialization to create a matcher. + static Matcher<T> CastImpl( + const M& value, BooleanConstant<false> /* convertible_to_matcher */, + BooleanConstant<true> /* convertible_to_T */) { + return Matcher<T>(ImplicitCast_<T>(value)); + } + + // M can't be implicitly converted to either Matcher<T> or T. Attempt to use + // polymorphic matcher Eq(value) in this case. + // + // Note that we first attempt to perform an implicit cast on the value and + // only fall back to the polymorphic Eq() matcher afterwards because the + // latter calls bool operator==(const Lhs& lhs, const Rhs& rhs) in the end + // which might be undefined even when Rhs is implicitly convertible to Lhs + // (e.g. std::pair<const int, int> vs. std::pair<int, int>). + // + // We don't define this method inline as we need the declaration of Eq(). + static Matcher<T> CastImpl( + const M& value, BooleanConstant<false> /* convertible_to_matcher */, + BooleanConstant<false> /* convertible_to_T */); }; // This more specialized version is used when MatcherCast()'s argument @@ -573,6 +726,22 @@ class MatcherCastImpl<T, Matcher<U> > { // We delegate the matching logic to the source matcher. virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { +#if GTEST_LANG_CXX11 + using FromType = typename std::remove_cv<typename std::remove_pointer< + typename std::remove_reference<T>::type>::type>::type; + using ToType = typename std::remove_cv<typename std::remove_pointer< + typename std::remove_reference<U>::type>::type>::type; + // Do not allow implicitly converting base*/& to derived*/&. + static_assert( + // Do not trigger if only one of them is a pointer. That implies a + // regular conversion and not a down_cast. + (std::is_pointer<typename std::remove_reference<T>::type>::value != + std::is_pointer<typename std::remove_reference<U>::type>::value) || + std::is_same<FromType, ToType>::value || + !std::is_base_of<FromType, ToType>::value, + "Can't implicitly convert from <base> to <derived>"); +#endif // GTEST_LANG_CXX11 + return source_matcher_.MatchAndExplain(static_cast<U>(x), listener); } @@ -750,10 +919,10 @@ class TuplePrefix { typename tuple_element<N - 1, MatcherTuple>::type matcher = get<N - 1>(matchers); typedef typename tuple_element<N - 1, ValueTuple>::type Value; - Value value = get<N - 1>(values); + GTEST_REFERENCE_TO_CONST_(Value) value = get<N - 1>(values); StringMatchResultListener listener; if (!matcher.MatchAndExplain(value, &listener)) { - // TODO(wan): include in the message the name of the parameter + // FIXME: include in the message the name of the parameter // as used in MOCK_METHOD*() when possible. *os << " Expected arg #" << N - 1 << ": "; get<N - 1>(matchers).DescribeTo(os); @@ -855,10 +1024,12 @@ OutIter TransformTupleValues(Func f, const Tuple& t, OutIter out) { // Implements A<T>(). template <typename T> -class AnyMatcherImpl : public MatcherInterface<T> { +class AnyMatcherImpl : public MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)> { public: - virtual bool MatchAndExplain( - T /* x */, MatchResultListener* /* listener */) const { return true; } + virtual bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) /* x */, + MatchResultListener* /* listener */) const { + return true; + } virtual void DescribeTo(::std::ostream* os) const { *os << "is anything"; } virtual void DescribeNegationTo(::std::ostream* os) const { // This is mostly for completeness' safe, as it's not very useful @@ -1128,6 +1299,19 @@ 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, + MatchResultListener* listener) const { + if (s.data() == NULL) { + return !expect_eq_; + } + // This should fail to compile if absl::string_view is used with wide + // strings. + const StringType& str = string(s); + return MatchAndExplain(str, listener); + } +#endif // GTEST_HAS_ABSL + // Accepts pointer types, particularly: // const char* // char* @@ -1144,7 +1328,7 @@ class StrEqualityMatcher { // Matches anything that can convert to StringType. // // This is a template, not just a plain function with const StringType&, - // because StringPiece has some interfering non-explicit constructors. + // because absl::string_view has some interfering non-explicit constructors. template <typename MatcheeStringType> bool MatchAndExplain(const MatcheeStringType& s, MatchResultListener* /* listener */) const { @@ -1188,6 +1372,19 @@ class HasSubstrMatcher { explicit HasSubstrMatcher(const StringType& substring) : substring_(substring) {} +#if GTEST_HAS_ABSL + bool MatchAndExplain(const absl::string_view& s, + MatchResultListener* listener) const { + if (s.data() == NULL) { + return false; + } + // This should fail to compile if absl::string_view is used with wide + // strings. + const StringType& str = string(s); + return MatchAndExplain(str, listener); + } +#endif // GTEST_HAS_ABSL + // Accepts pointer types, particularly: // const char* // char* @@ -1201,7 +1398,7 @@ class HasSubstrMatcher { // Matches anything that can convert to StringType. // // This is a template, not just a plain function with const StringType&, - // because StringPiece has some interfering non-explicit constructors. + // because absl::string_view has some interfering non-explicit constructors. template <typename MatcheeStringType> bool MatchAndExplain(const MatcheeStringType& s, MatchResultListener* /* listener */) const { @@ -1235,6 +1432,19 @@ class StartsWithMatcher { explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) { } +#if GTEST_HAS_ABSL + bool MatchAndExplain(const absl::string_view& s, + MatchResultListener* listener) const { + if (s.data() == NULL) { + return false; + } + // This should fail to compile if absl::string_view is used with wide + // strings. + const StringType& str = string(s); + return MatchAndExplain(str, listener); + } +#endif // GTEST_HAS_ABSL + // Accepts pointer types, particularly: // const char* // char* @@ -1248,7 +1458,7 @@ class StartsWithMatcher { // Matches anything that can convert to StringType. // // This is a template, not just a plain function with const StringType&, - // because StringPiece has some interfering non-explicit constructors. + // because absl::string_view has some interfering non-explicit constructors. template <typename MatcheeStringType> bool MatchAndExplain(const MatcheeStringType& s, MatchResultListener* /* listener */) const { @@ -1281,6 +1491,19 @@ class EndsWithMatcher { public: explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {} +#if GTEST_HAS_ABSL + bool MatchAndExplain(const absl::string_view& s, + MatchResultListener* listener) const { + if (s.data() == NULL) { + return false; + } + // This should fail to compile if absl::string_view is used with wide + // strings. + const StringType& str = string(s); + return MatchAndExplain(str, listener); + } +#endif // GTEST_HAS_ABSL + // Accepts pointer types, particularly: // const char* // char* @@ -1294,7 +1517,7 @@ class EndsWithMatcher { // Matches anything that can convert to StringType. // // This is a template, not just a plain function with const StringType&, - // because StringPiece has some interfering non-explicit constructors. + // because absl::string_view has some interfering non-explicit constructors. template <typename MatcheeStringType> bool MatchAndExplain(const MatcheeStringType& s, MatchResultListener* /* listener */) const { @@ -1327,6 +1550,13 @@ 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, + MatchResultListener* listener) const { + return s.data() && MatchAndExplain(string(s), listener); + } +#endif // GTEST_HAS_ABSL + // Accepts pointer types, particularly: // const char* // char* @@ -1340,7 +1570,7 @@ class MatchesRegexMatcher { // Matches anything that can convert to std::string. // // This is a template, not just a plain function with const std::string&, - // because StringPiece has some interfering non-explicit constructors. + // because absl::string_view has some interfering non-explicit constructors. template <class MatcheeStringType> bool MatchAndExplain(const MatcheeStringType& s, MatchResultListener* /* listener */) const { @@ -1440,12 +1670,13 @@ class Ge2Matcher : public PairMatchBase<Ge2Matcher, AnyGe> { // will prevent different instantiations of NotMatcher from sharing // the same NotMatcherImpl<T> class. template <typename T> -class NotMatcherImpl : public MatcherInterface<T> { +class NotMatcherImpl : public MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)> { public: explicit NotMatcherImpl(const Matcher<T>& matcher) : matcher_(matcher) {} - virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { + virtual bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) x, + MatchResultListener* listener) const { return !matcher_.MatchAndExplain(x, listener); } @@ -1488,117 +1719,66 @@ class NotMatcher { // that will prevent different instantiations of BothOfMatcher from // sharing the same BothOfMatcherImpl<T> class. template <typename T> -class BothOfMatcherImpl : public MatcherInterface<T> { +class AllOfMatcherImpl + : public MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)> { public: - BothOfMatcherImpl(const Matcher<T>& matcher1, const Matcher<T>& matcher2) - : matcher1_(matcher1), matcher2_(matcher2) {} + explicit AllOfMatcherImpl(std::vector<Matcher<T> > matchers) + : matchers_(internal::move(matchers)) {} virtual void DescribeTo(::std::ostream* os) const { *os << "("; - matcher1_.DescribeTo(os); - *os << ") and ("; - matcher2_.DescribeTo(os); + for (size_t i = 0; i < matchers_.size(); ++i) { + if (i != 0) *os << ") and ("; + matchers_[i].DescribeTo(os); + } *os << ")"; } virtual void DescribeNegationTo(::std::ostream* os) const { *os << "("; - matcher1_.DescribeNegationTo(os); - *os << ") or ("; - matcher2_.DescribeNegationTo(os); + for (size_t i = 0; i < matchers_.size(); ++i) { + if (i != 0) *os << ") or ("; + matchers_[i].DescribeNegationTo(os); + } *os << ")"; } - virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { + virtual bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) x, + MatchResultListener* listener) const { // If either matcher1_ or matcher2_ doesn't match x, we only need // to explain why one of them fails. - StringMatchResultListener listener1; - if (!matcher1_.MatchAndExplain(x, &listener1)) { - *listener << listener1.str(); - return false; - } + std::string all_match_result; - StringMatchResultListener listener2; - if (!matcher2_.MatchAndExplain(x, &listener2)) { - *listener << listener2.str(); - return false; + for (size_t i = 0; i < matchers_.size(); ++i) { + StringMatchResultListener slistener; + if (matchers_[i].MatchAndExplain(x, &slistener)) { + if (all_match_result.empty()) { + all_match_result = slistener.str(); + } else { + std::string result = slistener.str(); + if (!result.empty()) { + all_match_result += ", and "; + all_match_result += result; + } + } + } else { + *listener << slistener.str(); + return false; + } } // Otherwise we need to explain why *both* of them match. - const std::string s1 = listener1.str(); - const std::string s2 = listener2.str(); - - if (s1 == "") { - *listener << s2; - } else { - *listener << s1; - if (s2 != "") { - *listener << ", and " << s2; - } - } + *listener << all_match_result; return true; } private: - const Matcher<T> matcher1_; - const Matcher<T> matcher2_; + const std::vector<Matcher<T> > matchers_; - GTEST_DISALLOW_ASSIGN_(BothOfMatcherImpl); + GTEST_DISALLOW_ASSIGN_(AllOfMatcherImpl); }; #if GTEST_LANG_CXX11 -// MatcherList provides mechanisms for storing a variable number of matchers in -// a list structure (ListType) and creating a combining matcher from such a -// list. -// The template is defined recursively using the following template parameters: -// * kSize is the length of the MatcherList. -// * Head is the type of the first matcher of the list. -// * Tail denotes the types of the remaining matchers of the list. -template <int kSize, typename Head, typename... Tail> -struct MatcherList { - typedef MatcherList<kSize - 1, Tail...> MatcherListTail; - typedef ::std::pair<Head, typename MatcherListTail::ListType> ListType; - - // BuildList stores variadic type values in a nested pair structure. - // Example: - // MatcherList<3, int, string, float>::BuildList(5, "foo", 2.0) will return - // the corresponding result of type pair<int, pair<string, float>>. - static ListType BuildList(const Head& matcher, const Tail&... tail) { - return ListType(matcher, MatcherListTail::BuildList(tail...)); - } - - // CreateMatcher<T> creates a Matcher<T> from a given list of matchers (built - // by BuildList()). CombiningMatcher<T> is used to combine the matchers of the - // list. CombiningMatcher<T> must implement MatcherInterface<T> and have a - // constructor taking two Matcher<T>s as input. - template <typename T, template <typename /* T */> class CombiningMatcher> - static Matcher<T> CreateMatcher(const ListType& matchers) { - return Matcher<T>(new CombiningMatcher<T>( - SafeMatcherCast<T>(matchers.first), - MatcherListTail::template CreateMatcher<T, CombiningMatcher>( - matchers.second))); - } -}; - -// The following defines the base case for the recursive definition of -// MatcherList. -template <typename Matcher1, typename Matcher2> -struct MatcherList<2, Matcher1, Matcher2> { - typedef ::std::pair<Matcher1, Matcher2> ListType; - - static ListType BuildList(const Matcher1& matcher1, - const Matcher2& matcher2) { - return ::std::pair<Matcher1, Matcher2>(matcher1, matcher2); - } - - template <typename T, template <typename /* T */> class CombiningMatcher> - static Matcher<T> CreateMatcher(const ListType& matchers) { - return Matcher<T>(new CombiningMatcher<T>( - SafeMatcherCast<T>(matchers.first), - SafeMatcherCast<T>(matchers.second))); - } -}; - // VariadicMatcher is used for the variadic implementation of // AllOf(m_1, m_2, ...) and AnyOf(m_1, m_2, ...). // CombiningMatcher<T> is used to recursively combine the provided matchers @@ -1607,27 +1787,40 @@ template <template <typename T> class CombiningMatcher, typename... Args> class VariadicMatcher { public: VariadicMatcher(const Args&... matchers) // NOLINT - : matchers_(MatcherListType::BuildList(matchers...)) {} + : matchers_(matchers...) { + static_assert(sizeof...(Args) > 0, "Must have at least one matcher."); + } // This template type conversion operator allows an // VariadicMatcher<Matcher1, Matcher2...> object to match any type that // all of the provided matchers (Matcher1, Matcher2, ...) can match. template <typename T> operator Matcher<T>() const { - return MatcherListType::template CreateMatcher<T, CombiningMatcher>( - matchers_); + std::vector<Matcher<T> > values; + CreateVariadicMatcher<T>(&values, std::integral_constant<size_t, 0>()); + return Matcher<T>(new CombiningMatcher<T>(internal::move(values))); } private: - typedef MatcherList<sizeof...(Args), Args...> MatcherListType; + template <typename T, size_t I> + void CreateVariadicMatcher(std::vector<Matcher<T> >* values, + std::integral_constant<size_t, I>) const { + values->push_back(SafeMatcherCast<T>(std::get<I>(matchers_))); + CreateVariadicMatcher<T>(values, std::integral_constant<size_t, I + 1>()); + } + + template <typename T> + void CreateVariadicMatcher( + std::vector<Matcher<T> >*, + std::integral_constant<size_t, sizeof...(Args)>) const {} - const typename MatcherListType::ListType matchers_; + tuple<Args...> matchers_; GTEST_DISALLOW_ASSIGN_(VariadicMatcher); }; template <typename... Args> -using AllOfMatcher = VariadicMatcher<BothOfMatcherImpl, Args...>; +using AllOfMatcher = VariadicMatcher<AllOfMatcherImpl, Args...>; #endif // GTEST_LANG_CXX11 @@ -1644,8 +1837,10 @@ class BothOfMatcher { // both Matcher1 and Matcher2 can match. template <typename T> operator Matcher<T>() const { - return Matcher<T>(new BothOfMatcherImpl<T>(SafeMatcherCast<T>(matcher1_), - SafeMatcherCast<T>(matcher2_))); + std::vector<Matcher<T> > values; + values.push_back(SafeMatcherCast<T>(matcher1_)); + values.push_back(SafeMatcherCast<T>(matcher2_)); + return Matcher<T>(new AllOfMatcherImpl<T>(internal::move(values))); } private: @@ -1660,68 +1855,69 @@ class BothOfMatcher { // that will prevent different instantiations of AnyOfMatcher from // sharing the same EitherOfMatcherImpl<T> class. template <typename T> -class EitherOfMatcherImpl : public MatcherInterface<T> { +class AnyOfMatcherImpl + : public MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)> { public: - EitherOfMatcherImpl(const Matcher<T>& matcher1, const Matcher<T>& matcher2) - : matcher1_(matcher1), matcher2_(matcher2) {} + explicit AnyOfMatcherImpl(std::vector<Matcher<T> > matchers) + : matchers_(internal::move(matchers)) {} virtual void DescribeTo(::std::ostream* os) const { *os << "("; - matcher1_.DescribeTo(os); - *os << ") or ("; - matcher2_.DescribeTo(os); + for (size_t i = 0; i < matchers_.size(); ++i) { + if (i != 0) *os << ") or ("; + matchers_[i].DescribeTo(os); + } *os << ")"; } virtual void DescribeNegationTo(::std::ostream* os) const { *os << "("; - matcher1_.DescribeNegationTo(os); - *os << ") and ("; - matcher2_.DescribeNegationTo(os); + for (size_t i = 0; i < matchers_.size(); ++i) { + if (i != 0) *os << ") and ("; + matchers_[i].DescribeNegationTo(os); + } *os << ")"; } - virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { + virtual bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) x, + MatchResultListener* listener) const { + std::string no_match_result; + // If either matcher1_ or matcher2_ matches x, we just need to // explain why *one* of them matches. - StringMatchResultListener listener1; - if (matcher1_.MatchAndExplain(x, &listener1)) { - *listener << listener1.str(); - return true; - } - - StringMatchResultListener listener2; - if (matcher2_.MatchAndExplain(x, &listener2)) { - *listener << listener2.str(); - return true; + for (size_t i = 0; i < matchers_.size(); ++i) { + StringMatchResultListener slistener; + if (matchers_[i].MatchAndExplain(x, &slistener)) { + *listener << slistener.str(); + return true; + } else { + if (no_match_result.empty()) { + no_match_result = slistener.str(); + } else { + std::string result = slistener.str(); + if (!result.empty()) { + no_match_result += ", and "; + no_match_result += result; + } + } + } } // Otherwise we need to explain why *both* of them fail. - const std::string s1 = listener1.str(); - const std::string s2 = listener2.str(); - - if (s1 == "") { - *listener << s2; - } else { - *listener << s1; - if (s2 != "") { - *listener << ", and " << s2; - } - } + *listener << no_match_result; return false; } private: - const Matcher<T> matcher1_; - const Matcher<T> matcher2_; + const std::vector<Matcher<T> > matchers_; - GTEST_DISALLOW_ASSIGN_(EitherOfMatcherImpl); + GTEST_DISALLOW_ASSIGN_(AnyOfMatcherImpl); }; #if GTEST_LANG_CXX11 // AnyOfMatcher is used for the variadic implementation of AnyOf(m_1, m_2, ...). template <typename... Args> -using AnyOfMatcher = VariadicMatcher<EitherOfMatcherImpl, Args...>; +using AnyOfMatcher = VariadicMatcher<AnyOfMatcherImpl, Args...>; #endif // GTEST_LANG_CXX11 @@ -1739,8 +1935,10 @@ class EitherOfMatcher { // both Matcher1 and Matcher2 can match. template <typename T> operator Matcher<T>() const { - return Matcher<T>(new EitherOfMatcherImpl<T>( - SafeMatcherCast<T>(matcher1_), SafeMatcherCast<T>(matcher2_))); + std::vector<Matcher<T> > values; + values.push_back(SafeMatcherCast<T>(matcher1_)); + values.push_back(SafeMatcherCast<T>(matcher2_)); + return Matcher<T>(new AnyOfMatcherImpl<T>(internal::move(values))); } private: @@ -2036,6 +2234,82 @@ class FloatingEqMatcher { GTEST_DISALLOW_ASSIGN_(FloatingEqMatcher); }; +// A 2-tuple ("binary") wrapper around FloatingEqMatcher: +// FloatingEq2Matcher() matches (x, y) by matching FloatingEqMatcher(x, false) +// against y, and FloatingEq2Matcher(e) matches FloatingEqMatcher(x, false, e) +// against y. The former implements "Eq", the latter "Near". At present, there +// is no version that compares NaNs as equal. +template <typename FloatType> +class FloatingEq2Matcher { + public: + FloatingEq2Matcher() { Init(-1, false); } + + explicit FloatingEq2Matcher(bool nan_eq_nan) { Init(-1, nan_eq_nan); } + + explicit FloatingEq2Matcher(FloatType max_abs_error) { + Init(max_abs_error, false); + } + + FloatingEq2Matcher(FloatType max_abs_error, bool nan_eq_nan) { + Init(max_abs_error, nan_eq_nan); + } + + template <typename T1, typename T2> + operator Matcher< ::testing::tuple<T1, T2> >() const { + return MakeMatcher( + new Impl< ::testing::tuple<T1, T2> >(max_abs_error_, nan_eq_nan_)); + } + template <typename T1, typename T2> + operator Matcher<const ::testing::tuple<T1, T2>&>() const { + return MakeMatcher( + new Impl<const ::testing::tuple<T1, T2>&>(max_abs_error_, nan_eq_nan_)); + } + + private: + static ::std::ostream& GetDesc(::std::ostream& os) { // NOLINT + return os << "an almost-equal pair"; + } + + template <typename Tuple> + class Impl : public MatcherInterface<Tuple> { + public: + Impl(FloatType max_abs_error, bool nan_eq_nan) : + max_abs_error_(max_abs_error), + nan_eq_nan_(nan_eq_nan) {} + + virtual bool MatchAndExplain(Tuple args, + MatchResultListener* listener) const { + if (max_abs_error_ == -1) { + FloatingEqMatcher<FloatType> fm(::testing::get<0>(args), nan_eq_nan_); + return static_cast<Matcher<FloatType> >(fm).MatchAndExplain( + ::testing::get<1>(args), listener); + } else { + FloatingEqMatcher<FloatType> fm(::testing::get<0>(args), nan_eq_nan_, + max_abs_error_); + return static_cast<Matcher<FloatType> >(fm).MatchAndExplain( + ::testing::get<1>(args), listener); + } + } + virtual void DescribeTo(::std::ostream* os) const { + *os << "are " << GetDesc; + } + virtual void DescribeNegationTo(::std::ostream* os) const { + *os << "aren't " << GetDesc; + } + + private: + FloatType max_abs_error_; + const bool nan_eq_nan_; + }; + + void Init(FloatType max_abs_error_val, bool nan_eq_nan_val) { + max_abs_error_ = max_abs_error_val; + nan_eq_nan_ = nan_eq_nan_val; + } + FloatType max_abs_error_; + bool nan_eq_nan_; +}; + // Implements the Pointee(m) matcher for matching a pointer whose // pointee matches matcher m. The pointer can be either raw or smart. template <typename InnerMatcher> @@ -2053,7 +2327,8 @@ class PointeeMatcher { // enough for implementing the DescribeTo() method of Pointee(). template <typename Pointer> operator Matcher<Pointer>() const { - return MakeMatcher(new Impl<Pointer>(matcher_)); + return Matcher<Pointer>( + new Impl<GTEST_REFERENCE_TO_CONST_(Pointer)>(matcher_)); } private: @@ -2097,6 +2372,7 @@ class PointeeMatcher { GTEST_DISALLOW_ASSIGN_(PointeeMatcher); }; +#if GTEST_HAS_RTTI // Implements the WhenDynamicCastTo<T>(m) matcher that matches a pointer or // reference that matches inner_matcher when dynamic_cast<T> is applied. // The result of dynamic_cast<To> is forwarded to the inner matcher. @@ -2123,11 +2399,7 @@ class WhenDynamicCastToMatcherBase { const Matcher<To> matcher_; static std::string GetToName() { -#if GTEST_HAS_RTTI return GetTypeName<To>(); -#else // GTEST_HAS_RTTI - return "the target type"; -#endif // GTEST_HAS_RTTI } private: @@ -2148,7 +2420,7 @@ class WhenDynamicCastToMatcher : public WhenDynamicCastToMatcherBase<To> { template <typename From> bool MatchAndExplain(From from, MatchResultListener* listener) const { - // TODO(sbenza): Add more detail on failures. ie did the dyn_cast fail? + // FIXME: Add more detail on failures. ie did the dyn_cast fail? To to = dynamic_cast<To>(from); return MatchPrintAndExplain(to, this->matcher_, listener); } @@ -2173,6 +2445,7 @@ class WhenDynamicCastToMatcher<To&> : public WhenDynamicCastToMatcherBase<To&> { return MatchPrintAndExplain(*to, this->matcher_, listener); } }; +#endif // GTEST_HAS_RTTI // Implements the Field() matcher for matching a field (i.e. member // variable) of an object. @@ -2181,15 +2454,21 @@ class FieldMatcher { public: FieldMatcher(FieldType Class::*field, const Matcher<const FieldType&>& matcher) - : field_(field), matcher_(matcher) {} + : field_(field), matcher_(matcher), whose_field_("whose given field ") {} + + FieldMatcher(const std::string& field_name, FieldType Class::*field, + const Matcher<const FieldType&>& matcher) + : field_(field), + matcher_(matcher), + whose_field_("whose field `" + field_name + "` ") {} void DescribeTo(::std::ostream* os) const { - *os << "is an object whose given field "; + *os << "is an object " << whose_field_; matcher_.DescribeTo(os); } void DescribeNegationTo(::std::ostream* os) const { - *os << "is an object whose given field "; + *os << "is an object " << whose_field_; matcher_.DescribeNegationTo(os); } @@ -2207,7 +2486,7 @@ class FieldMatcher { // true_type iff the Field() matcher is used to match a pointer. bool MatchAndExplainImpl(false_type /* is_not_pointer */, const Class& obj, MatchResultListener* listener) const { - *listener << "whose given field is "; + *listener << whose_field_ << "is "; return MatchPrintAndExplain(obj.*field_, matcher_, listener); } @@ -2226,6 +2505,10 @@ class FieldMatcher { const FieldType Class::*field_; const Matcher<const FieldType&> matcher_; + // Contains either "whose given field " if the name of the field is unknown + // or "whose field `name_of_field` " if the name is known. + const std::string whose_field_; + GTEST_DISALLOW_ASSIGN_(FieldMatcher); }; @@ -2244,15 +2527,23 @@ class PropertyMatcher { typedef GTEST_REFERENCE_TO_CONST_(PropertyType) RefToConstProperty; PropertyMatcher(Property property, const Matcher<RefToConstProperty>& matcher) - : property_(property), matcher_(matcher) {} + : property_(property), + matcher_(matcher), + whose_property_("whose given property ") {} + + PropertyMatcher(const std::string& property_name, Property property, + const Matcher<RefToConstProperty>& matcher) + : property_(property), + matcher_(matcher), + whose_property_("whose property `" + property_name + "` ") {} void DescribeTo(::std::ostream* os) const { - *os << "is an object whose given property "; + *os << "is an object " << whose_property_; matcher_.DescribeTo(os); } void DescribeNegationTo(::std::ostream* os) const { - *os << "is an object whose given property "; + *os << "is an object " << whose_property_; matcher_.DescribeNegationTo(os); } @@ -2270,7 +2561,7 @@ class PropertyMatcher { // true_type iff the Property() matcher is used to match a pointer. bool MatchAndExplainImpl(false_type /* is_not_pointer */, const Class& obj, MatchResultListener* listener) const { - *listener << "whose given property is "; + *listener << whose_property_ << "is "; // Cannot pass the return value (for example, int) to MatchPrintAndExplain, // which takes a non-const reference as argument. #if defined(_PREFAST_ ) && _MSC_VER == 1800 @@ -2299,6 +2590,10 @@ class PropertyMatcher { Property property_; const Matcher<RefToConstProperty> matcher_; + // Contains either "whose given property " if the name of the property is + // unknown or "whose property `name_of_property` " if the name is known. + const std::string whose_property_; + GTEST_DISALLOW_ASSIGN_(PropertyMatcher); }; @@ -2692,6 +2987,10 @@ class WhenSortedByMatcher { // container and the RHS container respectively. template <typename TupleMatcher, typename RhsContainer> class PointwiseMatcher { + GTEST_COMPILE_ASSERT_( + !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(RhsContainer)>::value, + use_UnorderedPointwise_with_hash_tables); + public: typedef internal::StlContainerView<RhsContainer> RhsView; typedef typename RhsView::type RhsStlContainer; @@ -2709,6 +3008,10 @@ class PointwiseMatcher { template <typename LhsContainer> operator Matcher<LhsContainer>() const { + GTEST_COMPILE_ASSERT_( + !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)>::value, + use_UnorderedPointwise_with_hash_tables); + return MakeMatcher(new Impl<LhsContainer>(tuple_matcher_, rhs_)); } @@ -2759,12 +3062,15 @@ class PointwiseMatcher { typename LhsStlContainer::const_iterator left = lhs_stl_container.begin(); typename RhsStlContainer::const_iterator right = rhs_.begin(); for (size_t i = 0; i != actual_size; ++i, ++left, ++right) { - const InnerMatcherArg value_pair(*left, *right); - if (listener->IsInterested()) { StringMatchResultListener inner_listener; + // Create InnerMatcherArg as a temporarily object to avoid it outlives + // *left and *right. Dereference or the conversion to `const T&` may + // return temp objects, e.g for vector<bool>. if (!mono_tuple_matcher_.MatchAndExplain( - value_pair, &inner_listener)) { + InnerMatcherArg(ImplicitCast_<const LhsValue&>(*left), + ImplicitCast_<const RhsValue&>(*right)), + &inner_listener)) { *listener << "where the value pair ("; UniversalPrint(*left, listener->stream()); *listener << ", "; @@ -2774,7 +3080,9 @@ class PointwiseMatcher { return false; } } else { - if (!mono_tuple_matcher_.Matches(value_pair)) + if (!mono_tuple_matcher_.Matches( + InnerMatcherArg(ImplicitCast_<const LhsValue&>(*left), + ImplicitCast_<const RhsValue&>(*right)))) return false; } } @@ -2932,6 +3240,50 @@ class EachMatcher { GTEST_DISALLOW_ASSIGN_(EachMatcher); }; +struct Rank1 {}; +struct Rank0 : Rank1 {}; + +namespace pair_getters { +#if GTEST_LANG_CXX11 +using std::get; +template <typename T> +auto First(T& x, Rank1) -> decltype(get<0>(x)) { // NOLINT + return get<0>(x); +} +template <typename T> +auto First(T& x, Rank0) -> decltype((x.first)) { // NOLINT + return x.first; +} + +template <typename T> +auto Second(T& x, Rank1) -> decltype(get<1>(x)) { // NOLINT + return get<1>(x); +} +template <typename T> +auto Second(T& x, Rank0) -> decltype((x.second)) { // NOLINT + return x.second; +} +#else +template <typename T> +typename T::first_type& First(T& x, Rank0) { // NOLINT + return x.first; +} +template <typename T> +const typename T::first_type& First(const T& x, Rank0) { + return x.first; +} + +template <typename T> +typename T::second_type& Second(T& x, Rank0) { // NOLINT + return x.second; +} +template <typename T> +const typename T::second_type& Second(const T& x, Rank0) { + return x.second; +} +#endif // GTEST_LANG_CXX11 +} // namespace pair_getters + // Implements Key(inner_matcher) for the given argument pair type. // Key(inner_matcher) matches an std::pair whose 'first' field matches // inner_matcher. For example, Contains(Key(Ge(5))) can be used to match an @@ -2952,8 +3304,8 @@ class KeyMatcherImpl : public MatcherInterface<PairType> { virtual bool MatchAndExplain(PairType key_value, MatchResultListener* listener) const { StringMatchResultListener inner_listener; - const bool match = inner_matcher_.MatchAndExplain(key_value.first, - &inner_listener); + const bool match = inner_matcher_.MatchAndExplain( + pair_getters::First(key_value, Rank0()), &inner_listener); const std::string explanation = inner_listener.str(); if (explanation != "") { *listener << "whose first field is a value " << explanation; @@ -3036,18 +3388,18 @@ class PairMatcherImpl : public MatcherInterface<PairType> { if (!listener->IsInterested()) { // If the listener is not interested, we don't need to construct the // explanation. - return first_matcher_.Matches(a_pair.first) && - second_matcher_.Matches(a_pair.second); + return first_matcher_.Matches(pair_getters::First(a_pair, Rank0())) && + second_matcher_.Matches(pair_getters::Second(a_pair, Rank0())); } StringMatchResultListener first_inner_listener; - if (!first_matcher_.MatchAndExplain(a_pair.first, + if (!first_matcher_.MatchAndExplain(pair_getters::First(a_pair, Rank0()), &first_inner_listener)) { *listener << "whose first field does not match"; PrintIfNotEmpty(first_inner_listener.str(), listener->stream()); return false; } StringMatchResultListener second_inner_listener; - if (!second_matcher_.MatchAndExplain(a_pair.second, + if (!second_matcher_.MatchAndExplain(pair_getters::Second(a_pair, Rank0()), &second_inner_listener)) { *listener << "whose second field does not match"; PrintIfNotEmpty(second_inner_listener.str(), listener->stream()); @@ -3303,14 +3655,23 @@ typedef ::std::vector<ElementMatcherPair> ElementMatcherPairs; GTEST_API_ ElementMatcherPairs FindMaxBipartiteMatching(const MatchMatrix& g); -GTEST_API_ bool FindPairing(const MatchMatrix& matrix, - MatchResultListener* listener); +struct UnorderedMatcherRequire { + enum Flags { + Superset = 1 << 0, + Subset = 1 << 1, + ExactMatch = Superset | Subset, + }; +}; // Untyped base class for implementing UnorderedElementsAre. By // putting logic that's not specific to the element type here, we // reduce binary bloat and increase compilation speed. class GTEST_API_ UnorderedElementsAreMatcherImplBase { protected: + explicit UnorderedElementsAreMatcherImplBase( + UnorderedMatcherRequire::Flags matcher_flags) + : match_flags_(matcher_flags) {} + // A vector of matcher describers, one for each element matcher. // Does not own the describers (and thus can be used only when the // element matchers are alive). @@ -3322,9 +3683,12 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase { // Describes the negation of this UnorderedElementsAre matcher. void DescribeNegationToImpl(::std::ostream* os) const; - bool VerifyAllElementsAndMatchersAreMatched( - const ::std::vector<std::string>& element_printouts, - const MatchMatrix& matrix, MatchResultListener* listener) const; + bool VerifyMatchMatrix(const ::std::vector<std::string>& element_printouts, + const MatchMatrix& matrix, + MatchResultListener* listener) const; + + bool FindPairing(const MatchMatrix& matrix, + MatchResultListener* listener) const; MatcherDescriberVec& matcher_describers() { return matcher_describers_; @@ -3334,13 +3698,17 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase { return Message() << n << " element" << (n == 1 ? "" : "s"); } + UnorderedMatcherRequire::Flags match_flags() const { return match_flags_; } + private: + UnorderedMatcherRequire::Flags match_flags_; MatcherDescriberVec matcher_describers_; GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImplBase); }; -// Implements unordered ElementsAre and unordered ElementsAreArray. +// Implements UnorderedElementsAre, UnorderedElementsAreArray, IsSubsetOf, and +// IsSupersetOf. template <typename Container> class UnorderedElementsAreMatcherImpl : public MatcherInterface<Container>, @@ -3353,10 +3721,10 @@ class UnorderedElementsAreMatcherImpl typedef typename StlContainer::const_iterator StlContainerConstIterator; typedef typename StlContainer::value_type Element; - // Constructs the matcher from a sequence of element values or - // element matchers. template <typename InputIter> - UnorderedElementsAreMatcherImpl(InputIter first, InputIter last) { + UnorderedElementsAreMatcherImpl(UnorderedMatcherRequire::Flags matcher_flags, + InputIter first, InputIter last) + : UnorderedElementsAreMatcherImplBase(matcher_flags) { for (; first != last; ++first) { matchers_.push_back(MatcherCast<const Element&>(*first)); matcher_describers().push_back(matchers_.back().GetDescriber()); @@ -3377,34 +3745,32 @@ class UnorderedElementsAreMatcherImpl MatchResultListener* listener) const { StlContainerReference stl_container = View::ConstReference(container); ::std::vector<std::string> element_printouts; - MatchMatrix matrix = AnalyzeElements(stl_container.begin(), - stl_container.end(), - &element_printouts, - listener); + MatchMatrix matrix = + AnalyzeElements(stl_container.begin(), stl_container.end(), + &element_printouts, listener); - const size_t actual_count = matrix.LhsSize(); - if (actual_count == 0 && matchers_.empty()) { + if (matrix.LhsSize() == 0 && matrix.RhsSize() == 0) { return true; } - if (actual_count != matchers_.size()) { - // The element count doesn't match. If the container is empty, - // there's no need to explain anything as Google Mock already - // prints the empty container. Otherwise we just need to show - // how many elements there actually are. - if (actual_count != 0 && listener->IsInterested()) { - *listener << "which has " << Elements(actual_count); + + if (match_flags() == UnorderedMatcherRequire::ExactMatch) { + if (matrix.LhsSize() != matrix.RhsSize()) { + // The element count doesn't match. If the container is empty, + // there's no need to explain anything as Google Mock already + // prints the empty container. Otherwise we just need to show + // how many elements there actually are. + if (matrix.LhsSize() != 0 && listener->IsInterested()) { + *listener << "which has " << Elements(matrix.LhsSize()); + } + return false; } - return false; } - return VerifyAllElementsAndMatchersAreMatched(element_printouts, - matrix, listener) && + return VerifyMatchMatrix(element_printouts, matrix, listener) && FindPairing(matrix, listener); } private: - typedef ::std::vector<Matcher<const Element&> > MatcherVec; - template <typename ElementIter> MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last, ::std::vector<std::string>* element_printouts, @@ -3431,7 +3797,7 @@ class UnorderedElementsAreMatcherImpl return matrix; } - MatcherVec matchers_; + ::std::vector<Matcher<const Element&> > matchers_; GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImpl); }; @@ -3464,7 +3830,7 @@ class UnorderedElementsAreMatcher { TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_, ::std::back_inserter(matchers)); return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>( - matchers.begin(), matchers.end())); + UnorderedMatcherRequire::ExactMatch, matchers.begin(), matchers.end())); } private: @@ -3480,6 +3846,11 @@ class ElementsAreMatcher { template <typename Container> operator Matcher<Container>() const { + GTEST_COMPILE_ASSERT_( + !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value || + ::testing::tuple_size<MatcherTuple>::value < 2, + use_UnorderedElementsAre_with_hash_tables); + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; typedef typename internal::StlContainerView<RawContainer>::type View; typedef typename View::value_type Element; @@ -3497,24 +3868,23 @@ class ElementsAreMatcher { GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher); }; -// Implements UnorderedElementsAreArray(). +// Implements UnorderedElementsAreArray(), IsSubsetOf(), and IsSupersetOf(). template <typename T> class UnorderedElementsAreArrayMatcher { public: - UnorderedElementsAreArrayMatcher() {} - template <typename Iter> - UnorderedElementsAreArrayMatcher(Iter first, Iter last) - : matchers_(first, last) {} + UnorderedElementsAreArrayMatcher(UnorderedMatcherRequire::Flags match_flags, + Iter first, Iter last) + : match_flags_(match_flags), matchers_(first, last) {} template <typename Container> operator Matcher<Container>() const { - return MakeMatcher( - new UnorderedElementsAreMatcherImpl<Container>(matchers_.begin(), - matchers_.end())); + return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>( + match_flags_, matchers_.begin(), matchers_.end())); } private: + UnorderedMatcherRequire::Flags match_flags_; ::std::vector<T> matchers_; GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreArrayMatcher); @@ -3529,6 +3899,10 @@ class ElementsAreArrayMatcher { template <typename Container> operator Matcher<Container>() const { + GTEST_COMPILE_ASSERT_( + !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value, + use_UnorderedElementsAreArray_with_hash_tables); + return MakeMatcher(new ElementsAreMatcherImpl<Container>( matchers_.begin(), matchers_.end())); } @@ -3614,10 +3988,6 @@ BoundSecondMatcher<Tuple2Matcher, Second> MatcherBindSecond( return BoundSecondMatcher<Tuple2Matcher, Second>(tm, second); } -// Joins a vector of strings as if they are fields of a tuple; returns -// the joined string. This function is exported for testing. -GTEST_API_ string JoinAsTuple(const Strings& fields); - // Returns the description for a matcher defined using the MATCHER*() // macro where the user-supplied description string is "", if // 'negation' is false; otherwise returns the description of the @@ -3627,9 +3997,185 @@ GTEST_API_ std::string FormatMatcherDescription(bool negation, const char* matcher_name, const Strings& param_values); +// Implements a matcher that checks the value of a optional<> type variable. +template <typename ValueMatcher> +class OptionalMatcher { + public: + explicit OptionalMatcher(const ValueMatcher& value_matcher) + : value_matcher_(value_matcher) {} + + template <typename Optional> + operator Matcher<Optional>() const { + return MakeMatcher(new Impl<Optional>(value_matcher_)); + } + + template <typename Optional> + class Impl : public MatcherInterface<Optional> { + public: + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Optional) OptionalView; + typedef typename OptionalView::value_type ValueType; + explicit Impl(const ValueMatcher& value_matcher) + : value_matcher_(MatcherCast<ValueType>(value_matcher)) {} + + virtual void DescribeTo(::std::ostream* os) const { + *os << "value "; + value_matcher_.DescribeTo(os); + } + + virtual void DescribeNegationTo(::std::ostream* os) const { + *os << "value "; + value_matcher_.DescribeNegationTo(os); + } + + virtual bool MatchAndExplain(Optional optional, + MatchResultListener* listener) const { + if (!optional) { + *listener << "which is not engaged"; + return false; + } + const ValueType& value = *optional; + StringMatchResultListener value_listener; + const bool match = value_matcher_.MatchAndExplain(value, &value_listener); + *listener << "whose value " << PrintToString(value) + << (match ? " matches" : " doesn't match"); + PrintIfNotEmpty(value_listener.str(), listener->stream()); + return match; + } + + private: + const Matcher<ValueType> value_matcher_; + GTEST_DISALLOW_ASSIGN_(Impl); + }; + + private: + const ValueMatcher value_matcher_; + GTEST_DISALLOW_ASSIGN_(OptionalMatcher); +}; + +namespace variant_matcher { +// Overloads to allow VariantMatcher to do proper ADL lookup. +template <typename T> +void holds_alternative() {} +template <typename T> +void get() {} + +// Implements a matcher that checks the value of a variant<> type variable. +template <typename T> +class VariantMatcher { + public: + explicit VariantMatcher(::testing::Matcher<const T&> matcher) + : matcher_(internal::move(matcher)) {} + + template <typename Variant> + bool MatchAndExplain(const Variant& value, + ::testing::MatchResultListener* listener) const { + if (!listener->IsInterested()) { + return holds_alternative<T>(value) && matcher_.Matches(get<T>(value)); + } + + if (!holds_alternative<T>(value)) { + *listener << "whose value is not of type '" << GetTypeName() << "'"; + return false; + } + + const T& elem = get<T>(value); + StringMatchResultListener elem_listener; + const bool match = matcher_.MatchAndExplain(elem, &elem_listener); + *listener << "whose value " << PrintToString(elem) + << (match ? " matches" : " doesn't match"); + PrintIfNotEmpty(elem_listener.str(), listener->stream()); + return match; + } + + void DescribeTo(std::ostream* os) const { + *os << "is a variant<> with value of type '" << GetTypeName() + << "' and the value "; + matcher_.DescribeTo(os); + } + + void DescribeNegationTo(std::ostream* os) const { + *os << "is a variant<> with value of type other than '" << GetTypeName() + << "' or the value "; + matcher_.DescribeNegationTo(os); + } + + private: + static std::string GetTypeName() { +#if GTEST_HAS_RTTI + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_( + return internal::GetTypeName<T>()); +#endif + return "the element type"; + } + + const ::testing::Matcher<const T&> matcher_; +}; + +} // namespace variant_matcher + +namespace any_cast_matcher { + +// Overloads to allow AnyCastMatcher to do proper ADL lookup. +template <typename T> +void any_cast() {} + +// Implements a matcher that any_casts the value. +template <typename T> +class AnyCastMatcher { + public: + explicit AnyCastMatcher(const ::testing::Matcher<const T&>& matcher) + : matcher_(matcher) {} + + template <typename AnyType> + bool MatchAndExplain(const AnyType& value, + ::testing::MatchResultListener* listener) const { + if (!listener->IsInterested()) { + const T* ptr = any_cast<T>(&value); + return ptr != NULL && matcher_.Matches(*ptr); + } + + const T* elem = any_cast<T>(&value); + if (elem == NULL) { + *listener << "whose value is not of type '" << GetTypeName() << "'"; + return false; + } + + StringMatchResultListener elem_listener; + const bool match = matcher_.MatchAndExplain(*elem, &elem_listener); + *listener << "whose value " << PrintToString(*elem) + << (match ? " matches" : " doesn't match"); + PrintIfNotEmpty(elem_listener.str(), listener->stream()); + return match; + } + + void DescribeTo(std::ostream* os) const { + *os << "is an 'any' type with value of type '" << GetTypeName() + << "' and the value "; + matcher_.DescribeTo(os); + } + + void DescribeNegationTo(std::ostream* os) const { + *os << "is an 'any' type with value of type other than '" << GetTypeName() + << "' or the value "; + matcher_.DescribeNegationTo(os); + } + + private: + static std::string GetTypeName() { +#if GTEST_HAS_RTTI + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_( + return internal::GetTypeName<T>()); +#endif + return "the element type"; + } + + const ::testing::Matcher<const T&> matcher_; +}; + +} // namespace any_cast_matcher } // namespace internal -// ElementsAreArray(first, last) +// ElementsAreArray(iterator_first, iterator_last) // ElementsAreArray(pointer, count) // ElementsAreArray(array) // ElementsAreArray(container) @@ -3678,20 +4224,26 @@ ElementsAreArray(::std::initializer_list<T> xs) { } #endif -// UnorderedElementsAreArray(first, last) +// UnorderedElementsAreArray(iterator_first, iterator_last) // UnorderedElementsAreArray(pointer, count) // UnorderedElementsAreArray(array) // UnorderedElementsAreArray(container) // UnorderedElementsAreArray({ e1, e2, ..., en }) // -// The UnorderedElementsAreArray() functions are like -// ElementsAreArray(...), but allow matching the elements in any order. +// UnorderedElementsAreArray() verifies that a bijective mapping onto a +// collection of matchers exists. +// +// The matchers can be specified as an array, a pointer and count, a container, +// an initializer list, or an STL iterator range. In each of these cases, the +// underlying matchers can be either values or matchers. + template <typename Iter> inline internal::UnorderedElementsAreArrayMatcher< typename ::std::iterator_traits<Iter>::value_type> UnorderedElementsAreArray(Iter first, Iter last) { typedef typename ::std::iterator_traits<Iter>::value_type T; - return internal::UnorderedElementsAreArrayMatcher<T>(first, last); + return internal::UnorderedElementsAreArrayMatcher<T>( + internal::UnorderedMatcherRequire::ExactMatch, first, last); } template <typename T> @@ -3733,7 +4285,9 @@ UnorderedElementsAreArray(::std::initializer_list<T> xs) { const internal::AnythingMatcher _ = {}; // Creates a matcher that matches any value of the given type T. template <typename T> -inline Matcher<T> A() { return MakeMatcher(new internal::AnyMatcherImpl<T>()); } +inline Matcher<T> A() { + return Matcher<T>(new internal::AnyMatcherImpl<T>()); +} // Creates a matcher that matches any value of the given type T. template <typename T> @@ -3750,6 +4304,14 @@ inline internal::EqMatcher<T> Eq(T x) { return internal::EqMatcher<T>(x); } template <typename T> Matcher<T>::Matcher(T value) { *this = Eq(value); } +template <typename T, typename M> +Matcher<T> internal::MatcherCastImpl<T, M>::CastImpl( + const M& value, + internal::BooleanConstant<false> /* convertible_to_matcher */, + internal::BooleanConstant<false> /* convertible_to_T */) { + return Eq(value); +} + // Creates a monomorphic matcher that matches anything with type Lhs // and equal to rhs. A user may need to use this instead of Eq(...) // in order to resolve an overloading ambiguity. @@ -3878,6 +4440,7 @@ inline internal::PointeeMatcher<InnerMatcher> Pointee( return internal::PointeeMatcher<InnerMatcher>(inner_matcher); } +#if GTEST_HAS_RTTI // Creates a matcher that matches a pointer or reference that matches // inner_matcher when dynamic_cast<To> is applied. // The result of dynamic_cast<To> is forwarded to the inner matcher. @@ -3890,6 +4453,7 @@ WhenDynamicCastTo(const Matcher<To>& inner_matcher) { return MakePolymorphicMatcher( internal::WhenDynamicCastToMatcher<To>(inner_matcher)); } +#endif // GTEST_HAS_RTTI // Creates a matcher that matches an object whose given field matches // 'matcher'. For example, @@ -3908,6 +4472,16 @@ inline PolymorphicMatcher< // to compile where bar is an int32 and m is a matcher for int64. } +// Same as Field() but also takes the name of the field to provide better error +// messages. +template <typename Class, typename FieldType, typename FieldMatcher> +inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType> > Field( + const std::string& field_name, FieldType Class::*field, + const FieldMatcher& matcher) { + return MakePolymorphicMatcher(internal::FieldMatcher<Class, FieldType>( + field_name, field, MatcherCast<const FieldType&>(matcher))); +} + // Creates a matcher that matches an object whose given property // matches 'matcher'. For example, // Property(&Foo::str, StartsWith("hi")) @@ -3928,6 +4502,21 @@ Property(PropertyType (Class::*property)() const, // to compile where bar() returns an int32 and m is a matcher for int64. } +// Same as Property() above, but also takes the name of the property to provide +// better error messages. +template <typename Class, typename PropertyType, typename PropertyMatcher> +inline PolymorphicMatcher<internal::PropertyMatcher< + Class, PropertyType, PropertyType (Class::*)() const> > +Property(const std::string& property_name, + PropertyType (Class::*property)() const, + const PropertyMatcher& matcher) { + return MakePolymorphicMatcher( + internal::PropertyMatcher<Class, PropertyType, + PropertyType (Class::*)() const>( + property_name, property, + MatcherCast<GTEST_REFERENCE_TO_CONST_(PropertyType)>(matcher))); +} + #if GTEST_LANG_CXX11 // The same as above but for reference-qualified member functions. template <typename Class, typename PropertyType, typename PropertyMatcher> @@ -3941,6 +4530,20 @@ Property(PropertyType (Class::*property)() const &, property, MatcherCast<GTEST_REFERENCE_TO_CONST_(PropertyType)>(matcher))); } + +// Three-argument form for reference-qualified member functions. +template <typename Class, typename PropertyType, typename PropertyMatcher> +inline PolymorphicMatcher<internal::PropertyMatcher< + Class, PropertyType, PropertyType (Class::*)() const &> > +Property(const std::string& property_name, + PropertyType (Class::*property)() const &, + const PropertyMatcher& matcher) { + return MakePolymorphicMatcher( + internal::PropertyMatcher<Class, PropertyType, + PropertyType (Class::*)() const &>( + property_name, property, + MatcherCast<GTEST_REFERENCE_TO_CONST_(PropertyType)>(matcher))); +} #endif // Creates a matcher that matches an object iff the result of applying @@ -3956,6 +4559,7 @@ Property(PropertyType (Class::*property)() const &, // concurrent access. // * If it is a function object, it has to define type result_type. // We recommend deriving your functor classes from std::unary_function. +// template <typename Callable, typename ResultOfMatcher> internal::ResultOfMatcher<Callable> ResultOf( Callable callable, const ResultOfMatcher& matcher) { @@ -4046,53 +4650,53 @@ inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex( // Wide string matchers. // Matches a string equal to str. -inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> > - StrEq(const internal::wstring& str) { - return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>( - str, true, true)); +inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > StrEq( + const std::wstring& str) { + return MakePolymorphicMatcher( + internal::StrEqualityMatcher<std::wstring>(str, true, true)); } // Matches a string not equal to str. -inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> > - StrNe(const internal::wstring& str) { - return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>( - str, false, true)); +inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > StrNe( + const std::wstring& str) { + return MakePolymorphicMatcher( + internal::StrEqualityMatcher<std::wstring>(str, false, true)); } // Matches a string equal to str, ignoring case. -inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> > - StrCaseEq(const internal::wstring& str) { - return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>( - str, true, false)); +inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > +StrCaseEq(const std::wstring& str) { + return MakePolymorphicMatcher( + internal::StrEqualityMatcher<std::wstring>(str, true, false)); } // Matches a string not equal to str, ignoring case. -inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> > - StrCaseNe(const internal::wstring& str) { - return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>( - str, false, false)); +inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > +StrCaseNe(const std::wstring& str) { + return MakePolymorphicMatcher( + internal::StrEqualityMatcher<std::wstring>(str, false, false)); } -// Creates a matcher that matches any wstring, std::wstring, or C wide string +// Creates a matcher that matches any ::wstring, std::wstring, or C wide string // that contains the given substring. -inline PolymorphicMatcher<internal::HasSubstrMatcher<internal::wstring> > - HasSubstr(const internal::wstring& substring) { - return MakePolymorphicMatcher(internal::HasSubstrMatcher<internal::wstring>( - substring)); +inline PolymorphicMatcher<internal::HasSubstrMatcher<std::wstring> > HasSubstr( + const std::wstring& substring) { + return MakePolymorphicMatcher( + internal::HasSubstrMatcher<std::wstring>(substring)); } // Matches a string that starts with 'prefix' (case-sensitive). -inline PolymorphicMatcher<internal::StartsWithMatcher<internal::wstring> > - StartsWith(const internal::wstring& prefix) { - return MakePolymorphicMatcher(internal::StartsWithMatcher<internal::wstring>( - prefix)); +inline PolymorphicMatcher<internal::StartsWithMatcher<std::wstring> > +StartsWith(const std::wstring& prefix) { + return MakePolymorphicMatcher( + internal::StartsWithMatcher<std::wstring>(prefix)); } // Matches a string that ends with 'suffix' (case-sensitive). -inline PolymorphicMatcher<internal::EndsWithMatcher<internal::wstring> > - EndsWith(const internal::wstring& suffix) { - return MakePolymorphicMatcher(internal::EndsWithMatcher<internal::wstring>( - suffix)); +inline PolymorphicMatcher<internal::EndsWithMatcher<std::wstring> > EndsWith( + const std::wstring& suffix) { + return MakePolymorphicMatcher( + internal::EndsWithMatcher<std::wstring>(suffix)); } #endif // GTEST_HAS_GLOBAL_WSTRING || GTEST_HAS_STD_WSTRING @@ -4121,6 +4725,58 @@ inline internal::Lt2Matcher Lt() { return internal::Lt2Matcher(); } // first field != the second field. inline internal::Ne2Matcher Ne() { return internal::Ne2Matcher(); } +// Creates a polymorphic matcher that matches a 2-tuple where +// FloatEq(first field) matches the second field. +inline internal::FloatingEq2Matcher<float> FloatEq() { + return internal::FloatingEq2Matcher<float>(); +} + +// Creates a polymorphic matcher that matches a 2-tuple where +// DoubleEq(first field) matches the second field. +inline internal::FloatingEq2Matcher<double> DoubleEq() { + return internal::FloatingEq2Matcher<double>(); +} + +// Creates a polymorphic matcher that matches a 2-tuple where +// FloatEq(first field) matches the second field with NaN equality. +inline internal::FloatingEq2Matcher<float> NanSensitiveFloatEq() { + return internal::FloatingEq2Matcher<float>(true); +} + +// Creates a polymorphic matcher that matches a 2-tuple where +// DoubleEq(first field) matches the second field with NaN equality. +inline internal::FloatingEq2Matcher<double> NanSensitiveDoubleEq() { + return internal::FloatingEq2Matcher<double>(true); +} + +// Creates a polymorphic matcher that matches a 2-tuple where +// FloatNear(first field, max_abs_error) matches the second field. +inline internal::FloatingEq2Matcher<float> FloatNear(float max_abs_error) { + return internal::FloatingEq2Matcher<float>(max_abs_error); +} + +// Creates a polymorphic matcher that matches a 2-tuple where +// DoubleNear(first field, max_abs_error) matches the second field. +inline internal::FloatingEq2Matcher<double> DoubleNear(double max_abs_error) { + return internal::FloatingEq2Matcher<double>(max_abs_error); +} + +// Creates a polymorphic matcher that matches a 2-tuple where +// FloatNear(first field, max_abs_error) matches the second field with NaN +// equality. +inline internal::FloatingEq2Matcher<float> NanSensitiveFloatNear( + float max_abs_error) { + return internal::FloatingEq2Matcher<float>(max_abs_error, true); +} + +// Creates a polymorphic matcher that matches a 2-tuple where +// DoubleNear(first field, max_abs_error) matches the second field with NaN +// equality. +inline internal::FloatingEq2Matcher<double> NanSensitiveDoubleNear( + double max_abs_error) { + return internal::FloatingEq2Matcher<double>(max_abs_error, true); +} + // Creates a matcher that matches any value of type T that m doesn't // match. template <typename InnerMatcher> @@ -4303,6 +4959,128 @@ inline internal::ContainsMatcher<M> Contains(M matcher) { return internal::ContainsMatcher<M>(matcher); } +// IsSupersetOf(iterator_first, iterator_last) +// IsSupersetOf(pointer, count) +// IsSupersetOf(array) +// IsSupersetOf(container) +// IsSupersetOf({e1, e2, ..., en}) +// +// IsSupersetOf() verifies that a surjective partial mapping onto a collection +// of matchers exists. In other words, a container matches +// IsSupersetOf({e1, ..., en}) if and only if there is a permutation +// {y1, ..., yn} of some of the container's elements where y1 matches e1, +// ..., and yn matches en. Obviously, the size of the container must be >= n +// in order to have a match. Examples: +// +// - {1, 2, 3} matches IsSupersetOf({Ge(3), Ne(0)}), as 3 matches Ge(3) and +// 1 matches Ne(0). +// - {1, 2} doesn't match IsSupersetOf({Eq(1), Lt(2)}), even though 1 matches +// both Eq(1) and Lt(2). The reason is that different matchers must be used +// for elements in different slots of the container. +// - {1, 1, 2} matches IsSupersetOf({Eq(1), Lt(2)}), as (the first) 1 matches +// Eq(1) and (the second) 1 matches Lt(2). +// - {1, 2, 3} matches IsSupersetOf(Gt(1), Gt(1)), as 2 matches (the first) +// Gt(1) and 3 matches (the second) Gt(1). +// +// The matchers can be specified as an array, a pointer and count, a container, +// an initializer list, or an STL iterator range. In each of these cases, the +// underlying matchers can be either values or matchers. + +template <typename Iter> +inline internal::UnorderedElementsAreArrayMatcher< + typename ::std::iterator_traits<Iter>::value_type> +IsSupersetOf(Iter first, Iter last) { + typedef typename ::std::iterator_traits<Iter>::value_type T; + return internal::UnorderedElementsAreArrayMatcher<T>( + internal::UnorderedMatcherRequire::Superset, first, last); +} + +template <typename T> +inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf( + const T* pointer, size_t count) { + return IsSupersetOf(pointer, pointer + count); +} + +template <typename T, size_t N> +inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf( + const T (&array)[N]) { + return IsSupersetOf(array, N); +} + +template <typename Container> +inline internal::UnorderedElementsAreArrayMatcher< + typename Container::value_type> +IsSupersetOf(const Container& container) { + return IsSupersetOf(container.begin(), container.end()); +} + +#if GTEST_HAS_STD_INITIALIZER_LIST_ +template <typename T> +inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf( + ::std::initializer_list<T> xs) { + return IsSupersetOf(xs.begin(), xs.end()); +} +#endif + +// IsSubsetOf(iterator_first, iterator_last) +// IsSubsetOf(pointer, count) +// IsSubsetOf(array) +// IsSubsetOf(container) +// IsSubsetOf({e1, e2, ..., en}) +// +// IsSubsetOf() verifies that an injective mapping onto a collection of matchers +// exists. In other words, a container matches IsSubsetOf({e1, ..., en}) if and +// only if there is a subset of matchers {m1, ..., mk} which would match the +// container using UnorderedElementsAre. Obviously, the size of the container +// must be <= n in order to have a match. Examples: +// +// - {1} matches IsSubsetOf({Gt(0), Lt(0)}), as 1 matches Gt(0). +// - {1, -1} matches IsSubsetOf({Lt(0), Gt(0)}), as 1 matches Gt(0) and -1 +// matches Lt(0). +// - {1, 2} doesn't matches IsSubsetOf({Gt(0), Lt(0)}), even though 1 and 2 both +// match Gt(0). The reason is that different matchers must be used for +// elements in different slots of the container. +// +// The matchers can be specified as an array, a pointer and count, a container, +// an initializer list, or an STL iterator range. In each of these cases, the +// underlying matchers can be either values or matchers. + +template <typename Iter> +inline internal::UnorderedElementsAreArrayMatcher< + typename ::std::iterator_traits<Iter>::value_type> +IsSubsetOf(Iter first, Iter last) { + typedef typename ::std::iterator_traits<Iter>::value_type T; + return internal::UnorderedElementsAreArrayMatcher<T>( + internal::UnorderedMatcherRequire::Subset, first, last); +} + +template <typename T> +inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf( + const T* pointer, size_t count) { + return IsSubsetOf(pointer, pointer + count); +} + +template <typename T, size_t N> +inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf( + const T (&array)[N]) { + return IsSubsetOf(array, N); +} + +template <typename Container> +inline internal::UnorderedElementsAreArrayMatcher< + typename Container::value_type> +IsSubsetOf(const Container& container) { + return IsSubsetOf(container.begin(), container.end()); +} + +#if GTEST_HAS_STD_INITIALIZER_LIST_ +template <typename T> +inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf( + ::std::initializer_list<T> xs) { + return IsSubsetOf(xs.begin(), xs.end()); +} +#endif + // Matches an STL-style container or a native array that contains only // elements matching the given value or matcher. // @@ -4376,17 +5154,60 @@ inline bool ExplainMatchResult( return SafeMatcherCast<const T&>(matcher).MatchAndExplain(value, listener); } +// Returns a string representation of the given matcher. Useful for description +// strings of matchers defined using MATCHER_P* macros that accept matchers as +// their arguments. For example: +// +// MATCHER_P(XAndYThat, matcher, +// "X that " + DescribeMatcher<int>(matcher, negation) + +// " and Y that " + DescribeMatcher<double>(matcher, negation)) { +// return ExplainMatchResult(matcher, arg.x(), result_listener) && +// ExplainMatchResult(matcher, arg.y(), result_listener); +// } +template <typename T, typename M> +std::string DescribeMatcher(const M& matcher, bool negation = false) { + ::std::stringstream ss; + Matcher<T> monomorphic_matcher = SafeMatcherCast<T>(matcher); + if (negation) { + monomorphic_matcher.DescribeNegationTo(&ss); + } else { + monomorphic_matcher.DescribeTo(&ss); + } + return ss.str(); +} + #if GTEST_LANG_CXX11 // Define variadic matcher versions. They are overloaded in // gmock-generated-matchers.h for the cases supported by pre C++11 compilers. template <typename... Args> -inline internal::AllOfMatcher<Args...> AllOf(const Args&... matchers) { - return internal::AllOfMatcher<Args...>(matchers...); +internal::AllOfMatcher<typename std::decay<const Args&>::type...> AllOf( + const Args&... matchers) { + return internal::AllOfMatcher<typename std::decay<const Args&>::type...>( + matchers...); +} + +template <typename... Args> +internal::AnyOfMatcher<typename std::decay<const Args&>::type...> AnyOf( + const Args&... matchers) { + return internal::AnyOfMatcher<typename std::decay<const Args&>::type...>( + matchers...); +} + +template <typename... Args> +internal::ElementsAreMatcher<tuple<typename std::decay<const Args&>::type...>> +ElementsAre(const Args&... matchers) { + return internal::ElementsAreMatcher< + tuple<typename std::decay<const Args&>::type...>>( + make_tuple(matchers...)); } template <typename... Args> -inline internal::AnyOfMatcher<Args...> AnyOf(const Args&... matchers) { - return internal::AnyOfMatcher<Args...>(matchers...); +internal::UnorderedElementsAreMatcher< + tuple<typename std::decay<const Args&>::type...>> +UnorderedElementsAre(const Args&... matchers) { + return internal::UnorderedElementsAreMatcher< + tuple<typename std::decay<const Args&>::type...>>( + make_tuple(matchers...)); } #endif // GTEST_LANG_CXX11 @@ -4401,6 +5222,39 @@ inline internal::AnyOfMatcher<Args...> AnyOf(const Args&... matchers) { template <typename InnerMatcher> inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; } +// Returns a matcher that matches the value of an optional<> type variable. +// The matcher implementation only uses '!arg' and requires that the optional<> +// type has a 'value_type' member type and that '*arg' is of type 'value_type' +// and is printable using 'PrintToString'. It is compatible with +// std::optional/std::experimental::optional. +// Note that to compare an optional type variable against nullopt you should +// use Eq(nullopt) and not Optional(Eq(nullopt)). The latter implies that the +// optional value contains an optional itself. +template <typename ValueMatcher> +inline internal::OptionalMatcher<ValueMatcher> Optional( + const ValueMatcher& value_matcher) { + return internal::OptionalMatcher<ValueMatcher>(value_matcher); +} + +// Returns a matcher that matches the value of a absl::any type variable. +template <typename T> +PolymorphicMatcher<internal::any_cast_matcher::AnyCastMatcher<T> > AnyWith( + const Matcher<const T&>& matcher) { + return MakePolymorphicMatcher( + internal::any_cast_matcher::AnyCastMatcher<T>(matcher)); +} + +// Returns a matcher that matches the value of a variant<> type variable. +// The matcher implementation uses ADL to find the holds_alternative and get +// functions. +// It is compatible with std::variant. +template <typename T> +PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T> > VariantWith( + const Matcher<const T&>& matcher) { + return MakePolymorphicMatcher( + internal::variant_matcher::VariantMatcher<T>(matcher)); +} + // These macros allow using matchers to check values in Google Test // tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher) // succeed iff the value matches the matcher. If the assertion fails, @@ -4416,4 +5270,5 @@ inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; } // We must include this header at the end to make sure it can use the // declarations from this file. #include "gmock/internal/custom/gmock-matchers.h" + #endif // GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ diff --git a/googlemock/include/gmock/gmock-more-actions.h b/googlemock/include/gmock/gmock-more-actions.h index 3d387b6b..4d9a28ea 100644 --- a/googlemock/include/gmock/gmock-more-actions.h +++ b/googlemock/include/gmock/gmock-more-actions.h @@ -26,13 +26,14 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // // This file implements some actions that depend on gmock-generated-actions.h. +// GOOGLETEST_CM0002 DO NOT DELETE + #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_ diff --git a/googlemock/include/gmock/gmock-more-matchers.h b/googlemock/include/gmock/gmock-more-matchers.h index a5a8bfa5..1c9a399a 100644 --- a/googlemock/include/gmock/gmock-more-matchers.h +++ b/googlemock/include/gmock/gmock-more-matchers.h @@ -26,8 +26,7 @@ // 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. -// -// Author: marcus.boerger@google.com (Marcus Boerger) + // Google Mock - a framework for writing C++ mock classes. // @@ -36,13 +35,27 @@ // Note that tests are implemented in gmock-matchers_test.cc rather than // gmock-more-matchers-test.cc. -#ifndef GMOCK_GMOCK_MORE_MATCHERS_H_ -#define GMOCK_GMOCK_MORE_MATCHERS_H_ +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_ +#define GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_ #include "gmock/gmock-generated-matchers.h" namespace testing { +// Silence C4100 (unreferenced formal +// parameter) for MSVC +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4100) +#if (_MSC_VER == 1900) +// and silence C4800 (C4800: 'int *const ': forcing value +// to bool 'true' or 'false') for MSVC 14 +# pragma warning(disable:4800) + #endif +#endif + // Defines a matcher that matches an empty container. The container must // support both size() and empty(), which all STL-like containers provide. MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") { @@ -69,6 +82,11 @@ MATCHER(IsFalse, negation ? "is true" : "is false") { return !static_cast<bool>(arg); } +#ifdef _MSC_VER +# pragma warning(pop) +#endif + + } // namespace testing -#endif // GMOCK_GMOCK_MORE_MATCHERS_H_ +#endif // GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_ diff --git a/googlemock/include/gmock/gmock-spec-builders.h b/googlemock/include/gmock/gmock-spec-builders.h index c1b63014..0d83cd6f 100644 --- a/googlemock/include/gmock/gmock-spec-builders.h +++ b/googlemock/include/gmock/gmock-spec-builders.h @@ -26,8 +26,7 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // @@ -57,6 +56,8 @@ // where all clauses are optional, and .InSequence()/.After()/ // .WillOnce() can appear any number of times. +// GOOGLETEST_CM0002 DO NOT DELETE + #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ @@ -147,14 +148,13 @@ class GTEST_API_ UntypedFunctionMockerBase { // action fails. // L = * virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction( - const void* untyped_args, const std::string& call_description) const = 0; + void* untyped_args, const std::string& call_description) const = 0; // Performs the given action with the given arguments and returns // the action's result. // L = * virtual UntypedActionResultHolderBase* UntypedPerformAction( - const void* untyped_action, - const void* untyped_args) const = 0; + const void* untyped_action, void* untyped_args) const = 0; // Writes a message that the call is uninteresting (i.e. neither // explicitly expected nor explicitly unexpected) to the given @@ -184,7 +184,7 @@ class GTEST_API_ UntypedFunctionMockerBase { // this information in the global mock registry. Will be called // whenever an EXPECT_CALL() or ON_CALL() is executed on this mock // method. - // TODO(wan@google.com): rename to SetAndRegisterOwner(). + // FIXME: rename to SetAndRegisterOwner(). void RegisterOwner(const void* mock_obj) GTEST_LOCK_EXCLUDED_(g_gmock_mutex); @@ -209,9 +209,8 @@ class GTEST_API_ UntypedFunctionMockerBase { // arguments. This function can be safely called from multiple // threads concurrently. The caller is responsible for deleting the // result. - UntypedActionResultHolderBase* UntypedInvokeWith( - const void* untyped_args) - GTEST_LOCK_EXCLUDED_(g_gmock_mutex); + UntypedActionResultHolderBase* UntypedInvokeWith(void* untyped_args) + GTEST_LOCK_EXCLUDED_(g_gmock_mutex); protected: typedef std::vector<const void*> UntypedOnCallSpecs; @@ -236,6 +235,14 @@ class GTEST_API_ UntypedFunctionMockerBase { UntypedOnCallSpecs untyped_on_call_specs_; // All expectations for this function mocker. + // + // It's undefined behavior to interleave expectations (EXPECT_CALLs + // or ON_CALLs) and mock function calls. Also, the order of + // expectations is important. Therefore it's a logic race condition + // to read/write untyped_expectations_ concurrently. In order for + // tools like tsan to catch concurrent read/write accesses to + // untyped_expectations, we deliberately leave accesses to it + // unprotected. UntypedExpectations untyped_expectations_; }; // class UntypedFunctionMockerBase @@ -1200,7 +1207,7 @@ class TypedExpectation : public ExpectationBase { mocker->DescribeDefaultActionTo(args, what); DescribeCallCountTo(why); - // TODO(wan@google.com): allow the user to control whether + // FIXME: allow the user to control whether // unexpected calls should fail immediately or continue using a // flag --gmock_unexpected_calls_are_fatal. return NULL; @@ -1252,8 +1259,9 @@ class MockSpec { // Constructs a MockSpec object, given the function mocker object // that the spec is associated with. - explicit MockSpec(internal::FunctionMockerBase<F>* function_mocker) - : function_mocker_(function_mocker) {} + MockSpec(internal::FunctionMockerBase<F>* function_mocker, + const ArgumentMatcherTuple& matchers) + : function_mocker_(function_mocker), matchers_(matchers) {} // Adds a new default action spec to the function mocker and returns // the newly created spec. @@ -1275,14 +1283,17 @@ class MockSpec { file, line, source_text, matchers_); } + // This operator overload is used to swallow the superfluous parameter list + // introduced by the ON/EXPECT_CALL macros. See the macro comments for more + // explanation. + MockSpec<F>& operator()(const internal::WithoutMatchers&, void* const) { + return *this; + } + private: template <typename Function> friend class internal::FunctionMocker; - void SetMatchers(const ArgumentMatcherTuple& matchers) { - matchers_ = matchers; - } - // The function mocker that owns this spec. internal::FunctionMockerBase<F>* const function_mocker_; // The argument matchers specified in the spec. @@ -1390,19 +1401,20 @@ class ActionResultHolder : public UntypedActionResultHolderBase { template <typename F> static ActionResultHolder* PerformDefaultAction( const FunctionMockerBase<F>* func_mocker, - const typename Function<F>::ArgumentTuple& args, + typename RvalueRef<typename Function<F>::ArgumentTuple>::type args, const std::string& call_description) { - return new ActionResultHolder(Wrapper( - func_mocker->PerformDefaultAction(args, call_description))); + return new ActionResultHolder(Wrapper(func_mocker->PerformDefaultAction( + internal::move(args), call_description))); } // Performs the given action and returns the result in a new-ed // ActionResultHolder. template <typename F> - static ActionResultHolder* - PerformAction(const Action<F>& action, - const typename Function<F>::ArgumentTuple& args) { - return new ActionResultHolder(Wrapper(action.Perform(args))); + static ActionResultHolder* PerformAction( + const Action<F>& action, + typename RvalueRef<typename Function<F>::ArgumentTuple>::type args) { + return new ActionResultHolder( + Wrapper(action.Perform(internal::move(args)))); } private: @@ -1430,9 +1442,9 @@ class ActionResultHolder<void> : public UntypedActionResultHolderBase { template <typename F> static ActionResultHolder* PerformDefaultAction( const FunctionMockerBase<F>* func_mocker, - const typename Function<F>::ArgumentTuple& args, + typename RvalueRef<typename Function<F>::ArgumentTuple>::type args, const std::string& call_description) { - func_mocker->PerformDefaultAction(args, call_description); + func_mocker->PerformDefaultAction(internal::move(args), call_description); return new ActionResultHolder; } @@ -1441,8 +1453,8 @@ class ActionResultHolder<void> : public UntypedActionResultHolderBase { template <typename F> static ActionResultHolder* PerformAction( const Action<F>& action, - const typename Function<F>::ArgumentTuple& args) { - action.Perform(args); + typename RvalueRef<typename Function<F>::ArgumentTuple>::type args) { + action.Perform(internal::move(args)); return new ActionResultHolder; } @@ -1461,7 +1473,7 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { typedef typename Function<F>::ArgumentTuple ArgumentTuple; typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple; - FunctionMockerBase() : current_spec_(this) {} + FunctionMockerBase() {} // The destructor verifies that all expectations on this mock // function have been satisfied. If not, it will report Google Test @@ -1497,12 +1509,13 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { // mutable state of this object, and thus can be called concurrently // without locking. // L = * - Result PerformDefaultAction(const ArgumentTuple& args, - const std::string& call_description) const { + Result PerformDefaultAction( + typename RvalueRef<typename Function<F>::ArgumentTuple>::type args, + const std::string& call_description) const { const OnCallSpec<F>* const spec = this->FindOnCallSpec(args); if (spec != NULL) { - return spec->GetAction().Perform(args); + return spec->GetAction().Perform(internal::move(args)); } const std::string message = call_description + @@ -1524,11 +1537,11 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { // action fails. The caller is responsible for deleting the result. // L = * virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction( - const void* untyped_args, // must point to an ArgumentTuple + void* untyped_args, // must point to an ArgumentTuple const std::string& call_description) const { - const ArgumentTuple& args = - *static_cast<const ArgumentTuple*>(untyped_args); - return ResultHolder::PerformDefaultAction(this, args, call_description); + ArgumentTuple* args = static_cast<ArgumentTuple*>(untyped_args); + return ResultHolder::PerformDefaultAction(this, internal::move(*args), + call_description); } // Performs the given action with the given arguments and returns @@ -1536,13 +1549,12 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { // result. // L = * virtual UntypedActionResultHolderBase* UntypedPerformAction( - const void* untyped_action, const void* untyped_args) const { + const void* untyped_action, void* untyped_args) const { // Make a copy of the action before performing it, in case the // action deletes the mock object (and thus deletes itself). const Action<F> action = *static_cast<const Action<F>*>(untyped_action); - const ArgumentTuple& args = - *static_cast<const ArgumentTuple*>(untyped_args); - return ResultHolder::PerformAction(action, args); + ArgumentTuple* args = static_cast<ArgumentTuple*>(untyped_args); + return ResultHolder::PerformAction(action, internal::move(*args)); } // Implements UntypedFunctionMockerBase::ClearDefaultActionsLocked(): @@ -1582,10 +1594,14 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { // Returns the result of invoking this mock function with the given // arguments. This function can be safely called from multiple // threads concurrently. - Result InvokeWith(const ArgumentTuple& args) - GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { + Result InvokeWith( + typename RvalueRef<typename Function<F>::ArgumentTuple>::type args) + GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { + // const_cast is required since in C++98 we still pass ArgumentTuple around + // by const& instead of rvalue reference. + void* untyped_args = const_cast<void*>(static_cast<const void*>(&args)); scoped_ptr<ResultHolder> holder( - DownCast_<ResultHolder*>(this->UntypedInvokeWith(&args))); + DownCast_<ResultHolder*>(this->UntypedInvokeWith(untyped_args))); return holder->Unwrap(); } @@ -1609,6 +1625,8 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { TypedExpectation<F>* const expectation = new TypedExpectation<F>(this, file, line, source_text, m); const linked_ptr<ExpectationBase> untyped_expectation(expectation); + // See the definition of untyped_expectations_ for why access to + // it is unprotected here. untyped_expectations_.push_back(untyped_expectation); // Adds this expectation into the implicit sequence if there is one. @@ -1620,10 +1638,6 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { return *expectation; } - // The current spec (either default action spec or expectation spec) - // being described on this function mocker. - MockSpec<F>& current_spec() { return current_spec_; } - private: template <typename Func> friend class TypedExpectation; @@ -1716,6 +1730,8 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { const ArgumentTuple& args) const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { g_gmock_mutex.AssertHeld(); + // See the definition of untyped_expectations_ for why access to + // it is unprotected here. for (typename UntypedExpectations::const_reverse_iterator it = untyped_expectations_.rbegin(); it != untyped_expectations_.rend(); ++it) { @@ -1766,10 +1782,6 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { } } - // The current spec (either default action spec or expectation spec) - // being described on this function mocker. - MockSpec<F> current_spec_; - // There is no generally useful and implementable semantics of // copying a mock object, so copying a mock is usually a user error. // Thus we disallow copying function mockers. If the user really @@ -1832,17 +1844,76 @@ inline Expectation::Expectation(internal::ExpectationBase& exp) // NOLINT } // namespace testing -// A separate macro is required to avoid compile errors when the name -// of the method used in call is a result of macro expansion. -// See CompilesWithMethodNameExpandedFromMacro tests in -// internal/gmock-spec-builders_test.cc for more details. -#define GMOCK_ON_CALL_IMPL_(obj, call) \ - ((obj).gmock_##call).InternalDefaultActionSetAt(__FILE__, __LINE__, \ - #obj, #call) -#define ON_CALL(obj, call) GMOCK_ON_CALL_IMPL_(obj, call) - -#define GMOCK_EXPECT_CALL_IMPL_(obj, call) \ - ((obj).gmock_##call).InternalExpectedAt(__FILE__, __LINE__, #obj, #call) -#define EXPECT_CALL(obj, call) GMOCK_EXPECT_CALL_IMPL_(obj, call) +// Implementation for ON_CALL and EXPECT_CALL macros. A separate macro is +// required to avoid compile errors when the name of the method used in call is +// a result of macro expansion. See CompilesWithMethodNameExpandedFromMacro +// tests in internal/gmock-spec-builders_test.cc for more details. +// +// This macro supports statements both with and without parameter matchers. If +// the parameter list is omitted, gMock will accept any parameters, which allows +// tests to be written that don't need to encode the number of method +// parameter. This technique may only be used for non-overloaded methods. +// +// // These are the same: +// ON_CALL(mock, NoArgsMethod()).WillByDefault(...); +// ON_CALL(mock, NoArgsMethod).WillByDefault(...); +// +// // As are these: +// ON_CALL(mock, TwoArgsMethod(_, _)).WillByDefault(...); +// ON_CALL(mock, TwoArgsMethod).WillByDefault(...); +// +// // Can also specify args if you want, of course: +// ON_CALL(mock, TwoArgsMethod(_, 45)).WillByDefault(...); +// +// // Overloads work as long as you specify parameters: +// ON_CALL(mock, OverloadedMethod(_)).WillByDefault(...); +// ON_CALL(mock, OverloadedMethod(_, _)).WillByDefault(...); +// +// // Oops! Which overload did you want? +// ON_CALL(mock, OverloadedMethod).WillByDefault(...); +// => ERROR: call to member function 'gmock_OverloadedMethod' is ambiguous +// +// How this works: The mock class uses two overloads of the gmock_Method +// expectation setter method plus an operator() overload on the MockSpec object. +// In the matcher list form, the macro expands to: +// +// // This statement: +// ON_CALL(mock, TwoArgsMethod(_, 45))... +// +// // ...expands to: +// mock.gmock_TwoArgsMethod(_, 45)(WithoutMatchers(), nullptr)... +// |-------------v---------------||------------v-------------| +// invokes first overload swallowed by operator() +// +// // ...which is essentially: +// mock.gmock_TwoArgsMethod(_, 45)... +// +// Whereas the form without a matcher list: +// +// // This statement: +// ON_CALL(mock, TwoArgsMethod)... +// +// // ...expands to: +// mock.gmock_TwoArgsMethod(WithoutMatchers(), nullptr)... +// |-----------------------v--------------------------| +// invokes second overload +// +// // ...which is essentially: +// mock.gmock_TwoArgsMethod(_, _)... +// +// The WithoutMatchers() argument is used to disambiguate overloads and to +// block the caller from accidentally invoking the second overload directly. The +// second argument is an internal type derived from the method signature. The +// failure to disambiguate two overloads of this method in the ON_CALL statement +// is how we block callers from setting expectations on overloaded methods. +#define GMOCK_ON_CALL_IMPL_(mock_expr, Setter, call) \ + ((mock_expr).gmock_##call)(::testing::internal::GetWithoutMatchers(), NULL) \ + .Setter(__FILE__, __LINE__, #mock_expr, #call) + +#define ON_CALL(obj, call) \ + GMOCK_ON_CALL_IMPL_(obj, InternalDefaultActionSetAt, call) + +#define EXPECT_CALL(obj, call) \ + GMOCK_ON_CALL_IMPL_(obj, InternalExpectedAt, call) #endif // GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ diff --git a/googlemock/include/gmock/gmock.h b/googlemock/include/gmock/gmock.h index 6ccb118b..dd962260 100644 --- a/googlemock/include/gmock/gmock.h +++ b/googlemock/include/gmock/gmock.h @@ -26,13 +26,14 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // // This is the main header file a user should include. +// GOOGLETEST_CM0002 DO NOT DELETE + #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_H_ diff --git a/googlemock/include/gmock/internal/custom/README.md b/googlemock/include/gmock/internal/custom/README.md new file mode 100644 index 00000000..f6c93f61 --- /dev/null +++ b/googlemock/include/gmock/internal/custom/README.md @@ -0,0 +1,16 @@ +# Customization Points + +The custom directory is an injection point for custom user configurations. + +## Header `gmock-port.h` + +The following macros can be defined: + +### Flag related macros: + +* `GMOCK_DECLARE_bool_(name)` +* `GMOCK_DECLARE_int32_(name)` +* `GMOCK_DECLARE_string_(name)` +* `GMOCK_DEFINE_bool_(name, default_val, doc)` +* `GMOCK_DEFINE_int32_(name, default_val, doc)` +* `GMOCK_DEFINE_string_(name, default_val, doc)` diff --git a/googlemock/include/gmock/internal/custom/gmock-generated-actions.h b/googlemock/include/gmock/internal/custom/gmock-generated-actions.h index 7dc3b1ad..92d910cf 100644 --- a/googlemock/include/gmock/internal/custom/gmock-generated-actions.h +++ b/googlemock/include/gmock/internal/custom/gmock-generated-actions.h @@ -2,6 +2,8 @@ // pump.py gmock-generated-actions.h.pump // DO NOT EDIT BY HAND!!! +// GOOGLETEST_CM0002 DO NOT DELETE + #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ #define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ diff --git a/googlemock/include/gmock/internal/custom/gmock-generated-actions.h.pump b/googlemock/include/gmock/internal/custom/gmock-generated-actions.h.pump index d26c8a08..67c221f1 100644 --- a/googlemock/include/gmock/internal/custom/gmock-generated-actions.h.pump +++ b/googlemock/include/gmock/internal/custom/gmock-generated-actions.h.pump @@ -1,9 +1,11 @@ $$ -*- mode: c++; -*- -$$ This is a Pump source file (http://go/pump). Please use Pump to convert +$$ This is a Pump source file. Please use Pump to convert $$ it to callback-actions.h. $$ $var max_callback_arity = 5 $$}} This meta comment fixes auto-indentation in editors. + +// GOOGLETEST_CM0002 DO NOT DELETE #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ #define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ diff --git a/googlemock/include/gmock/internal/custom/gmock-matchers.h b/googlemock/include/gmock/internal/custom/gmock-matchers.h index f2efef91..14aafaab 100644 --- a/googlemock/include/gmock/internal/custom/gmock-matchers.h +++ b/googlemock/include/gmock/internal/custom/gmock-matchers.h @@ -27,13 +27,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// ============================================================ -// An installation-specific extension point for gmock-matchers.h. -// ============================================================ +// Injection point for custom user configurations. See README for details // -// Adds google3 callback support to CallableTraits. -// -#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_ -#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_ +// GOOGLETEST_CM0002 DO NOT DELETE -#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_ +#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ +#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ +#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ diff --git a/googlemock/include/gmock/internal/custom/gmock-port.h b/googlemock/include/gmock/internal/custom/gmock-port.h index 9ce8bfe0..0030fe91 100644 --- a/googlemock/include/gmock/internal/custom/gmock-port.h +++ b/googlemock/include/gmock/internal/custom/gmock-port.h @@ -27,19 +27,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Injection point for custom user configurations. -// The following macros can be defined: -// -// Flag related macros: -// GMOCK_DECLARE_bool_(name) -// GMOCK_DECLARE_int32_(name) -// GMOCK_DECLARE_string_(name) -// GMOCK_DEFINE_bool_(name, default_val, doc) -// GMOCK_DEFINE_int32_(name, default_val, doc) -// GMOCK_DEFINE_string_(name, default_val, doc) +// Injection point for custom user configurations. See README for details // // ** Custom implementation starts here ** +// GOOGLETEST_CM0002 DO NOT DELETE + #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ #define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ diff --git a/googlemock/include/gmock/internal/gmock-generated-internal-utils.h b/googlemock/include/gmock/internal/gmock-generated-internal-utils.h index cd94d644..eaa56be9 100644 --- a/googlemock/include/gmock/internal/gmock-generated-internal-utils.h +++ b/googlemock/include/gmock/internal/gmock-generated-internal-utils.h @@ -30,14 +30,15 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // // This file contains template meta-programming utility classes needed // for implementing Google Mock. +// GOOGLETEST_CM0002 DO NOT DELETE + #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_ #define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_ diff --git a/googlemock/include/gmock/internal/gmock-generated-internal-utils.h.pump b/googlemock/include/gmock/internal/gmock-generated-internal-utils.h.pump index 800af17c..c1032798 100644 --- a/googlemock/include/gmock/internal/gmock-generated-internal-utils.h.pump +++ b/googlemock/include/gmock/internal/gmock-generated-internal-utils.h.pump @@ -31,14 +31,15 @@ $var n = 10 $$ The maximum arity we support. // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // // This file contains template meta-programming utility classes needed // for implementing Google Mock. +// GOOGLETEST_CM0002 DO NOT DELETE + #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_ #define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_ diff --git a/googlemock/include/gmock/internal/gmock-internal-utils.h b/googlemock/include/gmock/internal/gmock-internal-utils.h index 319b389b..db64c65c 100644 --- a/googlemock/include/gmock/internal/gmock-internal-utils.h +++ b/googlemock/include/gmock/internal/gmock-internal-utils.h @@ -26,8 +26,7 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // @@ -35,6 +34,8 @@ // Mock. They are subject to change without notice, so please DO NOT // USE THEM IN USER CODE. +// GOOGLETEST_CM0002 DO NOT DELETE + #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ #define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ @@ -48,6 +49,14 @@ namespace testing { namespace internal { +// Silence MSVC C4100 (unreferenced formal parameter) and +// C4805('==': unsafe mix of type 'const int' and type 'const bool') +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4100) +# pragma warning(disable:4805) +#endif + // Joins a vector of strings as if they are fields of a tuple; returns // the joined string. GTEST_API_ std::string JoinAsTuple(const Strings& fields); @@ -117,9 +126,11 @@ struct LinkedPtrLessThan { // To gcc, // wchar_t == signed wchar_t != unsigned wchar_t == unsigned int #ifdef __GNUC__ +#if !defined(__WCHAR_UNSIGNED__) // signed/unsigned wchar_t are valid types. # define GMOCK_HAS_SIGNED_WCHAR_T_ 1 #endif +#endif // In what follows, we use the term "kind" to indicate whether a type // is bool, an integer type (excluding bool), a floating-point type, @@ -334,7 +345,22 @@ GTEST_API_ bool LogIsVisible(LogSeverity severity); GTEST_API_ void Log(LogSeverity severity, const std::string& message, int stack_frames_to_skip); -// TODO(wan@google.com): group all type utilities together. +// A marker class that is used to resolve parameterless expectations to the +// correct overload. This must not be instantiable, to prevent client code from +// accidentally resolving to the overload; for example: +// +// ON_CALL(mock, Method({}, nullptr))... +// +class WithoutMatchers { + private: + WithoutMatchers() {} + friend GTEST_API_ WithoutMatchers GetWithoutMatchers(); +}; + +// Internal use only: access the singleton instance of WithoutMatchers. +GTEST_API_ WithoutMatchers GetWithoutMatchers(); + +// FIXME: group all type utilities together. // Type traits. @@ -508,7 +534,7 @@ struct BooleanConstant {}; // Emit an assertion failure due to incorrect DoDefault() usage. Out-of-lined to // reduce code size. -void IllegalDoDefault(const char* file, int line); +GTEST_API_ void IllegalDoDefault(const char* file, int line); #if GTEST_LANG_CXX11 // Helper types for Apply() below. @@ -537,6 +563,12 @@ auto Apply(F&& f, Tuple&& args) make_int_pack<std::tuple_size<Tuple>::value>()); } #endif + + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } // namespace internal } // namespace testing diff --git a/googlemock/include/gmock/internal/gmock-port.h b/googlemock/include/gmock/internal/gmock-port.h index cb37f260..fda27dba 100644 --- a/googlemock/include/gmock/internal/gmock-port.h +++ b/googlemock/include/gmock/internal/gmock-port.h @@ -26,8 +26,7 @@ // 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. -// -// Author: vadimb@google.com (Vadim Berman) + // // Low-level types and utilities for porting Google Mock to various // platforms. All macros ending with _ and symbols defined in an @@ -36,6 +35,8 @@ // end with _ are part of Google Mock's public API and can be used by // code outside Google Mock. +// GOOGLETEST_CM0002 DO NOT DELETE + #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ #define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ diff --git a/googlemock/scripts/generator/README b/googlemock/scripts/generator/README index d6f95974..01fd463d 100644 --- a/googlemock/scripts/generator/README +++ b/googlemock/scripts/generator/README @@ -1,11 +1,10 @@ The Google Mock class generator is an application that is part of cppclean. -For more information about cppclean, see the README.cppclean file or -visit http://code.google.com/p/cppclean/ +For more information about cppclean, visit http://code.google.com/p/cppclean/ -cppclean requires Python 2.3.5 or later. If you don't have Python installed -on your system, you will also need to install it. You can download Python -from: http://www.python.org/download/releases/ +The mock generator requires Python 2.3.5 or later. If you don't have Python +installed on your system, you will also need to install it. You can download +Python from: http://www.python.org/download/releases/ To use the Google Mock class generator, you need to call it on the command line passing the header file and class for which you want diff --git a/googlemock/scripts/upload.py b/googlemock/scripts/upload.py index 6e6f9a14..95239dc2 100755 --- a/googlemock/scripts/upload.py +++ b/googlemock/scripts/upload.py @@ -242,7 +242,7 @@ class AbstractRpcServer(object): The authentication process works as follows: 1) We get a username and password from the user 2) We use ClientLogin to obtain an AUTH token for the user - (see http://code.google.com/apis/accounts/AuthForInstalledApps.html). + (see https://developers.google.com/identity/protocols/AuthForInstalledApps). 3) We pass the auth token to /_ah/login on the server to obtain an authentication cookie. If login was successful, it tries to redirect us to the URL we provided. @@ -506,7 +506,7 @@ def EncodeMultipartFormData(fields, files): (content_type, body) ready for httplib.HTTP instance. Source: - http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146306 + https://web.archive.org/web/20160116052001/code.activestate.com/recipes/146306 """ BOUNDARY = '-M-A-G-I-C---B-O-U-N-D-A-R-Y-' CRLF = '\r\n' @@ -807,7 +807,7 @@ class SubversionVCS(VersionControlSystem): # svn cat translates keywords but svn diff doesn't. As a result of this # behavior patching.PatchChunks() fails with a chunk mismatch error. # This part was originally written by the Review Board development team - # who had the same problem (http://reviews.review-board.org/r/276/). + # who had the same problem (https://reviews.reviewboard.org/r/276/). # Mapping of keywords to known aliases svn_keywords = { # Standard keywords @@ -860,7 +860,7 @@ class SubversionVCS(VersionControlSystem): status_lines = status.splitlines() # If file is in a cl, the output will begin with # "\n--- Changelist 'cl_name':\n". See - # http://svn.collab.net/repos/svn/trunk/notes/changelist-design.txt + # https://web.archive.org/web/20090918234815/svn.collab.net/repos/svn/trunk/notes/changelist-design.txt if (len(status_lines) == 3 and not status_lines[0] and status_lines[1].startswith("--- Changelist")): diff --git a/googlemock/src/gmock-all.cc b/googlemock/src/gmock-all.cc index 7aebce7a..e43c9b7b 100644 --- a/googlemock/src/gmock-all.cc +++ b/googlemock/src/gmock-all.cc @@ -26,8 +26,7 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // // Google C++ Mocking Framework (Google Mock) // diff --git a/googlemock/src/gmock-cardinalities.cc b/googlemock/src/gmock-cardinalities.cc index 335b966e..0549f727 100644 --- a/googlemock/src/gmock-cardinalities.cc +++ b/googlemock/src/gmock-cardinalities.cc @@ -26,8 +26,7 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // diff --git a/googlemock/src/gmock-internal-utils.cc b/googlemock/src/gmock-internal-utils.cc index 91bf3fd9..e3a67485 100644 --- a/googlemock/src/gmock-internal-utils.cc +++ b/googlemock/src/gmock-internal-utils.cc @@ -26,8 +26,7 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // @@ -47,12 +46,31 @@ namespace testing { namespace internal { +// Joins a vector of strings as if they are fields of a tuple; returns +// the joined string. +GTEST_API_ std::string JoinAsTuple(const Strings& fields) { + switch (fields.size()) { + case 0: + return ""; + case 1: + return fields[0]; + default: + std::string result = "(" + fields[0]; + for (size_t i = 1; i < fields.size(); i++) { + result += ", "; + result += fields[i]; + } + result += ")"; + return result; + } +} + // Converts an identifier name to a space-separated list of lower-case // words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is // treated as one word. For example, both "FooBar123" and // "foo_bar_123" are converted to "foo bar 123". -GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name) { - string result; +GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name) { + std::string result; char prev_char = '\0'; for (const char* p = id_name; *p != '\0'; prev_char = *(p++)) { // We don't care about the current locale as the input is @@ -169,5 +187,17 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message, std::cout << ::std::flush; } +GTEST_API_ WithoutMatchers GetWithoutMatchers() { return WithoutMatchers(); } + +GTEST_API_ void IllegalDoDefault(const char* file, int line) { + internal::Assert( + false, file, line, + "You are using DoDefault() inside a composite action like " + "DoAll() or WithArgs(). This is not supported for technical " + "reasons. Please instead spell out the default action, or " + "assign the default action to an Action variable and use " + "the variable in various places."); +} + } // namespace internal } // namespace testing diff --git a/googlemock/src/gmock-matchers.cc b/googlemock/src/gmock-matchers.cc index 6e40e5e8..f8ddff15 100644 --- a/googlemock/src/gmock-matchers.cc +++ b/googlemock/src/gmock-matchers.cc @@ -26,8 +26,7 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // @@ -38,98 +37,133 @@ #include "gmock/gmock-generated-matchers.h" #include <string.h> +#include <iostream> #include <sstream> #include <string> namespace testing { -// Constructs a matcher that matches a const string& whose value is +// Constructs a matcher that matches a const std::string& whose value is // equal to s. -Matcher<const internal::string&>::Matcher(const internal::string& s) { - *this = Eq(s); +Matcher<const std::string&>::Matcher(const std::string& s) { *this = Eq(s); } + +#if GTEST_HAS_GLOBAL_STRING +// Constructs a matcher that matches a const std::string& whose value is +// equal to s. +Matcher<const std::string&>::Matcher(const ::string& s) { + *this = Eq(static_cast<std::string>(s)); } +#endif // GTEST_HAS_GLOBAL_STRING -// Constructs a matcher that matches a const string& whose value is +// Constructs a matcher that matches a const std::string& whose value is // equal to s. -Matcher<const internal::string&>::Matcher(const char* s) { - *this = Eq(internal::string(s)); +Matcher<const std::string&>::Matcher(const char* s) { + *this = Eq(std::string(s)); } -// Constructs a matcher that matches a string whose value is equal to s. -Matcher<internal::string>::Matcher(const internal::string& s) { *this = Eq(s); } +// Constructs a matcher that matches a std::string whose value is equal to +// s. +Matcher<std::string>::Matcher(const std::string& s) { *this = Eq(s); } -// Constructs a matcher that matches a string whose value is equal to s. -Matcher<internal::string>::Matcher(const char* s) { - *this = Eq(internal::string(s)); +#if GTEST_HAS_GLOBAL_STRING +// Constructs a matcher that matches a std::string whose value is equal to +// s. +Matcher<std::string>::Matcher(const ::string& s) { + *this = Eq(static_cast<std::string>(s)); } +#endif // GTEST_HAS_GLOBAL_STRING + +// Constructs a matcher that matches a std::string whose value is equal to +// s. +Matcher<std::string>::Matcher(const char* s) { *this = Eq(std::string(s)); } -#if GTEST_HAS_STRING_PIECE_ -// Constructs a matcher that matches a const StringPiece& whose value is +#if GTEST_HAS_GLOBAL_STRING +// Constructs a matcher that matches a const ::string& whose value is // equal to s. -Matcher<const StringPiece&>::Matcher(const internal::string& s) { - *this = Eq(s); +Matcher<const ::string&>::Matcher(const std::string& s) { + *this = Eq(static_cast<::string>(s)); } -// Constructs a matcher that matches a const StringPiece& whose value is +// Constructs a matcher that matches a const ::string& whose value is // equal to s. -Matcher<const StringPiece&>::Matcher(const char* s) { - *this = Eq(internal::string(s)); -} +Matcher<const ::string&>::Matcher(const ::string& s) { *this = Eq(s); } -// Constructs a matcher that matches a const StringPiece& whose value is +// Constructs a matcher that matches a const ::string& whose value is // equal to s. -Matcher<const StringPiece&>::Matcher(StringPiece s) { - *this = Eq(s.ToString()); +Matcher<const ::string&>::Matcher(const char* s) { *this = Eq(::string(s)); } + +// Constructs a matcher that matches a ::string whose value is equal to s. +Matcher<::string>::Matcher(const std::string& s) { + *this = Eq(static_cast<::string>(s)); } -// Constructs a matcher that matches a StringPiece whose value is equal to s. -Matcher<StringPiece>::Matcher(const internal::string& s) { +// Constructs a matcher that matches a ::string whose value is equal to s. +Matcher<::string>::Matcher(const ::string& s) { *this = Eq(s); } + +// Constructs a matcher that matches a string whose value is equal to s. +Matcher<::string>::Matcher(const char* s) { *this = Eq(::string(s)); } +#endif // GTEST_HAS_GLOBAL_STRING + +#if GTEST_HAS_ABSL +// Constructs a matcher that matches a const absl::string_view& whose value is +// equal to s. +Matcher<const absl::string_view&>::Matcher(const std::string& s) { *this = Eq(s); } -// Constructs a matcher that matches a StringPiece whose value is equal to s. -Matcher<StringPiece>::Matcher(const char* s) { - *this = Eq(internal::string(s)); +#if GTEST_HAS_GLOBAL_STRING +// Constructs a matcher that matches a const absl::string_view& whose value is +// equal to s. +Matcher<const absl::string_view&>::Matcher(const ::string& s) { *this = Eq(s); } +#endif // GTEST_HAS_GLOBAL_STRING + +// Constructs a matcher that matches a const absl::string_view& whose value is +// equal to s. +Matcher<const absl::string_view&>::Matcher(const char* s) { + *this = Eq(std::string(s)); } -// Constructs a matcher that matches a StringPiece whose value is equal to s. -Matcher<StringPiece>::Matcher(StringPiece s) { - *this = Eq(s.ToString()); +// Constructs a matcher that matches a const absl::string_view& whose value is +// equal to s. +Matcher<const absl::string_view&>::Matcher(absl::string_view s) { + *this = Eq(std::string(s)); } -#endif // GTEST_HAS_STRING_PIECE_ -namespace internal { +// Constructs a matcher that matches a absl::string_view whose value is equal to +// s. +Matcher<absl::string_view>::Matcher(const std::string& s) { *this = Eq(s); } -// Joins a vector of strings as if they are fields of a tuple; returns -// the joined string. -GTEST_API_ string JoinAsTuple(const Strings& fields) { - switch (fields.size()) { - case 0: - return ""; - case 1: - return fields[0]; - default: - string result = "(" + fields[0]; - for (size_t i = 1; i < fields.size(); i++) { - result += ", "; - result += fields[i]; - } - result += ")"; - return result; - } +#if GTEST_HAS_GLOBAL_STRING +// Constructs a matcher that matches a absl::string_view whose value is equal to +// s. +Matcher<absl::string_view>::Matcher(const ::string& s) { *this = Eq(s); } +#endif // GTEST_HAS_GLOBAL_STRING + +// Constructs a matcher that matches a absl::string_view whose value is equal to +// s. +Matcher<absl::string_view>::Matcher(const char* s) { + *this = Eq(std::string(s)); } +// Constructs a matcher that matches a absl::string_view whose value is equal to +// s. +Matcher<absl::string_view>::Matcher(absl::string_view s) { + *this = Eq(std::string(s)); +} +#endif // GTEST_HAS_ABSL + +namespace internal { + // Returns the description for a matcher defined using the MATCHER*() // macro where the user-supplied description string is "", if // 'negation' is false; otherwise returns the description of the // negation of the matcher. 'param_values' contains a list of strings // that are the print-out of the matcher's parameters. -GTEST_API_ string FormatMatcherDescription(bool negation, - const char* matcher_name, - const Strings& param_values) { - string result = ConvertIdentifierNameToWords(matcher_name); - if (param_values.size() >= 1) - result += " " + JoinAsTuple(param_values); +GTEST_API_ std::string FormatMatcherDescription(bool negation, + const char* matcher_name, + const Strings& param_values) { + std::string result = ConvertIdentifierNameToWords(matcher_name); + if (param_values.size() >= 1) result += " " + JoinAsTuple(param_values); return negation ? "not (" + result + ")" : result; } @@ -200,8 +234,7 @@ class MaxBipartiteMatchState { explicit MaxBipartiteMatchState(const MatchMatrix& graph) : graph_(&graph), left_(graph_->LhsSize(), kUnused), - right_(graph_->RhsSize(), kUnused) { - } + right_(graph_->RhsSize(), kUnused) {} // Returns the edges of a maximal match, each in the form {left, right}. ElementMatcherPairs Compute() { @@ -258,10 +291,8 @@ class MaxBipartiteMatchState { // bool TryAugment(size_t ilhs, ::std::vector<char>* seen) { for (size_t irhs = 0; irhs < graph_->RhsSize(); ++irhs) { - if ((*seen)[irhs]) - continue; - if (!graph_->HasEdge(ilhs, irhs)) - continue; + if ((*seen)[irhs]) continue; + if (!graph_->HasEdge(ilhs, irhs)) continue; // There's an available edge from ilhs to irhs. (*seen)[irhs] = 1; // Next a search is performed to determine whether @@ -304,8 +335,7 @@ class MaxBipartiteMatchState { const size_t MaxBipartiteMatchState::kUnused; -GTEST_API_ ElementMatcherPairs -FindMaxBipartiteMatching(const MatchMatrix& g) { +GTEST_API_ ElementMatcherPairs FindMaxBipartiteMatching(const MatchMatrix& g) { return MaxBipartiteMatchState(g).Compute(); } @@ -314,7 +344,7 @@ static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs, typedef ElementMatcherPairs::const_iterator Iter; ::std::ostream& os = *stream; os << "{"; - const char *sep = ""; + const char* sep = ""; for (Iter it = pairs.begin(); it != pairs.end(); ++it) { os << sep << "\n (" << "element #" << it->first << ", " @@ -324,38 +354,6 @@ static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs, os << "\n}"; } -// Tries to find a pairing, and explains the result. -GTEST_API_ bool FindPairing(const MatchMatrix& matrix, - MatchResultListener* listener) { - ElementMatcherPairs matches = FindMaxBipartiteMatching(matrix); - - size_t max_flow = matches.size(); - bool result = (max_flow == matrix.RhsSize()); - - if (!result) { - if (listener->IsInterested()) { - *listener << "where no permutation of the elements can " - "satisfy all matchers, and the closest match is " - << max_flow << " of " << matrix.RhsSize() - << " matchers with the pairings:\n"; - LogElementMatcherPairVec(matches, listener->stream()); - } - return false; - } - - if (matches.size() > 1) { - if (listener->IsInterested()) { - const char *sep = "where:\n"; - for (size_t mi = 0; mi < matches.size(); ++mi) { - *listener << sep << " - element #" << matches[mi].first - << " is matched by matcher #" << matches[mi].second; - sep = ",\n"; - } - } - } - return true; -} - bool MatchMatrix::NextGraph() { for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) { for (size_t irhs = 0; irhs < RhsSize(); ++irhs) { @@ -381,7 +379,7 @@ void MatchMatrix::Randomize() { std::string MatchMatrix::DebugString() const { ::std::stringstream ss; - const char *sep = ""; + const char* sep = ""; for (size_t i = 0; i < LhsSize(); ++i) { ss << sep; for (size_t j = 0; j < RhsSize(); ++j) { @@ -394,44 +392,83 @@ std::string MatchMatrix::DebugString() const { void UnorderedElementsAreMatcherImplBase::DescribeToImpl( ::std::ostream* os) const { - if (matcher_describers_.empty()) { - *os << "is empty"; - return; - } - if (matcher_describers_.size() == 1) { - *os << "has " << Elements(1) << " and that element "; - matcher_describers_[0]->DescribeTo(os); - return; + switch (match_flags()) { + case UnorderedMatcherRequire::ExactMatch: + if (matcher_describers_.empty()) { + *os << "is empty"; + return; + } + if (matcher_describers_.size() == 1) { + *os << "has " << Elements(1) << " and that element "; + matcher_describers_[0]->DescribeTo(os); + return; + } + *os << "has " << Elements(matcher_describers_.size()) + << " and there exists some permutation of elements such that:\n"; + break; + case UnorderedMatcherRequire::Superset: + *os << "a surjection from elements to requirements exists such that:\n"; + break; + case UnorderedMatcherRequire::Subset: + *os << "an injection from elements to requirements exists such that:\n"; + break; } - *os << "has " << Elements(matcher_describers_.size()) - << " and there exists some permutation of elements such that:\n"; + const char* sep = ""; for (size_t i = 0; i != matcher_describers_.size(); ++i) { - *os << sep << " - element #" << i << " "; + *os << sep; + if (match_flags() == UnorderedMatcherRequire::ExactMatch) { + *os << " - element #" << i << " "; + } else { + *os << " - an element "; + } matcher_describers_[i]->DescribeTo(os); - sep = ", and\n"; + if (match_flags() == UnorderedMatcherRequire::ExactMatch) { + sep = ", and\n"; + } else { + sep = "\n"; + } } } void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl( ::std::ostream* os) const { - if (matcher_describers_.empty()) { - *os << "isn't empty"; - return; - } - if (matcher_describers_.size() == 1) { - *os << "doesn't have " << Elements(1) - << ", or has " << Elements(1) << " that "; - matcher_describers_[0]->DescribeNegationTo(os); - return; + switch (match_flags()) { + case UnorderedMatcherRequire::ExactMatch: + if (matcher_describers_.empty()) { + *os << "isn't empty"; + return; + } + if (matcher_describers_.size() == 1) { + *os << "doesn't have " << Elements(1) << ", or has " << Elements(1) + << " that "; + matcher_describers_[0]->DescribeNegationTo(os); + return; + } + *os << "doesn't have " << Elements(matcher_describers_.size()) + << ", or there exists no permutation of elements such that:\n"; + break; + case UnorderedMatcherRequire::Superset: + *os << "no surjection from elements to requirements exists such that:\n"; + break; + case UnorderedMatcherRequire::Subset: + *os << "no injection from elements to requirements exists such that:\n"; + break; } - *os << "doesn't have " << Elements(matcher_describers_.size()) - << ", or there exists no permutation of elements such that:\n"; const char* sep = ""; for (size_t i = 0; i != matcher_describers_.size(); ++i) { - *os << sep << " - element #" << i << " "; + *os << sep; + if (match_flags() == UnorderedMatcherRequire::ExactMatch) { + *os << " - element #" << i << " "; + } else { + *os << " - an element "; + } matcher_describers_[i]->DescribeTo(os); - sep = ", and\n"; + if (match_flags() == UnorderedMatcherRequire::ExactMatch) { + sep = ", and\n"; + } else { + sep = "\n"; + } } } @@ -440,10 +477,9 @@ void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl( // and better error reporting. // Returns false, writing an explanation to 'listener', if and only // if the success criteria are not met. -bool UnorderedElementsAreMatcherImplBase:: - VerifyAllElementsAndMatchersAreMatched( - const ::std::vector<std::string>& element_printouts, - const MatchMatrix& matrix, MatchResultListener* listener) const { +bool UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix( + const ::std::vector<std::string>& element_printouts, + const MatchMatrix& matrix, MatchResultListener* listener) const { bool result = true; ::std::vector<char> element_matched(matrix.LhsSize(), 0); ::std::vector<char> matcher_matched(matrix.RhsSize(), 0); @@ -456,12 +492,11 @@ bool UnorderedElementsAreMatcherImplBase:: } } - { + if (match_flags() & UnorderedMatcherRequire::Superset) { const char* sep = "where the following matchers don't match any elements:\n"; for (size_t mi = 0; mi < matcher_matched.size(); ++mi) { - if (matcher_matched[mi]) - continue; + if (matcher_matched[mi]) continue; result = false; if (listener->IsInterested()) { *listener << sep << "matcher #" << mi << ": "; @@ -471,7 +506,7 @@ bool UnorderedElementsAreMatcherImplBase:: } } - { + if (match_flags() & UnorderedMatcherRequire::Subset) { const char* sep = "where the following elements don't match any matchers:\n"; const char* outer_sep = ""; @@ -479,8 +514,7 @@ bool UnorderedElementsAreMatcherImplBase:: outer_sep = "\nand "; } for (size_t ei = 0; ei < element_matched.size(); ++ei) { - if (element_matched[ei]) - continue; + if (element_matched[ei]) continue; result = false; if (listener->IsInterested()) { *listener << outer_sep << sep << "element #" << ei << ": " @@ -493,5 +527,46 @@ bool UnorderedElementsAreMatcherImplBase:: return result; } +bool UnorderedElementsAreMatcherImplBase::FindPairing( + const MatchMatrix& matrix, MatchResultListener* listener) const { + ElementMatcherPairs matches = FindMaxBipartiteMatching(matrix); + + size_t max_flow = matches.size(); + if ((match_flags() & UnorderedMatcherRequire::Superset) && + max_flow < matrix.RhsSize()) { + if (listener->IsInterested()) { + *listener << "where no permutation of the elements can satisfy all " + "matchers, and the closest match is " + << max_flow << " of " << matrix.RhsSize() + << " matchers with the pairings:\n"; + LogElementMatcherPairVec(matches, listener->stream()); + } + return false; + } + if ((match_flags() & UnorderedMatcherRequire::Subset) && + max_flow < matrix.LhsSize()) { + if (listener->IsInterested()) { + *listener + << "where not all elements can be matched, and the closest match is " + << max_flow << " of " << matrix.RhsSize() + << " matchers with the pairings:\n"; + LogElementMatcherPairVec(matches, listener->stream()); + } + return false; + } + + if (matches.size() > 1) { + if (listener->IsInterested()) { + const char* sep = "where:\n"; + for (size_t mi = 0; mi < matches.size(); ++mi) { + *listener << sep << " - element #" << matches[mi].first + << " is matched by matcher #" << matches[mi].second; + sep = ",\n"; + } + } + } + return true; +} + } // namespace internal } // namespace testing diff --git a/googlemock/src/gmock-spec-builders.cc b/googlemock/src/gmock-spec-builders.cc index 93a83ae5..b93f4e0e 100644 --- a/googlemock/src/gmock-spec-builders.cc +++ b/googlemock/src/gmock-spec-builders.cc @@ -26,8 +26,7 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // @@ -41,6 +40,7 @@ #include <map> #include <set> #include <string> +#include <vector> #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -48,6 +48,15 @@ # include <unistd.h> // NOLINT #endif +// Silence C4800 (C4800: 'int *const ': forcing value +// to bool 'true' or 'false') for MSVC 14,15 +#ifdef _MSC_VER +#if _MSC_VER <= 1900 +# pragma warning(push) +# pragma warning(disable:4800) +#endif +#endif + namespace testing { namespace internal { @@ -99,12 +108,19 @@ void ExpectationBase::RetireAllPreRequisites() return; } - for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin(); - it != immediate_prerequisites_.end(); ++it) { - ExpectationBase* const prerequisite = it->expectation_base().get(); - if (!prerequisite->is_retired()) { - prerequisite->RetireAllPreRequisites(); - prerequisite->Retire(); + ::std::vector<ExpectationBase*> expectations(1, this); + while (!expectations.empty()) { + ExpectationBase* exp = expectations.back(); + expectations.pop_back(); + + for (ExpectationSet::const_iterator it = + exp->immediate_prerequisites_.begin(); + it != exp->immediate_prerequisites_.end(); ++it) { + ExpectationBase* next = it->expectation_base().get(); + if (!next->is_retired()) { + next->Retire(); + expectations.push_back(next); + } } } } @@ -114,11 +130,18 @@ void ExpectationBase::RetireAllPreRequisites() bool ExpectationBase::AllPrerequisitesAreSatisfied() const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { g_gmock_mutex.AssertHeld(); - for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin(); - it != immediate_prerequisites_.end(); ++it) { - if (!(it->expectation_base()->IsSatisfied()) || - !(it->expectation_base()->AllPrerequisitesAreSatisfied())) - return false; + ::std::vector<const ExpectationBase*> expectations(1, this); + while (!expectations.empty()) { + const ExpectationBase* exp = expectations.back(); + expectations.pop_back(); + + for (ExpectationSet::const_iterator it = + exp->immediate_prerequisites_.begin(); + it != exp->immediate_prerequisites_.end(); ++it) { + const ExpectationBase* next = it->expectation_base().get(); + if (!next->IsSatisfied()) return false; + expectations.push_back(next); + } } return true; } @@ -127,19 +150,28 @@ bool ExpectationBase::AllPrerequisitesAreSatisfied() const void ExpectationBase::FindUnsatisfiedPrerequisites(ExpectationSet* result) const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { g_gmock_mutex.AssertHeld(); - for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin(); - it != immediate_prerequisites_.end(); ++it) { - if (it->expectation_base()->IsSatisfied()) { - // If *it is satisfied and has a call count of 0, some of its - // pre-requisites may not be satisfied yet. - if (it->expectation_base()->call_count_ == 0) { - it->expectation_base()->FindUnsatisfiedPrerequisites(result); + ::std::vector<const ExpectationBase*> expectations(1, this); + while (!expectations.empty()) { + const ExpectationBase* exp = expectations.back(); + expectations.pop_back(); + + for (ExpectationSet::const_iterator it = + exp->immediate_prerequisites_.begin(); + it != exp->immediate_prerequisites_.end(); ++it) { + const ExpectationBase* next = it->expectation_base().get(); + + if (next->IsSatisfied()) { + // If *it is satisfied and has a call count of 0, some of its + // pre-requisites may not be satisfied yet. + if (next->call_count_ == 0) { + expectations.push_back(next); + } + } else { + // Now that we know next is unsatisfied, we are not so interested + // in whether its pre-requisites are satisfied. Therefore we + // don't iterate into it here. + *result += *it; } - } else { - // Now that we know *it is unsatisfied, we are not so interested - // in whether its pre-requisites are satisfied. Therefore we - // don't recursively call FindUnsatisfiedPrerequisites() here. - *result += *it; } } } @@ -254,11 +286,13 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg) { case kWarn: Log(kWarning, msg + - "\nNOTE: You can safely ignore the above warning unless this " - "call should not happen. Do not suppress it by blindly adding " - "an EXPECT_CALL() if you don't mean to enforce the call. " - "See https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md#" - "knowing-when-to-expect for details.\n", + "\nNOTE: You can safely ignore the above warning unless this " + "call should not happen. Do not suppress it by blindly adding " + "an EXPECT_CALL() if you don't mean to enforce the call. " + "See " + "https://github.com/google/googletest/blob/master/googlemock/" + "docs/CookBook.md#" + "knowing-when-to-expect for details.\n", stack_frames_to_skip); break; default: // FAIL @@ -334,9 +368,10 @@ const char* UntypedFunctionMockerBase::Name() const // Calculates the result of invoking this mock function with the given // arguments, prints it, and returns it. The caller is responsible // for deleting the result. -UntypedActionResultHolderBase* -UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args) - GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { +UntypedActionResultHolderBase* UntypedFunctionMockerBase::UntypedInvokeWith( + void* const untyped_args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { + // See the definition of untyped_expectations_ for why access to it + // is unprotected here. if (untyped_expectations_.size() == 0) { // No expectation is set on this mock method - we have an // uninteresting call. @@ -355,16 +390,19 @@ UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args) // If the user allows this uninteresting call, we print it // only when they want informational messages. reaction == kAllow ? LogIsVisible(kInfo) : - // If the user wants this to be a warning, we print it only - // when they want to see warnings. - reaction == kWarn ? LogIsVisible(kWarning) : - // Otherwise, the user wants this to be an error, and we - // should always print detailed information in the error. - true; + // If the user wants this to be a warning, we print + // it only when they want to see warnings. + reaction == kWarn + ? LogIsVisible(kWarning) + : + // Otherwise, the user wants this to be an error, and we + // should always print detailed information in the error. + true; if (!need_to_report_uninteresting_call) { // Perform the action without printing the call information. - return this->UntypedPerformDefaultAction(untyped_args, "Function call: " + std::string(Name())); + return this->UntypedPerformDefaultAction( + untyped_args, "Function call: " + std::string(Name())); } // Warns about the uninteresting call. @@ -446,6 +484,8 @@ UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args) // Returns an Expectation object that references and co-owns exp, // which must be an expectation on this mock function. Expectation UntypedFunctionMockerBase::GetHandleOf(ExpectationBase* exp) { + // See the definition of untyped_expectations_ for why access to it + // is unprotected here. for (UntypedExpectations::const_iterator it = untyped_expectations_.begin(); it != untyped_expectations_.end(); ++it) { @@ -508,7 +548,7 @@ bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked() return expectations_met; } -static CallReaction intToCallReaction(int mock_behavior) { +CallReaction intToCallReaction(int mock_behavior) { if (mock_behavior >= kAllow && mock_behavior <= kFail) { return static_cast<internal::CallReaction>(mock_behavior); } @@ -566,7 +606,7 @@ class MockObjectRegistry { if (it->second.leakable) // The user said it's fine to leak this object. continue; - // TODO(wan@google.com): Print the type of the leaked object. + // FIXME: Print the type of the leaked object. // This can help the user identify the leaked object. std::cout << "\n"; const MockObjectState& state = it->second; @@ -582,9 +622,15 @@ class MockObjectRegistry { leaked_count++; } if (leaked_count > 0) { - std::cout << "\nERROR: " << leaked_count - << " leaked mock " << (leaked_count == 1 ? "object" : "objects") - << " found at program exit.\n"; + std::cout << "\nERROR: " << leaked_count << " leaked mock " + << (leaked_count == 1 ? "object" : "objects") + << " found at program exit. Expectations on a mock object is " + "verified when the object is destructed. Leaking a mock " + "means that its expectations aren't verified, which is " + "usually a test bug. If you really intend to leak a mock, " + "you can suppress this error using " + "testing::Mock::AllowLeak(mock_object), or you may use a " + "fake or stub instead of a mock.\n"; std::cout.flush(); ::std::cerr.flush(); // RUN_ALL_TESTS() has already returned when this destructor is @@ -736,7 +782,7 @@ void Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj, const TestInfo* const test_info = UnitTest::GetInstance()->current_test_info(); if (test_info != NULL) { - // TODO(wan@google.com): record the test case name when the + // FIXME: record the test case name when the // ON_CALL or EXPECT_CALL is invoked from SetUpTestCase() or // TearDownTestCase(). state.first_used_test_case = test_info->test_case_name(); @@ -828,3 +874,9 @@ InSequence::~InSequence() { } } // namespace testing + +#ifdef _MSC_VER +#if _MSC_VER <= 1900 +# pragma warning(pop) +#endif +#endif diff --git a/googlemock/src/gmock.cc b/googlemock/src/gmock.cc index 3c370510..36356c93 100644 --- a/googlemock/src/gmock.cc +++ b/googlemock/src/gmock.cc @@ -26,15 +26,14 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + #include "gmock/gmock.h" #include "gmock/internal/gmock-port.h" namespace testing { -// TODO(wan@google.com): support using environment variables to +// FIXME: support using environment variables to // control the flag values, like what Google Test does. GMOCK_DEFINE_bool_(catch_leaked_mocks, true, @@ -136,8 +135,8 @@ static bool ParseGoogleMockIntFlag(const char* str, const char* flag, if (value_str == NULL) return false; // Sets *value to the value of the flag. - *value = atoi(value_str); - return true; + return ParseInt32(Message() << "The value of flag --" << flag, + value_str, value); } // The internal implementation of InitGoogleMock(). diff --git a/googlemock/src/gmock_main.cc b/googlemock/src/gmock_main.cc index bd5be03b..a3a271e6 100644 --- a/googlemock/src/gmock_main.cc +++ b/googlemock/src/gmock_main.cc @@ -26,8 +26,7 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + #include <iostream> #include "gmock/gmock.h" @@ -37,7 +36,8 @@ // causes a link error when _tmain is defined in a static library and UNICODE // is enabled. For this reason instead of _tmain, main function is used on // Windows. See the following link to track the current status of this bug: -// http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=394464 // NOLINT +// https://web.archive.org/web/20170912203238/connect.microsoft.com/VisualStudio/feedback/details/394464/wmain-link-error-in-the-static-library +// // NOLINT #if GTEST_OS_WINDOWS_MOBILE # include <tchar.h> // NOLINT diff --git a/googlemock/test/gmock-actions_test.cc b/googlemock/test/gmock-actions_test.cc index f7218391..06e29a1e 100644 --- a/googlemock/test/gmock-actions_test.cc +++ b/googlemock/test/gmock-actions_test.cc @@ -26,13 +26,21 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // // This file tests the built-in actions. +// Silence C4800 (C4800: 'int *const ': forcing value +// to bool 'true' or 'false') for MSVC 14,15 +#ifdef _MSC_VER +#if _MSC_VER <= 1900 +# pragma warning(push) +# pragma warning(disable:4800) +#endif +#endif + #include "gmock/gmock-actions.h" #include <algorithm> #include <iterator> @@ -65,6 +73,7 @@ using testing::ReturnRef; using testing::ReturnRefOfCopy; using testing::SetArgPointee; using testing::SetArgumentPointee; +using testing::Unused; using testing::_; using testing::get; using testing::internal::BuiltInDefaultValue; @@ -78,10 +87,6 @@ using testing::tuple_element; using testing::SetErrnoAndReturn; #endif -#if GTEST_HAS_PROTOBUF_ -using testing::internal::TestMessage; -#endif // GTEST_HAS_PROTOBUF_ - // Tests that BuiltInDefaultValue<T*>::Get() returns NULL. TEST(BuiltInDefaultValueTest, IsNullForPointerTypes) { EXPECT_TRUE(BuiltInDefaultValue<int*>::Get() == NULL); @@ -107,7 +112,11 @@ TEST(BuiltInDefaultValueTest, IsZeroForNumericTypes) { EXPECT_EQ(0, BuiltInDefaultValue<signed wchar_t>::Get()); #endif #if GMOCK_WCHAR_T_IS_NATIVE_ +#if !defined(__WCHAR_UNSIGNED__) EXPECT_EQ(0, BuiltInDefaultValue<wchar_t>::Get()); +#else + EXPECT_EQ(0U, BuiltInDefaultValue<wchar_t>::Get()); +#endif #endif EXPECT_EQ(0U, BuiltInDefaultValue<unsigned short>::Get()); // NOLINT EXPECT_EQ(0, BuiltInDefaultValue<signed short>::Get()); // NOLINT @@ -214,7 +223,7 @@ class MyNonDefaultConstructible { int value_; }; -#if GTEST_HAS_STD_TYPE_TRAITS_ +#if GTEST_LANG_CXX11 TEST(BuiltInDefaultValueTest, ExistsForDefaultConstructibleType) { EXPECT_TRUE(BuiltInDefaultValue<MyDefaultConstructible>::Exists()); @@ -224,7 +233,7 @@ TEST(BuiltInDefaultValueTest, IsDefaultConstructedForDefaultConstructibleType) { EXPECT_EQ(42, BuiltInDefaultValue<MyDefaultConstructible>::Get().value()); } -#endif // GTEST_HAS_STD_TYPE_TRAITS_ +#endif // GTEST_LANG_CXX11 TEST(BuiltInDefaultValueTest, DoesNotExistForNonDefaultConstructibleType) { EXPECT_FALSE(BuiltInDefaultValue<MyNonDefaultConstructible>::Exists()); @@ -700,6 +709,9 @@ class MockClass { MOCK_METHOD0(MakeUnique, std::unique_ptr<int>()); MOCK_METHOD0(MakeUniqueBase, std::unique_ptr<Base>()); MOCK_METHOD0(MakeVectorUnique, std::vector<std::unique_ptr<int>>()); + MOCK_METHOD1(TakeUnique, int(std::unique_ptr<int>)); + MOCK_METHOD2(TakeUnique, + int(const std::unique_ptr<int>&, std::unique_ptr<int>)); #endif private: @@ -751,7 +763,7 @@ TEST(DoDefaultDeathTest, DiesIfUsedInCompositeAction) { } // Tests that DoDefault() returns the default value set by -// DefaultValue<T>::Set() when it's not overridden by an ON_CALL(). +// DefaultValue<T>::Set() when it's not overriden by an ON_CALL(). TEST(DoDefaultTest, ReturnsUserSpecifiedPerTypeDefaultValueWhenThereIsOne) { DefaultValue<int>::Set(1); MockClass mock; @@ -878,105 +890,6 @@ TEST(SetArgPointeeTest, AcceptsWideCharPointer) { # endif } -#if GTEST_HAS_PROTOBUF_ - -// Tests that SetArgPointee<N>(proto_buffer) sets the v1 protobuf -// variable pointed to by the N-th (0-based) argument to proto_buffer. -TEST(SetArgPointeeTest, SetsTheNthPointeeOfProtoBufferType) { - TestMessage* const msg = new TestMessage; - msg->set_member("yes"); - TestMessage orig_msg; - orig_msg.CopyFrom(*msg); - - Action<void(bool, TestMessage*)> a = SetArgPointee<1>(*msg); - // SetArgPointee<N>(proto_buffer) makes a copy of proto_buffer - // s.t. the action works even when the original proto_buffer has - // died. We ensure this behavior by deleting msg before using the - // action. - delete msg; - - TestMessage dest; - EXPECT_FALSE(orig_msg.Equals(dest)); - a.Perform(make_tuple(true, &dest)); - EXPECT_TRUE(orig_msg.Equals(dest)); -} - -// Tests that SetArgPointee<N>(proto_buffer) sets the -// ::ProtocolMessage variable pointed to by the N-th (0-based) -// argument to proto_buffer. -TEST(SetArgPointeeTest, SetsTheNthPointeeOfProtoBufferBaseType) { - TestMessage* const msg = new TestMessage; - msg->set_member("yes"); - TestMessage orig_msg; - orig_msg.CopyFrom(*msg); - - Action<void(bool, ::ProtocolMessage*)> a = SetArgPointee<1>(*msg); - // SetArgPointee<N>(proto_buffer) makes a copy of proto_buffer - // s.t. the action works even when the original proto_buffer has - // died. We ensure this behavior by deleting msg before using the - // action. - delete msg; - - TestMessage dest; - ::ProtocolMessage* const dest_base = &dest; - EXPECT_FALSE(orig_msg.Equals(dest)); - a.Perform(make_tuple(true, dest_base)); - EXPECT_TRUE(orig_msg.Equals(dest)); -} - -// Tests that SetArgPointee<N>(proto2_buffer) sets the v2 -// protobuf variable pointed to by the N-th (0-based) argument to -// proto2_buffer. -TEST(SetArgPointeeTest, SetsTheNthPointeeOfProto2BufferType) { - using testing::internal::FooMessage; - FooMessage* const msg = new FooMessage; - msg->set_int_field(2); - msg->set_string_field("hi"); - FooMessage orig_msg; - orig_msg.CopyFrom(*msg); - - Action<void(bool, FooMessage*)> a = SetArgPointee<1>(*msg); - // SetArgPointee<N>(proto2_buffer) makes a copy of - // proto2_buffer s.t. the action works even when the original - // proto2_buffer has died. We ensure this behavior by deleting msg - // before using the action. - delete msg; - - FooMessage dest; - dest.set_int_field(0); - a.Perform(make_tuple(true, &dest)); - EXPECT_EQ(2, dest.int_field()); - EXPECT_EQ("hi", dest.string_field()); -} - -// Tests that SetArgPointee<N>(proto2_buffer) sets the -// proto2::Message variable pointed to by the N-th (0-based) argument -// to proto2_buffer. -TEST(SetArgPointeeTest, SetsTheNthPointeeOfProto2BufferBaseType) { - using testing::internal::FooMessage; - FooMessage* const msg = new FooMessage; - msg->set_int_field(2); - msg->set_string_field("hi"); - FooMessage orig_msg; - orig_msg.CopyFrom(*msg); - - Action<void(bool, ::proto2::Message*)> a = SetArgPointee<1>(*msg); - // SetArgPointee<N>(proto2_buffer) makes a copy of - // proto2_buffer s.t. the action works even when the original - // proto2_buffer has died. We ensure this behavior by deleting msg - // before using the action. - delete msg; - - FooMessage dest; - dest.set_int_field(0); - ::proto2::Message* const dest_base = &dest; - a.Perform(make_tuple(true, dest_base)); - EXPECT_EQ(2, dest.int_field()); - EXPECT_EQ("hi", dest.string_field()); -} - -#endif // GTEST_HAS_PROTOBUF_ - // Tests that SetArgumentPointee<N>(v) sets the variable pointed to by // the N-th (0-based) argument to v. TEST(SetArgumentPointeeTest, SetsTheNthPointee) { @@ -997,105 +910,6 @@ TEST(SetArgumentPointeeTest, SetsTheNthPointee) { EXPECT_EQ('a', ch); } -#if GTEST_HAS_PROTOBUF_ - -// Tests that SetArgumentPointee<N>(proto_buffer) sets the v1 protobuf -// variable pointed to by the N-th (0-based) argument to proto_buffer. -TEST(SetArgumentPointeeTest, SetsTheNthPointeeOfProtoBufferType) { - TestMessage* const msg = new TestMessage; - msg->set_member("yes"); - TestMessage orig_msg; - orig_msg.CopyFrom(*msg); - - Action<void(bool, TestMessage*)> a = SetArgumentPointee<1>(*msg); - // SetArgumentPointee<N>(proto_buffer) makes a copy of proto_buffer - // s.t. the action works even when the original proto_buffer has - // died. We ensure this behavior by deleting msg before using the - // action. - delete msg; - - TestMessage dest; - EXPECT_FALSE(orig_msg.Equals(dest)); - a.Perform(make_tuple(true, &dest)); - EXPECT_TRUE(orig_msg.Equals(dest)); -} - -// Tests that SetArgumentPointee<N>(proto_buffer) sets the -// ::ProtocolMessage variable pointed to by the N-th (0-based) -// argument to proto_buffer. -TEST(SetArgumentPointeeTest, SetsTheNthPointeeOfProtoBufferBaseType) { - TestMessage* const msg = new TestMessage; - msg->set_member("yes"); - TestMessage orig_msg; - orig_msg.CopyFrom(*msg); - - Action<void(bool, ::ProtocolMessage*)> a = SetArgumentPointee<1>(*msg); - // SetArgumentPointee<N>(proto_buffer) makes a copy of proto_buffer - // s.t. the action works even when the original proto_buffer has - // died. We ensure this behavior by deleting msg before using the - // action. - delete msg; - - TestMessage dest; - ::ProtocolMessage* const dest_base = &dest; - EXPECT_FALSE(orig_msg.Equals(dest)); - a.Perform(make_tuple(true, dest_base)); - EXPECT_TRUE(orig_msg.Equals(dest)); -} - -// Tests that SetArgumentPointee<N>(proto2_buffer) sets the v2 -// protobuf variable pointed to by the N-th (0-based) argument to -// proto2_buffer. -TEST(SetArgumentPointeeTest, SetsTheNthPointeeOfProto2BufferType) { - using testing::internal::FooMessage; - FooMessage* const msg = new FooMessage; - msg->set_int_field(2); - msg->set_string_field("hi"); - FooMessage orig_msg; - orig_msg.CopyFrom(*msg); - - Action<void(bool, FooMessage*)> a = SetArgumentPointee<1>(*msg); - // SetArgumentPointee<N>(proto2_buffer) makes a copy of - // proto2_buffer s.t. the action works even when the original - // proto2_buffer has died. We ensure this behavior by deleting msg - // before using the action. - delete msg; - - FooMessage dest; - dest.set_int_field(0); - a.Perform(make_tuple(true, &dest)); - EXPECT_EQ(2, dest.int_field()); - EXPECT_EQ("hi", dest.string_field()); -} - -// Tests that SetArgumentPointee<N>(proto2_buffer) sets the -// proto2::Message variable pointed to by the N-th (0-based) argument -// to proto2_buffer. -TEST(SetArgumentPointeeTest, SetsTheNthPointeeOfProto2BufferBaseType) { - using testing::internal::FooMessage; - FooMessage* const msg = new FooMessage; - msg->set_int_field(2); - msg->set_string_field("hi"); - FooMessage orig_msg; - orig_msg.CopyFrom(*msg); - - Action<void(bool, ::proto2::Message*)> a = SetArgumentPointee<1>(*msg); - // SetArgumentPointee<N>(proto2_buffer) makes a copy of - // proto2_buffer s.t. the action works even when the original - // proto2_buffer has died. We ensure this behavior by deleting msg - // before using the action. - delete msg; - - FooMessage dest; - dest.set_int_field(0); - ::proto2::Message* const dest_base = &dest; - a.Perform(make_tuple(true, dest_base)); - EXPECT_EQ(2, dest.int_field()); - EXPECT_EQ("hi", dest.string_field()); -} - -#endif // GTEST_HAS_PROTOBUF_ - // Sample functions and functors for testing Invoke() and etc. int Nullary() { return 1; } @@ -1406,6 +1220,153 @@ TEST(MockMethodTest, CanReturnMoveOnlyValue_Invoke) { EXPECT_EQ(7, *vresult[0]); } +TEST(MockMethodTest, CanTakeMoveOnlyValue) { + MockClass mock; + auto make = [](int i) { return std::unique_ptr<int>(new int(i)); }; + + EXPECT_CALL(mock, TakeUnique(_)).WillRepeatedly([](std::unique_ptr<int> i) { + return *i; + }); + // DoAll() does not compile, since it would move from its arguments twice. + // EXPECT_CALL(mock, TakeUnique(_, _)) + // .WillRepeatedly(DoAll(Invoke([](std::unique_ptr<int> j) {}), + // Return(1))); + EXPECT_CALL(mock, TakeUnique(testing::Pointee(7))) + .WillOnce(Return(-7)) + .RetiresOnSaturation(); + EXPECT_CALL(mock, TakeUnique(testing::IsNull())) + .WillOnce(Return(-1)) + .RetiresOnSaturation(); + + EXPECT_EQ(5, mock.TakeUnique(make(5))); + EXPECT_EQ(-7, mock.TakeUnique(make(7))); + EXPECT_EQ(7, mock.TakeUnique(make(7))); + EXPECT_EQ(7, mock.TakeUnique(make(7))); + EXPECT_EQ(-1, mock.TakeUnique({})); + + // Some arguments are moved, some passed by reference. + auto lvalue = make(6); + EXPECT_CALL(mock, TakeUnique(_, _)) + .WillOnce([](const std::unique_ptr<int>& i, std::unique_ptr<int> j) { + return *i * *j; + }); + EXPECT_EQ(42, mock.TakeUnique(lvalue, make(7))); + + // The unique_ptr can be saved by the action. + std::unique_ptr<int> saved; + EXPECT_CALL(mock, TakeUnique(_)).WillOnce([&saved](std::unique_ptr<int> i) { + saved = std::move(i); + return 0; + }); + EXPECT_EQ(0, mock.TakeUnique(make(42))); + EXPECT_EQ(42, *saved); +} + #endif // GTEST_HAS_STD_UNIQUE_PTR_ +#if GTEST_LANG_CXX11 +// Tests for std::function based action. + +int Add(int val, int& ref, int* ptr) { // NOLINT + int result = val + ref + *ptr; + ref = 42; + *ptr = 43; + return result; +} + +int Deref(std::unique_ptr<int> ptr) { return *ptr; } + +struct Double { + template <typename T> + T operator()(T t) { return 2 * t; } +}; + +std::unique_ptr<int> UniqueInt(int i) { + return std::unique_ptr<int>(new int(i)); +} + +TEST(FunctorActionTest, ActionFromFunction) { + Action<int(int, int&, int*)> a = &Add; + int x = 1, y = 2, z = 3; + EXPECT_EQ(6, a.Perform(std::forward_as_tuple(x, y, &z))); + EXPECT_EQ(42, y); + EXPECT_EQ(43, z); + + Action<int(std::unique_ptr<int>)> a1 = &Deref; + EXPECT_EQ(7, a1.Perform(std::make_tuple(UniqueInt(7)))); +} + +TEST(FunctorActionTest, ActionFromLambda) { + Action<int(bool, int)> a1 = [](bool b, int i) { return b ? i : 0; }; + EXPECT_EQ(5, a1.Perform(make_tuple(true, 5))); + EXPECT_EQ(0, a1.Perform(make_tuple(false, 5))); + + std::unique_ptr<int> saved; + Action<void(std::unique_ptr<int>)> a2 = [&saved](std::unique_ptr<int> p) { + saved = std::move(p); + }; + a2.Perform(make_tuple(UniqueInt(5))); + EXPECT_EQ(5, *saved); +} + +TEST(FunctorActionTest, PolymorphicFunctor) { + Action<int(int)> ai = Double(); + EXPECT_EQ(2, ai.Perform(make_tuple(1))); + Action<double(double)> ad = Double(); // Double? Double double! + EXPECT_EQ(3.0, ad.Perform(make_tuple(1.5))); +} + +TEST(FunctorActionTest, TypeConversion) { + // Numeric promotions are allowed. + const Action<bool(int)> a1 = [](int i) { return i > 1; }; + const Action<int(bool)> a2 = Action<int(bool)>(a1); + EXPECT_EQ(1, a1.Perform(make_tuple(42))); + EXPECT_EQ(0, a2.Perform(make_tuple(42))); + + // Implicit constructors are allowed. + const Action<bool(std::string)> s1 = [](std::string s) { return !s.empty(); }; + const Action<int(const char*)> s2 = Action<int(const char*)>(s1); + EXPECT_EQ(0, s2.Perform(make_tuple(""))); + EXPECT_EQ(1, s2.Perform(make_tuple("hello"))); + + // Also between the lambda and the action itself. + const Action<bool(std::string)> x = [](Unused) { return 42; }; + EXPECT_TRUE(x.Perform(make_tuple("hello"))); +} + +TEST(FunctorActionTest, UnusedArguments) { + // Verify that users can ignore uninteresting arguments. + Action<int(int, double y, double z)> a = + [](int i, Unused, Unused) { return 2 * i; }; + tuple<int, double, double> dummy = make_tuple(3, 7.3, 9.44); + EXPECT_EQ(6, a.Perform(dummy)); +} + +// Test that basic built-in actions work with move-only arguments. +// FIXME: Currently, almost all ActionInterface-based actions will not +// work, even if they only try to use other, copyable arguments. Implement them +// if necessary (but note that DoAll cannot work on non-copyable types anyway - +// so maybe it's better to make users use lambdas instead. +TEST(MoveOnlyArgumentsTest, ReturningActions) { + Action<int(std::unique_ptr<int>)> a = Return(1); + EXPECT_EQ(1, a.Perform(make_tuple(nullptr))); + + a = testing::WithoutArgs([]() { return 7; }); + EXPECT_EQ(7, a.Perform(make_tuple(nullptr))); + + Action<void(std::unique_ptr<int>, int*)> a2 = testing::SetArgPointee<1>(3); + int x = 0; + a2.Perform(make_tuple(nullptr, &x)); + EXPECT_EQ(x, 3); +} + +#endif // GTEST_LANG_CXX11 + } // Unnamed namespace + +#ifdef _MSC_VER +#if _MSC_VER == 1900 +# pragma warning(pop) +#endif +#endif + diff --git a/googlemock/test/gmock-cardinalities_test.cc b/googlemock/test/gmock-cardinalities_test.cc index 04c792b5..132591bc 100644 --- a/googlemock/test/gmock-cardinalities_test.cc +++ b/googlemock/test/gmock-cardinalities_test.cc @@ -26,8 +26,7 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // diff --git a/googlemock/test/gmock-generated-actions_test.cc b/googlemock/test/gmock-generated-actions_test.cc index 80bcb31c..a4602806 100644 --- a/googlemock/test/gmock-generated-actions_test.cc +++ b/googlemock/test/gmock-generated-actions_test.cc @@ -26,8 +26,7 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // @@ -374,10 +373,10 @@ class SubstractAction : public ActionInterface<int(int, int)> { // NOLINT }; TEST(WithArgsTest, NonInvokeAction) { - Action<int(const string&, int, int)> a = // NOLINT + Action<int(const std::string&, int, int)> a = // NOLINT WithArgs<2, 1>(MakeAction(new SubstractAction)); - string s("hello"); - EXPECT_EQ(8, a.Perform(tuple<const string&, int, int>(s, 2, 10))); + tuple<std::string, int, int> dummy = make_tuple(std::string("hi"), 2, 10); + EXPECT_EQ(8, a.Perform(dummy)); } // Tests using WithArgs to pass all original arguments in the original order. @@ -754,7 +753,8 @@ TEST(ActionPMacroTest, CanReferenceArgumentAndParameterTypes) { TEST(ActionPMacroTest, WorksInCompatibleMockFunction) { Action<std::string(const std::string& s)> a1 = Plus("tail"); const std::string re = "re"; - EXPECT_EQ("retail", a1.Perform(tuple<const std::string&>(re))); + tuple<const std::string> dummy = make_tuple(re); + EXPECT_EQ("retail", a1.Perform(dummy)); } // Tests that we can use ACTION*() to define actions overloaded on the @@ -796,7 +796,8 @@ TEST(ActionPnMacroTest, WorksFor3Parameters) { Action<std::string(const std::string& s)> a2 = Plus("tail", "-", ">"); const std::string re = "re"; - EXPECT_EQ("retail->", a2.Perform(tuple<const std::string&>(re))); + tuple<const std::string> dummy = make_tuple(re); + EXPECT_EQ("retail->", a2.Perform(dummy)); } ACTION_P4(Plus, p0, p1, p2, p3) { return arg0 + p0 + p1 + p2 + p3; } @@ -1120,7 +1121,7 @@ TEST(ActionTemplateTest, WorksForIntegralTemplateParams) { EXPECT_FALSE(b); // Verifies that resetter is deleted. } -// Tests that ACTION_TEMPLATE works for a template with template parameters. +// Tests that ACTION_TEMPLATES works for template template parameters. ACTION_TEMPLATE(ReturnSmartPointer, HAS_1_TEMPLATE_PARAMS(template <typename Pointee> class, Pointer), diff --git a/googlemock/test/gmock-generated-function-mockers_test.cc b/googlemock/test/gmock-generated-function-mockers_test.cc index 08e5eba1..f16833b2 100644 --- a/googlemock/test/gmock-generated-function-mockers_test.cc +++ b/googlemock/test/gmock-generated-function-mockers_test.cc @@ -26,8 +26,7 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // @@ -620,5 +619,28 @@ TEST(MockFunctionTest, AsStdFunctionReturnsReference) { } #endif // GTEST_HAS_STD_FUNCTION_ +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-internal-utils_test.cc b/googlemock/test/gmock-generated-internal-utils_test.cc index e0a535a3..ae0280fc 100644 --- a/googlemock/test/gmock-generated-internal-utils_test.cc +++ b/googlemock/test/gmock-generated-internal-utils_test.cc @@ -26,8 +26,7 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // @@ -63,10 +62,10 @@ TEST(MatcherTupleTest, ForSize2) { } TEST(MatcherTupleTest, ForSize5) { - CompileAssertTypesEqual<tuple<Matcher<int>, Matcher<char>, Matcher<bool>, - Matcher<double>, Matcher<char*> >, - MatcherTuple<tuple<int, char, bool, double, char*> - >::type>(); + CompileAssertTypesEqual< + tuple<Matcher<int>, Matcher<char>, Matcher<bool>, Matcher<double>, + Matcher<char*> >, + MatcherTuple<tuple<int, char, bool, double, char*> >::type>(); } // Tests the Function template struct. @@ -97,8 +96,9 @@ TEST(FunctionTest, Binary) { CompileAssertTypesEqual<bool, F::Argument1>(); CompileAssertTypesEqual<const long&, F::Argument2>(); // NOLINT CompileAssertTypesEqual<tuple<bool, const long&>, F::ArgumentTuple>(); // NOLINT - CompileAssertTypesEqual<tuple<Matcher<bool>, Matcher<const long&> >, // NOLINT - F::ArgumentMatcherTuple>(); + CompileAssertTypesEqual< + tuple<Matcher<bool>, Matcher<const long&> >, // NOLINT + F::ArgumentMatcherTuple>(); CompileAssertTypesEqual<void(bool, const long&), F::MakeResultVoid>(); // NOLINT CompileAssertTypesEqual<IgnoredValue(bool, const long&), // NOLINT F::MakeResultIgnoredValue>(); @@ -114,9 +114,10 @@ TEST(FunctionTest, LongArgumentList) { CompileAssertTypesEqual<const long&, F::Argument5>(); // NOLINT CompileAssertTypesEqual<tuple<bool, int, char*, int&, const long&>, // NOLINT F::ArgumentTuple>(); - CompileAssertTypesEqual<tuple<Matcher<bool>, Matcher<int>, Matcher<char*>, - Matcher<int&>, Matcher<const long&> >, // NOLINT - F::ArgumentMatcherTuple>(); + CompileAssertTypesEqual< + tuple<Matcher<bool>, Matcher<int>, Matcher<char*>, Matcher<int&>, + Matcher<const long&> >, // NOLINT + F::ArgumentMatcherTuple>(); CompileAssertTypesEqual<void(bool, int, char*, int&, const long&), // NOLINT F::MakeResultVoid>(); CompileAssertTypesEqual< diff --git a/googlemock/test/gmock-generated-matchers_test.cc b/googlemock/test/gmock-generated-matchers_test.cc index 6cba726d..0ebd4701 100644 --- a/googlemock/test/gmock-generated-matchers_test.cc +++ b/googlemock/test/gmock-generated-matchers_test.cc @@ -31,10 +31,19 @@ // // This file tests the built-in matchers generated by a script. +// Silence warning C4244: 'initializing': conversion from 'int' to 'short', +// possible loss of data and C4100, unreferenced local parameter +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4244) +# pragma warning(disable:4100) +#endif + #include "gmock/gmock-generated-matchers.h" #include <list> #include <map> +#include <memory> #include <set> #include <sstream> #include <string> @@ -57,6 +66,8 @@ using testing::get; using testing::make_tuple; using testing::tuple; using testing::_; +using testing::AllOf; +using testing::AnyOf; using testing::Args; using testing::Contains; using testing::ElementsAre; @@ -120,7 +131,7 @@ TEST(ArgsTest, AcceptsOneTemplateArg) { } TEST(ArgsTest, AcceptsTwoTemplateArgs) { - const tuple<short, int, long> t(static_cast<short>(4), 5, 6L); // NOLINT + const tuple<short, int, long> t(4, 5, 6L); // NOLINT EXPECT_THAT(t, (Args<0, 1>(Lt()))); EXPECT_THAT(t, (Args<1, 2>(Lt()))); @@ -128,13 +139,13 @@ TEST(ArgsTest, AcceptsTwoTemplateArgs) { } TEST(ArgsTest, AcceptsRepeatedTemplateArgs) { - const tuple<short, int, long> t(static_cast<short>(4), 5, 6L); // NOLINT + const tuple<short, int, long> t(4, 5, 6L); // NOLINT EXPECT_THAT(t, (Args<0, 0>(Eq()))); EXPECT_THAT(t, Not(Args<1, 1>(Ne()))); } TEST(ArgsTest, AcceptsDecreasingTemplateArgs) { - const tuple<short, int, long> t(static_cast<short>(4), 5, 6L); // NOLINT + const tuple<short, int, long> t(4, 5, 6L); // NOLINT EXPECT_THAT(t, (Args<2, 0>(Gt()))); EXPECT_THAT(t, Not(Args<2, 1>(Lt()))); } @@ -159,7 +170,7 @@ TEST(ArgsTest, AcceptsMoreTemplateArgsThanArityOfOriginalTuple) { } TEST(ArgsTest, CanBeNested) { - const tuple<short, int, long, int> t(static_cast<short>(4), 5, 6L, 6); // NOLINT + const tuple<short, int, long, int> t(4, 5, 6L, 6); // NOLINT EXPECT_THAT(t, (Args<1, 2, 3>(Args<1, 2>(Eq())))); EXPECT_THAT(t, (Args<0, 1, 3>(Args<0, 2>(Lt())))); } @@ -1283,4 +1294,48 @@ TEST(AnyOfTest, DoesNotCallAnyOfUnqualified) { # pragma warning(pop) #endif +#if GTEST_LANG_CXX11 + +TEST(AllOfTest, WorksOnMoveOnlyType) { + std::unique_ptr<int> p(new int(3)); + EXPECT_THAT(p, AllOf(Pointee(Eq(3)), Pointee(Gt(0)), Pointee(Lt(5)))); + EXPECT_THAT(p, Not(AllOf(Pointee(Eq(3)), Pointee(Gt(0)), Pointee(Lt(3))))); +} + +TEST(AnyOfTest, WorksOnMoveOnlyType) { + std::unique_ptr<int> p(new int(3)); + EXPECT_THAT(p, AnyOf(Pointee(Eq(5)), Pointee(Lt(0)), Pointee(Lt(5)))); + EXPECT_THAT(p, Not(AnyOf(Pointee(Eq(5)), Pointee(Lt(0)), Pointee(Gt(5))))); +} + +MATCHER(IsNotNull, "") { + return arg != nullptr; +} + +// Verifies that a matcher defined using MATCHER() can work on +// move-only types. +TEST(MatcherMacroTest, WorksOnMoveOnlyType) { + std::unique_ptr<int> p(new int(3)); + EXPECT_THAT(p, IsNotNull()); + EXPECT_THAT(std::unique_ptr<int>(), Not(IsNotNull())); +} + +MATCHER_P(UniquePointee, pointee, "") { + return *arg == pointee; +} + +// Verifies that a matcher defined using MATCHER_P*() can work on +// move-only types. +TEST(MatcherPMacroTest, WorksOnMoveOnlyType) { + std::unique_ptr<int> p(new int(3)); + EXPECT_THAT(p, UniquePointee(3)); + EXPECT_THAT(p, Not(UniquePointee(2))); +} + +#endif // GTEST_LASNG_CXX11 + } // namespace + +#ifdef _MSC_VER +# pragma warning(pop) +#endif diff --git a/googlemock/test/gmock-internal-utils_test.cc b/googlemock/test/gmock-internal-utils_test.cc index c7893ae2..5f53077c 100644 --- a/googlemock/test/gmock-internal-utils_test.cc +++ b/googlemock/test/gmock-internal-utils_test.cc @@ -26,8 +26,7 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // @@ -44,7 +43,15 @@ #include "gmock/internal/gmock-port.h" #include "gtest/gtest.h" #include "gtest/gtest-spi.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// their code. +#define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ #if GTEST_OS_CYGWIN # include <sys/types.h> // For ssize_t. NOLINT @@ -61,6 +68,26 @@ namespace internal { namespace { +TEST(JoinAsTupleTest, JoinsEmptyTuple) { + EXPECT_EQ("", JoinAsTuple(Strings())); +} + +TEST(JoinAsTupleTest, JoinsOneTuple) { + const char* fields[] = {"1"}; + EXPECT_EQ("1", JoinAsTuple(Strings(fields, fields + 1))); +} + +TEST(JoinAsTupleTest, JoinsTwoTuple) { + const char* fields[] = {"1", "a"}; + EXPECT_EQ("(1, a)", JoinAsTuple(Strings(fields, fields + 2))); +} + +TEST(JoinAsTupleTest, JoinsTenTuple) { + const char* fields[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}; + EXPECT_EQ("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)", + JoinAsTuple(Strings(fields, fields + 10))); +} + TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameContainsNoWord) { EXPECT_EQ("", ConvertIdentifierNameToWords("")); EXPECT_EQ("", ConvertIdentifierNameToWords("_")); diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc index 07e5fa63..d08f08f7 100644 --- a/googlemock/test/gmock-matchers_test.cc +++ b/googlemock/test/gmock-matchers_test.cc @@ -26,8 +26,7 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // @@ -45,6 +44,7 @@ #include <limits> #include <list> #include <map> +#include <memory> #include <set> #include <sstream> #include <string> @@ -58,13 +58,11 @@ # include <forward_list> // NOLINT #endif -// Disable MSVC2015 warning for std::pair: "decorated name length exceeded, name was truncated". -#if defined(_MSC_VER) && (_MSC_VER == 1900) -# pragma warning(disable:4503) +#if GTEST_LANG_CXX11 +# include <type_traits> #endif namespace testing { - namespace gmock_matchers_test { using std::greater; @@ -146,7 +144,6 @@ using testing::internal::ExplainMatchFailureTupleTo; using testing::internal::FloatingEqMatcher; using testing::internal::FormatMatcherDescription; using testing::internal::IsReadableTypeName; -using testing::internal::JoinAsTuple; using testing::internal::linked_ptr; using testing::internal::MatchMatrix; using testing::internal::RE; @@ -201,17 +198,13 @@ std::string OfType(const std::string& type_name) { // Returns the description of the given matcher. template <typename T> std::string Describe(const Matcher<T>& m) { - stringstream ss; - m.DescribeTo(&ss); - return ss.str(); + return DescribeMatcher<T>(m); } // Returns the description of the negation of the given matcher. template <typename T> std::string DescribeNegation(const Matcher<T>& m) { - stringstream ss; - m.DescribeNegationTo(&ss); - return ss.str(); + return DescribeMatcher<T>(m, true); } // Returns the reason why x matches, or doesn't match, m. @@ -222,6 +215,12 @@ std::string Explain(const MatcherType& m, const Value& x) { return listener.str(); } +TEST(MonotonicMatcherTest, IsPrintable) { + stringstream ss; + ss << GreaterThan(5); + EXPECT_EQ("is > 5", ss.str()); +} + TEST(MatchResultListenerTest, StreamingWorks) { StringMatchResultListener listener; listener << "hi" << 5; @@ -333,6 +332,22 @@ TEST(MatcherTest, CanBeImplicitlyConstructedFromNULL) { EXPECT_FALSE(m1.Matches(&n)); } +// Tests that matchers can be constructed from a variable that is not properly +// defined. This should be illegal, but many users rely on this accidentally. +struct Undefined { + virtual ~Undefined() = 0; + static const int kInt = 1; +}; + +TEST(MatcherTest, CanBeConstructedFromUndefinedVariable) { + Matcher<int> m1 = Undefined::kInt; + EXPECT_TRUE(m1.Matches(1)); + EXPECT_FALSE(m1.Matches(2)); +} + +// Test that a matcher parameterized with an abstract class compiles. +TEST(MatcherTest, CanAcceptAbstractClass) { Matcher<const Undefined&> m = _; } + // Tests that matchers are copyable. TEST(MatcherTest, IsCopyable) { // Tests the copy constructor. @@ -366,66 +381,132 @@ TEST(MatcherTest, MatchAndExplain) { } // Tests that a C-string literal can be implicitly converted to a -// Matcher<string> or Matcher<const string&>. +// Matcher<std::string> or Matcher<const std::string&>. TEST(StringMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) { - Matcher<string> m1 = "hi"; + Matcher<std::string> m1 = "hi"; EXPECT_TRUE(m1.Matches("hi")); EXPECT_FALSE(m1.Matches("hello")); - Matcher<const string&> m2 = "hi"; + Matcher<const std::string&> m2 = "hi"; EXPECT_TRUE(m2.Matches("hi")); EXPECT_FALSE(m2.Matches("hello")); } // Tests that a string object can be implicitly converted to a -// Matcher<string> or Matcher<const string&>. +// Matcher<std::string> or Matcher<const std::string&>. TEST(StringMatcherTest, CanBeImplicitlyConstructedFromString) { - Matcher<string> m1 = string("hi"); + Matcher<std::string> m1 = std::string("hi"); EXPECT_TRUE(m1.Matches("hi")); EXPECT_FALSE(m1.Matches("hello")); - Matcher<const string&> m2 = string("hi"); + Matcher<const std::string&> m2 = std::string("hi"); EXPECT_TRUE(m2.Matches("hi")); EXPECT_FALSE(m2.Matches("hello")); } -#if GTEST_HAS_STRING_PIECE_ +#if GTEST_HAS_GLOBAL_STRING +// Tests that a ::string object can be implicitly converted to a +// Matcher<std::string> or Matcher<const std::string&>. +TEST(StringMatcherTest, CanBeImplicitlyConstructedFromGlobalString) { + Matcher<std::string> m1 = ::string("hi"); + EXPECT_TRUE(m1.Matches("hi")); + EXPECT_FALSE(m1.Matches("hello")); + + Matcher<const std::string&> m2 = ::string("hi"); + EXPECT_TRUE(m2.Matches("hi")); + EXPECT_FALSE(m2.Matches("hello")); +} +#endif // GTEST_HAS_GLOBAL_STRING + +#if GTEST_HAS_GLOBAL_STRING // Tests that a C-string literal can be implicitly converted to a -// Matcher<StringPiece> or Matcher<const StringPiece&>. -TEST(StringPieceMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) { - Matcher<StringPiece> m1 = "cats"; +// Matcher<::string> or Matcher<const ::string&>. +TEST(GlobalStringMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) { + Matcher< ::string> m1 = "hi"; + EXPECT_TRUE(m1.Matches("hi")); + EXPECT_FALSE(m1.Matches("hello")); + + Matcher<const ::string&> m2 = "hi"; + EXPECT_TRUE(m2.Matches("hi")); + EXPECT_FALSE(m2.Matches("hello")); +} + +// Tests that a std::string object can be implicitly converted to a +// Matcher<::string> or Matcher<const ::string&>. +TEST(GlobalStringMatcherTest, CanBeImplicitlyConstructedFromString) { + Matcher< ::string> m1 = std::string("hi"); + EXPECT_TRUE(m1.Matches("hi")); + EXPECT_FALSE(m1.Matches("hello")); + + Matcher<const ::string&> m2 = std::string("hi"); + EXPECT_TRUE(m2.Matches("hi")); + EXPECT_FALSE(m2.Matches("hello")); +} + +// Tests that a ::string object can be implicitly converted to a +// Matcher<::string> or Matcher<const ::string&>. +TEST(GlobalStringMatcherTest, CanBeImplicitlyConstructedFromGlobalString) { + Matcher< ::string> m1 = ::string("hi"); + EXPECT_TRUE(m1.Matches("hi")); + EXPECT_FALSE(m1.Matches("hello")); + + Matcher<const ::string&> m2 = ::string("hi"); + EXPECT_TRUE(m2.Matches("hi")); + EXPECT_FALSE(m2.Matches("hello")); +} +#endif // GTEST_HAS_GLOBAL_STRING + +#if GTEST_HAS_ABSL +// Tests that a C-string literal can be implicitly converted to a +// Matcher<absl::string_view> or Matcher<const absl::string_view&>. +TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) { + Matcher<absl::string_view> m1 = "cats"; EXPECT_TRUE(m1.Matches("cats")); EXPECT_FALSE(m1.Matches("dogs")); - Matcher<const StringPiece&> m2 = "cats"; + Matcher<const absl::string_view&> m2 = "cats"; EXPECT_TRUE(m2.Matches("cats")); EXPECT_FALSE(m2.Matches("dogs")); } -// Tests that a string object can be implicitly converted to a -// Matcher<StringPiece> or Matcher<const StringPiece&>. -TEST(StringPieceMatcherTest, CanBeImplicitlyConstructedFromString) { - Matcher<StringPiece> m1 = string("cats"); +// Tests that a std::string object can be implicitly converted to a +// Matcher<absl::string_view> or Matcher<const absl::string_view&>. +TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromString) { + Matcher<absl::string_view> m1 = std::string("cats"); EXPECT_TRUE(m1.Matches("cats")); EXPECT_FALSE(m1.Matches("dogs")); - Matcher<const StringPiece&> m2 = string("cats"); + Matcher<const absl::string_view&> m2 = std::string("cats"); EXPECT_TRUE(m2.Matches("cats")); EXPECT_FALSE(m2.Matches("dogs")); } -// Tests that a StringPiece object can be implicitly converted to a -// Matcher<StringPiece> or Matcher<const StringPiece&>. -TEST(StringPieceMatcherTest, CanBeImplicitlyConstructedFromStringPiece) { - Matcher<StringPiece> m1 = StringPiece("cats"); +#if GTEST_HAS_GLOBAL_STRING +// Tests that a ::string object can be implicitly converted to a +// Matcher<absl::string_view> or Matcher<const absl::string_view&>. +TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromGlobalString) { + Matcher<absl::string_view> m1 = ::string("cats"); EXPECT_TRUE(m1.Matches("cats")); EXPECT_FALSE(m1.Matches("dogs")); - Matcher<const StringPiece&> m2 = StringPiece("cats"); + Matcher<const absl::string_view&> m2 = ::string("cats"); EXPECT_TRUE(m2.Matches("cats")); EXPECT_FALSE(m2.Matches("dogs")); } -#endif // GTEST_HAS_STRING_PIECE_ +#endif // GTEST_HAS_GLOBAL_STRING + +// Tests that a absl::string_view object can be implicitly converted to a +// Matcher<absl::string_view> or Matcher<const absl::string_view&>. +TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromStringView) { + Matcher<absl::string_view> m1 = absl::string_view("cats"); + EXPECT_TRUE(m1.Matches("cats")); + EXPECT_FALSE(m1.Matches("dogs")); + + Matcher<const absl::string_view&> m2 = absl::string_view("cats"); + EXPECT_TRUE(m2.Matches("cats")); + EXPECT_FALSE(m2.Matches("dogs")); +} +#endif // GTEST_HAS_ABSL // Tests that MakeMatcher() constructs a Matcher<T> from a // MatcherInterface* without requiring the user to explicitly @@ -610,11 +691,76 @@ TEST(MatcherCastTest, FromSameType) { EXPECT_FALSE(m2.Matches(1)); } +// Tests that MatcherCast<T>(m) works when m is a value of the same type as the +// value type of the Matcher. +TEST(MatcherCastTest, FromAValue) { + Matcher<int> m = MatcherCast<int>(42); + EXPECT_TRUE(m.Matches(42)); + EXPECT_FALSE(m.Matches(239)); +} + +// Tests that MatcherCast<T>(m) works when m is a value of the type implicitly +// convertible to the value type of the Matcher. +TEST(MatcherCastTest, FromAnImplicitlyConvertibleValue) { + const int kExpected = 'c'; + Matcher<int> m = MatcherCast<int>('c'); + EXPECT_TRUE(m.Matches(kExpected)); + EXPECT_FALSE(m.Matches(kExpected + 1)); +} + +struct NonImplicitlyConstructibleTypeWithOperatorEq { + friend bool operator==( + const NonImplicitlyConstructibleTypeWithOperatorEq& /* ignored */, + int rhs) { + return 42 == rhs; + } + friend bool operator==( + int lhs, + const NonImplicitlyConstructibleTypeWithOperatorEq& /* ignored */) { + return lhs == 42; + } +}; + +// Tests that MatcherCast<T>(m) works when m is a neither a matcher nor +// implicitly convertible to the value type of the Matcher, but the value type +// of the matcher has operator==() overload accepting m. +TEST(MatcherCastTest, NonImplicitlyConstructibleTypeWithOperatorEq) { + Matcher<NonImplicitlyConstructibleTypeWithOperatorEq> m1 = + MatcherCast<NonImplicitlyConstructibleTypeWithOperatorEq>(42); + EXPECT_TRUE(m1.Matches(NonImplicitlyConstructibleTypeWithOperatorEq())); + + Matcher<NonImplicitlyConstructibleTypeWithOperatorEq> m2 = + MatcherCast<NonImplicitlyConstructibleTypeWithOperatorEq>(239); + EXPECT_FALSE(m2.Matches(NonImplicitlyConstructibleTypeWithOperatorEq())); + + // When updating the following lines please also change the comment to + // namespace convertible_from_any. + Matcher<int> m3 = + MatcherCast<int>(NonImplicitlyConstructibleTypeWithOperatorEq()); + EXPECT_TRUE(m3.Matches(42)); + EXPECT_FALSE(m3.Matches(239)); +} + +// ConvertibleFromAny does not work with MSVC. resulting in +// error C2440: 'initializing': cannot convert from 'Eq' to 'M' +// No constructor could take the source type, or constructor overload +// resolution was ambiguous + +#if !defined _MSC_VER + +// The below ConvertibleFromAny struct is implicitly constructible from anything +// and when in the same namespace can interact with other tests. In particular, +// if it is in the same namespace as other tests and one removes +// NonImplicitlyConstructibleTypeWithOperatorEq::operator==(int lhs, ...); +// then the corresponding test still compiles (and it should not!) by implicitly +// converting NonImplicitlyConstructibleTypeWithOperatorEq to ConvertibleFromAny +// in m3.Matcher(). +namespace convertible_from_any { // Implicitly convertible from any type. struct ConvertibleFromAny { ConvertibleFromAny(int a_value) : value(a_value) {} template <typename T> - explicit ConvertibleFromAny(const T& /*a_value*/) : value(-1) { + ConvertibleFromAny(const T& /*a_value*/) : value(-1) { ADD_FAILURE() << "Conversion constructor called"; } int value; @@ -640,6 +786,9 @@ TEST(MatcherCastTest, FromConvertibleFromAny) { EXPECT_TRUE(m.Matches(ConvertibleFromAny(1))); EXPECT_FALSE(m.Matches(ConvertibleFromAny(2))); } +} // namespace convertible_from_any + +#endif // !defined _MSC_VER struct IntReferenceWrapper { IntReferenceWrapper(const int& a_value) : value(&a_value) {} @@ -745,6 +894,9 @@ TEST(SafeMatcherCastTest, FromSameType) { EXPECT_FALSE(m2.Matches(1)); } +#if !defined _MSC_VER + +namespace convertible_from_any { TEST(SafeMatcherCastTest, ConversionConstructorIsUsed) { Matcher<ConvertibleFromAny> m = SafeMatcherCast<ConvertibleFromAny>(1); EXPECT_TRUE(m.Matches(ConvertibleFromAny(1))); @@ -757,6 +909,9 @@ TEST(SafeMatcherCastTest, FromConvertibleFromAny) { EXPECT_TRUE(m.Matches(ConvertibleFromAny(1))); EXPECT_FALSE(m.Matches(ConvertibleFromAny(2))); } +} // namespace convertible_from_any + +#endif // !defined _MSC_VER TEST(SafeMatcherCastTest, ValueIsNotCopied) { int n = 42; @@ -768,7 +923,7 @@ TEST(SafeMatcherCastTest, ValueIsNotCopied) { TEST(ExpectThat, TakesLiterals) { EXPECT_THAT(1, 1); EXPECT_THAT(1.0, 1.0); - EXPECT_THAT(string(), ""); + EXPECT_THAT(std::string(), ""); } TEST(ExpectThat, TakesFunctions) { @@ -868,15 +1023,11 @@ class Unprintable { public: Unprintable() : c_('a') {} + bool operator==(const Unprintable& /* rhs */) const { return true; } private: char c_; }; -inline bool operator==(const Unprintable& /* lhs */, - const Unprintable& /* rhs */) { - return true; -} - TEST(EqTest, CanDescribeSelf) { Matcher<Unprintable> m = Eq(Unprintable()); EXPECT_EQ("is equal to 1-byte object <61>", Describe(m)); @@ -1047,14 +1198,14 @@ TEST(IsNullTest, ReferenceToConstLinkedPtr) { EXPECT_FALSE(m.Matches(non_null_p)); } -#if GTEST_HAS_STD_FUNCTION_ +#if GTEST_LANG_CXX11 TEST(IsNullTest, StdFunction) { const Matcher<std::function<void()>> m = IsNull(); EXPECT_TRUE(m.Matches(std::function<void()>())); EXPECT_FALSE(m.Matches([]{})); } -#endif // GTEST_HAS_STD_FUNCTION_ +#endif // GTEST_LANG_CXX11 // Tests that IsNull() describes itself properly. TEST(IsNullTest, CanDescribeSelf) { @@ -1095,14 +1246,14 @@ TEST(NotNullTest, ReferenceToConstLinkedPtr) { EXPECT_TRUE(m.Matches(non_null_p)); } -#if GTEST_HAS_STD_FUNCTION_ +#if GTEST_LANG_CXX11 TEST(NotNullTest, StdFunction) { const Matcher<std::function<void()>> m = NotNull(); EXPECT_TRUE(m.Matches([]{})); EXPECT_FALSE(m.Matches(std::function<void()>())); } -#endif // GTEST_HAS_STD_FUNCTION_ +#endif // GTEST_LANG_CXX11 // Tests that NotNull() describes itself properly. TEST(NotNullTest, CanDescribeSelf) { @@ -1178,6 +1329,13 @@ TEST(StrEqTest, MatchesEqualString) { Matcher<const std::string&> m2 = StrEq("Hello"); 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())); +#endif // GTEST_HAS_ABSL } TEST(StrEqTest, CanDescribeSelf) { @@ -1203,6 +1361,13 @@ TEST(StrNeTest, MatchesUnequalString) { Matcher<std::string> m2 = StrNe(std::string("Hello")); 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 } TEST(StrNeTest, CanDescribeSelf) { @@ -1211,15 +1376,23 @@ TEST(StrNeTest, CanDescribeSelf) { } TEST(StrCaseEqTest, MatchesEqualStringIgnoringCase) { - Matcher<const char*> m = StrCaseEq(string("Hello")); + Matcher<const char*> m = StrCaseEq(std::string("Hello")); EXPECT_TRUE(m.Matches("Hello")); EXPECT_TRUE(m.Matches("hello")); EXPECT_FALSE(m.Matches("Hi")); EXPECT_FALSE(m.Matches(NULL)); - Matcher<const string&> m2 = StrCaseEq("Hello"); + Matcher<const std::string&> m2 = StrCaseEq("Hello"); 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 } TEST(StrCaseEqTest, MatchesEqualStringWith0IgnoringCase) { @@ -1262,6 +1435,14 @@ TEST(StrCaseNeTest, MatchesUnequalStringIgnoringCase) { Matcher<std::string> m2 = StrCaseNe(std::string("Hello")); 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 } TEST(StrCaseNeTest, CanDescribeSelf) { @@ -1293,6 +1474,25 @@ TEST(HasSubstrTest, WorksForCStrings) { EXPECT_FALSE(m2.Matches(NULL)); } +#if GTEST_HAS_ABSL +// Tests that HasSubstr() works for matching absl::string_view-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<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 absl::string_view&> m3 = HasSubstr(""); + EXPECT_TRUE(m3.Matches(absl::string_view("foo"))); + EXPECT_FALSE(m3.Matches(absl::string_view())); +} +#endif // GTEST_HAS_ABSL + // Tests that HasSubstr(s) describes itself properly. TEST(HasSubstrTest, CanDescribeSelf) { Matcher<std::string> m = HasSubstr("foo\n\""); @@ -1321,6 +1521,35 @@ TEST(KeyTest, MatchesCorrectly) { EXPECT_THAT(p, Not(Key(Lt(25)))); } +#if GTEST_LANG_CXX11 +template <size_t I> +struct Tag {}; + +struct PairWithGet { + int member_1; + string member_2; + using first_type = int; + using second_type = string; + + const int& GetImpl(Tag<0>) const { return member_1; } + const string& GetImpl(Tag<1>) const { return member_2; } +}; +template <size_t I> +auto get(const PairWithGet& value) -> decltype(value.GetImpl(Tag<I>())) { + return value.GetImpl(Tag<I>()); +} +TEST(PairTest, MatchesPairWithGetCorrectly) { + PairWithGet p{25, "foo"}; + EXPECT_THAT(p, Key(25)); + EXPECT_THAT(p, Not(Key(42))); + EXPECT_THAT(p, Key(Ge(20))); + EXPECT_THAT(p, Not(Key(Lt(25)))); + + std::vector<PairWithGet> v = {{11, "Foo"}, {29, "gMockIsBestMock"}}; + EXPECT_THAT(v, Contains(Key(29))); +} +#endif // GTEST_LANG_CXX11 + TEST(KeyTest, SafelyCastsInnerMatcher) { Matcher<int> is_positive = Gt(0); Matcher<int> is_negative = Lt(0); @@ -1424,7 +1653,7 @@ TEST(PairTest, MatchesCorrectly) { EXPECT_THAT(p, Pair(25, "foo")); EXPECT_THAT(p, Pair(Ge(20), HasSubstr("o"))); - // 'first' does not match, but 'second' matches. + // 'first' doesnt' match, but 'second' matches. EXPECT_THAT(p, Not(Pair(42, "foo"))); EXPECT_THAT(p, Not(Pair(Lt(25), "foo"))); @@ -1458,6 +1687,18 @@ TEST(PairTest, InsideContainsUsingMap) { EXPECT_THAT(container, Not(Contains(Pair(3, _)))); } +#if GTEST_LANG_CXX11 +TEST(PairTest, UseGetInsteadOfMembers) { + PairWithGet pair{7, "ABC"}; + EXPECT_THAT(pair, Pair(7, "ABC")); + EXPECT_THAT(pair, Pair(Ge(7), HasSubstr("AB"))); + EXPECT_THAT(pair, Not(Pair(Lt(7), "ABC"))); + + std::vector<PairWithGet> v = {{11, "Foo"}, {29, "gMockIsBestMock"}}; + EXPECT_THAT(v, ElementsAre(Pair(11, string("Foo")), Pair(Ge(10), Not("")))); +} +#endif // GTEST_LANG_CXX11 + // Tests StartsWith(s). TEST(StartsWithTest, MatchesStringWithGivenPrefix) { @@ -1487,12 +1728,30 @@ TEST(EndsWithTest, MatchesStringWithGivenSuffix) { EXPECT_TRUE(m1.Matches("")); EXPECT_FALSE(m1.Matches(NULL)); - const Matcher<const string&> m2 = EndsWith(string("Hi")); + const Matcher<const std::string&> m2 = EndsWith(std::string("Hi")); EXPECT_TRUE(m2.Matches("Hi")); EXPECT_TRUE(m2.Matches("Wow Hi Hi")); EXPECT_TRUE(m2.Matches("Super Hi")); EXPECT_FALSE(m2.Matches("i")); EXPECT_FALSE(m2.Matches("Hi ")); + +#if GTEST_HAS_GLOBAL_STRING + const Matcher<const ::string&> m3 = EndsWith(::string("Hi")); + EXPECT_TRUE(m3.Matches("Hi")); + EXPECT_TRUE(m3.Matches("Wow Hi Hi")); + EXPECT_TRUE(m3.Matches("Super Hi")); + EXPECT_FALSE(m3.Matches("i")); + EXPECT_FALSE(m3.Matches("Hi ")); +#endif // GTEST_HAS_GLOBAL_STRING + +#if GTEST_HAS_ABSL + const Matcher<const absl::string_view&> m4 = EndsWith(""); + EXPECT_TRUE(m4.Matches("Hi")); + EXPECT_TRUE(m4.Matches("")); + // Default-constructed absl::string_view should not match anything, in order + // to distinguish it from an empty string. + EXPECT_FALSE(m4.Matches(absl::string_view())); +#endif // GTEST_HAS_ABSL } TEST(EndsWithTest, CanDescribeSelf) { @@ -1512,6 +1771,18 @@ TEST(MatchesRegexTest, MatchesStringMatchingGivenRegex) { EXPECT_TRUE(m2.Matches("azbz")); 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"))); + // Default-constructed absl::string_view should not match anything, in order + // to distinguish it from an empty string. + EXPECT_FALSE(m3.Matches(absl::string_view())); + const Matcher<const absl::string_view&> m4 = MatchesRegex(""); + EXPECT_FALSE(m4.Matches(absl::string_view())); +#endif // GTEST_HAS_ABSL } TEST(MatchesRegexTest, CanDescribeSelf) { @@ -1520,6 +1791,11 @@ 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.*")); + EXPECT_EQ("matches regular expression \"0.*\"", Describe(m3)); +#endif // GTEST_HAS_ABSL } // Tests ContainsRegex(). @@ -1534,6 +1810,18 @@ TEST(ContainsRegexTest, MatchesStringContainingGivenRegex) { EXPECT_TRUE(m2.Matches("azbz")); 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"))); + // Default-constructed absl::string_view should not match anything, in order + // to distinguish it from an empty string. + EXPECT_FALSE(m3.Matches(absl::string_view())); + const Matcher<const absl::string_view&> m4 = ContainsRegex(""); + EXPECT_FALSE(m4.Matches(absl::string_view())); +#endif // GTEST_HAS_ABSL } TEST(ContainsRegexTest, CanDescribeSelf) { @@ -1542,6 +1830,11 @@ 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.*")); + EXPECT_EQ("contains regular expression \"0.*\"", Describe(m3)); +#endif // GTEST_HAS_ABSL } // Tests for wide strings. @@ -2019,6 +2312,150 @@ TEST(Ne2Test, CanDescribeSelf) { EXPECT_EQ("are an unequal pair", Describe(m)); } +// Tests that FloatEq() matches a 2-tuple where +// FloatEq(first field) matches the second field. +TEST(FloatEq2Test, MatchesEqualArguments) { + typedef ::testing::tuple<float, float> Tpl; + Matcher<const Tpl&> m = FloatEq(); + EXPECT_TRUE(m.Matches(Tpl(1.0f, 1.0f))); + EXPECT_TRUE(m.Matches(Tpl(0.3f, 0.1f + 0.1f + 0.1f))); + EXPECT_FALSE(m.Matches(Tpl(1.1f, 1.0f))); +} + +// Tests that FloatEq() describes itself properly. +TEST(FloatEq2Test, CanDescribeSelf) { + Matcher<const ::testing::tuple<float, float>&> m = FloatEq(); + EXPECT_EQ("are an almost-equal pair", Describe(m)); +} + +// Tests that NanSensitiveFloatEq() matches a 2-tuple where +// NanSensitiveFloatEq(first field) matches the second field. +TEST(NanSensitiveFloatEqTest, MatchesEqualArgumentsWithNaN) { + typedef ::testing::tuple<float, float> Tpl; + Matcher<const Tpl&> m = NanSensitiveFloatEq(); + EXPECT_TRUE(m.Matches(Tpl(1.0f, 1.0f))); + EXPECT_TRUE(m.Matches(Tpl(std::numeric_limits<float>::quiet_NaN(), + std::numeric_limits<float>::quiet_NaN()))); + EXPECT_FALSE(m.Matches(Tpl(1.1f, 1.0f))); + EXPECT_FALSE(m.Matches(Tpl(1.0f, std::numeric_limits<float>::quiet_NaN()))); + EXPECT_FALSE(m.Matches(Tpl(std::numeric_limits<float>::quiet_NaN(), 1.0f))); +} + +// Tests that NanSensitiveFloatEq() describes itself properly. +TEST(NanSensitiveFloatEqTest, CanDescribeSelfWithNaNs) { + Matcher<const ::testing::tuple<float, float>&> m = NanSensitiveFloatEq(); + EXPECT_EQ("are an almost-equal pair", Describe(m)); +} + +// Tests that DoubleEq() matches a 2-tuple where +// DoubleEq(first field) matches the second field. +TEST(DoubleEq2Test, MatchesEqualArguments) { + typedef ::testing::tuple<double, double> Tpl; + Matcher<const Tpl&> m = DoubleEq(); + EXPECT_TRUE(m.Matches(Tpl(1.0, 1.0))); + EXPECT_TRUE(m.Matches(Tpl(0.3, 0.1 + 0.1 + 0.1))); + EXPECT_FALSE(m.Matches(Tpl(1.1, 1.0))); +} + +// Tests that DoubleEq() describes itself properly. +TEST(DoubleEq2Test, CanDescribeSelf) { + Matcher<const ::testing::tuple<double, double>&> m = DoubleEq(); + EXPECT_EQ("are an almost-equal pair", Describe(m)); +} + +// Tests that NanSensitiveDoubleEq() matches a 2-tuple where +// NanSensitiveDoubleEq(first field) matches the second field. +TEST(NanSensitiveDoubleEqTest, MatchesEqualArgumentsWithNaN) { + typedef ::testing::tuple<double, double> Tpl; + Matcher<const Tpl&> m = NanSensitiveDoubleEq(); + EXPECT_TRUE(m.Matches(Tpl(1.0f, 1.0f))); + EXPECT_TRUE(m.Matches(Tpl(std::numeric_limits<double>::quiet_NaN(), + std::numeric_limits<double>::quiet_NaN()))); + EXPECT_FALSE(m.Matches(Tpl(1.1f, 1.0f))); + EXPECT_FALSE(m.Matches(Tpl(1.0f, std::numeric_limits<double>::quiet_NaN()))); + EXPECT_FALSE(m.Matches(Tpl(std::numeric_limits<double>::quiet_NaN(), 1.0f))); +} + +// Tests that DoubleEq() describes itself properly. +TEST(NanSensitiveDoubleEqTest, CanDescribeSelfWithNaNs) { + Matcher<const ::testing::tuple<double, double>&> m = NanSensitiveDoubleEq(); + EXPECT_EQ("are an almost-equal pair", Describe(m)); +} + +// Tests that FloatEq() matches a 2-tuple where +// FloatNear(first field, max_abs_error) matches the second field. +TEST(FloatNear2Test, MatchesEqualArguments) { + typedef ::testing::tuple<float, float> Tpl; + Matcher<const Tpl&> m = FloatNear(0.5f); + EXPECT_TRUE(m.Matches(Tpl(1.0f, 1.0f))); + EXPECT_TRUE(m.Matches(Tpl(1.3f, 1.0f))); + EXPECT_FALSE(m.Matches(Tpl(1.8f, 1.0f))); +} + +// Tests that FloatNear() describes itself properly. +TEST(FloatNear2Test, CanDescribeSelf) { + Matcher<const ::testing::tuple<float, float>&> m = FloatNear(0.5f); + EXPECT_EQ("are an almost-equal pair", Describe(m)); +} + +// Tests that NanSensitiveFloatNear() matches a 2-tuple where +// NanSensitiveFloatNear(first field) matches the second field. +TEST(NanSensitiveFloatNearTest, MatchesNearbyArgumentsWithNaN) { + typedef ::testing::tuple<float, float> Tpl; + Matcher<const Tpl&> m = NanSensitiveFloatNear(0.5f); + EXPECT_TRUE(m.Matches(Tpl(1.0f, 1.0f))); + EXPECT_TRUE(m.Matches(Tpl(1.1f, 1.0f))); + EXPECT_TRUE(m.Matches(Tpl(std::numeric_limits<float>::quiet_NaN(), + std::numeric_limits<float>::quiet_NaN()))); + EXPECT_FALSE(m.Matches(Tpl(1.6f, 1.0f))); + EXPECT_FALSE(m.Matches(Tpl(1.0f, std::numeric_limits<float>::quiet_NaN()))); + EXPECT_FALSE(m.Matches(Tpl(std::numeric_limits<float>::quiet_NaN(), 1.0f))); +} + +// Tests that NanSensitiveFloatNear() describes itself properly. +TEST(NanSensitiveFloatNearTest, CanDescribeSelfWithNaNs) { + Matcher<const ::testing::tuple<float, float>&> m = + NanSensitiveFloatNear(0.5f); + EXPECT_EQ("are an almost-equal pair", Describe(m)); +} + +// Tests that FloatEq() matches a 2-tuple where +// DoubleNear(first field, max_abs_error) matches the second field. +TEST(DoubleNear2Test, MatchesEqualArguments) { + typedef ::testing::tuple<double, double> Tpl; + Matcher<const Tpl&> m = DoubleNear(0.5); + EXPECT_TRUE(m.Matches(Tpl(1.0, 1.0))); + EXPECT_TRUE(m.Matches(Tpl(1.3, 1.0))); + EXPECT_FALSE(m.Matches(Tpl(1.8, 1.0))); +} + +// Tests that DoubleNear() describes itself properly. +TEST(DoubleNear2Test, CanDescribeSelf) { + Matcher<const ::testing::tuple<double, double>&> m = DoubleNear(0.5); + EXPECT_EQ("are an almost-equal pair", Describe(m)); +} + +// Tests that NanSensitiveDoubleNear() matches a 2-tuple where +// NanSensitiveDoubleNear(first field) matches the second field. +TEST(NanSensitiveDoubleNearTest, MatchesNearbyArgumentsWithNaN) { + typedef ::testing::tuple<double, double> Tpl; + Matcher<const Tpl&> m = NanSensitiveDoubleNear(0.5f); + EXPECT_TRUE(m.Matches(Tpl(1.0f, 1.0f))); + EXPECT_TRUE(m.Matches(Tpl(1.1f, 1.0f))); + EXPECT_TRUE(m.Matches(Tpl(std::numeric_limits<double>::quiet_NaN(), + std::numeric_limits<double>::quiet_NaN()))); + EXPECT_FALSE(m.Matches(Tpl(1.6f, 1.0f))); + EXPECT_FALSE(m.Matches(Tpl(1.0f, std::numeric_limits<double>::quiet_NaN()))); + EXPECT_FALSE(m.Matches(Tpl(std::numeric_limits<double>::quiet_NaN(), 1.0f))); +} + +// Tests that NanSensitiveDoubleNear() describes itself properly. +TEST(NanSensitiveDoubleNearTest, CanDescribeSelfWithNaNs) { + Matcher<const ::testing::tuple<double, double>&> m = + NanSensitiveDoubleNear(0.5f); + EXPECT_EQ("are an almost-equal pair", Describe(m)); +} + // Tests that Not(m) matches any value that doesn't match m. TEST(NotTest, NegatesMatcher) { Matcher<int> m; @@ -2107,7 +2544,7 @@ TEST(AllOfTest, VariadicMatchesWhenAllMatch) { ::testing::AllOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); Matcher<int> m = AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5), Ne(6), Ne(7), Ne(8), Ne(9), Ne(10), Ne(11)); - EXPECT_THAT(Describe(m), EndsWith("and (isn't equal to 11))))))))))")); + EXPECT_THAT(Describe(m), EndsWith("and (isn't equal to 11)")); AllOfMatches(11, m); AllOfMatches(50, AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5), Ne(6), Ne(7), Ne(8), Ne(9), Ne(10), Ne(11), Ne(12), Ne(13), Ne(14), Ne(15), @@ -2242,7 +2679,7 @@ TEST(AllOfTest, ExplainsResult) { } // Helper to allow easy testing of AnyOf matchers with num parameters. -void AnyOfMatches(int num, const Matcher<int>& m) { +static void AnyOfMatches(int num, const Matcher<int>& m) { SCOPED_TRACE(Describe(m)); EXPECT_FALSE(m.Matches(0)); for (int i = 1; i <= num; ++i) { @@ -2251,6 +2688,18 @@ void AnyOfMatches(int num, const Matcher<int>& m) { EXPECT_FALSE(m.Matches(num + 1)); } +#if GTEST_LANG_CXX11 +static void AnyOfStringMatches(int num, const Matcher<std::string>& m) { + SCOPED_TRACE(Describe(m)); + EXPECT_FALSE(m.Matches(std::to_string(0))); + + for (int i = 1; i <= num; ++i) { + EXPECT_TRUE(m.Matches(std::to_string(i))); + } + EXPECT_FALSE(m.Matches(std::to_string(num + 1))); +} +#endif + // Tests that AnyOf(m1, ..., mn) matches any value that matches at // least one of the given matchers. TEST(AnyOfTest, MatchesWhenAnyMatches) { @@ -2301,13 +2750,46 @@ TEST(AnyOfTest, VariadicMatchesWhenAnyMatches) { // on ADL. Matcher<int> m = ::testing::AnyOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); - EXPECT_THAT(Describe(m), EndsWith("or (is equal to 11))))))))))")); + EXPECT_THAT(Describe(m), EndsWith("or (is equal to 11)")); AnyOfMatches(11, m); AnyOfMatches(50, AnyOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50)); + AnyOfStringMatches( + 50, AnyOf("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", + "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", + "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", + "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", + "43", "44", "45", "46", "47", "48", "49", "50")); +} + +// Tests the variadic version of the ElementsAreMatcher +TEST(ElementsAreTest, HugeMatcher) { + vector<int> test_vector{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + + EXPECT_THAT(test_vector, + ElementsAre(Eq(1), Eq(2), Lt(13), Eq(4), Eq(5), Eq(6), Eq(7), + Eq(8), Eq(9), Eq(10), Gt(1), Eq(12))); +} + +// Tests the variadic version of the UnorderedElementsAreMatcher +TEST(ElementsAreTest, HugeMatcherStr) { + vector<string> test_vector{ + "literal_string", "", "", "", "", "", "", "", "", "", "", ""}; + + EXPECT_THAT(test_vector, UnorderedElementsAre("literal_string", _, _, _, _, _, + _, _, _, _, _, _)); +} + +// Tests the variadic version of the UnorderedElementsAreMatcher +TEST(ElementsAreTest, HugeMatcherUnordered) { + vector<int> test_vector{2, 1, 8, 5, 4, 6, 7, 3, 9, 12, 11, 10}; + + EXPECT_THAT(test_vector, UnorderedElementsAre( + Eq(2), Eq(1), Gt(7), Eq(5), Eq(4), Eq(6), Eq(7), + Eq(3), Eq(9), Eq(12), Eq(11), Ne(122))); } #endif // GTEST_LANG_CXX11 @@ -2584,6 +3066,22 @@ TEST(ExplainMatchResultTest, WorksInsideMATCHER) { EXPECT_THAT(0, Really(Eq(0))); } +TEST(DescribeMatcherTest, WorksWithValue) { + EXPECT_EQ("is equal to 42", DescribeMatcher<int>(42)); + EXPECT_EQ("isn't equal to 42", DescribeMatcher<int>(42, true)); +} + +TEST(DescribeMatcherTest, WorksWithMonomorphicMatcher) { + const Matcher<int> monomorphic = Le(0); + EXPECT_EQ("is <= 0", DescribeMatcher<int>(monomorphic)); + EXPECT_EQ("isn't <= 0", DescribeMatcher<int>(monomorphic, true)); +} + +TEST(DescribeMatcherTest, WorksWithPolymorphicMatcher) { + EXPECT_EQ("is even", DescribeMatcher<int>(PolymorphicIsEven())); + EXPECT_EQ("is odd", DescribeMatcher<int>(PolymorphicIsEven(), true)); +} + TEST(AllArgsTest, WorksForTuple) { EXPECT_THAT(make_tuple(1, 2L), AllArgs(Lt())); EXPECT_THAT(make_tuple(2L, 1), Not(AllArgs(Lt()))); @@ -2618,6 +3116,44 @@ TEST(AllArgsTest, WorksInWithClause) { EXPECT_EQ(2, helper.Helper('a', 1)); } +class OptionalMatchersHelper { + public: + OptionalMatchersHelper() {} + + MOCK_METHOD0(NoArgs, int()); + + MOCK_METHOD1(OneArg, int(int y)); + + MOCK_METHOD2(TwoArgs, int(char x, int y)); + + MOCK_METHOD1(Overloaded, int(char x)); + MOCK_METHOD2(Overloaded, int(char x, int y)); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(OptionalMatchersHelper); +}; + +TEST(AllArgsTest, WorksWithoutMatchers) { + OptionalMatchersHelper helper; + + ON_CALL(helper, NoArgs).WillByDefault(Return(10)); + ON_CALL(helper, OneArg).WillByDefault(Return(20)); + ON_CALL(helper, TwoArgs).WillByDefault(Return(30)); + + EXPECT_EQ(10, helper.NoArgs()); + EXPECT_EQ(20, helper.OneArg(1)); + EXPECT_EQ(30, helper.TwoArgs('\1', 2)); + + EXPECT_CALL(helper, NoArgs).Times(1); + EXPECT_CALL(helper, OneArg).WillOnce(Return(100)); + EXPECT_CALL(helper, OneArg(17)).WillOnce(Return(200)); + EXPECT_CALL(helper, TwoArgs).Times(0); + + EXPECT_EQ(10, helper.NoArgs()); + EXPECT_EQ(100, helper.OneArg(1)); + EXPECT_EQ(200, helper.OneArg(17)); +} + // Tests that ASSERT_THAT() and EXPECT_THAT() work when the value // matches the matcher. TEST(MatcherAssertionTest, WorksWhenMatcherIsSatisfied) { @@ -2713,18 +3249,22 @@ class FloatingPointTest : public testing::Test { zero_bits_(Floating(0).bits()), one_bits_(Floating(1).bits()), infinity_bits_(Floating(Floating::Infinity()).bits()), - close_to_positive_zero_(AsBits(zero_bits_ + max_ulps_/2)), - close_to_negative_zero_(AsBits(zero_bits_ + max_ulps_ - max_ulps_/2)), - further_from_negative_zero_(-AsBits( + close_to_positive_zero_( + Floating::ReinterpretBits(zero_bits_ + max_ulps_/2)), + close_to_negative_zero_( + -Floating::ReinterpretBits(zero_bits_ + max_ulps_ - max_ulps_/2)), + further_from_negative_zero_(-Floating::ReinterpretBits( zero_bits_ + max_ulps_ + 1 - max_ulps_/2)), - close_to_one_(AsBits(one_bits_ + max_ulps_)), - further_from_one_(AsBits(one_bits_ + max_ulps_ + 1)), + close_to_one_(Floating::ReinterpretBits(one_bits_ + max_ulps_)), + further_from_one_(Floating::ReinterpretBits(one_bits_ + max_ulps_ + 1)), infinity_(Floating::Infinity()), - close_to_infinity_(AsBits(infinity_bits_ - max_ulps_)), - further_from_infinity_(AsBits(infinity_bits_ - max_ulps_ - 1)), + close_to_infinity_( + Floating::ReinterpretBits(infinity_bits_ - max_ulps_)), + further_from_infinity_( + Floating::ReinterpretBits(infinity_bits_ - max_ulps_ - 1)), max_(Floating::Max()), - nan1_(AsBits(Floating::kExponentBitMask | 1)), - nan2_(AsBits(Floating::kExponentBitMask | 200)) { + nan1_(Floating::ReinterpretBits(Floating::kExponentBitMask | 1)), + nan2_(Floating::ReinterpretBits(Floating::kExponentBitMask | 200)) { } void TestSize() { @@ -2779,7 +3319,7 @@ class FloatingPointTest : public testing::Test { // Pre-calculated numbers to be used by the tests. - const size_t max_ulps_; + const Bits max_ulps_; const Bits zero_bits_; // The bits that represent 0.0. const Bits one_bits_; // The bits that represent 1.0. @@ -2805,12 +3345,6 @@ class FloatingPointTest : public testing::Test { // Some NaNs. const RawType nan1_; const RawType nan2_; - - private: - template <typename T> - static RawType AsBits(T value) { - return Floating::ReinterpretBits(static_cast<Bits>(value)); - } }; // Tests floating-point matchers with fixed epsilons. @@ -3188,7 +3722,6 @@ MATCHER_P(FieldIIs, inner_matcher, "") { } #if GTEST_HAS_RTTI - TEST(WhenDynamicCastToTest, SameType) { Derived derived; derived.i = 4; @@ -3246,7 +3779,7 @@ TEST(WhenDynamicCastToTest, AmbiguousCast) { TEST(WhenDynamicCastToTest, Describe) { Matcher<Base*> matcher = WhenDynamicCastTo<Derived*>(Pointee(_)); - const string prefix = + const std::string prefix = "when dynamic_cast to " + internal::GetTypeName<Derived*>() + ", "; EXPECT_EQ(prefix + "points to a value that is anything", Describe(matcher)); EXPECT_EQ(prefix + "does not point to a value that is anything", @@ -3280,7 +3813,6 @@ TEST(WhenDynamicCastToTest, BadReference) { Base& as_base_ref = derived; EXPECT_THAT(as_base_ref, Not(WhenDynamicCastTo<const OtherDerived&>(_))); } - #endif // GTEST_HAS_RTTI // Minimal const-propagating pointer. @@ -3402,11 +3934,14 @@ struct DerivedStruct : public AStruct { // Tests that Field(&Foo::field, ...) works when field is non-const. TEST(FieldTest, WorksForNonConstField) { Matcher<AStruct> m = Field(&AStruct::x, Ge(0)); + Matcher<AStruct> m_with_name = Field("x", &AStruct::x, Ge(0)); AStruct a; EXPECT_TRUE(m.Matches(a)); + EXPECT_TRUE(m_with_name.Matches(a)); a.x = -1; EXPECT_FALSE(m.Matches(a)); + EXPECT_FALSE(m_with_name.Matches(a)); } // Tests that Field(&Foo::field, ...) works when field is const. @@ -3414,9 +3949,13 @@ TEST(FieldTest, WorksForConstField) { AStruct a; Matcher<AStruct> m = Field(&AStruct::y, Ge(0.0)); + Matcher<AStruct> m_with_name = Field("y", &AStruct::y, Ge(0.0)); EXPECT_TRUE(m.Matches(a)); + EXPECT_TRUE(m_with_name.Matches(a)); m = Field(&AStruct::y, Le(0.0)); + m_with_name = Field("y", &AStruct::y, Le(0.0)); EXPECT_FALSE(m.Matches(a)); + EXPECT_FALSE(m_with_name.Matches(a)); } // Tests that Field(&Foo::field, ...) works when field is not copyable. @@ -3490,6 +4029,14 @@ TEST(FieldTest, CanDescribeSelf) { EXPECT_EQ("is an object whose given field isn't >= 0", DescribeNegation(m)); } +TEST(FieldTest, CanDescribeSelfWithFieldName) { + Matcher<const AStruct&> m = Field("field_name", &AStruct::x, Ge(0)); + + EXPECT_EQ("is an object whose field `field_name` is >= 0", Describe(m)); + EXPECT_EQ("is an object whose field `field_name` isn't >= 0", + DescribeNegation(m)); +} + // Tests that Field() can explain the match result. TEST(FieldTest, CanExplainMatchResult) { Matcher<const AStruct&> m = Field(&AStruct::x, Ge(0)); @@ -3504,6 +4051,19 @@ TEST(FieldTest, CanExplainMatchResult) { Explain(m, a)); } +TEST(FieldTest, CanExplainMatchResultWithFieldName) { + Matcher<const AStruct&> m = Field("field_name", &AStruct::x, Ge(0)); + + AStruct a; + a.x = 1; + EXPECT_EQ("whose field `field_name` is 1" + OfType("int"), Explain(m, a)); + + m = Field("field_name", &AStruct::x, GreaterThan(0)); + EXPECT_EQ("whose field `field_name` is 1" + OfType("int") + + ", which is 1 more than 0", + Explain(m, a)); +} + // Tests that Field() works when the argument is a pointer to const. TEST(FieldForPointerTest, WorksForPointerToConst) { Matcher<const AStruct*> m = Field(&AStruct::x, Ge(0)); @@ -3561,6 +4121,14 @@ TEST(FieldForPointerTest, CanDescribeSelf) { EXPECT_EQ("is an object whose given field isn't >= 0", DescribeNegation(m)); } +TEST(FieldForPointerTest, CanDescribeSelfWithFieldName) { + Matcher<const AStruct*> m = Field("field_name", &AStruct::x, Ge(0)); + + EXPECT_EQ("is an object whose field `field_name` is >= 0", Describe(m)); + EXPECT_EQ("is an object whose field `field_name` isn't >= 0", + DescribeNegation(m)); +} + // Tests that Field() can explain the result of matching a pointer. TEST(FieldForPointerTest, CanExplainMatchResult) { Matcher<const AStruct*> m = Field(&AStruct::x, Ge(0)); @@ -3576,6 +4144,22 @@ TEST(FieldForPointerTest, CanExplainMatchResult) { ", which is 1 more than 0", Explain(m, &a)); } +TEST(FieldForPointerTest, CanExplainMatchResultWithFieldName) { + Matcher<const AStruct*> m = Field("field_name", &AStruct::x, Ge(0)); + + AStruct a; + a.x = 1; + EXPECT_EQ("", Explain(m, static_cast<const AStruct*>(NULL))); + EXPECT_EQ( + "which points to an object whose field `field_name` is 1" + OfType("int"), + Explain(m, &a)); + + m = Field("field_name", &AStruct::x, GreaterThan(0)); + EXPECT_EQ("which points to an object whose field `field_name` is 1" + + OfType("int") + ", which is 1 more than 0", + Explain(m, &a)); +} + // A user-defined class for testing Property(). class AClass { public: @@ -3619,26 +4203,33 @@ class DerivedClass : public AClass { // returns a non-reference. TEST(PropertyTest, WorksForNonReferenceProperty) { Matcher<const AClass&> m = Property(&AClass::n, Ge(0)); + Matcher<const AClass&> m_with_name = Property("n", &AClass::n, Ge(0)); AClass a; a.set_n(1); EXPECT_TRUE(m.Matches(a)); + EXPECT_TRUE(m_with_name.Matches(a)); a.set_n(-1); EXPECT_FALSE(m.Matches(a)); + EXPECT_FALSE(m_with_name.Matches(a)); } // Tests that Property(&Foo::property, ...) works when property() // returns a reference to const. TEST(PropertyTest, WorksForReferenceToConstProperty) { Matcher<const AClass&> m = Property(&AClass::s, StartsWith("hi")); + Matcher<const AClass&> m_with_name = + Property("s", &AClass::s, StartsWith("hi")); AClass a; a.set_s("hill"); EXPECT_TRUE(m.Matches(a)); + EXPECT_TRUE(m_with_name.Matches(a)); a.set_s("hole"); EXPECT_FALSE(m.Matches(a)); + EXPECT_FALSE(m_with_name.Matches(a)); } #if GTEST_LANG_CXX11 @@ -3646,13 +4237,17 @@ TEST(PropertyTest, WorksForReferenceToConstProperty) { // ref-qualified. TEST(PropertyTest, WorksForRefQualifiedProperty) { Matcher<const AClass&> m = Property(&AClass::s_ref, StartsWith("hi")); + Matcher<const AClass&> m_with_name = + Property("s", &AClass::s_ref, StartsWith("hi")); AClass a; a.set_s("hill"); EXPECT_TRUE(m.Matches(a)); + EXPECT_TRUE(m_with_name.Matches(a)); a.set_s("hole"); EXPECT_FALSE(m.Matches(a)); + EXPECT_FALSE(m_with_name.Matches(a)); } #endif @@ -3704,10 +4299,15 @@ TEST(PropertyTest, WorksForCompatibleMatcherType) { Matcher<const AClass&> m = Property(&AClass::n, Matcher<signed char>(Ge(0))); + Matcher<const AClass&> m_with_name = + Property("n", &AClass::n, Matcher<signed char>(Ge(0))); + AClass a; EXPECT_TRUE(m.Matches(a)); + EXPECT_TRUE(m_with_name.Matches(a)); a.set_n(-1); EXPECT_FALSE(m.Matches(a)); + EXPECT_FALSE(m_with_name.Matches(a)); } // Tests that Property() can describe itself. @@ -3719,6 +4319,14 @@ TEST(PropertyTest, CanDescribeSelf) { DescribeNegation(m)); } +TEST(PropertyTest, CanDescribeSelfWithPropertyName) { + Matcher<const AClass&> m = Property("fancy_name", &AClass::n, Ge(0)); + + EXPECT_EQ("is an object whose property `fancy_name` is >= 0", Describe(m)); + EXPECT_EQ("is an object whose property `fancy_name` isn't >= 0", + DescribeNegation(m)); +} + // Tests that Property() can explain the match result. TEST(PropertyTest, CanExplainMatchResult) { Matcher<const AClass&> m = Property(&AClass::n, Ge(0)); @@ -3733,6 +4341,19 @@ TEST(PropertyTest, CanExplainMatchResult) { Explain(m, a)); } +TEST(PropertyTest, CanExplainMatchResultWithPropertyName) { + Matcher<const AClass&> m = Property("fancy_name", &AClass::n, Ge(0)); + + AClass a; + a.set_n(1); + EXPECT_EQ("whose property `fancy_name` is 1" + OfType("int"), Explain(m, a)); + + m = Property("fancy_name", &AClass::n, GreaterThan(0)); + EXPECT_EQ("whose property `fancy_name` is 1" + OfType("int") + + ", which is 1 more than 0", + Explain(m, a)); +} + // Tests that Property() works when the argument is a pointer to const. TEST(PropertyForPointerTest, WorksForPointerToConst) { Matcher<const AClass*> m = Property(&AClass::n, Ge(0)); @@ -3800,6 +4421,14 @@ TEST(PropertyForPointerTest, CanDescribeSelf) { DescribeNegation(m)); } +TEST(PropertyForPointerTest, CanDescribeSelfWithPropertyDescription) { + Matcher<const AClass*> m = Property("fancy_name", &AClass::n, Ge(0)); + + EXPECT_EQ("is an object whose property `fancy_name` is >= 0", Describe(m)); + EXPECT_EQ("is an object whose property `fancy_name` isn't >= 0", + DescribeNegation(m)); +} + // Tests that Property() can explain the result of matching a pointer. TEST(PropertyForPointerTest, CanExplainMatchResult) { Matcher<const AClass*> m = Property(&AClass::n, Ge(0)); @@ -3817,6 +4446,22 @@ TEST(PropertyForPointerTest, CanExplainMatchResult) { Explain(m, &a)); } +TEST(PropertyForPointerTest, CanExplainMatchResultWithPropertyName) { + Matcher<const AClass*> m = Property("fancy_name", &AClass::n, Ge(0)); + + AClass a; + a.set_n(1); + EXPECT_EQ("", Explain(m, static_cast<const AClass*>(NULL))); + EXPECT_EQ("which points to an object whose property `fancy_name` is 1" + + OfType("int"), + Explain(m, &a)); + + m = Property("fancy_name", &AClass::n, GreaterThan(0)); + EXPECT_EQ("which points to an object whose property `fancy_name` is 1" + + OfType("int") + ", which is 1 more than 0", + Explain(m, &a)); +} + // Tests ResultOf. // Tests that ResultOf(f, ...) compiles and works as expected when f is a @@ -3932,11 +4577,8 @@ TEST(ResultOfTest, WorksForFunctionReferences) { // Tests that ResultOf(f, ...) compiles and works as expected when f is a // function object. -struct Functor { - typedef std::string result_type; - typedef int argument_type; - - std::string operator()(int input) const { +struct Functor : public ::std::unary_function<int, std::string> { + result_type operator()(argument_type input) const { return IntToStringFunction(input); } }; @@ -3949,7 +4591,7 @@ TEST(ResultOfTest, WorksForFunctors) { } // Tests that ResultOf(f, ...) compiles and works as expected when f is a -// functor with more then one operator() defined. ResultOf() must work +// functor with more than one operator() defined. ResultOf() must work // for each defined operator(). struct PolymorphicFunctor { typedef int result_type; @@ -4130,6 +4772,44 @@ TEST(IsEmptyTest, ExplainsResult) { EXPECT_EQ("whose size is 1", Explain(m, container)); } +TEST(IsTrueTest, IsTrueIsFalse) { + EXPECT_THAT(true, IsTrue()); + EXPECT_THAT(false, IsFalse()); + EXPECT_THAT(true, Not(IsFalse())); + EXPECT_THAT(false, Not(IsTrue())); + EXPECT_THAT(0, Not(IsTrue())); + EXPECT_THAT(0, IsFalse()); + EXPECT_THAT(NULL, Not(IsTrue())); + EXPECT_THAT(NULL, IsFalse()); + EXPECT_THAT(-1, IsTrue()); + EXPECT_THAT(-1, Not(IsFalse())); + EXPECT_THAT(1, IsTrue()); + EXPECT_THAT(1, Not(IsFalse())); + EXPECT_THAT(2, IsTrue()); + EXPECT_THAT(2, Not(IsFalse())); + int a = 42; + EXPECT_THAT(a, IsTrue()); + EXPECT_THAT(a, Not(IsFalse())); + EXPECT_THAT(&a, IsTrue()); + EXPECT_THAT(&a, Not(IsFalse())); + EXPECT_THAT(false, Not(IsTrue())); + EXPECT_THAT(true, Not(IsFalse())); +#if GTEST_LANG_CXX11 + EXPECT_THAT(std::true_type(), IsTrue()); + EXPECT_THAT(std::true_type(), Not(IsFalse())); + EXPECT_THAT(std::false_type(), IsFalse()); + EXPECT_THAT(std::false_type(), Not(IsTrue())); + EXPECT_THAT(nullptr, Not(IsTrue())); + EXPECT_THAT(nullptr, IsFalse()); + std::unique_ptr<int> null_unique; + std::unique_ptr<int> nonnull_unique(new int(0)); + EXPECT_THAT(null_unique, Not(IsTrue())); + EXPECT_THAT(null_unique, IsFalse()); + EXPECT_THAT(nonnull_unique, IsTrue()); + EXPECT_THAT(nonnull_unique, Not(IsFalse())); +#endif // GTEST_LANG_CXX11 +} + TEST(SizeIsTest, ImplementsSizeIs) { vector<int> container; EXPECT_THAT(container, SizeIs(0)); @@ -4684,6 +5364,250 @@ TEST(WhenSortedTest, WorksForVectorConstRefMatcherOnStreamlike) { EXPECT_THAT(s, Not(WhenSorted(ElementsAre(2, 1, 4, 5, 3)))); } +TEST(IsSupersetOfTest, WorksForNativeArray) { + const int subset[] = {1, 4}; + const int superset[] = {1, 2, 4}; + const int disjoint[] = {1, 0, 3}; + EXPECT_THAT(subset, IsSupersetOf(subset)); + EXPECT_THAT(subset, Not(IsSupersetOf(superset))); + EXPECT_THAT(superset, IsSupersetOf(subset)); + EXPECT_THAT(subset, Not(IsSupersetOf(disjoint))); + EXPECT_THAT(disjoint, Not(IsSupersetOf(subset))); +} + +TEST(IsSupersetOfTest, WorksWithDuplicates) { + const int not_enough[] = {1, 2}; + const int enough[] = {1, 1, 2}; + const int expected[] = {1, 1}; + EXPECT_THAT(not_enough, Not(IsSupersetOf(expected))); + EXPECT_THAT(enough, IsSupersetOf(expected)); +} + +TEST(IsSupersetOfTest, WorksForEmpty) { + vector<int> numbers; + vector<int> expected; + EXPECT_THAT(numbers, IsSupersetOf(expected)); + expected.push_back(1); + EXPECT_THAT(numbers, Not(IsSupersetOf(expected))); + expected.clear(); + numbers.push_back(1); + numbers.push_back(2); + EXPECT_THAT(numbers, IsSupersetOf(expected)); + expected.push_back(1); + EXPECT_THAT(numbers, IsSupersetOf(expected)); + expected.push_back(2); + EXPECT_THAT(numbers, IsSupersetOf(expected)); + expected.push_back(3); + EXPECT_THAT(numbers, Not(IsSupersetOf(expected))); +} + +TEST(IsSupersetOfTest, WorksForStreamlike) { + const int a[5] = {1, 2, 3, 4, 5}; + Streamlike<int> s(a, a + GTEST_ARRAY_SIZE_(a)); + + vector<int> expected; + expected.push_back(1); + expected.push_back(2); + expected.push_back(5); + EXPECT_THAT(s, IsSupersetOf(expected)); + + expected.push_back(0); + EXPECT_THAT(s, Not(IsSupersetOf(expected))); +} + +TEST(IsSupersetOfTest, TakesStlContainer) { + const int actual[] = {3, 1, 2}; + + ::std::list<int> expected; + expected.push_back(1); + expected.push_back(3); + EXPECT_THAT(actual, IsSupersetOf(expected)); + + expected.push_back(4); + EXPECT_THAT(actual, Not(IsSupersetOf(expected))); +} + +TEST(IsSupersetOfTest, Describe) { + typedef std::vector<int> IntVec; + IntVec expected; + expected.push_back(111); + expected.push_back(222); + expected.push_back(333); + EXPECT_THAT( + Describe<IntVec>(IsSupersetOf(expected)), + Eq("a surjection from elements to requirements exists such that:\n" + " - an element is equal to 111\n" + " - an element is equal to 222\n" + " - an element is equal to 333")); +} + +TEST(IsSupersetOfTest, DescribeNegation) { + typedef std::vector<int> IntVec; + IntVec expected; + expected.push_back(111); + expected.push_back(222); + expected.push_back(333); + EXPECT_THAT( + DescribeNegation<IntVec>(IsSupersetOf(expected)), + Eq("no surjection from elements to requirements exists such that:\n" + " - an element is equal to 111\n" + " - an element is equal to 222\n" + " - an element is equal to 333")); +} + +TEST(IsSupersetOfTest, MatchAndExplain) { + std::vector<int> v; + v.push_back(2); + v.push_back(3); + std::vector<int> expected; + expected.push_back(1); + expected.push_back(2); + StringMatchResultListener listener; + ASSERT_FALSE(ExplainMatchResult(IsSupersetOf(expected), v, &listener)) + << listener.str(); + EXPECT_THAT(listener.str(), + Eq("where the following matchers don't match any elements:\n" + "matcher #0: is equal to 1")); + + v.push_back(1); + listener.Clear(); + ASSERT_TRUE(ExplainMatchResult(IsSupersetOf(expected), v, &listener)) + << listener.str(); + EXPECT_THAT(listener.str(), Eq("where:\n" + " - element #0 is matched by matcher #1,\n" + " - element #2 is matched by matcher #0")); +} + +#if GTEST_HAS_STD_INITIALIZER_LIST_ +TEST(IsSupersetOfTest, WorksForRhsInitializerList) { + const int numbers[] = {1, 3, 6, 2, 4, 5}; + EXPECT_THAT(numbers, IsSupersetOf({1, 2})); + EXPECT_THAT(numbers, Not(IsSupersetOf({3, 0}))); +} +#endif + +TEST(IsSubsetOfTest, WorksForNativeArray) { + const int subset[] = {1, 4}; + const int superset[] = {1, 2, 4}; + const int disjoint[] = {1, 0, 3}; + EXPECT_THAT(subset, IsSubsetOf(subset)); + EXPECT_THAT(subset, IsSubsetOf(superset)); + EXPECT_THAT(superset, Not(IsSubsetOf(subset))); + EXPECT_THAT(subset, Not(IsSubsetOf(disjoint))); + EXPECT_THAT(disjoint, Not(IsSubsetOf(subset))); +} + +TEST(IsSubsetOfTest, WorksWithDuplicates) { + const int not_enough[] = {1, 2}; + const int enough[] = {1, 1, 2}; + const int actual[] = {1, 1}; + EXPECT_THAT(actual, Not(IsSubsetOf(not_enough))); + EXPECT_THAT(actual, IsSubsetOf(enough)); +} + +TEST(IsSubsetOfTest, WorksForEmpty) { + vector<int> numbers; + vector<int> expected; + EXPECT_THAT(numbers, IsSubsetOf(expected)); + expected.push_back(1); + EXPECT_THAT(numbers, IsSubsetOf(expected)); + expected.clear(); + numbers.push_back(1); + numbers.push_back(2); + EXPECT_THAT(numbers, Not(IsSubsetOf(expected))); + expected.push_back(1); + EXPECT_THAT(numbers, Not(IsSubsetOf(expected))); + expected.push_back(2); + EXPECT_THAT(numbers, IsSubsetOf(expected)); + expected.push_back(3); + EXPECT_THAT(numbers, IsSubsetOf(expected)); +} + +TEST(IsSubsetOfTest, WorksForStreamlike) { + const int a[5] = {1, 2}; + Streamlike<int> s(a, a + GTEST_ARRAY_SIZE_(a)); + + vector<int> expected; + expected.push_back(1); + EXPECT_THAT(s, Not(IsSubsetOf(expected))); + expected.push_back(2); + expected.push_back(5); + EXPECT_THAT(s, IsSubsetOf(expected)); +} + +TEST(IsSubsetOfTest, TakesStlContainer) { + const int actual[] = {3, 1, 2}; + + ::std::list<int> expected; + expected.push_back(1); + expected.push_back(3); + EXPECT_THAT(actual, Not(IsSubsetOf(expected))); + + expected.push_back(2); + expected.push_back(4); + EXPECT_THAT(actual, IsSubsetOf(expected)); +} + +TEST(IsSubsetOfTest, Describe) { + typedef std::vector<int> IntVec; + IntVec expected; + expected.push_back(111); + expected.push_back(222); + expected.push_back(333); + + EXPECT_THAT( + Describe<IntVec>(IsSubsetOf(expected)), + Eq("an injection from elements to requirements exists such that:\n" + " - an element is equal to 111\n" + " - an element is equal to 222\n" + " - an element is equal to 333")); +} + +TEST(IsSubsetOfTest, DescribeNegation) { + typedef std::vector<int> IntVec; + IntVec expected; + expected.push_back(111); + expected.push_back(222); + expected.push_back(333); + EXPECT_THAT( + DescribeNegation<IntVec>(IsSubsetOf(expected)), + Eq("no injection from elements to requirements exists such that:\n" + " - an element is equal to 111\n" + " - an element is equal to 222\n" + " - an element is equal to 333")); +} + +TEST(IsSubsetOfTest, MatchAndExplain) { + std::vector<int> v; + v.push_back(2); + v.push_back(3); + std::vector<int> expected; + expected.push_back(1); + expected.push_back(2); + StringMatchResultListener listener; + ASSERT_FALSE(ExplainMatchResult(IsSubsetOf(expected), v, &listener)) + << listener.str(); + EXPECT_THAT(listener.str(), + Eq("where the following elements don't match any matchers:\n" + "element #1: 3")); + + expected.push_back(3); + listener.Clear(); + ASSERT_TRUE(ExplainMatchResult(IsSubsetOf(expected), v, &listener)) + << listener.str(); + EXPECT_THAT(listener.str(), Eq("where:\n" + " - element #0 is matched by matcher #1,\n" + " - element #1 is matched by matcher #2")); +} + +#if GTEST_HAS_STD_INITIALIZER_LIST_ +TEST(IsSubsetOfTest, WorksForRhsInitializerList) { + const int numbers[] = {1, 2, 3}; + EXPECT_THAT(numbers, IsSubsetOf({1, 2, 3, 4})); + EXPECT_THAT(numbers, Not(IsSubsetOf({1, 2}))); +} +#endif + // Tests using ElementsAre() and ElementsAreArray() with stream-like // "containers". @@ -5268,28 +6192,6 @@ TEST(IsReadableTypeNameTest, ReturnsFalseForLongFunctionTypeNames) { EXPECT_FALSE(IsReadableTypeName("void (&)(int, bool, char, float)")); } -// Tests JoinAsTuple(). - -TEST(JoinAsTupleTest, JoinsEmptyTuple) { - EXPECT_EQ("", JoinAsTuple(Strings())); -} - -TEST(JoinAsTupleTest, JoinsOneTuple) { - const char* fields[] = {"1"}; - EXPECT_EQ("1", JoinAsTuple(Strings(fields, fields + 1))); -} - -TEST(JoinAsTupleTest, JoinsTwoTuple) { - const char* fields[] = {"1", "a"}; - EXPECT_EQ("(1, a)", JoinAsTuple(Strings(fields, fields + 2))); -} - -TEST(JoinAsTupleTest, JoinsTenTuple) { - const char* fields[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}; - EXPECT_EQ("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)", - JoinAsTuple(Strings(fields, fields + 10))); -} - // Tests FormatMatcherDescription(). TEST(FormatMatcherDescriptionTest, WorksForEmptyDescription) { @@ -5513,6 +6415,16 @@ TEST(PointwiseTest, WorksForRhsNativeArray) { EXPECT_THAT(lhs, Not(Pointwise(Lt(), rhs))); } +// Test is effective only with sanitizers. +TEST(PointwiseTest, WorksForVectorOfBool) { + vector<bool> rhs(3, false); + rhs[1] = true; + vector<bool> lhs = rhs; + EXPECT_THAT(lhs, Pointwise(Eq(), rhs)); + rhs[0] = true; + EXPECT_THAT(lhs, Not(Pointwise(Eq(), rhs))); +} + #if GTEST_HAS_STD_INITIALIZER_LIST_ TEST(PointwiseTest, WorksForRhsInitializerList) { @@ -5678,5 +6590,198 @@ TEST(UnorderedPointwiseTest, AllowsMonomorphicInnerMatcher) { EXPECT_THAT(lhs, UnorderedPointwise(m2, rhs)); } +// Sample optional type implementation with minimal requirements for use with +// Optional matcher. +class SampleOptionalInt { + public: + typedef int value_type; + explicit SampleOptionalInt(int value) : value_(value), has_value_(true) {} + SampleOptionalInt() : value_(0), has_value_(false) {} + operator bool() const { + return has_value_; + } + const int& operator*() const { + return value_; + } + private: + int value_; + bool has_value_; +}; + +TEST(OptionalTest, DescribesSelf) { + const Matcher<SampleOptionalInt> m = Optional(Eq(1)); + EXPECT_EQ("value is equal to 1", Describe(m)); +} + +TEST(OptionalTest, ExplainsSelf) { + const Matcher<SampleOptionalInt> m = Optional(Eq(1)); + EXPECT_EQ("whose value 1 matches", Explain(m, SampleOptionalInt(1))); + EXPECT_EQ("whose value 2 doesn't match", Explain(m, SampleOptionalInt(2))); +} + +TEST(OptionalTest, MatchesNonEmptyOptional) { + const Matcher<SampleOptionalInt> m1 = Optional(1); + const Matcher<SampleOptionalInt> m2 = Optional(Eq(2)); + const Matcher<SampleOptionalInt> m3 = Optional(Lt(3)); + SampleOptionalInt opt(1); + EXPECT_TRUE(m1.Matches(opt)); + EXPECT_FALSE(m2.Matches(opt)); + EXPECT_TRUE(m3.Matches(opt)); +} + +TEST(OptionalTest, DoesNotMatchNullopt) { + const Matcher<SampleOptionalInt> m = Optional(1); + SampleOptionalInt empty; + EXPECT_FALSE(m.Matches(empty)); +} + +class SampleVariantIntString { + public: + SampleVariantIntString(int i) : i_(i), has_int_(true) {} + SampleVariantIntString(const std::string& s) : s_(s), has_int_(false) {} + + template <typename T> + friend bool holds_alternative(const SampleVariantIntString& value) { + return value.has_int_ == internal::IsSame<T, int>::value; + } + + template <typename T> + friend const T& get(const SampleVariantIntString& value) { + return value.get_impl(static_cast<T*>(NULL)); + } + + private: + const int& get_impl(int*) const { return i_; } + const std::string& get_impl(std::string*) const { return s_; } + + int i_; + std::string s_; + bool has_int_; +}; + +TEST(VariantTest, DescribesSelf) { + const Matcher<SampleVariantIntString> m = VariantWith<int>(Eq(1)); + EXPECT_THAT(Describe(m), ContainsRegex("is a variant<> with value of type " + "'.*' and the value is equal to 1")); +} + +TEST(VariantTest, ExplainsSelf) { + const Matcher<SampleVariantIntString> m = VariantWith<int>(Eq(1)); + EXPECT_THAT(Explain(m, SampleVariantIntString(1)), + ContainsRegex("whose value 1")); + EXPECT_THAT(Explain(m, SampleVariantIntString("A")), + HasSubstr("whose value is not of type '")); + EXPECT_THAT(Explain(m, SampleVariantIntString(2)), + "whose value 2 doesn't match"); +} + +TEST(VariantTest, FullMatch) { + Matcher<SampleVariantIntString> m = VariantWith<int>(Eq(1)); + EXPECT_TRUE(m.Matches(SampleVariantIntString(1))); + + m = VariantWith<std::string>(Eq("1")); + EXPECT_TRUE(m.Matches(SampleVariantIntString("1"))); +} + +TEST(VariantTest, TypeDoesNotMatch) { + Matcher<SampleVariantIntString> m = VariantWith<int>(Eq(1)); + EXPECT_FALSE(m.Matches(SampleVariantIntString("1"))); + + m = VariantWith<std::string>(Eq("1")); + EXPECT_FALSE(m.Matches(SampleVariantIntString(1))); +} + +TEST(VariantTest, InnerDoesNotMatch) { + Matcher<SampleVariantIntString> m = VariantWith<int>(Eq(1)); + EXPECT_FALSE(m.Matches(SampleVariantIntString(2))); + + m = VariantWith<std::string>(Eq("1")); + EXPECT_FALSE(m.Matches(SampleVariantIntString("2"))); +} + +class SampleAnyType { + public: + explicit SampleAnyType(int i) : index_(0), i_(i) {} + explicit SampleAnyType(const std::string& s) : index_(1), s_(s) {} + + template <typename T> + friend const T* any_cast(const SampleAnyType* any) { + return any->get_impl(static_cast<T*>(NULL)); + } + + private: + int index_; + int i_; + std::string s_; + + const int* get_impl(int*) const { return index_ == 0 ? &i_ : NULL; } + const std::string* get_impl(std::string*) const { + return index_ == 1 ? &s_ : NULL; + } +}; + +TEST(AnyWithTest, FullMatch) { + Matcher<SampleAnyType> m = AnyWith<int>(Eq(1)); + EXPECT_TRUE(m.Matches(SampleAnyType(1))); +} + +TEST(AnyWithTest, TestBadCastType) { + Matcher<SampleAnyType> m = AnyWith<std::string>(Eq("fail")); + EXPECT_FALSE(m.Matches(SampleAnyType(1))); +} + +#if GTEST_LANG_CXX11 +TEST(AnyWithTest, TestUseInContainers) { + std::vector<SampleAnyType> a; + a.emplace_back(1); + a.emplace_back(2); + a.emplace_back(3); + EXPECT_THAT( + a, ElementsAreArray({AnyWith<int>(1), AnyWith<int>(2), AnyWith<int>(3)})); + + std::vector<SampleAnyType> b; + b.emplace_back("hello"); + b.emplace_back("merhaba"); + b.emplace_back("salut"); + EXPECT_THAT(b, ElementsAreArray({AnyWith<std::string>("hello"), + AnyWith<std::string>("merhaba"), + AnyWith<std::string>("salut")})); +} +#endif // GTEST_LANG_CXX11 +TEST(AnyWithTest, TestCompare) { + EXPECT_THAT(SampleAnyType(1), AnyWith<int>(Gt(0))); +} + +TEST(AnyWithTest, DescribesSelf) { + const Matcher<const SampleAnyType&> m = AnyWith<int>(Eq(1)); + EXPECT_THAT(Describe(m), ContainsRegex("is an 'any' type with value of type " + "'.*' and the value is equal to 1")); +} + +TEST(AnyWithTest, ExplainsSelf) { + const Matcher<const SampleAnyType&> m = AnyWith<int>(Eq(1)); + + EXPECT_THAT(Explain(m, SampleAnyType(1)), ContainsRegex("whose value 1")); + EXPECT_THAT(Explain(m, SampleAnyType("A")), + HasSubstr("whose value is not of type '")); + EXPECT_THAT(Explain(m, SampleAnyType(2)), "whose value 2 doesn't match"); +} + +#if GTEST_LANG_CXX11 + +TEST(PointeeTest, WorksOnMoveOnlyType) { + std::unique_ptr<int> p(new int(3)); + EXPECT_THAT(p, Pointee(Eq(3))); + EXPECT_THAT(p, Not(Pointee(Eq(2)))); +} + +TEST(NotTest, WorksOnMoveOnlyType) { + std::unique_ptr<int> p(new int(3)); + EXPECT_THAT(p, Pointee(Eq(3))); + EXPECT_THAT(p, Not(Pointee(Eq(2)))); +} + +#endif // GTEST_LANG_CXX11 + } // namespace gmock_matchers_test } // namespace testing diff --git a/googlemock/test/gmock-more-actions_test.cc b/googlemock/test/gmock-more-actions_test.cc index f5e28eae..08a2df09 100644 --- a/googlemock/test/gmock-more-actions_test.cc +++ b/googlemock/test/gmock-more-actions_test.cc @@ -26,8 +26,7 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // @@ -327,11 +326,10 @@ TEST(InvokeTest, FunctionThatTakes10Arguments) { // Tests using Invoke() with functions with parameters declared as Unused. TEST(InvokeTest, FunctionWithUnusedParameters) { - Action<int(int, int, double, const string&)> a1 = - Invoke(SumOfFirst2); - string s("hi"); - EXPECT_EQ(12, a1.Perform( - tuple<int, int, double, const string&>(10, 2, 5.6, s))); + Action<int(int, int, double, const std::string&)> a1 = Invoke(SumOfFirst2); + tuple<int, int, double, std::string> dummy = + make_tuple(10, 2, 5.6, std::string("hi")); + EXPECT_EQ(12, a1.Perform(dummy)); Action<int(int, int, bool, int*)> a2 = Invoke(SumOfFirst2); @@ -380,10 +378,10 @@ TEST(InvokeMethodTest, Unary) { // Tests using Invoke() with a binary method. TEST(InvokeMethodTest, Binary) { Foo foo; - Action<string(const string&, char)> a = Invoke(&foo, &Foo::Binary); - string s("Hell"); - EXPECT_EQ("Hello", a.Perform( - tuple<const string&, char>(s, 'o'))); + Action<std::string(const std::string&, char)> a = Invoke(&foo, &Foo::Binary); + std::string s("Hell"); + tuple<std::string, char> dummy = make_tuple(s, 'o'); + EXPECT_EQ("Hello", a.Perform(dummy)); } // Tests using Invoke() with a ternary method. diff --git a/googlemock/test/gmock-nice-strict_test.cc b/googlemock/test/gmock-nice-strict_test.cc index 0eac6439..dce66423 100644 --- a/googlemock/test/gmock-nice-strict_test.cc +++ b/googlemock/test/gmock-nice-strict_test.cc @@ -26,15 +26,15 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + #include "gmock/gmock-generated-nice-strict.h" #include <string> +#include <utility> #include "gmock/gmock.h" -#include "gtest/gtest.h" #include "gtest/gtest-spi.h" +#include "gtest/gtest.h" // This must not be defined inside the ::testing namespace, or it will // clash with ::testing::Mock. @@ -114,6 +114,24 @@ class MockBar { GTEST_DISALLOW_COPY_AND_ASSIGN_(MockBar); }; +#if GTEST_GTEST_LANG_CXX11 + +class MockBaz { + public: + class MoveOnly { + MoveOnly() = default; + + MoveOnly(const MoveOnly&) = delete; + operator=(const MoveOnly&) = delete; + + MoveOnly(MoveOnly&&) = default; + operator=(MoveOnly&&) = default; + }; + + MockBaz(MoveOnly) {} +} +#endif // GTEST_GTEST_LANG_CXX11 && GTEST_HAS_STD_MOVE_ + #if GTEST_HAS_STREAM_REDIRECTION // Tests that a raw mock generates warnings for uninteresting calls. @@ -214,8 +232,9 @@ TEST(NiceMockTest, AllowsExpectedCall) { nice_foo.DoThis(); } -// Tests that an unexpected call on a nice mock which returns a not-default-constructible -// type throws an exception and the exception contains the method's name. +// Tests that an unexpected call on a nice mock which returns a +// not-default-constructible type throws an exception and the exception contains +// the method's name. TEST(NiceMockTest, ThrowsExceptionForUnknownReturnTypes) { NiceMock<MockFoo> nice_foo; #if GTEST_HAS_EXCEPTIONS @@ -259,6 +278,21 @@ TEST(NiceMockTest, NonDefaultConstructor10) { nice_bar.That(5, true); } +TEST(NiceMockTest, AllowLeak) { + NiceMock<MockFoo>* leaked = new NiceMock<MockFoo>; + Mock::AllowLeak(leaked); + EXPECT_CALL(*leaked, DoThis()); + leaked->DoThis(); +} + +#if GTEST_GTEST_LANG_CXX11 && GTEST_HAS_STD_MOVE_ + +TEST(NiceMockTest, MoveOnlyConstructor) { + NiceMock<MockBaz> nice_baz(MockBaz::MoveOnly()); +} + +#endif // GTEST_LANG_CXX11 && GTEST_HAS_STD_MOVE_ + #if !GTEST_OS_SYMBIAN && !GTEST_OS_WINDOWS_MOBILE // Tests that NiceMock<Mock> compiles where Mock is a user-defined // class (as opposed to ::testing::Mock). We had to work around an @@ -352,6 +386,21 @@ TEST(NaggyMockTest, NonDefaultConstructor10) { naggy_bar.That(5, true); } +TEST(NaggyMockTest, AllowLeak) { + NaggyMock<MockFoo>* leaked = new NaggyMock<MockFoo>; + Mock::AllowLeak(leaked); + EXPECT_CALL(*leaked, DoThis()); + leaked->DoThis(); +} + +#if GTEST_GTEST_LANG_CXX11 && GTEST_HAS_STD_MOVE_ + +TEST(NaggyMockTest, MoveOnlyConstructor) { + NaggyMock<MockBaz> naggy_baz(MockBaz::MoveOnly()); +} + +#endif // GTEST_LANG_CXX11 && GTEST_HAS_STD_MOVE_ + #if !GTEST_OS_SYMBIAN && !GTEST_OS_WINDOWS_MOBILE // Tests that NaggyMock<Mock> compiles where Mock is a user-defined // class (as opposed to ::testing::Mock). We had to work around an @@ -426,6 +475,21 @@ TEST(StrictMockTest, NonDefaultConstructor10) { "Uninteresting mock function call"); } +TEST(StrictMockTest, AllowLeak) { + StrictMock<MockFoo>* leaked = new StrictMock<MockFoo>; + Mock::AllowLeak(leaked); + EXPECT_CALL(*leaked, DoThis()); + leaked->DoThis(); +} + +#if GTEST_GTEST_LANG_CXX11 && GTEST_HAS_STD_MOVE_ + +TEST(StrictMockTest, MoveOnlyConstructor) { + StrictMock<MockBaz> strict_baz(MockBaz::MoveOnly()); +} + +#endif // GTEST_LANG_CXX11 && GTEST_HAS_STD_MOVE_ + #if !GTEST_OS_SYMBIAN && !GTEST_OS_WINDOWS_MOBILE // Tests that StrictMock<Mock> compiles where Mock is a user-defined // class (as opposed to ::testing::Mock). We had to work around an diff --git a/googlemock/test/gmock-port_test.cc b/googlemock/test/gmock-port_test.cc index d6a8d444..a2c2be24 100644 --- a/googlemock/test/gmock-port_test.cc +++ b/googlemock/test/gmock-port_test.cc @@ -26,8 +26,7 @@ // 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. -// -// Author: vladl@google.com (Vlad Losev) + // Google Mock - a framework for writing C++ mock classes. // diff --git a/googlemock/test/gmock-spec-builders_test.cc b/googlemock/test/gmock-spec-builders_test.cc index a7bf03e5..7056c43c 100644 --- a/googlemock/test/gmock-spec-builders_test.cc +++ b/googlemock/test/gmock-spec-builders_test.cc @@ -26,8 +26,7 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // @@ -89,6 +88,7 @@ using testing::Mock; using testing::NaggyMock; using testing::Ne; using testing::Return; +using testing::SaveArg; using testing::Sequence; using testing::SetArgPointee; using testing::internal::ExpectationTester; @@ -748,7 +748,6 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) { testing::GMOCK_FLAG(default_mock_behavior) = original_behavior; } - #endif // GTEST_HAS_STREAM_REDIRECTION // Tests the semantics of ON_CALL(). @@ -1176,7 +1175,7 @@ TEST(UnexpectedCallTest, UnsatisifiedPrerequisites) { TEST(UndefinedReturnValueTest, ReturnValueIsMandatoryWhenNotDefaultConstructible) { MockA a; - // TODO(wan@google.com): We should really verify the output message, + // FIXME: We should really verify the output message, // but we cannot yet due to that EXPECT_DEATH only captures stderr // while Google Mock logs to stdout. #if GTEST_HAS_EXCEPTIONS @@ -2174,7 +2173,9 @@ class GMockVerboseFlagTest : public VerboseFlagPreservingFixture { "NOTE: You can safely ignore the above warning unless this " "call should not happen. Do not suppress it by blindly adding " "an EXPECT_CALL() if you don't mean to enforce the call. " - "See https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md#" + "See " + "https://github.com/google/googletest/blob/master/googlemock/docs/" + "CookBook.md#" "knowing-when-to-expect for details."; // A void-returning function. @@ -2680,6 +2681,75 @@ TEST(SynchronizationTest, CanCallMockMethodInAction) { // EXPECT_CALL() did not specify an action. } +TEST(ParameterlessExpectationsTest, CanSetExpectationsWithoutMatchers) { + MockA a; + int do_a_arg0 = 0; + ON_CALL(a, DoA).WillByDefault(SaveArg<0>(&do_a_arg0)); + int do_a_47_arg0 = 0; + ON_CALL(a, DoA(47)).WillByDefault(SaveArg<0>(&do_a_47_arg0)); + + a.DoA(17); + EXPECT_THAT(do_a_arg0, 17); + EXPECT_THAT(do_a_47_arg0, 0); + a.DoA(47); + EXPECT_THAT(do_a_arg0, 17); + EXPECT_THAT(do_a_47_arg0, 47); + + ON_CALL(a, Binary).WillByDefault(Return(true)); + ON_CALL(a, Binary(_, 14)).WillByDefault(Return(false)); + EXPECT_THAT(a.Binary(14, 17), true); + EXPECT_THAT(a.Binary(17, 14), false); +} + +TEST(ParameterlessExpectationsTest, CanSetExpectationsForOverloadedMethods) { + MockB b; + ON_CALL(b, DoB()).WillByDefault(Return(9)); + ON_CALL(b, DoB(5)).WillByDefault(Return(11)); + + EXPECT_THAT(b.DoB(), 9); + EXPECT_THAT(b.DoB(1), 0); // default value + EXPECT_THAT(b.DoB(5), 11); +} + +struct MockWithConstMethods { + public: + MOCK_CONST_METHOD1(Foo, int(int)); + MOCK_CONST_METHOD2(Bar, int(int, const char*)); +}; + +TEST(ParameterlessExpectationsTest, CanSetExpectationsForConstMethods) { + MockWithConstMethods mock; + ON_CALL(mock, Foo).WillByDefault(Return(7)); + ON_CALL(mock, Bar).WillByDefault(Return(33)); + + EXPECT_THAT(mock.Foo(17), 7); + EXPECT_THAT(mock.Bar(27, "purple"), 33); +} + +class MockConstOverload { + public: + MOCK_METHOD1(Overloaded, int(int)); + MOCK_CONST_METHOD1(Overloaded, int(int)); +}; + +TEST(ParameterlessExpectationsTest, + CanSetExpectationsForConstOverloadedMethods) { + MockConstOverload mock; + ON_CALL(mock, Overloaded(_)).WillByDefault(Return(7)); + ON_CALL(mock, Overloaded(5)).WillByDefault(Return(9)); + ON_CALL(Const(mock), Overloaded(5)).WillByDefault(Return(11)); + ON_CALL(Const(mock), Overloaded(7)).WillByDefault(Return(13)); + + EXPECT_THAT(mock.Overloaded(1), 7); + EXPECT_THAT(mock.Overloaded(5), 9); + EXPECT_THAT(mock.Overloaded(7), 7); + + const MockConstOverload& const_mock = mock; + EXPECT_THAT(const_mock.Overloaded(1), 0); + EXPECT_THAT(const_mock.Overloaded(5), 11); + EXPECT_THAT(const_mock.Overloaded(7), 13); +} + } // namespace // Allows the user to define their own main and then invoke gmock_main @@ -2691,7 +2761,6 @@ int gmock_main(int argc, char **argv) { int main(int argc, char **argv) { #endif // GMOCK_RENAME_MAIN testing::InitGoogleMock(&argc, argv); - // Ensures that the tests pass no matter what value of // --gmock_catch_leaked_mocks and --gmock_verbose the user specifies. testing::GMOCK_FLAG(catch_leaked_mocks) = true; diff --git a/googlemock/test/gmock_all_test.cc b/googlemock/test/gmock_all_test.cc index 56d6c49c..e1774fbb 100644 --- a/googlemock/test/gmock_all_test.cc +++ b/googlemock/test/gmock_all_test.cc @@ -26,8 +26,7 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // // Tests for Google C++ Mocking Framework (Google Mock) // diff --git a/googlemock/test/gmock_ex_test.cc b/googlemock/test/gmock_ex_test.cc index 3afed86a..72eb43f7 100644 --- a/googlemock/test/gmock_ex_test.cc +++ b/googlemock/test/gmock_ex_test.cc @@ -26,17 +26,18 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Tests Google Mock's functionality that depends on exceptions. #include "gmock/gmock.h" #include "gtest/gtest.h" +#if GTEST_HAS_EXCEPTIONS namespace { using testing::HasSubstr; + using testing::internal::GoogleTestFailureException; // A type that cannot be default constructed. @@ -52,8 +53,6 @@ class MockFoo { MOCK_METHOD0(GetNonDefaultConstructible, NonDefaultConstructible()); }; -#if GTEST_HAS_EXCEPTIONS - TEST(DefaultValueTest, ThrowsRuntimeErrorWhenNoDefaultValue) { MockFoo mock; try { @@ -76,6 +75,6 @@ TEST(DefaultValueTest, ThrowsRuntimeErrorWhenNoDefaultValue) { } } -#endif } // unnamed namespace +#endif diff --git a/googlemock/test/gmock_leak_test.py b/googlemock/test/gmock_leak_test.py index 997680ce..7e4b1eea 100755 --- a/googlemock/test/gmock_leak_test.py +++ b/googlemock/test/gmock_leak_test.py @@ -31,12 +31,8 @@ """Tests that leaked mock objects can be caught be Google Mock.""" -__author__ = 'wan@google.com (Zhanyong Wan)' - - import gmock_test_utils - PROGRAM_PATH = gmock_test_utils.GetTestExecutablePath('gmock_leak_test_') TEST_WITH_EXPECT_CALL = [PROGRAM_PATH, '--gtest_filter=*ExpectCall*'] TEST_WITH_ON_CALL = [PROGRAM_PATH, '--gtest_filter=*OnCall*'] diff --git a/googlemock/test/gmock_leak_test_.cc b/googlemock/test/gmock_leak_test_.cc index 1d27d22f..2e095abc 100644 --- a/googlemock/test/gmock_leak_test_.cc +++ b/googlemock/test/gmock_leak_test_.cc @@ -26,8 +26,7 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // diff --git a/googlemock/test/gmock_link2_test.cc b/googlemock/test/gmock_link2_test.cc index 4c310c3d..d27ce176 100644 --- a/googlemock/test/gmock_link2_test.cc +++ b/googlemock/test/gmock_link2_test.cc @@ -26,8 +26,7 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev) + // Google Mock - a framework for writing C++ mock classes. // @@ -37,4 +36,4 @@ #define LinkTest LinkTest2 -#include "test/gmock_link_test.h" +#include "test/gmock_link_test.h" diff --git a/googlemock/test/gmock_link_test.cc b/googlemock/test/gmock_link_test.cc index 61e97d10..e7c54cc2 100644 --- a/googlemock/test/gmock_link_test.cc +++ b/googlemock/test/gmock_link_test.cc @@ -26,8 +26,7 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev) + // Google Mock - a framework for writing C++ mock classes. // @@ -37,4 +36,4 @@ #define LinkTest LinkTest1 -#include "test/gmock_link_test.h" +#include "test/gmock_link_test.h" diff --git a/googlemock/test/gmock_link_test.h b/googlemock/test/gmock_link_test.h index 1f55f5bd..d26670ec 100644 --- a/googlemock/test/gmock_link_test.h +++ b/googlemock/test/gmock_link_test.h @@ -26,8 +26,7 @@ // 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. -// -// Author: vladl@google.com (Vlad Losev) + // Google Mock - a framework for writing C++ mock classes. // @@ -90,8 +89,10 @@ // Field // Property // ResultOf(function) +// ResultOf(callback) // Pointee // Truly(predicate) +// AddressSatisfies // AllOf // AnyOf // Not @@ -120,13 +121,15 @@ # include <errno.h> #endif -#include "gmock/internal/gmock-port.h" -#include "gtest/gtest.h" #include <iostream> #include <vector> +#include "gtest/gtest.h" +#include "gtest/internal/gtest-port.h" + using testing::_; using testing::A; +using testing::Action; using testing::AllOf; using testing::AnyOf; using testing::Assign; @@ -148,6 +151,8 @@ using testing::Invoke; using testing::InvokeArgument; using testing::InvokeWithoutArgs; using testing::IsNull; +using testing::IsSubsetOf; +using testing::IsSupersetOf; using testing::Le; using testing::Lt; using testing::Matcher; @@ -592,6 +597,22 @@ TEST(LinkTest, TestMatcherElementsAreArray) { ON_CALL(mock, VoidFromVector(ElementsAreArray(arr))).WillByDefault(Return()); } +// Tests the linkage of the IsSubsetOf matcher. +TEST(LinkTest, TestMatcherIsSubsetOf) { + Mock mock; + char arr[] = {'a', 'b'}; + + ON_CALL(mock, VoidFromVector(IsSubsetOf(arr))).WillByDefault(Return()); +} + +// Tests the linkage of the IsSupersetOf matcher. +TEST(LinkTest, TestMatcherIsSupersetOf) { + Mock mock; + char arr[] = {'a', 'b'}; + + ON_CALL(mock, VoidFromVector(IsSupersetOf(arr))).WillByDefault(Return()); +} + // Tests the linkage of the ContainerEq matcher. TEST(LinkTest, TestMatcherContainerEq) { Mock mock; diff --git a/googlemock/test/gmock_output_test.py b/googlemock/test/gmock_output_test.py index 9d73d570..0527bd93 100755 --- a/googlemock/test/gmock_output_test.py +++ b/googlemock/test/gmock_output_test.py @@ -29,21 +29,19 @@ # (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++ Mocking Framework. +r"""Tests the text output of Google C++ Mocking Framework. To update the golden file: gmock_output_test.py --build_dir=BUILD/DIR --gengolden -# where BUILD/DIR contains the built gmock_output_test_ file. +where BUILD/DIR contains the built gmock_output_test_ file. gmock_output_test.py --gengolden gmock_output_test.py -""" -__author__ = 'wan@google.com (Zhanyong Wan)' +""" import os import re import sys - import gmock_test_utils diff --git a/googlemock/test/gmock_output_test_.cc b/googlemock/test/gmock_output_test_.cc index 44cba342..3955c733 100644 --- a/googlemock/test/gmock_output_test_.cc +++ b/googlemock/test/gmock_output_test_.cc @@ -26,8 +26,7 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Tests Google Mock's output in various scenarios. This ensures that // Google Mock's messages are readable and useful. @@ -39,6 +38,12 @@ #include "gtest/gtest.h" +// Silence C4100 (unreferenced formal parameter) +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4100) +#endif + using testing::_; using testing::AnyNumber; using testing::Ge; @@ -47,6 +52,7 @@ using testing::NaggyMock; using testing::Ref; using testing::Return; using testing::Sequence; +using testing::Value; class MockFoo { public: @@ -268,6 +274,15 @@ TEST_F(GMockOutputTest, CatchesLeakedMocks) { // Both foo1 and foo2 are deliberately leaked. } +MATCHER_P2(IsPair, first, second, "") { + return Value(arg.first, first) && Value(arg.second, second); +} + +TEST_F(GMockOutputTest, PrintsMatcher) { + const testing::Matcher<int> m1 = Ge(48); + EXPECT_THAT((std::pair<int, bool>(42, true)), IsPair(m1, true)); +} + void TestCatchesLeakedMocksInAdHocTests() { MockFoo* foo = new MockFoo; @@ -280,7 +295,6 @@ void TestCatchesLeakedMocksInAdHocTests() { int main(int argc, char **argv) { testing::InitGoogleMock(&argc, argv); - // Ensures that the tests pass no matter what value of // --gmock_catch_leaked_mocks and --gmock_verbose the user specifies. testing::GMOCK_FLAG(catch_leaked_mocks) = true; @@ -289,3 +303,7 @@ int main(int argc, char **argv) { TestCatchesLeakedMocksInAdHocTests(); return RUN_ALL_TESTS(); } + +#ifdef _MSC_VER +# pragma warning(pop) +#endif diff --git a/googlemock/test/gmock_output_test_golden.txt b/googlemock/test/gmock_output_test_golden.txt index 689d5eeb..dbcb2118 100644 --- a/googlemock/test/gmock_output_test_golden.txt +++ b/googlemock/test/gmock_output_test_golden.txt @@ -288,6 +288,12 @@ Stack trace: [ OK ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction [ RUN ] GMockOutputTest.CatchesLeakedMocks [ OK ] GMockOutputTest.CatchesLeakedMocks +[ RUN ] GMockOutputTest.PrintsMatcher +FILE:#: Failure +Value of: (std::pair<int, bool>(42, true)) +Expected: is pair (is >= 48, true) + Actual: (42, true) (of type std::pair<int, bool>) +[ FAILED ] GMockOutputTest.PrintsMatcher [ FAILED ] GMockOutputTest.UnexpectedCall [ FAILED ] GMockOutputTest.UnexpectedCallToVoidFunction [ FAILED ] GMockOutputTest.ExcessiveCall @@ -302,9 +308,10 @@ Stack trace: [ FAILED ] GMockOutputTest.MismatchArgumentsAndWith [ FAILED ] GMockOutputTest.UnexpectedCallWithDefaultAction [ FAILED ] GMockOutputTest.ExcessiveCallWithDefaultAction +[ FAILED ] GMockOutputTest.PrintsMatcher FILE:#: ERROR: this mock object should be deleted but never is. Its address is @0x#. FILE:#: ERROR: this mock object should be deleted but never is. Its address is @0x#. FILE:#: ERROR: this mock object should be deleted but never is. Its address is @0x#. -ERROR: 3 leaked mock objects found at program exit. +ERROR: 3 leaked mock objects found at program exit. Expectations on a mock object is verified when the object is destructed. Leaking a mock means that its expectations aren't verified, which is usually a test bug. If you really intend to leak a mock, you can suppress this error using testing::Mock::AllowLeak(mock_object), or you may use a fake or stub instead of a mock. diff --git a/googlemock/test/gmock_stress_test.cc b/googlemock/test/gmock_stress_test.cc index b9fdc45c..0d99bede 100644 --- a/googlemock/test/gmock_stress_test.cc +++ b/googlemock/test/gmock_stress_test.cc @@ -26,20 +26,18 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Tests that Google Mock constructs can be used in a large number of // threads concurrently. #include "gmock/gmock.h" - #include "gtest/gtest.h" namespace testing { namespace { -// From "gtest/internal/gtest-port.h". +// From gtest-port.h. using ::testing::internal::ThreadWithParam; // The maximum number of test threads (not including helper threads) diff --git a/googlemock/test/gmock_test.cc b/googlemock/test/gmock_test.cc index 70075679..341a17da 100644 --- a/googlemock/test/gmock_test.cc +++ b/googlemock/test/gmock_test.cc @@ -26,8 +26,7 @@ // 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. -// -// Author: wan@google.com (Zhanyong Wan) + // Google Mock - a framework for writing C++ mock classes. // diff --git a/googlemock/test/gmock_test_utils.py b/googlemock/test/gmock_test_utils.py index b5130001..7dc4e119 100755 --- a/googlemock/test/gmock_test_utils.py +++ b/googlemock/test/gmock_test_utils.py @@ -29,8 +29,6 @@ """Unit test utilities for Google C++ Mocking Framework.""" -__author__ = 'wan@google.com (Zhanyong Wan)' - import os import sys @@ -38,7 +36,7 @@ import sys SCRIPT_DIR = os.path.dirname(__file__) or '.' # isdir resolves symbolic links. -gtest_tests_util_dir = os.path.join(SCRIPT_DIR, '../googletest/test') +gtest_tests_util_dir = os.path.join(SCRIPT_DIR, '../../googletest/test') if os.path.isdir(gtest_tests_util_dir): GTEST_TESTS_UTIL_DIR = gtest_tests_util_dir else: |