test kvs short-circuit and store.set revert paths in LibFlow.flow#449
test kvs short-circuit and store.set revert paths in LibFlow.flow#449thedavidmeister wants to merge 1 commit intomainfrom
Conversation
Two new tests: - testFlowBasicFlowTimeNoStoreSetWhenKvsEmpty: explicit count=0 expectCall on STORE.set when kvs is empty. Pins the existing short-circuit so a future change that drops it is caught. Mutation verified: removing the `kvs.length > 0` guard makes the test fail; reverting passes. - testFlowBasicFlowTimeStoreSetRevertBubbles: when kvs is non-empty and store.set reverts, the revert MUST propagate out of flow(). Closes #329. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
WalkthroughTwo new test cases verify uncovered code paths in ChangesLibFlow.flow edge-case test coverage
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Possibly related issues
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@test/src/concrete/Flow.time.t.sol`:
- Around line 59-63: Replace the ABI-encoded revert payloads with raw string
literals: in the vm.mockCallRevert call that currently passes
abi.encode("STORE_SET_FAILED") (with IInterpreterStoreV2.set.selector) and in
the vm.expectRevert call that uses abi.encode("STORE_SET_FAILED"), change both
to the raw string "STORE_SET_FAILED" so the mock revert and the expected revert
use the same raw UTF-8 message per Foundry convention.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 8cd9ee35-495a-4e6e-ade6-3a31d9623c5b
📒 Files selected for processing (1)
test/src/concrete/Flow.time.t.sol
| vm.mockCallRevert( | ||
| address(STORE), abi.encodeWithSelector(IInterpreterStoreV2.set.selector), abi.encode("STORE_SET_FAILED") | ||
| ); | ||
|
|
||
| vm.expectRevert(abi.encode("STORE_SET_FAILED")); |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
Foundry vm.mockCallRevert revert data bytes encoding — does passing a string literal differ from abi.encode of a string?
💡 Result:
Yes, passing a string literal to vm.mockCallRevert differs from abi.encode(string) for the retdata bytes. The official Foundry documentation shows examples using string literals directly for retdata, such as vm.mockCallRevert(..., "BALANCE_CHECK_FAILED") [1], and then vm.expectRevert("BALANCE_CHECK_FAILED") succeeds [1][2]. This works because Solidity implicitly converts the string literal "msg" to bytes via bytes("msg"), producing raw bytes equal to the UTF-8 encoding of the string (length-prefixed dynamic bytes data without Error(string) selector) [3][4]. In contrast, abi.encode(string) on a string produces ABI-encoded bytes for a single dynamic string argument: 32-byte offset (0x20) followed by length and data [5]. For example, abi.encode("msg") yields different bytes than bytes("msg"). A plain string literal revert like revert("msg") produces Error(string) ABI-encoded data: 0x08c379a0 + offset + length + "msg" [6]. But Foundry docs specify "raw return message" for retdata [1], and examples use raw string bytes to match vm.expectRevert(string) [1]. Thus, string literal → bytes("msg") (raw) ≠ abi.encode("msg") (ABI single arg) ≠ abi.encodeWithSignature("Error(string)", "msg") (full revert) [3]. Use string literals for raw revert messages matching vm.expectRevert(string); use abi.encodeWithSelector for custom errors [1].
Citations:
- 1: https://book.getfoundry.sh/reference/cheatcodes/mock-call-revert
- 2: https://foundry-book.zksync.io/reference/cheatcodes/mock-call-revert
- 3: incorrect docs for vm.expectRevert foundry-rs/foundry#5288
- 4: https://getfoundry.sh/reference/cheatcodes/expect-revert
- 5: https://saxenism.com/blog/solidity-encodings
- 6: https://gist.github.com/pcaversaccio/e1aebf9222424e9c1fbc82b8bf5fea8b
🏁 Script executed:
rg "slither-disable-next-line" test/src/concrete/Flow.time.t.solRepository: rainlanguage/flow
Length of output: 43
Use a raw string literal for the mock revert payload instead of abi.encode().
The test is self-consistent and will pass, but abi.encode("STORE_SET_FAILED") produces ABI-encoded bytes (32-byte offset + 32-byte length + 32-byte padded data), whereas a raw string literal produces raw UTF-8 bytes without the ABI encoding wrapper. These are different formats.
The idiomatic Foundry pattern (as shown in official mockCallRevert documentation) is to pass a raw string literal directly:
vm.mockCallRevert(address(token), ..., "BALANCE_CHECK_FAILED");
vm.expectRevert("BALANCE_CHECK_FAILED");Using abi.encode() here diverges from Foundry convention and could mislead future readers about the intended format.
♻️ Proposed fix
- vm.mockCallRevert(
- address(STORE), abi.encodeWithSelector(IInterpreterStoreV2.set.selector), abi.encode("STORE_SET_FAILED")
- );
-
- vm.expectRevert(abi.encode("STORE_SET_FAILED"));
+ vm.mockCallRevert(
+ address(STORE), abi.encodeWithSelector(IInterpreterStoreV2.set.selector), "STORE_SET_FAILED"
+ );
+
+ vm.expectRevert("STORE_SET_FAILED");🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@test/src/concrete/Flow.time.t.sol` around lines 59 - 63, Replace the
ABI-encoded revert payloads with raw string literals: in the vm.mockCallRevert
call that currently passes abi.encode("STORE_SET_FAILED") (with
IInterpreterStoreV2.set.selector) and in the vm.expectRevert call that uses
abi.encode("STORE_SET_FAILED"), change both to the raw string "STORE_SET_FAILED"
so the mock revert and the expected revert use the same raw UTF-8 message per
Foundry convention.
Summary
Two new tests pinning
LibFlow.flow's store-side behavior:testFlowBasicFlowTimeNoStoreSetWhenKvsEmpty— explicitcount=0expectCallonSTORE.setwhen kvs is empty. Locks the existing short-circuit so a future change that drops it is caught. Mutation verified: removing thekvs.length > 0guard makes the test fail; reverting passes.testFlowBasicFlowTimeStoreSetRevertBubbles— when kvs is non-empty andstore.setreverts, the revert MUST propagate out offlow()rather than be caught and swallowed.Closes #329.
Test plan
kvs.length > 0guard → empty-kvs test fails🤖 Generated with Claude Code
Summary by CodeRabbit