General feedback #7
Replies: 5 comments 12 replies
-
Thanks for the feedback @andreivladbrg ! Excited to iterate until we get something that matches your workflow at Sablier.
Yes, this makes sense. I wasn't aware that this was a best practice.
Hmmm, I think I need help understanding exactly this one. For the subtree bellow, we don't need either of
I guess the invariant here would be that leaf
That resulted in: modifier whenIncludedInMerkleTree() {
_;
}
function test_Claim() external whenCampaignHasNotExpired whenNotClaimed whenIncludedInMerkleTree {
...
} So, it is not immediately clear to me what the criteria for generating the modifiers is. What are your thoughts?
Yes, this makes total sense to me, I'm not sure why I didn't do this from the beginning. Will create issues for the actionable items for now, and will work on them when I have some time. PS: You have an extra test case not covered in the tree: function test_RevertWhen_InvalidAmount()
external
whenCampaignHasNotExpired
whenNotClaimed
whenNotIncludedInMerkleTree
{
uint256 index1 = defaults.INDEX1();
uint128 invalidAmount = 1;
bytes32[] memory merkleProof = defaults.index1Proof();
vm.expectRevert(abi.encodeWithSelector(Errors.SablierV2AirstreamCampaign_InvalidProof.selector));
campaignLL.claim(index1, users.recipient1.addr, invalidAmount, merkleProof);
} |
Beta Was this translation helpful? Give feedback.
-
No worries, glad I can help.
Yes, we don't need the modifiers enumerated because we declare another modifier,
I am not sure I understand this part. modifier whenNotIncludedInMerkleTree() {
_;
}
function test_RevertWhen_InvalidIndex() external whenNotIncludedInMerkleTree { }
function test_RevertWhen_InvalidRecipient() external whenNotIncludedInMerkleTree { }
function test_RevertWhen_InvalidAmount() external whenNotIncludedInMerkleTree { }
function test_RevertWhen_InvalidMerkleProof() external whenNotIncludedInMerkleTree { }
modifier whenIncludedInMerkleTree() {
_;
}
function test_Claim() external whenIncludedInMerkleTree { } See, for the I hope it's cleared now.
That's right, thank you🙌. |
Beta Was this translation helpful? Give feedback.
-
Main IssueHey guys, I have just been able to catch up with the discussion here. Great feedback @andreivladbrg, and thanks for your questions, @alexfertel - poking holes in our tests is the best way to improve them and make our implicit assumptions explicit. In short, the issue is that at Sablier we have applied a seemingly inconsistent methodology for mapping leaf nodes ( Detour: "It" BranchesThe main issue is connected to another inconsistency regarding the multiplicity of "it" leaves (a point made by @mds1 in #22 (comment)). How should multiple "it"s be handled by Bulloak?
There is no one-size-fits-all solution, unfortunately. There are cases where we've chosen the 1st approach in Sablier, and other cases when we've chosen the 2nd approach. It all depends upon the "topology" of the function under test. In an ideal world, Bulloak would let users specify their preference via a CLI flag. But to make progress in this discussion, let's assume that we go with the 1st approach and generate one test-per-it-branch (1st approach). Proposed SolutionIt has been suggested above that the solution is related to whether the leaf is a revert or whether it is the only child of a What matters is whether the
ExamplesLet's look at two examples: Claim1
Cancel2The following
Footnotes |
Beta Was this translation helpful? Give feedback.
-
I got some good feedback about modifiers for leaf |
Beta Was this translation helpful? Give feedback.
-
As discussed privately I will leave my feedback here:
When naming the function tests, it should be "RevertWhen" instead of "RevertsWhen" (without the "s"). All functions should include underscores between the word "test" and "RevertWhen," or "test" and the function name. You can have a look at point 6 in the Foundry book's best practices.
When handling branches that are a bit more complex,
bulloak
prints more modifiers than needed. Let's take, for example, this tree I just wrote:https://github.com/sablier-labs/v2-periphery/blob/feat/airstreams-linear/test/integration/airstream/campaign-ll/claim/claim.tree
The modifiers and functions should look like what I wrote here:
https://github.com/sablier-labs/v2-periphery/blob/feat/airstreams-linear/test/integration/airstream/campaign-ll/claim/claim.t.sol
What bulloak prints can be seen here: https://app.warp.dev/block/eKFFjxZ1wm3LinXNX1ZDRC
There shouldn't be a modifier for each branch inside the "when the claim is not included in the Merkle tree" branch; instead, the conditions should be at the end of the function.
Also, it would be really cool if you could manage to merge the modifiers and functions all together, rather than printing all the modifiers at the beginning and then all the functions. It would look like this:
Please let me know if you have any questions about these suggestions.
Beta Was this translation helpful? Give feedback.
All reactions