Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for std::function in MockFunction (#2277) #2350

Merged
merged 2 commits into from
Mar 24, 2020

Conversation

adambadura
Copy link
Contributor

MocFunction is slightly changed to transform its argument through (added in this change) SignatureOf meta-function. The meta-function extracts the function signature type from the provided type. Thanks to this approach MockFunction<F> can now be used with F being both function signature (like bool(int)) and std::function (like std::function<bool(int)>).

Besides the immediate benefit, extra extensibility is added. Library user can specialize SignaturOf for other types (like boost::function) to gain the same support level.

Note that this PR comes from #2319.

@adambadura adambadura force-pushed the MockFunctionFromStdFunction branch 2 times, most recently from e51f252 to b9b50e3 Compare August 8, 2019 16:51
@adambadura adambadura force-pushed the MockFunctionFromStdFunction branch from b9b50e3 to 75c17f9 Compare August 16, 2019 23:58
Copy link
Contributor

@kuzkry kuzkry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice style, that's a very clean piece of code. I like the cleverness of how you approached writing unit tests as you employ a compiler to do most of the work.

Copy link
Contributor

@kuzkry kuzkry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I forgot to ask you is whether the diff in googlemock/include/gmock/gmock-spec-builders.h has to be so huge :)

@adambadura
Copy link
Contributor Author

adambadura commented Aug 17, 2019

One thing I forgot to ask you is whether the diff in googlemock/include/gmock/gmock-spec-builders.h has to be so huge :)

I don't know how to make it smaller. The change is simple - added part around SignatureOf and moving of MockFunction to internal namespace. Yet Git somehow perceives it in a more difficult way.

@kuzkry
Copy link
Contributor

kuzkry commented Aug 18, 2019

Yes, sometimes the diff algorithm gets crazy. Thanks and keep up the good work :)

@adambadura adambadura force-pushed the MockFunctionFromStdFunction branch 4 times, most recently from d971444 to 6892c20 Compare August 26, 2019 19:49
@akonradi
Copy link
Contributor

@gennadiycivil this was split out from #2319, would you mind taking a look? I was looking for something like this today and realized @adambadura had already written it in OSS land.

@adambadura adambadura force-pushed the MockFunctionFromStdFunction branch 2 times, most recently from 985ba25 to b536866 Compare August 29, 2019 20:39
@adambadura adambadura force-pushed the MockFunctionFromStdFunction branch from b536866 to 4d48d6b Compare September 16, 2019 21:43
@adambadura adambadura force-pushed the MockFunctionFromStdFunction branch from 4d48d6b to 30f54af Compare September 30, 2019 16:38
@CJ-Johnson
Copy link
Contributor

@adambadura Thank you for the PR! After discussing this with the other owners, we're not interested in changing the "meaning" of the name MockFunction (from class template to alias template).

That said, we would be willing to consider a new name for this exact behavior. The new name would be an alias template out the gate. Is that a change you'd be open to?

@adambadura
Copy link
Contributor Author

adambadura commented Oct 1, 2019

@adambadura Thank you for the PR! After discussing this with the other owners, we're not interested in changing the "meaning" of the name MockFunction (from class template to alias template).

That said, we would be willing to consider a new name for this exact behavior. The new name would be an alias template out the gate. Is that a change you'd be open to?

@CJ-Johnson Sure. I prefer my approach, but I'm fine with your approach as well. And definitely either one is better than none. ;)

However, what precisely you want to get?

  1. I will get the MockFunction back to the main namespace (from internal where I have put it in this change).
  2. But what name to pick for the new entity that will handle std::function? MockFunctor?
  3. Should the new entity work with both std::function and function signatures? I would recommend so to have a universal solution.
  4. Should the SignatureOf remain part of the public interface or should it be handled by the new entity directly? Either way, I would strongly recommend an approach that allows users to extend the behavior for compatible function wrappers (like boost::function for example).

@sbenzaquen
Copy link
Collaborator

Sorry for the delay.
I consulted with a coworker and my misgivings about this change have been solved.
Let's do this:

  1. MockFunction<T> supports T=std::function<F>. We talked about supporting other callable types, like function pointers, but decided that we don't need to do that now. If there is a need in the future, it could be easily added.
  2. SignatureOf would be an implementation detail, live in internal and not be mentioned in the .md documentation.

Thanks for the effort!

@adambadura adambadura force-pushed the MockFunctionFromStdFunction branch 3 times, most recently from 519c495 to ec9081a Compare October 30, 2019 23:24
@adambadura adambadura force-pushed the MockFunctionFromStdFunction branch 2 times, most recently from d5d0e9e to f028173 Compare November 6, 2019 22:17
@adambadura adambadura force-pushed the MockFunctionFromStdFunction branch from f028173 to f04d2a0 Compare November 10, 2019 09:34
@adambadura adambadura force-pushed the MockFunctionFromStdFunction branch from f04d2a0 to 334d349 Compare November 18, 2019 22:21
@adambadura adambadura force-pushed the MockFunctionFromStdFunction branch from 334d349 to 69de33e Compare November 28, 2019 00:26
@sbenzaquen
Copy link
Collaborator

After testing this change, I found that this breaks valid use cases.
We can't make testing::MockFunction<T> be an alias with a dependent type on it. That breaks type deduction, specializations, etc.

Eg, this code:

template <typename T>
void Foo(testing::MockFunction<T>& t);

will not be able to deduce the T anymore when passing an instance of the type.

We have to keep testing::MockFunction as a class template.
An alternative solution is to make testing::MockFunction be like:

template <typename T>
class MockFunction : public internal::MockFunction<internal::SignatureOfT<T>> {
  using Base = internal::MockFunction<internal::SignatureOfT<T>>;
 public:
  using Base::Base;
};

@adambadura
Copy link
Contributor Author

@sbenzaquen, I have implemented it the way you suggested. Also, I have added tests that check the property you asked for so that no such error is made in the future.

However, I don't know why the verification failed. It did work on my (similar I think) configuration at my end. And I don't know how to get to exact logs of the failure. What can I do about it?

@adambadura adambadura force-pushed the MockFunctionFromStdFunction branch from 5ee757d to a47a850 Compare January 4, 2020 20:04
@adambadura adambadura force-pushed the MockFunctionFromStdFunction branch from a47a850 to b73a04a Compare January 25, 2020 11:12
@sbenzaquen
Copy link
Collaborator

The problem is that tests in the different _test.cc files have the same names and are colliding when running the gmock_all test. (they are all linked together and failing then).
Maybe rename the one in generated- to have Generated in its name.

@adambadura adambadura force-pushed the MockFunctionFromStdFunction branch from b73a04a to 0dbed89 Compare January 28, 2020 22:38
@adambadura
Copy link
Contributor Author

The problem is that tests in the different _test.cc files have the same names and are colliding when running the gmock_all test. (they are all linked together and failing then).
Maybe rename the one in generated- to have Generated in its name.

It did help! Thanks! I just couldn't see what is the problem. I tried building on Linux subsystem on my Windows and even on Linux itself at work but got the same and didn't know how to proceed. Now it works.

Although I used a different naming approach, to mimic already existing one in those files.

However, I wonder why those tests are duplicated in the first place.

@adambadura adambadura force-pushed the MockFunctionFromStdFunction branch from 0dbed89 to dbdc618 Compare February 10, 2020 20:14
@adambadura adambadura force-pushed the MockFunctionFromStdFunction branch from dbdc618 to 5b7a3fb Compare March 1, 2020 22:46
Add tests checking that ::testing::MockFunction template argument can
be deduced in a function call context. This is a property raised in the
review, however, not checked before by any tests.
@adambadura adambadura force-pushed the MockFunctionFromStdFunction branch from 5b7a3fb to 53740eb Compare March 18, 2020 00:12
@adambadura
Copy link
Contributor Author

@sbenzaquen , can we finally proceed with this change?

zhangxy988 pushed a commit that referenced this pull request Mar 24, 2020
@zhangxy988 zhangxy988 merged commit 67cc660 into google:master Mar 24, 2020
@adambadura adambadura deleted the MockFunctionFromStdFunction branch March 25, 2020 00:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants