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

feat: add count to expectCall cheatcodes #4833

Merged
merged 1 commit into from
Apr 27, 2023

Conversation

reubenr0d
Copy link
Contributor

Closes #4513

Motivation

Currently we can only assert that a call is made to a function using expectCall(), it would be nice to have another cheatcode to check the number of time a call was made, which can also be useful to assert if a call is not made.

Solution

Overriding the expectCall cheatcodes to also accept the number of times it is expected to be called and enforce the same.

@reubenr0d
Copy link
Contributor Author

reubenr0d commented Apr 26, 2023

Adding cheatcodes to VM.sol : foundry-rs/forge-std#360

@reubenr0d reubenr0d closed this Apr 26, 2023
@reubenr0d reubenr0d reopened this Apr 26, 2023
Copy link
Member

@mattsse mattsse left a comment

Choose a reason for hiding this comment

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

wdyt @mds1

Comment on lines +213 to +214
/// The number of times the call is expected to be made
pub count: u64,
Copy link
Member

Choose a reason for hiding this comment

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

I can see how this could be useful

@mds1
Copy link
Collaborator

mds1 commented Apr 27, 2023

Yep in favor of this, per #509 (comment). We should also add a similar overload for expectEmit in a follow up PR.

Also @reubenr0d two questions:

  • Thanks for this + the forge-std PR! Can you also open a PR to the book repo for docs?
  • If want to expect no calls for a given target/selector (i.e. just the selector, and not caring about the rest of the calldata), can I just past 4 bytes to the cheat? I forget how it works exactly 😅

Copy link
Member

@mattsse mattsse left a comment

Choose a reason for hiding this comment

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

lgtm,

tests look great

@mattsse mattsse merged commit 8f246e0 into foundry-rs:master Apr 27, 2023
@reubenr0d
Copy link
Contributor Author

Can you also open a PR to the book repo for docs?

Sure, @mds1

can I just past 4 bytes to the cheat?

Yep, but as bytes not bytes4, so something like:

cheats.expectCall(address(target), abi.encodeWithSelector(target.add.selector), 0);

@mds1
Copy link
Collaborator

mds1 commented Apr 28, 2023

It looks like the regular expectCall methods without the new overload now fail if the call count is not 1, i.e. this was a breaking change because previously expectCall allowed any number of calls, but now it defaults to 1.

I'm not sure if this was intentional, but personally I'm ok with this change. Curious to hear your thoughts here @reubenr0d @mattsse. If we keep it, @reubenr0d do you mind getting another PR in to forge-std to update the code comments in Vm.sol to mention that the versions that don't take a count arg default to 1? (and mention this in the book PR too of course)

@reubenr0d
Copy link
Contributor Author

I'm not sure if this was intentional

Oh that's right! It was intentional, but it didn't strike me earlier, good catch.

Personally I'm okay with this as well, but I will let you'll (@mds1 and @mattsse) decide on how to proceed here.

@lnist
Copy link

lnist commented Apr 28, 2023

Just to chime in: we were using expectCall to generically verify all functions from our ABI had been called in a test with code similar to:

    for (uint i = 0; i < selectors.length; i++) {
      vm.expectCall(address(foo), selectors[i]);
    }

With the new API we cannot do this entirely generically since some functions will be invoked multiple times.

I am OK with the change, just wanted to mention it :)

@reubenr0d
Copy link
Contributor Author

Hmm, on second thought and on seeing that other might have issues with this, I think it's best we preserve compatibility. I'll push a fix for this shortly.

@vicnaum
Copy link

vicnaum commented Apr 28, 2023

If I put 10 expectCalls, would it expect 10 calls? I.e. do they sum up if I add more expectCall lines? Cause that's what I was thinking how it works and had several expectCalls lines if I expected several (identical) calls.

But now it fails after I've upgraded. So should I just leave one expectCall put a number there now?

@PaulRBerg
Copy link
Contributor

If I put 10 expectCalls, would it expect 10 calls? I.e. do they sum up if I add more expectCall lines?

It should definitely work like this. See @reubenr0d's comment here:

#4845 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

mockCall count
6 participants