Closed erikdoe closed 4 years ago
Actually variadic macros is still possible, see this link, but it's a bit bulky.
Also, I'd prefer quantifier at second place, especially with universal OCMVerify
version.
BTW, why do you omit "exact" version of quantifier (e.g. [OCMQnt exactly:2]
)?
Thank you for the link. I had seen that the pre-processor itself can do variadic macros but I don't see a way how to use those for our purposes. The trick described in the answer you linked to may work. I just need to check how often the arguments to the top-level macro are evaluated.
Putting the quantifier second makes sense in case of variadic macros. For the statement-based approach it's not possible.
Once it's clear what path to take, I'd add more quantifiers, including the "exact" one you mentioned. I've only used a few so far to show how it would look.
I'm getting OCMock/OCMVerifier.h file not found
:(
@erikdoe, hi! Can you merge this feature and release new version of library? It very useful for my project.
@atom-wintermute Theoretically yes. I'm still unsure which syntax to use, though. Do you have an opinion on which of the three options (listed above) is the most preferrable?
@erikdoe, I like the second option with shortlands most, it looks as concise as possible.
Thanks to @tarbayev I now found a much nicer solution. OCMVerify
becomes variadic and as an optional argument before the invocation you can pass a quantifier. This can now be created with a variation of the factory as implemented previously. In total the invocations look like this:
OCMVerify([someObject doStuff]); // no quantifier
OCMVerify(OCMQ.atLeastOnce, [someObject doStuff]); // quantifier without args
OCMVerify(OCMQ.atLeast(2), [someObject doStuff]); // quantifier with args
Unless someone objects in the next week or so, I'll add the remaining quantifiers, mainly an exactly quantifier, and then merge this into master.
To simplify the implementation and increase readability, I replaced the clever factory with plain macros. So, the syntax is now:
OCMVerify([someObject doStuff]); // no quantifier
OCMVerify(atLeastOnce(), [someObject doStuff]); // quantifier without args
OCMVerify(atLeast(2), [someObject doStuff]); // quantifier with args
This is similar to option 2 in the original version. I got a bit worried about name collisions, which is why there is a prefixed version of the macros, e.g. OCMAtLeastOnce()
instead of just atLeastOnce()
. The short macros can be disabled by defining OCM_DISABLE_SHORT_SYNTAX
like in OCHamcrest.
By the way, I decided to have the quantifier as a first argument because that way it is more visible with long method invocations.
Planned for a long time (see #109 for example), this change contains several proposals how quantifiers could be implemented. Currently it is only possible to verify that a method has been called at least once (using verify) or that it was never called (using reject). With quantifiers it is possible to specify precisely how often a method should be invoked.
This proposal showcases three different options to implement quantifiers. This PR is meant as a basis to discuss the best option. It will only be merged once we've settled on one option.
The three options are: (for details see OCMQuantifierTests)
1) Creating the quantifier, passing it as an argument to a new verify macro. (Unfortunately, variadic macros won't work so we can't re-use the existing
OCMVerify()
macro for this.)2) Using some macro/block trickery to avoid the "boring" part of the quantifier creation. This still needs a macro with a new name because it still has two arguments. Note that there won't be IDE support for discovering/typing this shorthand.
3) Using multiple statements. This looks a bit weird but means we could use the existing macro:
What do you think? Which option would you prefer? And why?