diff --git a/src/storage/src/list.cairo b/src/storage/src/list.cairo index 81668206..db161a1f 100644 --- a/src/storage/src/list.cairo +++ b/src/storage/src/list.cairo @@ -25,6 +25,7 @@ trait ListTrait { fn append(ref self: List, value: T) -> u32; fn get(self: @List, index: u32) -> Option; fn set(ref self: List, index: u32, value: T); + fn clean(ref self: List); fn pop_front(ref self: List) -> Option; fn array(self: @List) -> Array; } @@ -71,6 +72,11 @@ impl ListImpl, impl TDrop: Drop, impl TStore: Store Store::write_at_offset(self.address_domain, base, offset, value).unwrap_syscall(); } + fn clean(ref self: List) { + self.len = 0; + Store::write(self.address_domain, self.base, self.len); + } + fn pop_front(ref self: List) -> Option { if self.len == 0 { return Option::None; diff --git a/src/storage/src/tests/list_test.cairo b/src/storage/src/tests/list_test.cairo index 0bfb4c8a..abf0d6d1 100644 --- a/src/storage/src/tests/list_test.cairo +++ b/src/storage/src/tests/list_test.cairo @@ -13,6 +13,7 @@ trait IAListHolder { fn do_set( ref self: TContractState, index: u32, addrs_value: ContractAddress, numbers_value: u256 ); + fn do_clean(ref self: TContractState); fn do_pop_front(ref self: TContractState) -> (Option, Option); fn do_array(self: @TContractState) -> (Array, Array); } @@ -67,6 +68,13 @@ mod AListHolder { n.set(index, numbers_value); } + fn do_clean(ref self: ContractState) { + let mut a = self.addrs.read(); + let mut n = self.numbers.read(); + a.clean(); + n.clean(); + } + fn do_pop_front(ref self: ContractState) -> (Option, Option) { let mut a = self.addrs.read(); let mut n = self.numbers.read(); @@ -359,4 +367,52 @@ mod tests { let (array_addr, array_number) = contract.do_array(); assert((array_addr.len(), array_number.len()) == (0, 0), 'lens must be null'); } + + #[test] + #[available_gas(100000000)] + fn test_array_clean() { + let contract = deploy_mock(); + let mock_addr = mock_addr(); + + contract.do_append(mock_addr, 100); // idx 0 + contract.do_append(mock_addr, 200); // idx 1 + contract.do_append(mock_addr, 300); // idx 2 + contract.do_clean(); + assert(contract.do_get_len() == (0, 0), 'is empty'); + } + + #[test] + #[available_gas(100000000)] + fn test_array_clean_with_empty_array() { + let contract = deploy_mock(); + let mock_addr = mock_addr(); + + assert(contract.do_get_len() == (0, 0), 'is empty'); + + contract.do_clean(); + + assert(contract.do_get_len() == (0, 0), 'is still empty'); + } + + #[test] + #[available_gas(100000000)] + fn test_array_get_value_after_clean() { + let contract = deploy_mock(); + let mock_addr = mock_addr(); + + contract.do_append(mock_addr, 100); // idx 0 + let (addr, number) = contract.do_get(0); + assert(addr.is_some(), 'addr is some'); + assert(addr.unwrap() == mock_addr, 'should be mock_addr'); + assert(number.is_some(), 'number is some'); + assert(number.unwrap() == 100, 'should be 100'); + + contract.do_clean(); + + assert(contract.do_get_len() == (0, 0), 'len'); + + let (addr, number) = contract.do_get(0); + assert(addr.is_none(), 'addr is none'); + assert(number.is_none(), 'number is none'); + } }