Skip to content

Commit 0ff1663

Browse files
committed
feat(snforge_std): add "dynamic" return value for mock_call
1 parent 9542c93 commit 0ff1663

File tree

2 files changed

+51
-8
lines changed

2 files changed

+51
-8
lines changed

snforge_std/src/cheatcodes.cairo

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,36 @@ pub enum CheatSpan {
2020
TargetCalls: usize,
2121
}
2222

23+
/// Enum used to specify the call data that should be matched when mocking a contract call.
24+
#[derive(Copy, Drop, PartialEq, Clone, Debug)]
25+
pub enum MockCallData {
26+
/// Matches any call data.
27+
Any,
28+
/// Matches the specified serialized call data.
29+
Values: Span<felt252>,
30+
}
31+
32+
impl MockCallDataSerde of Serde<MockCallData> {
33+
fn deserialize(ref serialized: Span<felt252>) -> Option<MockCallData> {
34+
let value: Option<Option<Span<felt252>>> = Serde::deserialize(ref serialized);
35+
36+
match value {
37+
Option::None => Option::None,
38+
Option::Some(call_data) => match call_data {
39+
Option::None => Option::Some(MockCallData::Any),
40+
Option::Some(data) => Option::Some(MockCallData::Values(data)),
41+
},
42+
}
43+
}
44+
45+
fn serialize(self: @MockCallData, ref output: Array<felt252>) {
46+
match self {
47+
MockCallData::Any => Option::<Span<felt252>>::None.serialize(ref output),
48+
MockCallData::Values(data) => Option::Some(*data).serialize(ref output),
49+
}
50+
}
51+
}
52+
2353
pub fn test_selector() -> felt252 {
2454
// Result of selector!("TEST_CONTRACT_SELECTOR") since `selector!` macro requires dependency on
2555
// `starknet`.
@@ -43,13 +73,17 @@ pub fn test_address() -> ContractAddress {
4373
/// - `ret_data` - data to return by the function `function_selector`
4474
/// - `n_times` - number of calls to mock the function for
4575
pub fn mock_call<T, impl TSerde: core::serde::Serde<T>, impl TDestruct: Destruct<T>>(
46-
contract_address: ContractAddress, function_selector: felt252, ret_data: T, n_times: u32
76+
contract_address: ContractAddress,
77+
function_selector: felt252,
78+
call_data: MockCallData,
79+
ret_data: T,
80+
n_times: u32
4781
) {
4882
assert!(n_times > 0, "cannot mock_call 0 times, n_times argument must be greater than 0");
4983

5084
let contract_address_felt: felt252 = contract_address.into();
5185
let mut inputs = array![contract_address_felt, function_selector];
52-
86+
call_data.serialize(ref inputs);
5387
CheatSpan::TargetCalls(n_times).serialize(ref inputs);
5488

5589
let mut ret_data_arr = ArrayTrait::new();
@@ -66,13 +100,17 @@ pub fn mock_call<T, impl TSerde: core::serde::Serde<T>, impl TDestruct: Destruct
66100
/// - `contract_address` - targeted contracts' address
67101
/// - `function_selector` - hashed name of the target function (can be obtained with `selector!`
68102
/// macro)
103+
/// - `call_data` - matching call data
69104
/// - `ret_data` - data to be returned by the function
70105
pub fn start_mock_call<T, impl TSerde: core::serde::Serde<T>, impl TDestruct: Destruct<T>>(
71-
contract_address: ContractAddress, function_selector: felt252, ret_data: T
106+
contract_address: ContractAddress,
107+
function_selector: felt252,
108+
call_data: MockCallData,
109+
ret_data: T
72110
) {
73111
let contract_address_felt: felt252 = contract_address.into();
74112
let mut inputs = array![contract_address_felt, function_selector];
75-
113+
call_data.serialize(ref inputs);
76114
CheatSpan::Indefinite.serialize(ref inputs);
77115

78116
let mut ret_data_arr = ArrayTrait::new();
@@ -87,12 +125,16 @@ pub fn start_mock_call<T, impl TSerde: core::serde::Serde<T>, impl TDestruct: De
87125
/// address.
88126
/// - `contract_address` - targeted contracts' address
89127
/// - `function_selector` - hashed name of the target function (can be obtained with `selector!`
128+
/// - `call_data` - matching call data
90129
/// macro)
91-
pub fn stop_mock_call(contract_address: ContractAddress, function_selector: felt252) {
130+
pub fn stop_mock_call(
131+
contract_address: ContractAddress, function_selector: felt252, call_data: MockCallData
132+
) {
92133
let contract_address_felt: felt252 = contract_address.into();
93-
execute_cheatcode_and_deserialize::<
94-
'stop_mock_call', ()
95-
>(array![contract_address_felt, function_selector].span());
134+
let mut inputs = array![contract_address_felt, function_selector];
135+
call_data.serialize(ref inputs);
136+
137+
execute_cheatcode_and_deserialize::<'stop_mock_call', ()>(inputs.span());
96138
}
97139

98140
#[derive(Drop, Serde, PartialEq, Debug)]

snforge_std/src/lib.cairo

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pub use cheatcodes::CheatSpan;
3030
pub use cheatcodes::ReplaceBytecodeError;
3131
pub use cheatcodes::test_address;
3232
pub use cheatcodes::test_selector;
33+
pub use cheatcodes::MockCallData;
3334
pub use cheatcodes::mock_call;
3435
pub use cheatcodes::start_mock_call;
3536
pub use cheatcodes::stop_mock_call;

0 commit comments

Comments
 (0)