-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
fix(forge): expectCall
with no count
#4845
fix(forge): expectCall
with no count
#4845
Conversation
expectCall
with no countexpectCall
with no count
expectCall
with no countexpectCall
with no count
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.
Thanks! Agreed it makes sense to revert this back to the original behavior per the discussion in the prior PR
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.
yep, agree
I don't think this is working as expected. I pulled the latest Forge:
And our existing tests (which are using multiple standard
Upgrading to the latest |
@reubenr0d mind taking another look at this? Do you an example where it broke @PaulRBerg? |
@mattsse sure, here's an example. Code Snippet
pragma solidity >=0.8.19 <0.9.0;
import { Test } from "forge-std/Test.sol";
contract Foo {
function func() external pure returns (uint256) {
return 1;
}
}
contract Bar {
Foo internal foo;
constructor(Foo foo_) {
foo = foo_;
}
function func(uint256 times) external view returns (uint256) {
for (uint256 i = 0; i < times; ++i) {
foo.func();
}
return 1;
}
}
contract ExpectCallTest is Test {
Foo internal foo = new Foo();
Bar internal bar = new Bar(foo);
// Fails on forge 0.2.0 (f128ff9 2023-04-29T00:16:05.704419000Z)
function test_MultipleExpectCalls_1() external {
vm.expectCall({ callee: address(foo), data: abi.encodeWithSelector(foo.func.selector) });
vm.expectCall({ callee: address(foo), data: abi.encodeWithSelector(foo.func.selector) });
bar.func({ times: 2 });
}
// Passes
function test_MultipleExpectCalls_2() external {
vm.expectCall({ callee: address(foo), data: abi.encodeWithSelector(foo.func.selector), count: uint64(2) });
bar.func({ times: 2 });
}
} |
Thanks for reporting, @PaulRBerg. This was also reported here: #4833 (comment) This needs some more work in that case! Just to clarify,
But this behaviour would be different from if
While in the older versions, when There are some conflicting ideas here; keen to hear on what you'll think on how we should proceed with this. |
Nice write up, so my thoughts are:
|
💯 This is actually a useful thing in and of itself; even if there had not been a path dependence on this behavior, I would have preferred Foundry to offer it because it is needed e.g. when fuzzing and the exact number of token transfers cannot be known in advance. Basically, when not passing |
@reubenr0d do you have an ETA for reverting the previous behavior as per point 1 above? Sorry to chase - it's just that our test suite is broken now, and the only ways to fix it are to either (i) remove certain |
agree, @reubenr0d do you have bandwidth to make this work? |
I’m a bit held up at the moment, but I should be able to get around to it later in the week. |
oof, this also broke a test in one of our repos:
I guess ideally they would be in two separate test functions, but I should preserve this functionality as well I suppose. |
My guess is that a lot of Foundry repos have been affected by this breaking change - many of which will not manage to trace the issue to our discussion here, and will end up opening new issues or asking questions in the Telegram group. As a quick patch, I would suggest reverting the changes introduced by this PR (as well as #4833) until the additive behavior of |
I can try to fix this asap but need a test case that I can just use. |
Doesn't my code snippet from above work, @mattsse? We ended up disabling all of our |
Motivation
#4833 introduced a breaking change to
expectCall
whereby if nocount
was specified it would default to 1. This PR preserves the older behaviour of checking that a call is made at least once ifcount
is not specified.Solution
Change
count
type toOption<u64>
and revert to older behaviour ifis_none()