-
Notifications
You must be signed in to change notification settings - Fork 176
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 ReturnCapture for methods returning a ref to capture a value inside the mock then return a ref to it. #332
Add ReturnCapture for methods returning a ref to capture a value inside the mock then return a ref to it. #332
Conversation
…urn for return by ref or const ref function.
…com:iress/FakeIt into OSS-7-copy-return-for-return-by-ref-methods
…rn-by-ref-methods' into iress-OSS-7-copy-return-for-return-by-ref-methods
TL;DR - I'm happy enough for the PR to be merged as is. Good pickup with the slicing issue.
My own thinking, that when there is only one possible implementation, then it might make sense. From memory I added a test which indicates this, but haven't checked the updated PR. However not to fussed for the current PR. At least there is an option to work around it. And we could change our minds later as it wouldn't be a breaking change. ReturnCapture - I guess it's okay as a name. Don't want to hold it up based on that.
I guess they are lower priority. For me I sort of wanted to fix these hopefully straight forward Return improvements to handle all sensible and common C++11 scenarios. (it's simple and easy to pass in temporaries to a (Always)Return). After that I was hoping there would be an agreed way forward to handle the dangling reference problem with argument passing for mocked methods and then validating afterwards ... I think this is the biggest problem with the library as it is, and was also meant to be a selling point. I think the assumption that args are either values, or long lived is usually not the case for things like strings or container classes. If it's a breaking change then we may need a way to opt into it. |
Thanks for the feedback. I think you're right, the PR looks good enough as is and future improvements can always be added later in another PR, as it seems they won't break anything. If you're talking about #274, yeah it's a tricky issue, I've never looked too deep into it. But I guess that an opt-in way of copying reference arguments (instead of the reference itself) could be a short-term workaround for most usages (it will only work for copyable types that don't have too disruptive side effects on their copy constructor, which is probably true for the majority of types but not for all). |
…eplaced implicit ReturnCopy by compile error.
833de50
to
c579f5a
Compare
Follow up on was was started by #280 (and #310).
What this PR contains:
(Always)ReturnCapture
for methods returning a reference that will either copy or move the parameter inside the lambda and return a reference to it when the mocked function is called.(Always)Return
taking an rvalue reference as parameter for methods returning a reference.(Always)Return
doesn't support mocking methods returning rvalues reference anyway, and most often this overload would be called with a temporary which would result in returning a dangling reference.What changed compared to the previous PR:
(Always)ReturnCopy
was renamed to(Always)ReturnCapture
because it also support moving values instead of only copying it.(Always)ReturnCopy
when passing an rvalue reference to(Always)Return()
for methods returning a reference was replaced by a compilation error. The intent is to not introduce too much magic inside the different functions, and make their behavior a bit more explicit ((Always)Return()
always only forward references for methods returning references, and if you want to capture then the only way to do it is to call(Always)ReturnCapture
). The error message should be clear enough to not cause too much trouble to the user:(Always)ReturnCapture
, this will prevent slicing issues, but forces us to pass a type that can be bound to the return value of the method:The last point make the syntax a bit worse than
(Always)ReturnCopy
, but it prevents a bug so I guess it's ok, and the error message is somewhat nice if the wrong type is passed so it's not that bad:The things I'm not so sure about:
(Always)ReturnCapture
is only implemented for methods returning a reference, as it doesn't really make any sense for methods returning a value as(Always)Return
already captures. But maybe it's better to make it available for all methods to make the API more consistent, I don't know.(Always)ReturnAndSet
orMethod(mock, func) = obj
, maybe they should be expanded to impact them as well.(Always)Return
should work for methods returning rvalue references. But(Always)ReturnCapture
should already work with these methods so maybe it's enough (but it's not tested I guess so tests should be added to ensure it works).(Always)ReturnCapture
a good name ?@malcolmdavey Does it seem like the feature still covers your needs ?