-
Notifications
You must be signed in to change notification settings - Fork 528
Expected calls matching several actual calls - (3) Implementation of "multi-matching" expectedCalls. #1023
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
Expected calls matching several actual calls - (3) Implementation of "multi-matching" expectedCalls. #1023
Conversation
Now a single expectedCall object can match multiple actual calls. The method expectNCalls is not handled any more as just a collection of N expectedCall objects, but just a single expectedCall that requires exactly N calls to be considered fulfilled. Strict ordering checks are not working for the moment, except when all expected calls are for exactly 1 call (e.g. only using expectOneCall). Actual calls order is not registered properly, so for the meantime failure messages just show the expectations that were fulfilled in declaration order, as it has no sense anymore to order them by call order. Composite calls are not needed any more, they have been disabled by pre- compiling them out (#if 0) along with their tests.
The decrease in coverage is just due to mathematics: Having deleted the composite calls, there are fewer lines of code, so the already uncovered ones gain a bit of weight. |
virtual ~MockCheckedExpectedCall(); | ||
|
||
virtual MockExpectedCall& withName(const SimpleString& name) _override; | ||
virtual MockExpectedCall& withCallOrder(unsigned int callOrder) _override; | ||
virtual MockExpectedCall& withCallOrder(unsigned int callOrder) _override { return withCallOrder(callOrder, callOrder); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you avoid inline implementations, as they have caused problems in the past (on some platform)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's just temporary, in subsequent PRs I clean this up, removing that superfluous call.
But I can fix that anyway for the meantime if you want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@basvodde would you like to give more information about the unexpected behavior for inline function :)? I have also met unexpected behavior on one TI's platform but can't dig out the reason
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually do not know. I just know that @arstrube removed all inline functions over time :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe @arstrube could give his opinion on this. Shall I fix that in this PR, or is it OK to leave it for a short while, taking in account that the next 2 PRs that I've planned are cleanup ones, where actually that superfluous method is removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cuitoldfish I'm not sure if this is the reason why @arstrube removed inline implementations, but it might be just because, for testing, inline methods can't be mocked up.
In my projects I only accept inline implementations when these are only trivial calls to other overloaded methods for the same function (i.e. just adding default values or simple transformations of parameters). In these cases, it's fine doing it like that because it doesn't affect testability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's been a long time, and it had to do with the TI Cl2000 compiler. I can't recall what the problem was and, unfortunately, have no longer access to that compiler for testing. The only way to find out would be to look at old commit comments..... I can't completely rule out that it was unexpected runtime behavior, although I am fairly certain it wasn't.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jgonzalezdr I think it's okay to leave it until the method is removed. There were worse problems for the Ti Cl2000 in the past and the only person who noticed them was me :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jgonzalezdr ...after many moons.
This PR is rather huge. But, based on the comments, won't this cause a problem by not failing the test in the actualCall as soon as it is possible to fail it? |
The effect of delaying the callWasMade has no incidence on failures, because out of order calls actually don't make the tests fail immediately when a call is made out of order, that behavior hasn't changed at all: an out of order failure is triggered only when calling checkExpectations() on the mock support, and only if there isn't any other failure (like expected calls not fulfilled). In fact, with these changes, the internal state of expected calls is more coherent: In the current implementation, when strict ordering is enabled, all the unfulfilled expected calls that match the actual call function name are marked as "out of order" if they don't match the order (i.e. normally all the calls except one), even if they are later discarded and not actually "called" at all. If the test doesn't fail it's not relevant, because finally all the calls will match and be marked as "in order"; and if the test does fail it's also irrelevant, because this information is not displayed to the user. With the new implementation, the expected call is considered "out of order" only if it's actually called out of order, in other cases it's considered to be "in order". |
You may find it easier to review this PR if you review the individual commits:
|
Could you next time make the PRs still smaller :) |
Any way, from the users perspective, the behaviour of the framework is the same than before, except for the information displayed when a test fails. |
I would have loved to push a smaller PR, but sincerely I didn't manage to reduce this one without passing by an intermediate state where the framework is actually broken :-(. |
@basvodde: Do yo need any extra information that may help you review this PR? May I help in any way? |
For now, just need more time. Been trying to have a short vacation :) |
Then enjoy your vacation! ;-) |
Any update on this stale PR? Still very interested in this major performance enhancement. |
Hi all. Sorry for the delay on this one. I finally spend a couple hours checking this (and checking an alternative implementation). I guess the above implementation is pretty clean. Though the mocking code needs to be cleaned up a bit more in the future. I'll merge this. Hope everyone can make smaller commits in the future. Sorry for being the bottleneck on this important change. Thanks @jgonzalezdr !! |
Woohoo! Better late than never. Thanks @basvodde |
Woohoo! Better late than never. Thanks Bas!
…On Sun, Jan 7, 2018 at 1:48 AM, Bas Vodde ***@***.***> wrote:
Merged #1023 <#1023>.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#1023 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ACGwY-vi-2QkJUjKbzWz2UkvfCza16cXks5tIJLpgaJpZM4JM26p>
.
|
Great news! Thanks @jgonzalezdr and @basvodde. |
This PR adds at least the initial implementation of multi-matching expected calls, but only for a fixed number of expected calls.
The basic idea is simple: An actual call is not considered to be made until checkExpectations() is called on it (i.e. another actual call has been created or checkExpectations() is called on the mock support), therefore callWasMade() is not called on the matching expected call until there is only a single one selected (i.e. the one which fulfills the actual call). When this occurs, the corresponding count of matched actual calls on the expected call is increased.
The drawback of this is that actual calls order is not registered properly, so for the meantime
failure messages just show the expectations that were fulfilled in
declaration order, as it has no sense anymore to order them by call
order. This will be corrected in subsequent PRs.