From bb0d6db163e46cb4a7c3c4d95e22b23991206512 Mon Sep 17 00:00:00 2001 From: Turka Turki Date: Thu, 3 Apr 2025 11:15:13 -0700 Subject: [PATCH 01/29] feat(testing): verify indexed keys in event assertions Add verification of indexed keys in event assertions --- packages/testing/src/events.cairo | 38 +++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/packages/testing/src/events.cairo b/packages/testing/src/events.cairo index d5874aa0f..90a1ff9bd 100644 --- a/packages/testing/src/events.cairo +++ b/packages/testing/src/events.cairo @@ -130,6 +130,31 @@ impl EventSpyQueueAssertionsTraitImpl< } } + +fn verify_indexed_keys, impl TDrop: Drop>( + expected_event: @T, + actual_keys: @Array +) -> bool { + let mut expected_keys = array![]; + let mut expected_data = array![]; + expected_event.append_keys_and_data(ref expected_keys, ref expected_data); + + + if actual_keys.len() != expected_keys.len() { + return false; + } + + let mut i = 0; + while i != expected_keys.len() { + if *actual_keys.at(i) != *expected_keys.at(i) { + return false; + } + i += 1; + } + + true +} + fn is_emitted, impl TDrop: Drop>( self: @Events, expected_emitted_by: @ContractAddress, expected_event: @T, ) -> bool { @@ -142,11 +167,14 @@ fn is_emitted, impl TDrop: Drop>( while i != self.events.len() { let (from, event) = self.events.at(i); - if from == expected_emitted_by - && event.keys == @expected_keys - && event.data == @expected_data { - is_emitted = true; - break; + if from == expected_emitted_by { + let keys_match = verify_indexed_keys(expected_event, event.keys); + let data_match = event.data == @expected_data; + + if keys_match && data_match { + is_emitted = true; + break; + } } i += 1; From 68783cd51e92d14af92b911b530040dcbb68ecce Mon Sep 17 00:00:00 2001 From: Turka Turki Date: Fri, 4 Apr 2025 00:37:44 +0600 Subject: [PATCH 02/29] update CHANGELOG for indexed keys verification in event assertions --- CHANGELOG.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c2a02596..74f09e47b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The openzeppelin_macros package with the `with_components` macro (#1282) - ERC4626Component (#1170) - `Math::u256_mul_div` (#1170) +- Add verification of indexed keys in event assertions (#1054) ### Changed @@ -87,7 +88,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bump scarb to v2.9.1 (#1239) - The initializer in `OwnableComponent` now checks that `owner` is not the zero address (#1221) - Add `verifying_contract` member to the `Delegation` struct used in Votes `delegate_by_sig` (#1214) -use crate::votes::VotesComponent::VotingUnitsTrait; + use crate::votes::VotesComponent::VotingUnitsTrait; - VotingUnitsTrait moved from `openzeppelin_governance::votes::votes` to `openzeppelin_governance::votes::VotesComponent` (#1214) - VestingComponent `release` function won't emit an event or attempt to transfer when the amount is zero (#1209) - Bump snforge_std to v0.33.0 (#1203) @@ -119,7 +120,7 @@ use crate::votes::VotesComponent::VotingUnitsTrait; - `Secp256k1PointPartialEq` replaced by a generic `Secp256PointPartialEq` - `DebugSecp256k1Point` replaced by a generic `DebugSecp256Point` - Apply underscore pattern to the internal functions of `ERC2981Component` to prevent collisions -with new external functions (#1173) + with new external functions (#1173) - Move `Hash` and `PartialEq` impls of `Call` struct from `openzeppelin_governance::timelock::utils` to `openzeppelin_governance::utils` (#1193) ## 0.18.0 (2024-10-17) @@ -261,6 +262,7 @@ with new external functions (#1173) ### Changed (Breaking) - Migrated to the `2023_11` edition (#995): + - Component implementations annotated with `#[embeddable_as()]` (e.g: `AccessControlComponent::AccessControl`) are not public anymore. Note that the embeddable versions are still public (e.g: `AccessControlComponent::AccessControlImpl`). - Implementations that can be compiler-derived from traits are not public anymore (e.g: `DualCaseAccessControlImpl` is not public while `DualCaseAccessControlTrait` is). - `Secp256k1PointPartialEq` and `DebugSecp256k1Point` are not public anymore. From 3f27d68d6999f2e34ead5aea6e79be8d9ac16c25 Mon Sep 17 00:00:00 2001 From: Turka Turki Date: Mon, 7 Apr 2025 23:26:41 +0600 Subject: [PATCH 03/29] chore: Update CHANGELOG --- CHANGELOG.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74f09e47b..274388286 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The openzeppelin_macros package with the `with_components` macro (#1282) - ERC4626Component (#1170) - `Math::u256_mul_div` (#1170) -- Add verification of indexed keys in event assertions (#1054) ### Changed @@ -88,7 +87,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bump scarb to v2.9.1 (#1239) - The initializer in `OwnableComponent` now checks that `owner` is not the zero address (#1221) - Add `verifying_contract` member to the `Delegation` struct used in Votes `delegate_by_sig` (#1214) - use crate::votes::VotesComponent::VotingUnitsTrait; - VotingUnitsTrait moved from `openzeppelin_governance::votes::votes` to `openzeppelin_governance::votes::VotesComponent` (#1214) - VestingComponent `release` function won't emit an event or attempt to transfer when the amount is zero (#1209) - Bump snforge_std to v0.33.0 (#1203) @@ -120,7 +118,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Secp256k1PointPartialEq` replaced by a generic `Secp256PointPartialEq` - `DebugSecp256k1Point` replaced by a generic `DebugSecp256Point` - Apply underscore pattern to the internal functions of `ERC2981Component` to prevent collisions - with new external functions (#1173) +with new external functions (#1173) - Move `Hash` and `PartialEq` impls of `Call` struct from `openzeppelin_governance::timelock::utils` to `openzeppelin_governance::utils` (#1193) ## 0.18.0 (2024-10-17) @@ -262,7 +260,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed (Breaking) - Migrated to the `2023_11` edition (#995): - - Component implementations annotated with `#[embeddable_as()]` (e.g: `AccessControlComponent::AccessControl`) are not public anymore. Note that the embeddable versions are still public (e.g: `AccessControlComponent::AccessControlImpl`). - Implementations that can be compiler-derived from traits are not public anymore (e.g: `DualCaseAccessControlImpl` is not public while `DualCaseAccessControlTrait` is). - `Secp256k1PointPartialEq` and `DebugSecp256k1Point` are not public anymore. @@ -410,4 +407,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Account events indexed keys (#853) - Support higher tx versions in Account (#858) - Bump scarb to v2.4.1 (#858) -- Add security section to Upgrades docs (#861) +- Add security section to Upgrades docs (#861) \ No newline at end of file From f1628dadddb9b927639dbf4b42057d92b9323b4a Mon Sep 17 00:00:00 2001 From: Turka Turki Date: Thu, 10 Apr 2025 18:38:47 +0600 Subject: [PATCH 04/29] fix(testing): improve approach to event indexed key verification - Tests will fail if indexed fields are changed in event definitions - Must explicitly specify expected indexed fields --- packages/testing/src/events.cairo | 55 +++++++++++++++---------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/packages/testing/src/events.cairo b/packages/testing/src/events.cairo index 90a1ff9bd..3d71b89d6 100644 --- a/packages/testing/src/events.cairo +++ b/packages/testing/src/events.cairo @@ -130,54 +130,53 @@ impl EventSpyQueueAssertionsTraitImpl< } } - -fn verify_indexed_keys, impl TDrop: Drop>( - expected_event: @T, - actual_keys: @Array -) -> bool { - let mut expected_keys = array![]; - let mut expected_data = array![]; - expected_event.append_keys_and_data(ref expected_keys, ref expected_data); - - - if actual_keys.len() != expected_keys.len() { - return false; - } +/// Asserts that the event's indexed keys match the expected values in order. +/// This checks that specific fields are properly marked as indexed in the event definition. +fn assert_indexed_keys, impl TDrop: Drop>( + event: @T, + expected_indexed_values: @Array +) { + let mut actual_keys = array![]; + let mut data = array![]; + event.append_keys_and_data(ref actual_keys, ref data); + + assert!( + actual_keys.len() == expected_indexed_values.len(), + "Number of indexed keys does not match expected" + ); let mut i = 0; - while i != expected_keys.len() { - if *actual_keys.at(i) != *expected_keys.at(i) { - return false; - } + while i != actual_keys.len() { + assert!( + *actual_keys.at(i) == *expected_indexed_values.at(i), + "Indexed key value does not match expected" + ); i += 1; } - - true } fn is_emitted, impl TDrop: Drop>( self: @Events, expected_emitted_by: @ContractAddress, expected_event: @T, ) -> bool { - let mut expected_keys = array![]; let mut expected_data = array![]; - expected_event.append_keys_and_data(ref expected_keys, ref expected_data); + let mut _ = array![]; + expected_event.append_keys_and_data(ref _, ref expected_data); let mut i = 0; - let mut is_emitted = false; while i != self.events.len() { let (from, event) = self.events.at(i); if from == expected_emitted_by { - let keys_match = verify_indexed_keys(expected_event, event.keys); - let data_match = event.data == @expected_data; + let mut actual_data = array![]; + let mut _ = array![]; + event.append_keys_and_data(ref _, ref actual_data); - if keys_match && data_match { - is_emitted = true; - break; + if actual_data == expected_data { + return true; } } i += 1; } - return is_emitted; + return false; } From 0ee23943d41a16af90a04069aa185c879bf80a84 Mon Sep 17 00:00:00 2001 From: Turka Turki Date: Mon, 14 Apr 2025 22:57:12 +0600 Subject: [PATCH 05/29] feat(testing): restore is_emitted to its original form --- packages/testing/src/events.cairo | 50 +++++++++++++++---------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/packages/testing/src/events.cairo b/packages/testing/src/events.cairo index 3d71b89d6..8d7dde1e8 100644 --- a/packages/testing/src/events.cairo +++ b/packages/testing/src/events.cairo @@ -130,6 +130,30 @@ impl EventSpyQueueAssertionsTraitImpl< } } +fn is_emitted, impl TDrop: Drop>( + self: @Events, expected_emitted_by: @ContractAddress, expected_event: @T, +) -> bool { + let mut expected_keys = array![]; + let mut expected_data = array![]; + expected_event.append_keys_and_data(ref expected_keys, ref expected_data); + + let mut i = 0; + let mut is_emitted = false; + while i != self.events.len() { + let (from, event) = self.events.at(i); + + if from == expected_emitted_by + && event.keys == @expected_keys + && event.data == @expected_data { + is_emitted = true; + break; + } + + i += 1; + } + return is_emitted; +} + /// Asserts that the event's indexed keys match the expected values in order. /// This checks that specific fields are properly marked as indexed in the event definition. fn assert_indexed_keys, impl TDrop: Drop>( @@ -154,29 +178,3 @@ fn assert_indexed_keys, impl TDrop: Drop>( i += 1; } } - -fn is_emitted, impl TDrop: Drop>( - self: @Events, expected_emitted_by: @ContractAddress, expected_event: @T, -) -> bool { - let mut expected_data = array![]; - let mut _ = array![]; - expected_event.append_keys_and_data(ref _, ref expected_data); - - let mut i = 0; - while i != self.events.len() { - let (from, event) = self.events.at(i); - - if from == expected_emitted_by { - let mut actual_data = array![]; - let mut _ = array![]; - event.append_keys_and_data(ref _, ref actual_data); - - if actual_data == expected_data { - return true; - } - } - - i += 1; - } - return false; -} From b1ffbabc429d7600f8bfb1198910e245a3632ec8 Mon Sep 17 00:00:00 2001 From: Turka Turki Date: Wed, 30 Apr 2025 11:33:51 +0600 Subject: [PATCH 06/29] Implement tests for event indexed keys across various components, including AccessControl, Ownable, Account, EthAccount, Votes, Pausable, ERC1155, ERC20, ERC4626, and ERC721. Each test verifies the correct indexed keys for events such as role grants, ownership transfers, and token transfers. --- .../access/src/tests/test_accesscontrol.cairo | 35 +++++++++++++++++ packages/access/src/tests/test_ownable.cairo | 13 ++++++- packages/account/src/tests/test_account.cairo | 20 ++++++++++ .../account/src/tests/test_eth_account.cairo | 20 ++++++++++ .../governance/src/tests/test_votes.cairo | 25 ++++++++++++ .../security/src/tests/test_pausable.cairo | 21 ++++++++++ .../src/tests/erc1155/test_erc1155.cairo | 38 +++++++++++++++++++ .../token/src/tests/erc20/test_erc20.cairo | 24 ++++++++++++ .../src/tests/erc4626/test_erc4626.cairo | 34 ++++++++++++++--- .../token/src/tests/erc721/test_erc721.cairo | 34 +++++++++++++++++ 10 files changed, 258 insertions(+), 6 deletions(-) diff --git a/packages/access/src/tests/test_accesscontrol.cairo b/packages/access/src/tests/test_accesscontrol.cairo index d040b953d..d2a406a8a 100644 --- a/packages/access/src/tests/test_accesscontrol.cairo +++ b/packages/access/src/tests/test_accesscontrol.cairo @@ -13,6 +13,8 @@ use crate::accesscontrol::interface::{ IACCESSCONTROL_ID, IAccessControl, IAccessControlCamel, IAccessControlWithDelay, RoleStatus, }; use crate::accesscontrol::{AccessControlComponent, DEFAULT_ADMIN_ROLE}; +use openzeppelin_test_common::accesscontrol::AccessControlSpyHelpers; +use openzeppelin_testing::events::assert_indexed_keys; // // Setup @@ -746,3 +748,36 @@ impl AccessControlSpyHelpersImpl of AccessControlSpyHelpers { self.assert_only_event(from_address, expected); } } + +#[test] +fn test_role_granted_event_indexed_keys() { + let role = ROLE; + let account = OTHER; + let sender = ADMIN; + + let grant_event = AccessControlComponent::RoleGranted { role, account, sender }; + let expected_keys = array![role.into(), account.into(), sender.into()]; + assert_indexed_keys(@grant_event, @expected_keys); +} + +#[test] +fn test_role_revoked_event_indexed_keys() { + let role = ROLE; + let account = OTHER; + let sender = ADMIN; + + let revoke_event = AccessControlComponent::RoleRevoked { role, account, sender }; + let expected_keys = array![role.into(), account.into(), sender.into()]; + assert_indexed_keys(@revoke_event, @expected_keys); +} + +#[test] +fn test_role_admin_changed_event_indexed_keys() { + let role = ROLE; + let previous_admin_role = ZERO; + let new_admin_role = ADMIN; + + let admin_event = AccessControlComponent::RoleAdminChanged { role, previous_admin_role, new_admin_role }; + let expected_keys = array![role.into(), previous_admin_role.into(), new_admin_role.into()]; + assert_indexed_keys(@admin_event, @expected_keys); +} diff --git a/packages/access/src/tests/test_ownable.cairo b/packages/access/src/tests/test_ownable.cairo index fc2c21a42..fe9f56d06 100644 --- a/packages/access/src/tests/test_ownable.cairo +++ b/packages/access/src/tests/test_ownable.cairo @@ -2,12 +2,13 @@ use core::num::traits::Zero; use openzeppelin_test_common::mocks::access::DualCaseOwnableMock; use openzeppelin_test_common::ownable::OwnableSpyHelpers; use openzeppelin_testing::constants::{OTHER, OWNER, RECIPIENT, ZERO}; -use openzeppelin_testing::spy_events; +use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; use snforge_std::{start_cheat_caller_address, test_address}; use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; use crate::ownable::OwnableComponent; use crate::ownable::OwnableComponent::InternalTrait; use crate::ownable::interface::{IOwnable, IOwnableCamelOnly}; +use openzeppelin_testing::events::assert_indexed_keys; // // Setup @@ -204,3 +205,13 @@ fn test_renounceOwnership_from_nonowner() { start_cheat_caller_address(test_address(), OTHER); state.renounceOwnership(); } + +#[test] +fn test_ownership_transferred_event_indexed_keys() { + let previous_owner = ZERO; + let new_owner = OWNER; + + let transfer_event = OwnableComponent::OwnershipTransferred { previous_owner, new_owner }; + let expected_keys = array![previous_owner.into(), new_owner.into()]; + assert_indexed_keys(@transfer_event, @expected_keys); +} diff --git a/packages/account/src/tests/test_account.cairo b/packages/account/src/tests/test_account.cairo index 26973f002..4f60ea299 100644 --- a/packages/account/src/tests/test_account.cairo +++ b/packages/account/src/tests/test_account.cairo @@ -9,6 +9,7 @@ use openzeppelin_testing as utils; use openzeppelin_testing::constants::stark::{KEY_PAIR, KEY_PAIR_2}; use openzeppelin_testing::constants::{ CALLER, MIN_TRANSACTION_VERSION, OTHER, QUERY_OFFSET, QUERY_VERSION, SALT, ZERO, + NEW_PUBKEY, PUBKEY, }; use openzeppelin_testing::signing::StarkKeyPair; use openzeppelin_testing::spy_events; @@ -20,6 +21,7 @@ use starknet::account::Call; use crate::AccountComponent; use crate::AccountComponent::{InternalTrait, PublicKeyCamelImpl, PublicKeyImpl, SRC6CamelOnlyImpl}; use crate::interface::{AccountABIDispatcher, AccountABIDispatcherTrait, ISRC6, ISRC6_ID}; +use openzeppelin_testing::events::assert_indexed_keys; // // Setup @@ -497,3 +499,21 @@ fn test__set_public_key() { spy.assert_only_event_owner_added(account_address, public_key); assert_eq!(state.get_public_key(), public_key); } + +#[test] +fn test_owner_added_event_indexed_keys() { + let new_owner = NEW_PUBKEY; + + let owner_added_event = AccountComponent::OwnerAdded { new_owner }; + let expected_keys = array![new_owner.into()]; + assert_indexed_keys(@owner_added_event, @expected_keys); +} + +#[test] +fn test_owner_removed_event_indexed_keys() { + let removed_owner = PUBKEY; + + let owner_removed_event = AccountComponent::OwnerRemoved { removed_owner }; + let expected_keys = array![removed_owner.into()]; + assert_indexed_keys(@owner_removed_event, @expected_keys); +} diff --git a/packages/account/src/tests/test_eth_account.cairo b/packages/account/src/tests/test_eth_account.cairo index 809b8321f..df7e0d58d 100644 --- a/packages/account/src/tests/test_eth_account.cairo +++ b/packages/account/src/tests/test_eth_account.cairo @@ -8,6 +8,7 @@ use openzeppelin_testing as utils; use openzeppelin_testing::constants::secp256k1::{KEY_PAIR, KEY_PAIR_2}; use openzeppelin_testing::constants::{ CALLER, MIN_TRANSACTION_VERSION, OTHER, QUERY_VERSION, SALT, ZERO, + ETH_SIGNER, NEW_ETH_SIGNER, }; use openzeppelin_testing::signing::Secp256k1KeyPair; use openzeppelin_testing::spy_events; @@ -24,6 +25,7 @@ use crate::EthAccountComponent::{ use crate::interface::{EthAccountABIDispatcher, EthAccountABIDispatcherTrait, ISRC6, ISRC6_ID}; use crate::utils::secp256_point::{DebugSecp256Point, Secp256PointPartialEq}; use crate::utils::signature::Secp256Signature; +use openzeppelin_testing::events::assert_indexed_keys; // // Setup @@ -540,3 +542,21 @@ fn test__set_public_key() { assert_eq!(state.get_public_key(), key_pair.public_key); } + +#[test] +fn test_eth_owner_added_event_indexed_keys() { + let new_owner = NEW_ETH_SIGNER; + + let owner_added_event = EthAccountComponent::EthOwnerAdded { new_owner }; + let expected_keys = array![new_owner.into()]; + assert_indexed_keys(@owner_added_event, @expected_keys); +} + +#[test] +fn test_eth_owner_removed_event_indexed_keys() { + let removed_owner = ETH_SIGNER; + + let owner_removed_event = EthAccountComponent::EthOwnerRemoved { removed_owner }; + let expected_keys = array![removed_owner.into()]; + assert_indexed_keys(@owner_removed_event, @expected_keys); +} diff --git a/packages/governance/src/tests/test_votes.cairo b/packages/governance/src/tests/test_votes.cairo index d8c5d014d..72e431b6e 100644 --- a/packages/governance/src/tests/test_votes.cairo +++ b/packages/governance/src/tests/test_votes.cairo @@ -22,6 +22,9 @@ use crate::votes::VotesComponent::{ DelegateChanged, DelegateVotesChanged, InternalImpl, VotesImpl, VotingUnitsTrait, }; use crate::votes::{Delegation, VotesComponent}; +use core::num::traits::Zero; +use openzeppelin_test_common::votes::VotesSpyHelpers; +use openzeppelin_testing::events::assert_indexed_keys; const ERC721_INITIAL_MINT: u256 = 10; @@ -673,3 +676,25 @@ impl VotesSpyHelpersImpl of VotesSpyHelpers { self.assert_no_events_left_from(contract); } } + +#[test] +fn test_delegate_changed_event_indexed_keys() { + let delegator = DELEGATOR; + let from_delegate = ZERO; + let to_delegate = RECIPIENT; + + let delegate_event = VotesComponent::DelegateChanged { delegator, from_delegate, to_delegate }; + let expected_keys = array![delegator.into(), from_delegate.into(), to_delegate.into()]; + assert_indexed_keys(@delegate_event, @expected_keys); +} + +#[test] +fn test_delegate_votes_changed_event_indexed_keys() { + let delegate = DELEGATOR; + let old_votes = 0; + let new_votes = SUPPLY; + + let votes_event = VotesComponent::DelegateVotesChanged { delegate, old_votes, new_votes }; + let expected_keys = array![delegate.into()]; + assert_indexed_keys(@votes_event, @expected_keys); +} diff --git a/packages/security/src/tests/test_pausable.cairo b/packages/security/src/tests/test_pausable.cairo index 7f5d70c7d..c6a901816 100644 --- a/packages/security/src/tests/test_pausable.cairo +++ b/packages/security/src/tests/test_pausable.cairo @@ -5,6 +5,9 @@ use snforge_std::{start_cheat_caller_address, test_address}; use starknet::ContractAddress; use crate::PausableComponent; use crate::PausableComponent::{InternalImpl, PausableImpl, Paused, Unpaused}; +use openzeppelin_test_common::pausable::PausableSpyHelpers; +use openzeppelin_testing::constants::OWNER; +use openzeppelin_testing::events::assert_indexed_keys; type ComponentState = PausableComponent::ComponentState; @@ -150,3 +153,21 @@ impl PausableSpyHelpersImpl of PausableSpyHelpers { self.assert_no_events_left_from(contract); } } + +#[test] +fn test_paused_event_indexed_keys() { + let account = OWNER; + + let paused_event = PausableComponent::Paused { account }; + let expected_keys = array![account.into()]; + assert_indexed_keys(@paused_event, @expected_keys); +} + +#[test] +fn test_unpaused_event_indexed_keys() { + let account = OWNER; + + let unpaused_event = PausableComponent::Unpaused { account }; + let expected_keys = array![account.into()]; + assert_indexed_keys(@unpaused_event, @expected_keys); +} diff --git a/packages/token/src/tests/erc1155/test_erc1155.cairo b/packages/token/src/tests/erc1155/test_erc1155.cairo index 579515701..cc156675e 100644 --- a/packages/token/src/tests/erc1155/test_erc1155.cairo +++ b/packages/token/src/tests/erc1155/test_erc1155.cairo @@ -18,6 +18,7 @@ use crate::erc1155::ERC1155Component; use crate::erc1155::ERC1155Component::{ ERC1155CamelImpl, ERC1155Impl, ERC1155MetadataURIImpl, InternalImpl, }; +use openzeppelin_testing::events::assert_indexed_keys; // // Setup @@ -1412,3 +1413,40 @@ impl ERC1155HooksSpyHelpersImpl of ERC1155HooksSpyHelpers { self.assert_emitted_single(contract, expected); } } + +#[test] +fn test_transfer_single_event_indexed_keys() { + let operator = OPERATOR; + let from = OWNER; + let to = RECIPIENT; + let id = TOKEN_ID; + let amount = TOKEN_VALUE; + + let transfer_event = ERC1155Component::TransferSingle { operator, from, to, id, amount }; + let expected_keys = array![operator.into(), from.into(), to.into()]; + assert_indexed_keys(@transfer_event, @expected_keys); +} + +#[test] +fn test_transfer_batch_event_indexed_keys() { + let operator = OPERATOR; + let from = OWNER; + let to = RECIPIENT; + let ids = array![TOKEN_ID, TOKEN_ID_2, TOKEN_ID_3]; + let amounts = array![TOKEN_VALUE, TOKEN_VALUE_2, TOKEN_VALUE_3]; + + let transfer_event = ERC1155Component::TransferBatch { operator, from, to, ids, amounts }; + let expected_keys = array![operator.into(), from.into(), to.into()]; + assert_indexed_keys(@transfer_event, @expected_keys); +} + +#[test] +fn test_approval_for_all_event_indexed_keys() { + let owner = OWNER; + let operator = OPERATOR; + let approved = true; + + let approval_event = ERC1155Component::ApprovalForAll { owner, operator, approved }; + let expected_keys = array![owner.into(), operator.into()]; + assert_indexed_keys(@approval_event, @expected_keys); +} diff --git a/packages/token/src/tests/erc20/test_erc20.cairo b/packages/token/src/tests/erc20/test_erc20.cairo index 3b0c9fcfe..510e33686 100644 --- a/packages/token/src/tests/erc20/test_erc20.cairo +++ b/packages/token/src/tests/erc20/test_erc20.cairo @@ -7,6 +7,7 @@ use snforge_std::{start_cheat_caller_address, test_address}; use starknet::ContractAddress; use crate::erc20::ERC20Component; use crate::erc20::ERC20Component::{ERC20CamelOnlyImpl, ERC20Impl, ERC20MetadataImpl, InternalImpl}; +use openzeppelin_testing::events::assert_indexed_keys; // Custom implementation of the ERC20Component ImmutableConfig used for testing. impl ERC20ImmutableConfig of ERC20Component::ImmutableConfig { @@ -687,3 +688,26 @@ impl ERC20HooksSpyHelpersImpl of ERC20HooksSpyHelpers { self.assert_emitted_single(contract, expected); } } + +#[test] +fn test_transfer_event_indexed_keys() { + let mut state = setup(); + let from = OWNER; + let to = RECIPIENT; + let value = VALUE; + + let transfer_event = ERC20Component::Transfer { from, to, value }; + let expected_keys = array![from.into(), to.into()]; + assert_indexed_keys(@transfer_event, @expected_keys); +} + +#[test] +fn test_approval_event_indexed_keys() { + let owner = OWNER; + let spender = SPENDER; + let value = VALUE; + + let approval_event = ERC20Component::Approval { owner, spender, value }; + let expected_keys = array![owner.into(), spender.into()]; + assert_indexed_keys(@approval_event, @expected_keys); +} diff --git a/packages/token/src/tests/erc4626/test_erc4626.cairo b/packages/token/src/tests/erc4626/test_erc4626.cairo index 9a8bc29ba..e2c7f1070 100644 --- a/packages/token/src/tests/erc4626/test_erc4626.cairo +++ b/packages/token/src/tests/erc4626/test_erc4626.cairo @@ -5,7 +5,7 @@ use openzeppelin_test_common::mocks::erc20::{ }; use openzeppelin_test_common::mocks::erc4626::{ERC4626LimitsMock, ERC4626Mock}; use openzeppelin_testing as utils; -use openzeppelin_testing::constants::{ALICE, BOB, NAME, OTHER, RECIPIENT, SPENDER, SYMBOL, ZERO}; +use openzeppelin_testing::constants::{ALICE, BOB, NAME, OTHER, RECIPIENT, SPENDER, SYMBOL, ZERO, OWNER, VALUE}; use openzeppelin_testing::{AsAddressTrait, EventSpyExt, EventSpyQueue as EventSpy, spy_events}; use openzeppelin_utils::serde::SerializedAppend; use snforge_std::{CheatSpan, cheat_caller_address}; @@ -16,6 +16,7 @@ use crate::erc20::extensions::erc4626::ERC4626Component::{ }; use crate::erc20::extensions::erc4626::interface::{ERC4626ABIDispatcher, ERC4626ABIDispatcherTrait}; use crate::erc20::extensions::erc4626::{DefaultConfig, ERC4626Component}; +use openzeppelin_testing::events::assert_indexed_keys; // // Constants @@ -1631,7 +1632,7 @@ pub impl ERC4626SpyHelpersImpl of ERC4626SpyHelpers { assets: u256, shares: u256, ) { - let expected = ERC4626Component::Event::Deposit(Deposit { sender, owner, assets, shares }); + let expected = ERC4626Component::Deposit { sender, owner, assets, shares }; self.assert_emitted_single(contract, expected); } @@ -1656,9 +1657,7 @@ pub impl ERC4626SpyHelpersImpl of ERC4626SpyHelpers { assets: u256, shares: u256, ) { - let expected = ERC4626Component::Event::Withdraw( - Withdraw { sender, receiver, owner, assets, shares }, - ); + let expected = ERC4626Component::Withdraw { sender, receiver, owner, assets, shares }; self.assert_emitted_single(contract, expected); } @@ -1675,3 +1674,28 @@ pub impl ERC4626SpyHelpersImpl of ERC4626SpyHelpers { self.assert_no_events_left_from(contract); } } + +#[test] +fn test_deposit_event_indexed_keys() { + let sender = OWNER; + let owner = RECIPIENT; + let assets = VALUE; + let shares = VALUE; + + let deposit_event = ERC4626Component::Deposit { sender, owner, assets, shares }; + let expected_keys = array![sender.into(), owner.into()]; + assert_indexed_keys(@deposit_event, @expected_keys); +} + +#[test] +fn test_withdraw_event_indexed_keys() { + let sender = OWNER; + let receiver = RECIPIENT; + let owner = SPENDER; + let assets = VALUE; + let shares = VALUE; + + let withdraw_event = ERC4626Component::Withdraw { sender, receiver, owner, assets, shares }; + let expected_keys = array![sender.into(), receiver.into(), owner.into()]; + assert_indexed_keys(@withdraw_event, @expected_keys); +} diff --git a/packages/token/src/tests/erc721/test_erc721.cairo b/packages/token/src/tests/erc721/test_erc721.cairo index 53ff3023e..9063f524b 100644 --- a/packages/token/src/tests/erc721/test_erc721.cairo +++ b/packages/token/src/tests/erc721/test_erc721.cairo @@ -16,6 +16,7 @@ use crate::erc721::ERC721Component; use crate::erc721::ERC721Component::{ ERC721CamelOnlyImpl, ERC721Impl, ERC721MetadataImpl, InternalImpl, }; +use openzeppelin_testing::events::assert_indexed_keys; // // Setup @@ -1508,3 +1509,36 @@ impl ERC721HooksSpyHelpersImpl of ERC721HooksSpyHelpers { self.assert_emitted_single(contract, expected); } } + +#[test] +fn test_transfer_event_indexed_keys() { + let from = OWNER; + let to = RECIPIENT; + let token_id = TOKEN_ID; + + let transfer_event = ERC721Component::Transfer { from, to, token_id }; + let expected_keys = array![from.into(), to.into(), token_id.into()]; + assert_indexed_keys(@transfer_event, @expected_keys); +} + +#[test] +fn test_approval_event_indexed_keys() { + let owner = OWNER; + let approved = SPENDER; + let token_id = TOKEN_ID; + + let approval_event = ERC721Component::Approval { owner, approved, token_id }; + let expected_keys = array![owner.into(), approved.into(), token_id.into()]; + assert_indexed_keys(@approval_event, @expected_keys); +} + +#[test] +fn test_approval_for_all_event_indexed_keys() { + let owner = OWNER; + let operator = OPERATOR; + let approved = true; + + let approval_for_all_event = ERC721Component::ApprovalForAll { owner, operator, approved }; + let expected_keys = array![owner.into(), operator.into()]; + assert_indexed_keys(@approval_for_all_event, @expected_keys); +} From b3f8b744e755db0e023a41c99777c2e9d2be6fca Mon Sep 17 00:00:00 2001 From: Turka Turki Date: Wed, 30 Apr 2025 11:41:17 +0600 Subject: [PATCH 07/29] Update CHANGELOG to include a single newline character at the end --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32ad06caf..e7e463704 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -412,4 +412,4 @@ with new external functions (#1173) - Account events indexed keys (#853) - Support higher tx versions in Account (#858) - Bump scarb to v2.4.1 (#858) -- Add security section to Upgrades docs (#861) \ No newline at end of file +- Add security section to Upgrades docs (#861) From e71b558893ba3d97d64f1dc64495f710a80fc9ba Mon Sep 17 00:00:00 2001 From: Turka Turki Date: Wed, 30 Apr 2025 12:12:25 +0600 Subject: [PATCH 08/29] fix formatting fails --- packages/access/src/tests/test_accesscontrol.cairo | 8 +++++--- packages/access/src/tests/test_ownable.cairo | 2 +- packages/account/src/tests/test_account.cairo | 6 +++--- packages/account/src/tests/test_eth_account.cairo | 5 ++--- packages/governance/src/tests/test_votes.cairo | 6 +++--- packages/security/src/tests/test_pausable.cairo | 7 +++---- packages/testing/src/events.cairo | 7 +++---- packages/token/src/tests/erc1155/test_erc1155.cairo | 2 +- packages/token/src/tests/erc20/test_erc20.cairo | 2 +- packages/token/src/tests/erc4626/test_erc4626.cairo | 6 ++++-- packages/token/src/tests/erc721/test_erc721.cairo | 2 +- 11 files changed, 27 insertions(+), 26 deletions(-) diff --git a/packages/access/src/tests/test_accesscontrol.cairo b/packages/access/src/tests/test_accesscontrol.cairo index d2a406a8a..9b60b3a58 100644 --- a/packages/access/src/tests/test_accesscontrol.cairo +++ b/packages/access/src/tests/test_accesscontrol.cairo @@ -1,8 +1,10 @@ use openzeppelin_introspection::interface::ISRC5; +use openzeppelin_test_common::accesscontrol::AccessControlSpyHelpers; use openzeppelin_test_common::mocks::access::DualCaseAccessControlMock; use openzeppelin_testing::constants::{ ADMIN, AUTHORIZED, OTHER, OTHER_ADMIN, OTHER_ROLE, ROLE, TIMESTAMP, ZERO, }; +use openzeppelin_testing::events::assert_indexed_keys; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; use snforge_std::{start_cheat_block_timestamp_global, start_cheat_caller_address, test_address}; use starknet::ContractAddress; @@ -13,8 +15,6 @@ use crate::accesscontrol::interface::{ IACCESSCONTROL_ID, IAccessControl, IAccessControlCamel, IAccessControlWithDelay, RoleStatus, }; use crate::accesscontrol::{AccessControlComponent, DEFAULT_ADMIN_ROLE}; -use openzeppelin_test_common::accesscontrol::AccessControlSpyHelpers; -use openzeppelin_testing::events::assert_indexed_keys; // // Setup @@ -777,7 +777,9 @@ fn test_role_admin_changed_event_indexed_keys() { let previous_admin_role = ZERO; let new_admin_role = ADMIN; - let admin_event = AccessControlComponent::RoleAdminChanged { role, previous_admin_role, new_admin_role }; + let admin_event = AccessControlComponent::RoleAdminChanged { + role, previous_admin_role, new_admin_role, + }; let expected_keys = array![role.into(), previous_admin_role.into(), new_admin_role.into()]; assert_indexed_keys(@admin_event, @expected_keys); } diff --git a/packages/access/src/tests/test_ownable.cairo b/packages/access/src/tests/test_ownable.cairo index fe9f56d06..7e936a02b 100644 --- a/packages/access/src/tests/test_ownable.cairo +++ b/packages/access/src/tests/test_ownable.cairo @@ -2,13 +2,13 @@ use core::num::traits::Zero; use openzeppelin_test_common::mocks::access::DualCaseOwnableMock; use openzeppelin_test_common::ownable::OwnableSpyHelpers; use openzeppelin_testing::constants::{OTHER, OWNER, RECIPIENT, ZERO}; +use openzeppelin_testing::events::assert_indexed_keys; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; use snforge_std::{start_cheat_caller_address, test_address}; use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; use crate::ownable::OwnableComponent; use crate::ownable::OwnableComponent::InternalTrait; use crate::ownable::interface::{IOwnable, IOwnableCamelOnly}; -use openzeppelin_testing::events::assert_indexed_keys; // // Setup diff --git a/packages/account/src/tests/test_account.cairo b/packages/account/src/tests/test_account.cairo index 4f60ea299..03640cbe4 100644 --- a/packages/account/src/tests/test_account.cairo +++ b/packages/account/src/tests/test_account.cairo @@ -8,9 +8,10 @@ use openzeppelin_test_common::mocks::simple::{ISimpleMockDispatcher, ISimpleMock use openzeppelin_testing as utils; use openzeppelin_testing::constants::stark::{KEY_PAIR, KEY_PAIR_2}; use openzeppelin_testing::constants::{ - CALLER, MIN_TRANSACTION_VERSION, OTHER, QUERY_OFFSET, QUERY_VERSION, SALT, ZERO, - NEW_PUBKEY, PUBKEY, + CALLER, MIN_TRANSACTION_VERSION, NEW_PUBKEY, OTHER, PUBKEY, QUERY_OFFSET, QUERY_VERSION, SALT, + ZERO, }; +use openzeppelin_testing::events::assert_indexed_keys; use openzeppelin_testing::signing::StarkKeyPair; use openzeppelin_testing::spy_events; use snforge_std::{ @@ -21,7 +22,6 @@ use starknet::account::Call; use crate::AccountComponent; use crate::AccountComponent::{InternalTrait, PublicKeyCamelImpl, PublicKeyImpl, SRC6CamelOnlyImpl}; use crate::interface::{AccountABIDispatcher, AccountABIDispatcherTrait, ISRC6, ISRC6_ID}; -use openzeppelin_testing::events::assert_indexed_keys; // // Setup diff --git a/packages/account/src/tests/test_eth_account.cairo b/packages/account/src/tests/test_eth_account.cairo index df7e0d58d..9b409e715 100644 --- a/packages/account/src/tests/test_eth_account.cairo +++ b/packages/account/src/tests/test_eth_account.cairo @@ -7,9 +7,9 @@ use openzeppelin_test_common::mocks::simple::{ISimpleMockDispatcher, ISimpleMock use openzeppelin_testing as utils; use openzeppelin_testing::constants::secp256k1::{KEY_PAIR, KEY_PAIR_2}; use openzeppelin_testing::constants::{ - CALLER, MIN_TRANSACTION_VERSION, OTHER, QUERY_VERSION, SALT, ZERO, - ETH_SIGNER, NEW_ETH_SIGNER, + CALLER, ETH_SIGNER, MIN_TRANSACTION_VERSION, NEW_ETH_SIGNER, OTHER, QUERY_VERSION, SALT, ZERO, }; +use openzeppelin_testing::events::assert_indexed_keys; use openzeppelin_testing::signing::Secp256k1KeyPair; use openzeppelin_testing::spy_events; use openzeppelin_utils::serde::SerializedAppend; @@ -25,7 +25,6 @@ use crate::EthAccountComponent::{ use crate::interface::{EthAccountABIDispatcher, EthAccountABIDispatcherTrait, ISRC6, ISRC6_ID}; use crate::utils::secp256_point::{DebugSecp256Point, Secp256PointPartialEq}; use crate::utils::signature::Secp256Signature; -use openzeppelin_testing::events::assert_indexed_keys; // // Setup diff --git a/packages/governance/src/tests/test_votes.cairo b/packages/governance/src/tests/test_votes.cairo index 72e431b6e..4ee666f79 100644 --- a/packages/governance/src/tests/test_votes.cairo +++ b/packages/governance/src/tests/test_votes.cairo @@ -1,7 +1,10 @@ +use core::num::traits::Zero; use openzeppelin_test_common::mocks::votes::ERC721VotesMock::SNIP12MetadataImpl; use openzeppelin_test_common::mocks::votes::{ERC20VotesMock, ERC721VotesMock}; +use openzeppelin_test_common::votes::VotesSpyHelpers; use openzeppelin_testing as utils; use openzeppelin_testing::constants::{DELEGATEE, DELEGATOR, OTHER, RECIPIENT, SUPPLY, ZERO}; +use openzeppelin_testing::events::assert_indexed_keys; use openzeppelin_testing::{AsAddressTrait, EventSpyExt, EventSpyQueue as EventSpy, spy_events}; use openzeppelin_token::erc20::ERC20Component::InternalTrait; use openzeppelin_token::erc20::interface::IERC20; @@ -22,9 +25,6 @@ use crate::votes::VotesComponent::{ DelegateChanged, DelegateVotesChanged, InternalImpl, VotesImpl, VotingUnitsTrait, }; use crate::votes::{Delegation, VotesComponent}; -use core::num::traits::Zero; -use openzeppelin_test_common::votes::VotesSpyHelpers; -use openzeppelin_testing::events::assert_indexed_keys; const ERC721_INITIAL_MINT: u256 = 10; diff --git a/packages/security/src/tests/test_pausable.cairo b/packages/security/src/tests/test_pausable.cairo index c6a901816..150fdb65d 100644 --- a/packages/security/src/tests/test_pausable.cairo +++ b/packages/security/src/tests/test_pausable.cairo @@ -1,13 +1,12 @@ use openzeppelin_test_common::mocks::security::PausableMock; -use openzeppelin_testing::constants::CALLER; +use openzeppelin_test_common::pausable::PausableSpyHelpers; +use openzeppelin_testing::constants::{CALLER, OWNER}; +use openzeppelin_testing::events::assert_indexed_keys; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; use snforge_std::{start_cheat_caller_address, test_address}; use starknet::ContractAddress; use crate::PausableComponent; use crate::PausableComponent::{InternalImpl, PausableImpl, Paused, Unpaused}; -use openzeppelin_test_common::pausable::PausableSpyHelpers; -use openzeppelin_testing::constants::OWNER; -use openzeppelin_testing::events::assert_indexed_keys; type ComponentState = PausableComponent::ComponentState; diff --git a/packages/testing/src/events.cairo b/packages/testing/src/events.cairo index 8d7dde1e8..52954682a 100644 --- a/packages/testing/src/events.cairo +++ b/packages/testing/src/events.cairo @@ -157,8 +157,7 @@ fn is_emitted, impl TDrop: Drop>( /// Asserts that the event's indexed keys match the expected values in order. /// This checks that specific fields are properly marked as indexed in the event definition. fn assert_indexed_keys, impl TDrop: Drop>( - event: @T, - expected_indexed_values: @Array + event: @T, expected_indexed_values: @Array, ) { let mut actual_keys = array![]; let mut data = array![]; @@ -166,14 +165,14 @@ fn assert_indexed_keys, impl TDrop: Drop>( assert!( actual_keys.len() == expected_indexed_values.len(), - "Number of indexed keys does not match expected" + "Number of indexed keys does not match expected", ); let mut i = 0; while i != actual_keys.len() { assert!( *actual_keys.at(i) == *expected_indexed_values.at(i), - "Indexed key value does not match expected" + "Indexed key value does not match expected", ); i += 1; } diff --git a/packages/token/src/tests/erc1155/test_erc1155.cairo b/packages/token/src/tests/erc1155/test_erc1155.cairo index cc156675e..697c79575 100644 --- a/packages/token/src/tests/erc1155/test_erc1155.cairo +++ b/packages/token/src/tests/erc1155/test_erc1155.cairo @@ -9,6 +9,7 @@ use openzeppelin_testing::constants::{ EMPTY_DATA, OPERATOR, OTHER, OWNER, RECIPIENT, TOKEN_ID, TOKEN_ID_2, TOKEN_VALUE, TOKEN_VALUE_2, ZERO, }; +use openzeppelin_testing::events::assert_indexed_keys; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; use snforge_std::{start_cheat_caller_address, test_address}; use starknet::ContractAddress; @@ -18,7 +19,6 @@ use crate::erc1155::ERC1155Component; use crate::erc1155::ERC1155Component::{ ERC1155CamelImpl, ERC1155Impl, ERC1155MetadataURIImpl, InternalImpl, }; -use openzeppelin_testing::events::assert_indexed_keys; // // Setup diff --git a/packages/token/src/tests/erc20/test_erc20.cairo b/packages/token/src/tests/erc20/test_erc20.cairo index 510e33686..fa4f1913f 100644 --- a/packages/token/src/tests/erc20/test_erc20.cairo +++ b/packages/token/src/tests/erc20/test_erc20.cairo @@ -2,12 +2,12 @@ use core::num::traits::Bounded; use openzeppelin_test_common::erc20::ERC20SpyHelpers; use openzeppelin_test_common::mocks::erc20::{DualCaseERC20Mock, SnakeERC20MockWithHooks}; use openzeppelin_testing::constants::{NAME, OWNER, RECIPIENT, SPENDER, SUPPLY, SYMBOL, VALUE, ZERO}; +use openzeppelin_testing::events::assert_indexed_keys; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; use snforge_std::{start_cheat_caller_address, test_address}; use starknet::ContractAddress; use crate::erc20::ERC20Component; use crate::erc20::ERC20Component::{ERC20CamelOnlyImpl, ERC20Impl, ERC20MetadataImpl, InternalImpl}; -use openzeppelin_testing::events::assert_indexed_keys; // Custom implementation of the ERC20Component ImmutableConfig used for testing. impl ERC20ImmutableConfig of ERC20Component::ImmutableConfig { diff --git a/packages/token/src/tests/erc4626/test_erc4626.cairo b/packages/token/src/tests/erc4626/test_erc4626.cairo index e2c7f1070..24edcc1f4 100644 --- a/packages/token/src/tests/erc4626/test_erc4626.cairo +++ b/packages/token/src/tests/erc4626/test_erc4626.cairo @@ -5,7 +5,10 @@ use openzeppelin_test_common::mocks::erc20::{ }; use openzeppelin_test_common::mocks::erc4626::{ERC4626LimitsMock, ERC4626Mock}; use openzeppelin_testing as utils; -use openzeppelin_testing::constants::{ALICE, BOB, NAME, OTHER, RECIPIENT, SPENDER, SYMBOL, ZERO, OWNER, VALUE}; +use openzeppelin_testing::constants::{ + ALICE, BOB, NAME, OTHER, OWNER, RECIPIENT, SPENDER, SYMBOL, VALUE, ZERO, +}; +use openzeppelin_testing::events::assert_indexed_keys; use openzeppelin_testing::{AsAddressTrait, EventSpyExt, EventSpyQueue as EventSpy, spy_events}; use openzeppelin_utils::serde::SerializedAppend; use snforge_std::{CheatSpan, cheat_caller_address}; @@ -16,7 +19,6 @@ use crate::erc20::extensions::erc4626::ERC4626Component::{ }; use crate::erc20::extensions::erc4626::interface::{ERC4626ABIDispatcher, ERC4626ABIDispatcherTrait}; use crate::erc20::extensions::erc4626::{DefaultConfig, ERC4626Component}; -use openzeppelin_testing::events::assert_indexed_keys; // // Constants diff --git a/packages/token/src/tests/erc721/test_erc721.cairo b/packages/token/src/tests/erc721/test_erc721.cairo index 9063f524b..5be3743b3 100644 --- a/packages/token/src/tests/erc721/test_erc721.cairo +++ b/packages/token/src/tests/erc721/test_erc721.cairo @@ -7,6 +7,7 @@ use openzeppelin_testing::constants::{ BASE_URI, BASE_URI_2, CALLER, DATA, NAME, OPERATOR, OTHER, OWNER, PUBKEY, RECIPIENT, SPENDER, SYMBOL, TOKEN_ID, TOKEN_ID_2, ZERO, }; +use openzeppelin_testing::events::assert_indexed_keys; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; use snforge_std::{start_cheat_caller_address, test_address}; use starknet::ContractAddress; @@ -16,7 +17,6 @@ use crate::erc721::ERC721Component; use crate::erc721::ERC721Component::{ ERC721CamelOnlyImpl, ERC721Impl, ERC721MetadataImpl, InternalImpl, }; -use openzeppelin_testing::events::assert_indexed_keys; // // Setup From cc763617543ca5bb7490e0ab399bc7c2522399d9 Mon Sep 17 00:00:00 2001 From: Turka Turki Date: Thu, 1 May 2025 11:05:26 +0600 Subject: [PATCH 09/29] fix: resolve compilation errors in ERC20 and ERC721 tests --- .../access/src/accesscontrol/accesscontrol.cairo | 12 ++++++++++++ packages/access/src/tests/test_accesscontrol.cairo | 5 +++-- packages/access/src/tests/test_ownable.cairo | 3 +-- packages/account/src/tests/test_account.cairo | 4 ++-- packages/account/src/tests/test_eth_account.cairo | 6 ++++-- packages/governance/src/tests/test_votes.cairo | 7 +++---- packages/security/src/tests/test_pausable.cairo | 1 - packages/testing/src/constants.cairo | 4 ++++ packages/testing/src/events.cairo | 2 +- packages/testing/src/lib.cairo | 2 +- packages/token/src/tests/erc1155/test_erc1155.cairo | 10 +++++----- packages/token/src/tests/erc20/test_erc20.cairo | 6 ++++++ packages/token/src/tests/erc4626/test_erc4626.cairo | 2 +- packages/token/src/tests/erc721/test_erc721.cairo | 4 ++-- 14 files changed, 45 insertions(+), 23 deletions(-) diff --git a/packages/access/src/accesscontrol/accesscontrol.cairo b/packages/access/src/accesscontrol/accesscontrol.cairo index 144dc5c2e..e2255161c 100644 --- a/packages/access/src/accesscontrol/accesscontrol.cairo +++ b/packages/access/src/accesscontrol/accesscontrol.cairo @@ -52,8 +52,11 @@ pub mod AccessControlComponent { /// or the deployer address if `_grant_role` is called from the constructor. #[derive(Drop, Debug, PartialEq, starknet::Event)] pub struct RoleGranted { + #[key] pub role: felt252, + #[key] pub account: ContractAddress, + #[key] pub sender: ContractAddress, } @@ -63,8 +66,11 @@ pub mod AccessControlComponent { /// or the deployer address if `_grant_role_with_delay` is called from the constructor. #[derive(Drop, Debug, PartialEq, starknet::Event)] pub struct RoleGrantedWithDelay { + #[key] pub role: felt252, + #[key] pub account: ContractAddress, + #[key] pub sender: ContractAddress, pub delay: u64, } @@ -76,8 +82,11 @@ pub mod AccessControlComponent { /// - If using `renounce_role`, it is the role bearer (i.e. `account`). #[derive(Drop, Debug, PartialEq, starknet::Event)] pub struct RoleRevoked { + #[key] pub role: felt252, + #[key] pub account: ContractAddress, + #[key] pub sender: ContractAddress, } @@ -87,8 +96,11 @@ pub mod AccessControlComponent { /// `RoleAdminChanged` not being emitted signaling this. #[derive(Drop, Debug, PartialEq, starknet::Event)] pub struct RoleAdminChanged { + #[key] pub role: felt252, + #[key] pub previous_admin_role: felt252, + #[key] pub new_admin_role: felt252, } diff --git a/packages/access/src/tests/test_accesscontrol.cairo b/packages/access/src/tests/test_accesscontrol.cairo index 9b60b3a58..97f9e3e5c 100644 --- a/packages/access/src/tests/test_accesscontrol.cairo +++ b/packages/access/src/tests/test_accesscontrol.cairo @@ -1,5 +1,4 @@ use openzeppelin_introspection::interface::ISRC5; -use openzeppelin_test_common::accesscontrol::AccessControlSpyHelpers; use openzeppelin_test_common::mocks::access::DualCaseAccessControlMock; use openzeppelin_testing::constants::{ ADMIN, AUTHORIZED, OTHER, OTHER_ADMIN, OTHER_ROLE, ROLE, TIMESTAMP, ZERO, @@ -778,7 +777,9 @@ fn test_role_admin_changed_event_indexed_keys() { let new_admin_role = ADMIN; let admin_event = AccessControlComponent::RoleAdminChanged { - role, previous_admin_role, new_admin_role, + role: role.into(), + previous_admin_role: previous_admin_role.into(), + new_admin_role: new_admin_role.into(), }; let expected_keys = array![role.into(), previous_admin_role.into(), new_admin_role.into()]; assert_indexed_keys(@admin_event, @expected_keys); diff --git a/packages/access/src/tests/test_ownable.cairo b/packages/access/src/tests/test_ownable.cairo index 7e936a02b..c4fed5f54 100644 --- a/packages/access/src/tests/test_ownable.cairo +++ b/packages/access/src/tests/test_ownable.cairo @@ -2,8 +2,7 @@ use core::num::traits::Zero; use openzeppelin_test_common::mocks::access::DualCaseOwnableMock; use openzeppelin_test_common::ownable::OwnableSpyHelpers; use openzeppelin_testing::constants::{OTHER, OWNER, RECIPIENT, ZERO}; -use openzeppelin_testing::events::assert_indexed_keys; -use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; +use openzeppelin_testing::events::{assert_indexed_keys, spy_events}; use snforge_std::{start_cheat_caller_address, test_address}; use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; use crate::ownable::OwnableComponent; diff --git a/packages/account/src/tests/test_account.cairo b/packages/account/src/tests/test_account.cairo index 03640cbe4..209eabdfb 100644 --- a/packages/account/src/tests/test_account.cairo +++ b/packages/account/src/tests/test_account.cairo @@ -504,7 +504,7 @@ fn test__set_public_key() { fn test_owner_added_event_indexed_keys() { let new_owner = NEW_PUBKEY; - let owner_added_event = AccountComponent::OwnerAdded { new_owner }; + let owner_added_event = AccountComponent::OwnerAdded { new_owner_guid: new_owner }; let expected_keys = array![new_owner.into()]; assert_indexed_keys(@owner_added_event, @expected_keys); } @@ -513,7 +513,7 @@ fn test_owner_added_event_indexed_keys() { fn test_owner_removed_event_indexed_keys() { let removed_owner = PUBKEY; - let owner_removed_event = AccountComponent::OwnerRemoved { removed_owner }; + let owner_removed_event = AccountComponent::OwnerRemoved { removed_owner_guid: removed_owner }; let expected_keys = array![removed_owner.into()]; assert_indexed_keys(@owner_removed_event, @expected_keys); } diff --git a/packages/account/src/tests/test_eth_account.cairo b/packages/account/src/tests/test_eth_account.cairo index 9b409e715..4f8815028 100644 --- a/packages/account/src/tests/test_eth_account.cairo +++ b/packages/account/src/tests/test_eth_account.cairo @@ -546,7 +546,7 @@ fn test__set_public_key() { fn test_eth_owner_added_event_indexed_keys() { let new_owner = NEW_ETH_SIGNER; - let owner_added_event = EthAccountComponent::EthOwnerAdded { new_owner }; + let owner_added_event = EthAccountComponent::OwnerAdded { new_owner_guid: new_owner }; let expected_keys = array![new_owner.into()]; assert_indexed_keys(@owner_added_event, @expected_keys); } @@ -555,7 +555,9 @@ fn test_eth_owner_added_event_indexed_keys() { fn test_eth_owner_removed_event_indexed_keys() { let removed_owner = ETH_SIGNER; - let owner_removed_event = EthAccountComponent::EthOwnerRemoved { removed_owner }; + let owner_removed_event = EthAccountComponent::OwnerRemoved { + removed_owner_guid: removed_owner, + }; let expected_keys = array![removed_owner.into()]; assert_indexed_keys(@owner_removed_event, @expected_keys); } diff --git a/packages/governance/src/tests/test_votes.cairo b/packages/governance/src/tests/test_votes.cairo index 4ee666f79..9f17ea016 100644 --- a/packages/governance/src/tests/test_votes.cairo +++ b/packages/governance/src/tests/test_votes.cairo @@ -1,7 +1,6 @@ -use core::num::traits::Zero; +// use core::num::traits::Zero; use openzeppelin_test_common::mocks::votes::ERC721VotesMock::SNIP12MetadataImpl; use openzeppelin_test_common::mocks::votes::{ERC20VotesMock, ERC721VotesMock}; -use openzeppelin_test_common::votes::VotesSpyHelpers; use openzeppelin_testing as utils; use openzeppelin_testing::constants::{DELEGATEE, DELEGATOR, OTHER, RECIPIENT, SUPPLY, ZERO}; use openzeppelin_testing::events::assert_indexed_keys; @@ -691,10 +690,10 @@ fn test_delegate_changed_event_indexed_keys() { #[test] fn test_delegate_votes_changed_event_indexed_keys() { let delegate = DELEGATOR; - let old_votes = 0; + let previous_votes = 0; let new_votes = SUPPLY; - let votes_event = VotesComponent::DelegateVotesChanged { delegate, old_votes, new_votes }; + let votes_event = VotesComponent::DelegateVotesChanged { delegate, previous_votes, new_votes }; let expected_keys = array![delegate.into()]; assert_indexed_keys(@votes_event, @expected_keys); } diff --git a/packages/security/src/tests/test_pausable.cairo b/packages/security/src/tests/test_pausable.cairo index 150fdb65d..6b0f22000 100644 --- a/packages/security/src/tests/test_pausable.cairo +++ b/packages/security/src/tests/test_pausable.cairo @@ -1,5 +1,4 @@ use openzeppelin_test_common::mocks::security::PausableMock; -use openzeppelin_test_common::pausable::PausableSpyHelpers; use openzeppelin_testing::constants::{CALLER, OWNER}; use openzeppelin_testing::events::assert_indexed_keys; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; diff --git a/packages/testing/src/constants.cairo b/packages/testing/src/constants.cairo index 00485627e..818117710 100644 --- a/packages/testing/src/constants.cairo +++ b/packages/testing/src/constants.cairo @@ -20,10 +20,14 @@ pub const OTHER_ROLE: felt252 = 'OTHER_ROLE'; pub const CHAIN_ID: felt252 = 'CHAIN_ID'; pub const TOKEN_ID: u256 = 21; pub const TOKEN_ID_2: u256 = 121; +pub const TOKEN_ID_3: u256 = 321; pub const TOKEN_VALUE: u256 = 42; pub const TOKEN_VALUE_2: u256 = 142; +pub const TOKEN_VALUE_3: u256 = 342; pub const PUBKEY: felt252 = 'PUBKEY'; pub const NEW_PUBKEY: felt252 = 0x26da8d11938b76025862be14fdb8b28438827f73e75e86f7bfa38b196951fa7; +pub const ETH_SIGNER: felt252 = 'ETH_SIGNER'; +pub const NEW_ETH_SIGNER: felt252 = 'NEW_ETH_SIGNER'; pub const DAPP_NAME: felt252 = 'DAPP_NAME'; pub const DAPP_VERSION: felt252 = 'DAPP_VERSION'; pub const SALT: felt252 = 'SALT'; diff --git a/packages/testing/src/events.cairo b/packages/testing/src/events.cairo index 52954682a..01111d08b 100644 --- a/packages/testing/src/events.cairo +++ b/packages/testing/src/events.cairo @@ -156,7 +156,7 @@ fn is_emitted, impl TDrop: Drop>( /// Asserts that the event's indexed keys match the expected values in order. /// This checks that specific fields are properly marked as indexed in the event definition. -fn assert_indexed_keys, impl TDrop: Drop>( +pub fn assert_indexed_keys, impl TDrop: Drop>( event: @T, expected_indexed_values: @Array, ) { let mut actual_keys = array![]; diff --git a/packages/testing/src/lib.cairo b/packages/testing/src/lib.cairo index 9d3e0e935..5a2a26747 100644 --- a/packages/testing/src/lib.cairo +++ b/packages/testing/src/lib.cairo @@ -13,4 +13,4 @@ pub use deployment::{ declare_and_deploy, declare_and_deploy_at, declare_class, deploy, deploy_another_at, deploy_at, }; -pub use events::{EventSpyExt, EventSpyQueue, spy_events}; +pub use events::{EventSpyExt, EventSpyQueue, assert_indexed_keys, spy_events}; diff --git a/packages/token/src/tests/erc1155/test_erc1155.cairo b/packages/token/src/tests/erc1155/test_erc1155.cairo index 697c79575..4c1f83847 100644 --- a/packages/token/src/tests/erc1155/test_erc1155.cairo +++ b/packages/token/src/tests/erc1155/test_erc1155.cairo @@ -1420,9 +1420,9 @@ fn test_transfer_single_event_indexed_keys() { let from = OWNER; let to = RECIPIENT; let id = TOKEN_ID; - let amount = TOKEN_VALUE; + let value = TOKEN_VALUE; - let transfer_event = ERC1155Component::TransferSingle { operator, from, to, id, amount }; + let transfer_event = ERC1155Component::TransferSingle { operator, from, to, id, value }; let expected_keys = array![operator.into(), from.into(), to.into()]; assert_indexed_keys(@transfer_event, @expected_keys); } @@ -1432,10 +1432,10 @@ fn test_transfer_batch_event_indexed_keys() { let operator = OPERATOR; let from = OWNER; let to = RECIPIENT; - let ids = array![TOKEN_ID, TOKEN_ID_2, TOKEN_ID_3]; - let amounts = array![TOKEN_VALUE, TOKEN_VALUE_2, TOKEN_VALUE_3]; + let ids = array![TOKEN_ID, TOKEN_ID_2].span(); + let values = array![TOKEN_VALUE, TOKEN_VALUE_2].span(); - let transfer_event = ERC1155Component::TransferBatch { operator, from, to, ids, amounts }; + let transfer_event = ERC1155Component::TransferBatch { operator, from, to, ids, values }; let expected_keys = array![operator.into(), from.into(), to.into()]; assert_indexed_keys(@transfer_event, @expected_keys); } diff --git a/packages/token/src/tests/erc20/test_erc20.cairo b/packages/token/src/tests/erc20/test_erc20.cairo index fa4f1913f..40fa7cd59 100644 --- a/packages/token/src/tests/erc20/test_erc20.cairo +++ b/packages/token/src/tests/erc20/test_erc20.cairo @@ -711,3 +711,9 @@ fn test_approval_event_indexed_keys() { let expected_keys = array![owner.into(), spender.into()]; assert_indexed_keys(@approval_event, @expected_keys); } + +#[test] +fn test_setup() { + let mut _state = setup(); + // ... rest of the test +} diff --git a/packages/token/src/tests/erc4626/test_erc4626.cairo b/packages/token/src/tests/erc4626/test_erc4626.cairo index 24edcc1f4..94453d349 100644 --- a/packages/token/src/tests/erc4626/test_erc4626.cairo +++ b/packages/token/src/tests/erc4626/test_erc4626.cairo @@ -15,7 +15,7 @@ use snforge_std::{CheatSpan, cheat_caller_address}; use starknet::ContractAddress; use crate::erc20::ERC20Component::InternalImpl as ERC20InternalImpl; use crate::erc20::extensions::erc4626::ERC4626Component::{ - Deposit, ERC4626Impl, ERC4626MetadataImpl, InternalImpl, Withdraw, + ERC4626Impl, ERC4626MetadataImpl, InternalImpl, }; use crate::erc20::extensions::erc4626::interface::{ERC4626ABIDispatcher, ERC4626ABIDispatcherTrait}; use crate::erc20::extensions::erc4626::{DefaultConfig, ERC4626Component}; diff --git a/packages/token/src/tests/erc721/test_erc721.cairo b/packages/token/src/tests/erc721/test_erc721.cairo index 5be3743b3..c31fbd3d9 100644 --- a/packages/token/src/tests/erc721/test_erc721.cairo +++ b/packages/token/src/tests/erc721/test_erc721.cairo @@ -1517,7 +1517,7 @@ fn test_transfer_event_indexed_keys() { let token_id = TOKEN_ID; let transfer_event = ERC721Component::Transfer { from, to, token_id }; - let expected_keys = array![from.into(), to.into(), token_id.into()]; + let expected_keys = array![from.into(), to.into(), token_id.try_into().unwrap()]; assert_indexed_keys(@transfer_event, @expected_keys); } @@ -1528,7 +1528,7 @@ fn test_approval_event_indexed_keys() { let token_id = TOKEN_ID; let approval_event = ERC721Component::Approval { owner, approved, token_id }; - let expected_keys = array![owner.into(), approved.into(), token_id.into()]; + let expected_keys = array![owner.into(), approved.into(), token_id.try_into().unwrap()]; assert_indexed_keys(@approval_event, @expected_keys); } From cf473a4791cd5c946dad5e6d1e955c82474311ea Mon Sep 17 00:00:00 2001 From: Turka Turki Date: Tue, 3 Jun 2025 16:16:38 +0600 Subject: [PATCH 10/29] feat: add indexed keys to Paused and Unpaused events in PausableComponent --- packages/security/src/pausable.cairo | 2 ++ packages/token/src/tests/erc20/test_erc20.cairo | 6 ------ 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/security/src/pausable.cairo b/packages/security/src/pausable.cairo index d7635c1d8..bff6a70c7 100644 --- a/packages/security/src/pausable.cairo +++ b/packages/security/src/pausable.cairo @@ -27,12 +27,14 @@ pub mod PausableComponent { /// Emitted when the pause is triggered by `account`. #[derive(Drop, Debug, PartialEq, starknet::Event)] pub struct Paused { + #[key] pub account: ContractAddress, } /// Emitted when the pause is lifted by `account`. #[derive(Drop, Debug, PartialEq, starknet::Event)] pub struct Unpaused { + #[key] pub account: ContractAddress, } diff --git a/packages/token/src/tests/erc20/test_erc20.cairo b/packages/token/src/tests/erc20/test_erc20.cairo index 40fa7cd59..fa4f1913f 100644 --- a/packages/token/src/tests/erc20/test_erc20.cairo +++ b/packages/token/src/tests/erc20/test_erc20.cairo @@ -711,9 +711,3 @@ fn test_approval_event_indexed_keys() { let expected_keys = array![owner.into(), spender.into()]; assert_indexed_keys(@approval_event, @expected_keys); } - -#[test] -fn test_setup() { - let mut _state = setup(); - // ... rest of the test -} From 38f3124d104b3b4d31bf64e33c5d3445ff44fab6 Mon Sep 17 00:00:00 2001 From: Turka Turki Date: Tue, 3 Jun 2025 18:05:34 +0600 Subject: [PATCH 11/29] fix: update token_id handling in ERC721 event tests to use felt252 type --- packages/token/src/tests/erc721/test_erc721.cairo | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/token/src/tests/erc721/test_erc721.cairo b/packages/token/src/tests/erc721/test_erc721.cairo index c31fbd3d9..9c1d6e9b5 100644 --- a/packages/token/src/tests/erc721/test_erc721.cairo +++ b/packages/token/src/tests/erc721/test_erc721.cairo @@ -1517,7 +1517,8 @@ fn test_transfer_event_indexed_keys() { let token_id = TOKEN_ID; let transfer_event = ERC721Component::Transfer { from, to, token_id }; - let expected_keys = array![from.into(), to.into(), token_id.try_into().unwrap()]; + let token_id_felt: felt252 = token_id.low.into(); + let expected_keys = array![from.into(), to.into(), token_id_felt]; assert_indexed_keys(@transfer_event, @expected_keys); } @@ -1528,7 +1529,8 @@ fn test_approval_event_indexed_keys() { let token_id = TOKEN_ID; let approval_event = ERC721Component::Approval { owner, approved, token_id }; - let expected_keys = array![owner.into(), approved.into(), token_id.try_into().unwrap()]; + let token_id_felt: felt252 = token_id.low.into(); + let expected_keys = array![owner.into(), approved.into(), token_id_felt]; assert_indexed_keys(@approval_event, @expected_keys); } From 1ffd1901698e2a31cc89677927db05288b753e8c Mon Sep 17 00:00:00 2001 From: Eric Nordelo Date: Wed, 16 Jul 2025 16:41:19 +0200 Subject: [PATCH 12/29] feat: rollback unnecessary changes --- Scarb.lock | 1 + packages/access/Scarb.toml | 1 + .../src/accesscontrol/accesscontrol.cairo | 12 ------ .../access/src/tests/test_accesscontrol.cairo | 38 ------------------- ...st_accesscontrol_default_admin_rules.cairo | 18 ++++++--- packages/access/src/tests/test_ownable.cairo | 12 +----- packages/account/src/tests/test_account.cairo | 22 +---------- .../account/src/tests/test_eth_account.cairo | 23 +---------- .../src/tests/votes/test_timestamp.cairo | 22 ----------- packages/security/src/pausable.cairo | 2 - .../security/src/tests/test_pausable.cairo | 21 +--------- packages/testing/src/constants.cairo | 4 -- packages/testing/src/events.cairo | 24 ------------ packages/testing/src/lib.cairo | 2 +- .../src/tests/erc1155/test_erc1155.cairo | 38 ------------------- .../token/src/tests/erc20/test_erc20.cairo | 24 ------------ .../src/tests/erc4626/test_erc4626.cairo | 1 - .../token/src/tests/erc721/test_erc721.cairo | 36 ------------------ 18 files changed, 20 insertions(+), 281 deletions(-) diff --git a/Scarb.lock b/Scarb.lock index abef5ce86..5415c9e69 100644 --- a/Scarb.lock +++ b/Scarb.lock @@ -28,6 +28,7 @@ dependencies = [ "openzeppelin_introspection", "openzeppelin_test_common", "openzeppelin_testing", + "openzeppelin_utils", "snforge_std", ] diff --git a/packages/access/Scarb.toml b/packages/access/Scarb.toml index 2ab2428fb..bb9aa373b 100644 --- a/packages/access/Scarb.toml +++ b/packages/access/Scarb.toml @@ -31,6 +31,7 @@ assert_macros.workspace = true snforge_std.workspace = true openzeppelin_testing = { path = "../testing" } openzeppelin_test_common = { path = "../test_common" } +openzeppelin_utils = { path = "../utils" } [lib] diff --git a/packages/access/src/accesscontrol/accesscontrol.cairo b/packages/access/src/accesscontrol/accesscontrol.cairo index 616d9991e..b15d28625 100644 --- a/packages/access/src/accesscontrol/accesscontrol.cairo +++ b/packages/access/src/accesscontrol/accesscontrol.cairo @@ -52,11 +52,8 @@ pub mod AccessControlComponent { /// or the deployer address if `_grant_role` is called from the constructor. #[derive(Drop, Debug, PartialEq, starknet::Event)] pub struct RoleGranted { - #[key] pub role: felt252, - #[key] pub account: ContractAddress, - #[key] pub sender: ContractAddress, } @@ -66,11 +63,8 @@ pub mod AccessControlComponent { /// or the deployer address if `_grant_role_with_delay` is called from the constructor. #[derive(Drop, Debug, PartialEq, starknet::Event)] pub struct RoleGrantedWithDelay { - #[key] pub role: felt252, - #[key] pub account: ContractAddress, - #[key] pub sender: ContractAddress, pub delay: u64, } @@ -82,11 +76,8 @@ pub mod AccessControlComponent { /// - If using `renounce_role`, it is the role bearer (i.e. `account`). #[derive(Drop, Debug, PartialEq, starknet::Event)] pub struct RoleRevoked { - #[key] pub role: felt252, - #[key] pub account: ContractAddress, - #[key] pub sender: ContractAddress, } @@ -96,11 +87,8 @@ pub mod AccessControlComponent { /// `RoleAdminChanged` not being emitted signaling this. #[derive(Drop, Debug, PartialEq, starknet::Event)] pub struct RoleAdminChanged { - #[key] pub role: felt252, - #[key] pub previous_admin_role: felt252, - #[key] pub new_admin_role: felt252, } diff --git a/packages/access/src/tests/test_accesscontrol.cairo b/packages/access/src/tests/test_accesscontrol.cairo index f8d164187..8397c9b58 100644 --- a/packages/access/src/tests/test_accesscontrol.cairo +++ b/packages/access/src/tests/test_accesscontrol.cairo @@ -3,7 +3,6 @@ use openzeppelin_test_common::mocks::access::DualCaseAccessControlMock; use openzeppelin_testing::constants::{ ADMIN, AUTHORIZED, OTHER, OTHER_ADMIN, OTHER_ROLE, ROLE, TIMESTAMP, ZERO, }; -use openzeppelin_testing::events::assert_indexed_keys; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; use snforge_std::{start_cheat_block_timestamp_global, start_cheat_caller_address, test_address}; use starknet::ContractAddress; @@ -760,40 +759,3 @@ pub impl AccessControlSpyHelpersImpl of AccessControlSpyHelpers { self.assert_only_event(from_address, expected); } } - -#[test] -fn test_role_granted_event_indexed_keys() { - let role = ROLE; - let account = OTHER; - let sender = ADMIN; - - let grant_event = AccessControlComponent::RoleGranted { role, account, sender }; - let expected_keys = array![role.into(), account.into(), sender.into()]; - assert_indexed_keys(@grant_event, @expected_keys); -} - -#[test] -fn test_role_revoked_event_indexed_keys() { - let role = ROLE; - let account = OTHER; - let sender = ADMIN; - - let revoke_event = AccessControlComponent::RoleRevoked { role, account, sender }; - let expected_keys = array![role.into(), account.into(), sender.into()]; - assert_indexed_keys(@revoke_event, @expected_keys); -} - -#[test] -fn test_role_admin_changed_event_indexed_keys() { - let role = ROLE; - let previous_admin_role = ZERO; - let new_admin_role = ADMIN; - - let admin_event = AccessControlComponent::RoleAdminChanged { - role: role.into(), - previous_admin_role: previous_admin_role.into(), - new_admin_role: new_admin_role.into(), - }; - let expected_keys = array![role.into(), previous_admin_role.into(), new_admin_role.into()]; - assert_indexed_keys(@admin_event, @expected_keys); -} diff --git a/packages/access/src/tests/test_accesscontrol_default_admin_rules.cairo b/packages/access/src/tests/test_accesscontrol_default_admin_rules.cairo index 5c0cd6d97..13b6782ee 100644 --- a/packages/access/src/tests/test_accesscontrol_default_admin_rules.cairo +++ b/packages/access/src/tests/test_accesscontrol_default_admin_rules.cairo @@ -5,7 +5,7 @@ use openzeppelin_testing::constants::{ ADMIN, AUTHORIZED, OTHER, OTHER_ADMIN, OTHER_ROLE, ROLE, TIMESTAMP, ZERO, }; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; -use snforge_std::{start_cheat_block_timestamp_global, start_cheat_caller_address, test_address}; +use snforge_std::{Event, start_cheat_block_timestamp_global, start_cheat_caller_address, test_address}; use starknet::ContractAddress; use crate::accesscontrol::extensions::AccessControlDefaultAdminRulesComponent::{ DefaultAdminDelayChangeCanceled, DefaultAdminDelayChangeScheduled, DefaultAdminTransferCanceled, @@ -1161,6 +1161,8 @@ fn test_default_admin_role_is_its_own_admin() { // Helpers // +use openzeppelin_utils::serde::SerializedAppend; + #[generate_trait] impl AccessControlDefaultAdminRulesSpyHelpersImpl of AccessControlDefaultAdminRulesSpyHelpers { fn assert_only_event_default_admin_transfer_scheduled( @@ -1169,10 +1171,16 @@ impl AccessControlDefaultAdminRulesSpyHelpersImpl of AccessControlDefaultAdminRu new_admin: ContractAddress, accept_schedule: u64, ) { - let expected = - AccessControlDefaultAdminRulesComponent::Event::DefaultAdminTransferScheduled( - DefaultAdminTransferScheduled { new_admin, accept_schedule }, - ); + let mut keys = array![]; + keys.append_serde(selector!("DefaultAdminTransferScheduled")); + keys.append_serde(new_admin); + let mut data = array![]; + data.append_serde(accept_schedule); + let expected = Event { keys, data }; + // let expected = + // AccessControlDefaultAdminRulesComponent::Event::DefaultAdminTransferScheduled( + // DefaultAdminTransferScheduled { new_admin, accept_schedule }, + // ); self.assert_only_event(contract, expected); } diff --git a/packages/access/src/tests/test_ownable.cairo b/packages/access/src/tests/test_ownable.cairo index c4fed5f54..e5fc5e509 100644 --- a/packages/access/src/tests/test_ownable.cairo +++ b/packages/access/src/tests/test_ownable.cairo @@ -2,7 +2,7 @@ use core::num::traits::Zero; use openzeppelin_test_common::mocks::access::DualCaseOwnableMock; use openzeppelin_test_common::ownable::OwnableSpyHelpers; use openzeppelin_testing::constants::{OTHER, OWNER, RECIPIENT, ZERO}; -use openzeppelin_testing::events::{assert_indexed_keys, spy_events}; +use openzeppelin_testing::events::spy_events; use snforge_std::{start_cheat_caller_address, test_address}; use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; use crate::ownable::OwnableComponent; @@ -204,13 +204,3 @@ fn test_renounceOwnership_from_nonowner() { start_cheat_caller_address(test_address(), OTHER); state.renounceOwnership(); } - -#[test] -fn test_ownership_transferred_event_indexed_keys() { - let previous_owner = ZERO; - let new_owner = OWNER; - - let transfer_event = OwnableComponent::OwnershipTransferred { previous_owner, new_owner }; - let expected_keys = array![previous_owner.into(), new_owner.into()]; - assert_indexed_keys(@transfer_event, @expected_keys); -} diff --git a/packages/account/src/tests/test_account.cairo b/packages/account/src/tests/test_account.cairo index 209eabdfb..26973f002 100644 --- a/packages/account/src/tests/test_account.cairo +++ b/packages/account/src/tests/test_account.cairo @@ -8,10 +8,8 @@ use openzeppelin_test_common::mocks::simple::{ISimpleMockDispatcher, ISimpleMock use openzeppelin_testing as utils; use openzeppelin_testing::constants::stark::{KEY_PAIR, KEY_PAIR_2}; use openzeppelin_testing::constants::{ - CALLER, MIN_TRANSACTION_VERSION, NEW_PUBKEY, OTHER, PUBKEY, QUERY_OFFSET, QUERY_VERSION, SALT, - ZERO, + CALLER, MIN_TRANSACTION_VERSION, OTHER, QUERY_OFFSET, QUERY_VERSION, SALT, ZERO, }; -use openzeppelin_testing::events::assert_indexed_keys; use openzeppelin_testing::signing::StarkKeyPair; use openzeppelin_testing::spy_events; use snforge_std::{ @@ -499,21 +497,3 @@ fn test__set_public_key() { spy.assert_only_event_owner_added(account_address, public_key); assert_eq!(state.get_public_key(), public_key); } - -#[test] -fn test_owner_added_event_indexed_keys() { - let new_owner = NEW_PUBKEY; - - let owner_added_event = AccountComponent::OwnerAdded { new_owner_guid: new_owner }; - let expected_keys = array![new_owner.into()]; - assert_indexed_keys(@owner_added_event, @expected_keys); -} - -#[test] -fn test_owner_removed_event_indexed_keys() { - let removed_owner = PUBKEY; - - let owner_removed_event = AccountComponent::OwnerRemoved { removed_owner_guid: removed_owner }; - let expected_keys = array![removed_owner.into()]; - assert_indexed_keys(@owner_removed_event, @expected_keys); -} diff --git a/packages/account/src/tests/test_eth_account.cairo b/packages/account/src/tests/test_eth_account.cairo index 4f8815028..809b8321f 100644 --- a/packages/account/src/tests/test_eth_account.cairo +++ b/packages/account/src/tests/test_eth_account.cairo @@ -7,9 +7,8 @@ use openzeppelin_test_common::mocks::simple::{ISimpleMockDispatcher, ISimpleMock use openzeppelin_testing as utils; use openzeppelin_testing::constants::secp256k1::{KEY_PAIR, KEY_PAIR_2}; use openzeppelin_testing::constants::{ - CALLER, ETH_SIGNER, MIN_TRANSACTION_VERSION, NEW_ETH_SIGNER, OTHER, QUERY_VERSION, SALT, ZERO, + CALLER, MIN_TRANSACTION_VERSION, OTHER, QUERY_VERSION, SALT, ZERO, }; -use openzeppelin_testing::events::assert_indexed_keys; use openzeppelin_testing::signing::Secp256k1KeyPair; use openzeppelin_testing::spy_events; use openzeppelin_utils::serde::SerializedAppend; @@ -541,23 +540,3 @@ fn test__set_public_key() { assert_eq!(state.get_public_key(), key_pair.public_key); } - -#[test] -fn test_eth_owner_added_event_indexed_keys() { - let new_owner = NEW_ETH_SIGNER; - - let owner_added_event = EthAccountComponent::OwnerAdded { new_owner_guid: new_owner }; - let expected_keys = array![new_owner.into()]; - assert_indexed_keys(@owner_added_event, @expected_keys); -} - -#[test] -fn test_eth_owner_removed_event_indexed_keys() { - let removed_owner = ETH_SIGNER; - - let owner_removed_event = EthAccountComponent::OwnerRemoved { - removed_owner_guid: removed_owner, - }; - let expected_keys = array![removed_owner.into()]; - assert_indexed_keys(@owner_removed_event, @expected_keys); -} diff --git a/packages/governance/src/tests/votes/test_timestamp.cairo b/packages/governance/src/tests/votes/test_timestamp.cairo index 0986ffbbd..9a221d035 100644 --- a/packages/governance/src/tests/votes/test_timestamp.cairo +++ b/packages/governance/src/tests/votes/test_timestamp.cairo @@ -637,25 +637,3 @@ fn test_CLOCK_MODE() { let state = COMPONENT_STATE(); assert_eq!(state.CLOCK_MODE(), "mode=timestamp&from=starknet::SN_MAIN"); } - -#[test] -fn test_delegate_changed_event_indexed_keys() { - let delegator = DELEGATOR; - let from_delegate = ZERO; - let to_delegate = RECIPIENT; - - let delegate_event = VotesComponent::DelegateChanged { delegator, from_delegate, to_delegate }; - let expected_keys = array![delegator.into(), from_delegate.into(), to_delegate.into()]; - assert_indexed_keys(@delegate_event, @expected_keys); -} - -#[test] -fn test_delegate_votes_changed_event_indexed_keys() { - let delegate = DELEGATOR; - let previous_votes = 0; - let new_votes = SUPPLY; - - let votes_event = VotesComponent::DelegateVotesChanged { delegate, previous_votes, new_votes }; - let expected_keys = array![delegate.into()]; - assert_indexed_keys(@votes_event, @expected_keys); -} diff --git a/packages/security/src/pausable.cairo b/packages/security/src/pausable.cairo index d3f8051fd..8efa73c46 100644 --- a/packages/security/src/pausable.cairo +++ b/packages/security/src/pausable.cairo @@ -27,14 +27,12 @@ pub mod PausableComponent { /// Emitted when the pause is triggered by `account`. #[derive(Drop, Debug, PartialEq, starknet::Event)] pub struct Paused { - #[key] pub account: ContractAddress, } /// Emitted when the pause is lifted by `account`. #[derive(Drop, Debug, PartialEq, starknet::Event)] pub struct Unpaused { - #[key] pub account: ContractAddress, } diff --git a/packages/security/src/tests/test_pausable.cairo b/packages/security/src/tests/test_pausable.cairo index 6b0f22000..7f5d70c7d 100644 --- a/packages/security/src/tests/test_pausable.cairo +++ b/packages/security/src/tests/test_pausable.cairo @@ -1,6 +1,5 @@ use openzeppelin_test_common::mocks::security::PausableMock; -use openzeppelin_testing::constants::{CALLER, OWNER}; -use openzeppelin_testing::events::assert_indexed_keys; +use openzeppelin_testing::constants::CALLER; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; use snforge_std::{start_cheat_caller_address, test_address}; use starknet::ContractAddress; @@ -151,21 +150,3 @@ impl PausableSpyHelpersImpl of PausableSpyHelpers { self.assert_no_events_left_from(contract); } } - -#[test] -fn test_paused_event_indexed_keys() { - let account = OWNER; - - let paused_event = PausableComponent::Paused { account }; - let expected_keys = array![account.into()]; - assert_indexed_keys(@paused_event, @expected_keys); -} - -#[test] -fn test_unpaused_event_indexed_keys() { - let account = OWNER; - - let unpaused_event = PausableComponent::Unpaused { account }; - let expected_keys = array![account.into()]; - assert_indexed_keys(@unpaused_event, @expected_keys); -} diff --git a/packages/testing/src/constants.cairo b/packages/testing/src/constants.cairo index 818117710..00485627e 100644 --- a/packages/testing/src/constants.cairo +++ b/packages/testing/src/constants.cairo @@ -20,14 +20,10 @@ pub const OTHER_ROLE: felt252 = 'OTHER_ROLE'; pub const CHAIN_ID: felt252 = 'CHAIN_ID'; pub const TOKEN_ID: u256 = 21; pub const TOKEN_ID_2: u256 = 121; -pub const TOKEN_ID_3: u256 = 321; pub const TOKEN_VALUE: u256 = 42; pub const TOKEN_VALUE_2: u256 = 142; -pub const TOKEN_VALUE_3: u256 = 342; pub const PUBKEY: felt252 = 'PUBKEY'; pub const NEW_PUBKEY: felt252 = 0x26da8d11938b76025862be14fdb8b28438827f73e75e86f7bfa38b196951fa7; -pub const ETH_SIGNER: felt252 = 'ETH_SIGNER'; -pub const NEW_ETH_SIGNER: felt252 = 'NEW_ETH_SIGNER'; pub const DAPP_NAME: felt252 = 'DAPP_NAME'; pub const DAPP_VERSION: felt252 = 'DAPP_VERSION'; pub const SALT: felt252 = 'SALT'; diff --git a/packages/testing/src/events.cairo b/packages/testing/src/events.cairo index 270c1dbfa..b871a1a46 100644 --- a/packages/testing/src/events.cairo +++ b/packages/testing/src/events.cairo @@ -221,27 +221,3 @@ fn is_emitted, impl TDrop: Drop>( } return is_emitted; } - -/// Asserts that the event's indexed keys match the expected values in order. -/// This checks that specific fields are properly marked as indexed in the event definition. -pub fn assert_indexed_keys, impl TDrop: Drop>( - event: @T, expected_indexed_values: @Array, -) { - let mut actual_keys = array![]; - let mut data = array![]; - event.append_keys_and_data(ref actual_keys, ref data); - - assert!( - actual_keys.len() == expected_indexed_values.len(), - "Number of indexed keys does not match expected", - ); - - let mut i = 0; - while i != actual_keys.len() { - assert!( - *actual_keys.at(i) == *expected_indexed_values.at(i), - "Indexed key value does not match expected", - ); - i += 1; - } -} diff --git a/packages/testing/src/lib.cairo b/packages/testing/src/lib.cairo index 5a2a26747..9d3e0e935 100644 --- a/packages/testing/src/lib.cairo +++ b/packages/testing/src/lib.cairo @@ -13,4 +13,4 @@ pub use deployment::{ declare_and_deploy, declare_and_deploy_at, declare_class, deploy, deploy_another_at, deploy_at, }; -pub use events::{EventSpyExt, EventSpyQueue, assert_indexed_keys, spy_events}; +pub use events::{EventSpyExt, EventSpyQueue, spy_events}; diff --git a/packages/token/src/tests/erc1155/test_erc1155.cairo b/packages/token/src/tests/erc1155/test_erc1155.cairo index 4c1f83847..579515701 100644 --- a/packages/token/src/tests/erc1155/test_erc1155.cairo +++ b/packages/token/src/tests/erc1155/test_erc1155.cairo @@ -9,7 +9,6 @@ use openzeppelin_testing::constants::{ EMPTY_DATA, OPERATOR, OTHER, OWNER, RECIPIENT, TOKEN_ID, TOKEN_ID_2, TOKEN_VALUE, TOKEN_VALUE_2, ZERO, }; -use openzeppelin_testing::events::assert_indexed_keys; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; use snforge_std::{start_cheat_caller_address, test_address}; use starknet::ContractAddress; @@ -1413,40 +1412,3 @@ impl ERC1155HooksSpyHelpersImpl of ERC1155HooksSpyHelpers { self.assert_emitted_single(contract, expected); } } - -#[test] -fn test_transfer_single_event_indexed_keys() { - let operator = OPERATOR; - let from = OWNER; - let to = RECIPIENT; - let id = TOKEN_ID; - let value = TOKEN_VALUE; - - let transfer_event = ERC1155Component::TransferSingle { operator, from, to, id, value }; - let expected_keys = array![operator.into(), from.into(), to.into()]; - assert_indexed_keys(@transfer_event, @expected_keys); -} - -#[test] -fn test_transfer_batch_event_indexed_keys() { - let operator = OPERATOR; - let from = OWNER; - let to = RECIPIENT; - let ids = array![TOKEN_ID, TOKEN_ID_2].span(); - let values = array![TOKEN_VALUE, TOKEN_VALUE_2].span(); - - let transfer_event = ERC1155Component::TransferBatch { operator, from, to, ids, values }; - let expected_keys = array![operator.into(), from.into(), to.into()]; - assert_indexed_keys(@transfer_event, @expected_keys); -} - -#[test] -fn test_approval_for_all_event_indexed_keys() { - let owner = OWNER; - let operator = OPERATOR; - let approved = true; - - let approval_event = ERC1155Component::ApprovalForAll { owner, operator, approved }; - let expected_keys = array![owner.into(), operator.into()]; - assert_indexed_keys(@approval_event, @expected_keys); -} diff --git a/packages/token/src/tests/erc20/test_erc20.cairo b/packages/token/src/tests/erc20/test_erc20.cairo index fa4f1913f..3b0c9fcfe 100644 --- a/packages/token/src/tests/erc20/test_erc20.cairo +++ b/packages/token/src/tests/erc20/test_erc20.cairo @@ -2,7 +2,6 @@ use core::num::traits::Bounded; use openzeppelin_test_common::erc20::ERC20SpyHelpers; use openzeppelin_test_common::mocks::erc20::{DualCaseERC20Mock, SnakeERC20MockWithHooks}; use openzeppelin_testing::constants::{NAME, OWNER, RECIPIENT, SPENDER, SUPPLY, SYMBOL, VALUE, ZERO}; -use openzeppelin_testing::events::assert_indexed_keys; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; use snforge_std::{start_cheat_caller_address, test_address}; use starknet::ContractAddress; @@ -688,26 +687,3 @@ impl ERC20HooksSpyHelpersImpl of ERC20HooksSpyHelpers { self.assert_emitted_single(contract, expected); } } - -#[test] -fn test_transfer_event_indexed_keys() { - let mut state = setup(); - let from = OWNER; - let to = RECIPIENT; - let value = VALUE; - - let transfer_event = ERC20Component::Transfer { from, to, value }; - let expected_keys = array![from.into(), to.into()]; - assert_indexed_keys(@transfer_event, @expected_keys); -} - -#[test] -fn test_approval_event_indexed_keys() { - let owner = OWNER; - let spender = SPENDER; - let value = VALUE; - - let approval_event = ERC20Component::Approval { owner, spender, value }; - let expected_keys = array![owner.into(), spender.into()]; - assert_indexed_keys(@approval_event, @expected_keys); -} diff --git a/packages/token/src/tests/erc4626/test_erc4626.cairo b/packages/token/src/tests/erc4626/test_erc4626.cairo index 44a9f637c..e4ee03c1b 100644 --- a/packages/token/src/tests/erc4626/test_erc4626.cairo +++ b/packages/token/src/tests/erc4626/test_erc4626.cairo @@ -10,7 +10,6 @@ use openzeppelin_testing as utils; use openzeppelin_testing::constants::{ ALICE, BOB, NAME, OTHER, OWNER, RECIPIENT, SPENDER, SYMBOL, VALUE, ZERO, }; -use openzeppelin_testing::events::assert_indexed_keys; use openzeppelin_testing::{AsAddressTrait, EventSpyExt, EventSpyQueue as EventSpy, spy_events}; use openzeppelin_utils::serde::SerializedAppend; use snforge_std::{CheatSpan, cheat_caller_address}; diff --git a/packages/token/src/tests/erc721/test_erc721.cairo b/packages/token/src/tests/erc721/test_erc721.cairo index 9c1d6e9b5..53ff3023e 100644 --- a/packages/token/src/tests/erc721/test_erc721.cairo +++ b/packages/token/src/tests/erc721/test_erc721.cairo @@ -7,7 +7,6 @@ use openzeppelin_testing::constants::{ BASE_URI, BASE_URI_2, CALLER, DATA, NAME, OPERATOR, OTHER, OWNER, PUBKEY, RECIPIENT, SPENDER, SYMBOL, TOKEN_ID, TOKEN_ID_2, ZERO, }; -use openzeppelin_testing::events::assert_indexed_keys; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; use snforge_std::{start_cheat_caller_address, test_address}; use starknet::ContractAddress; @@ -1509,38 +1508,3 @@ impl ERC721HooksSpyHelpersImpl of ERC721HooksSpyHelpers { self.assert_emitted_single(contract, expected); } } - -#[test] -fn test_transfer_event_indexed_keys() { - let from = OWNER; - let to = RECIPIENT; - let token_id = TOKEN_ID; - - let transfer_event = ERC721Component::Transfer { from, to, token_id }; - let token_id_felt: felt252 = token_id.low.into(); - let expected_keys = array![from.into(), to.into(), token_id_felt]; - assert_indexed_keys(@transfer_event, @expected_keys); -} - -#[test] -fn test_approval_event_indexed_keys() { - let owner = OWNER; - let approved = SPENDER; - let token_id = TOKEN_ID; - - let approval_event = ERC721Component::Approval { owner, approved, token_id }; - let token_id_felt: felt252 = token_id.low.into(); - let expected_keys = array![owner.into(), approved.into(), token_id_felt]; - assert_indexed_keys(@approval_event, @expected_keys); -} - -#[test] -fn test_approval_for_all_event_indexed_keys() { - let owner = OWNER; - let operator = OPERATOR; - let approved = true; - - let approval_for_all_event = ERC721Component::ApprovalForAll { owner, operator, approved }; - let expected_keys = array![owner.into(), operator.into()]; - assert_indexed_keys(@approval_for_all_event, @expected_keys); -} From 4851c1f39de6d7066ff8b84b285bec58b2e76061 Mon Sep 17 00:00:00 2001 From: Eric Nordelo Date: Wed, 16 Jul 2025 16:44:09 +0200 Subject: [PATCH 13/29] feat: remove updates --- packages/access/src/tests/test_ownable.cairo | 2 +- packages/token/src/tests/erc4626/test_erc4626.cairo | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/access/src/tests/test_ownable.cairo b/packages/access/src/tests/test_ownable.cairo index e5fc5e509..fc2c21a42 100644 --- a/packages/access/src/tests/test_ownable.cairo +++ b/packages/access/src/tests/test_ownable.cairo @@ -2,7 +2,7 @@ use core::num::traits::Zero; use openzeppelin_test_common::mocks::access::DualCaseOwnableMock; use openzeppelin_test_common::ownable::OwnableSpyHelpers; use openzeppelin_testing::constants::{OTHER, OWNER, RECIPIENT, ZERO}; -use openzeppelin_testing::events::spy_events; +use openzeppelin_testing::spy_events; use snforge_std::{start_cheat_caller_address, test_address}; use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; use crate::ownable::OwnableComponent; diff --git a/packages/token/src/tests/erc4626/test_erc4626.cairo b/packages/token/src/tests/erc4626/test_erc4626.cairo index e4ee03c1b..56ec64bec 100644 --- a/packages/token/src/tests/erc4626/test_erc4626.cairo +++ b/packages/token/src/tests/erc4626/test_erc4626.cairo @@ -7,16 +7,14 @@ use openzeppelin_test_common::mocks::erc4626::{ ERC4626LimitsMock, ERC4626Mock, ERC4626MockWithHooks, }; use openzeppelin_testing as utils; -use openzeppelin_testing::constants::{ - ALICE, BOB, NAME, OTHER, OWNER, RECIPIENT, SPENDER, SYMBOL, VALUE, ZERO, -}; +use openzeppelin_testing::constants::{ALICE, BOB, NAME, OTHER, RECIPIENT, SPENDER, SYMBOL, ZERO}; use openzeppelin_testing::{AsAddressTrait, EventSpyExt, EventSpyQueue as EventSpy, spy_events}; use openzeppelin_utils::serde::SerializedAppend; use snforge_std::{CheatSpan, cheat_caller_address}; use starknet::ContractAddress; use crate::erc20::ERC20Component::InternalImpl as ERC20InternalImpl; use crate::erc20::extensions::erc4626::ERC4626Component::{ - ERC4626Impl, ERC4626MetadataImpl, InternalImpl, + Deposit, ERC4626Impl, ERC4626MetadataImpl, InternalImpl, Withdraw, }; use crate::erc20::extensions::erc4626::interface::{ERC4626ABIDispatcher, ERC4626ABIDispatcherTrait}; use crate::erc20::extensions::erc4626::{DefaultConfig, ERC4626Component}; @@ -1725,7 +1723,7 @@ pub impl ERC4626SpyHelpersImpl of ERC4626SpyHelpers { assets: u256, shares: u256, ) { - let expected = ERC4626Component::Deposit { sender, owner, assets, shares }; + let expected = ERC4626Component::Event::Deposit(Deposit { sender, owner, assets, shares }); self.assert_emitted_single(contract, expected); } @@ -1750,7 +1748,9 @@ pub impl ERC4626SpyHelpersImpl of ERC4626SpyHelpers { assets: u256, shares: u256, ) { - let expected = ERC4626Component::Withdraw { sender, receiver, owner, assets, shares }; + let expected = ERC4626Component::Event::Withdraw( + Withdraw { sender, receiver, owner, assets, shares }, + ); self.assert_emitted_single(contract, expected); } From 11c548db0f121a3ed50200ea1d10b384d7fa7001 Mon Sep 17 00:00:00 2001 From: Eric Nordelo Date: Wed, 16 Jul 2025 17:25:19 +0200 Subject: [PATCH 14/29] fix: macros --- Scarb.toml | 8 +- ...st_accesscontrol_default_admin_rules.cairo | 36 +- packages/macros/Cargo.lock | 228 +++-- packages/macros/Cargo.toml | 15 +- .../src/attribute/type_hash/definition.rs | 6 +- .../macros/src/attribute/type_hash/parser.rs | 2 +- .../src/attribute/with_components/parser.rs | 4 +- packages/macros/src/lib.rs | 4 +- .../macros/src/tests/test_with_components.rs | 2 +- packages/macros/src/with_components.rs | 851 ------------------ 10 files changed, 202 insertions(+), 954 deletions(-) delete mode 100644 packages/macros/src/with_components.rs diff --git a/Scarb.toml b/Scarb.toml index 20a422b19..40d959313 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -26,8 +26,8 @@ edition.workspace = true [workspace.package] version = "2.0.0" edition = "2024_07" -cairo-version = "2.11.4" -scarb-version = "2.11.4" +cairo-version = "2.12.0-rc.1" +scarb-version = "2.12.0-rc.1" authors = ["OpenZeppelin Community "] description = "OpenZeppelin Contracts written in Cairo for Starknet, a decentralized ZK Rollup" documentation = "https://docs.openzeppelin.com/contracts-cairo" @@ -42,8 +42,8 @@ keywords = [ ] [workspace.dependencies] -assert_macros = "2.11.4" -starknet = "2.11.4" +assert_macros = "2.12.0-rc.1" +starknet = "2.12.0-rc.1" snforge_std = "0.46.0" [dependencies] diff --git a/packages/access/src/tests/test_accesscontrol_default_admin_rules.cairo b/packages/access/src/tests/test_accesscontrol_default_admin_rules.cairo index 13b6782ee..98c34eb76 100644 --- a/packages/access/src/tests/test_accesscontrol_default_admin_rules.cairo +++ b/packages/access/src/tests/test_accesscontrol_default_admin_rules.cairo @@ -21,6 +21,7 @@ use crate::accesscontrol::interface::{ IACCESSCONTROL_ID, IAccessControl, IAccessControlCamel, IAccessControlWithDelay, RoleStatus, }; use crate::tests::test_accesscontrol::AccessControlSpyHelpers; +use openzeppelin_utils::serde::SerializedAppend; // // Setup @@ -1161,8 +1162,6 @@ fn test_default_admin_role_is_its_own_admin() { // Helpers // -use openzeppelin_utils::serde::SerializedAppend; - #[generate_trait] impl AccessControlDefaultAdminRulesSpyHelpersImpl of AccessControlDefaultAdminRulesSpyHelpers { fn assert_only_event_default_admin_transfer_scheduled( @@ -1174,42 +1173,45 @@ impl AccessControlDefaultAdminRulesSpyHelpersImpl of AccessControlDefaultAdminRu let mut keys = array![]; keys.append_serde(selector!("DefaultAdminTransferScheduled")); keys.append_serde(new_admin); + let mut data = array![]; data.append_serde(accept_schedule); + let expected = Event { keys, data }; - // let expected = - // AccessControlDefaultAdminRulesComponent::Event::DefaultAdminTransferScheduled( - // DefaultAdminTransferScheduled { new_admin, accept_schedule }, - // ); self.assert_only_event(contract, expected); } fn assert_only_event_default_admin_transfer_canceled( ref self: EventSpy, contract: ContractAddress, ) { - let expected = AccessControlDefaultAdminRulesComponent::Event::DefaultAdminTransferCanceled( - DefaultAdminTransferCanceled {}, - ); + let mut keys = array![]; + keys.append_serde(selector!("DefaultAdminTransferCanceled")); + + let expected = Event { keys, data: array![] }; self.assert_only_event(contract, expected); } fn assert_only_event_default_admin_delay_change_scheduled( ref self: EventSpy, contract: ContractAddress, new_delay: u64, effect_schedule: u64, ) { - let expected = - AccessControlDefaultAdminRulesComponent::Event::DefaultAdminDelayChangeScheduled( - DefaultAdminDelayChangeScheduled { new_delay, effect_schedule }, - ); + let mut keys = array![]; + keys.append_serde(selector!("DefaultAdminDelayChangeScheduled")); + + let mut data = array![]; + data.append_serde(new_delay); + data.append_serde(effect_schedule); + + let expected = Event { keys, data }; self.assert_only_event(contract, expected); } fn assert_only_event_default_admin_delay_change_canceled( ref self: EventSpy, contract: ContractAddress, ) { - let expected = - AccessControlDefaultAdminRulesComponent::Event::DefaultAdminDelayChangeCanceled( - DefaultAdminDelayChangeCanceled {}, - ); + let mut keys = array![]; + keys.append_serde(selector!("DefaultAdminDelayChangeCanceled")); + + let expected = Event { keys, data: array![] }; self.assert_only_event(contract, expected); } } diff --git a/packages/macros/Cargo.lock b/packages/macros/Cargo.lock index dbf2a27a1..743589201 100644 --- a/packages/macros/Cargo.lock +++ b/packages/macros/Cargo.lock @@ -50,6 +50,26 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "bincode" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36eaf5d7b090263e8150820482d5d93cd964a81e4019913c972f4edcc6edb740" +dependencies = [ + "bincode_derive", + "serde", + "unty", +] + +[[package]] +name = "bincode_derive" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf95709a440f45e986983918d0e8a1f30a9b1df04918fc828670606804ac3c09" +dependencies = [ + "virtue", +] + [[package]] name = "bit-set" version = "0.8.0" @@ -92,6 +112,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "borsh" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce" +dependencies = [ + "cfg_aliases", +] + [[package]] name = "bstr" version = "1.11.3" @@ -110,9 +139,9 @@ checksum = "7575182f7272186991736b70173b0ea045398f984bf5ebbb3804736ce1330c9d" [[package]] name = "cairo-lang-casm" -version = "2.11.4" +version = "2.12.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34f666086bfda27b0b1c708d4c9aca097508870381ddfcc1c97f442b2430d079" +checksum = "b4d4c4d35619430a42278b858364cd655e2544cf11086d8d93c9be2457cc814a" dependencies = [ "cairo-lang-utils", "indoc", @@ -124,19 +153,20 @@ dependencies = [ [[package]] name = "cairo-lang-debug" -version = "2.11.4" +version = "2.12.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94e438aea97ef0d360b0e1eff98c9bd7077407993fae735ac450031faf0a7cb1" +checksum = "bf9da3e821fd0aa724963aa9e9034d60e38c8e18aef8a1f56d093d8e33a427bb" dependencies = [ "cairo-lang-utils", ] [[package]] name = "cairo-lang-defs" -version = "2.11.4" +version = "2.12.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f9c075e393b2e120ab32e981a2af9c36e9ec78405e86d6c8a2c4c11a3df9257" +checksum = "85bd972126413ee8516db68300cb5355b12b45e1861b9529f9ef989d4f847018" dependencies = [ + "bincode", "cairo-lang-debug", "cairo-lang-diagnostics", "cairo-lang-filesystem", @@ -145,14 +175,17 @@ dependencies = [ "cairo-lang-utils", "itertools", "rust-analyzer-salsa", + "serde", "smol_str", + "typetag", + "xxhash-rust", ] [[package]] name = "cairo-lang-diagnostics" -version = "2.11.4" +version = "2.12.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0366f2ba4f0d523e1da8bae918566bb67a0030b15958b7185a889df58475dc7" +checksum = "12ec9787c46ceda3676f8ba2b8f1e253d242c68d2b0c3cde70573cebfe40cad4" dependencies = [ "cairo-lang-debug", "cairo-lang-filesystem", @@ -162,9 +195,9 @@ dependencies = [ [[package]] name = "cairo-lang-eq-solver" -version = "2.11.4" +version = "2.12.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b540174610928874781672632c2a84a7352201a6a12f635362468b98e71050" +checksum = "4159473d4716ca8c80c2a9cd3c6c1536b62e5d96690500f8e7717fb960634454" dependencies = [ "cairo-lang-utils", "good_lp", @@ -172,9 +205,9 @@ dependencies = [ [[package]] name = "cairo-lang-filesystem" -version = "2.11.4" +version = "2.12.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de819fdd43ea61c051c7a876d0ea44626c7ee7447a72ef63f48672c7745c86b5" +checksum = "891c976745b04b9c37fdb1c0c8599b544c141ae4fb6fd83d6e004d079e281cdc" dependencies = [ "cairo-lang-debug", "cairo-lang-utils", @@ -188,9 +221,9 @@ dependencies = [ [[package]] name = "cairo-lang-formatter" -version = "2.11.4" +version = "2.12.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3f5327e5cc48880249d8bc9edc8f5ab534a18e002b5069f1a67f4a8f3f2003a" +checksum = "1aae69538736123b030aa6621769f4aa42e9e9c1a1246418b49299dfa86b5d12" dependencies = [ "anyhow", "cairo-lang-diagnostics", @@ -201,7 +234,6 @@ dependencies = [ "diffy", "ignore", "itertools", - "rust-analyzer-salsa", "serde", "thiserror 2.0.12", ] @@ -225,7 +257,7 @@ checksum = "e32e958decd95ae122ee64daa26721da2f76e83231047f947fd9cdc5d3c90cc6" dependencies = [ "quote", "scarb-stable-hash", - "syn 2.0.90", + "syn 2.0.104", ] [[package]] @@ -236,9 +268,9 @@ checksum = "c49906d6b1c215e5814be7c5c65ecf2328898b335bee8c2409ec07cfb5530daf" [[package]] name = "cairo-lang-parser" -version = "2.11.4" +version = "2.12.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0154b6c5bf6e75cc672a5a47775829f4248946c96855a2483e0b41f7e43c0248" +checksum = "10a250db6b5a8af39c67b26d62546c1dc3955a5078ca2f8d72151b0096d83e61" dependencies = [ "cairo-lang-diagnostics", "cairo-lang-filesystem", @@ -257,9 +289,9 @@ dependencies = [ [[package]] name = "cairo-lang-plugins" -version = "2.11.4" +version = "2.12.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aed019a1665d85930366bd2cc76a9c5bedb6052dbc82c55a141c3066077c00cb" +checksum = "488c227d3997552ff0a29053b0a370c596d420b4d21917e42525ab1646a2c752" dependencies = [ "cairo-lang-defs", "cairo-lang-diagnostics", @@ -282,14 +314,14 @@ checksum = "123ac0ecadf31bacae77436d72b88fa9caef2b8e92c89ce63a125ae911a12fae" [[package]] name = "cairo-lang-sierra" -version = "2.11.4" +version = "2.12.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "461500d262ac78744c7b39087b033c36a448e047390c71f5c92ac27ef6a6edda" +checksum = "4e8eb3e014faa26a2b1b8f69dd2c735254d85ba96b5baff3ed79467331dfa98d" dependencies = [ "anyhow", "cairo-lang-utils", "const-fnv1a-hash", - "convert_case 0.7.1", + "convert_case", "derivative", "itertools", "lalrpop", @@ -309,9 +341,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-ap-change" -version = "2.11.4" +version = "2.12.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7153bdd6d3f46c3045c0b3e23c9f5e8458fe4da673864f95ddfc5ff9f4ef981c" +checksum = "6e18b0197cf7cea960e3d71f97fe7f76f427d5272121df315e0132a66f34b8d1" dependencies = [ "cairo-lang-eq-solver", "cairo-lang-sierra", @@ -325,9 +357,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-gas" -version = "2.11.4" +version = "2.12.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0330f6846da0d59b32feae23dfc97887e81b4f51cf9fe17a39ef493ed8cabe23" +checksum = "0d66cb4ced9d63185f825c07083a4810f0e168562f6cfe2b72bc8fc1a37ec48d" dependencies = [ "cairo-lang-eq-solver", "cairo-lang-sierra", @@ -341,9 +373,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-to-casm" -version = "2.11.4" +version = "2.12.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a91e32d7eeac0e4c7837e87bb75375c2d42eaa05dd314a636b162c68f5326e56" +checksum = "420cae89a2f0a0ce8c2fe49210539d5c47654141f86211e63728cd1fb0098a40" dependencies = [ "assert_matches", "cairo-lang-casm", @@ -362,9 +394,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-type-size" -version = "2.11.4" +version = "2.12.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40197fac8db5540008ae6c4e9ba40ebf0e402f8cf7c709e9959b48913ebd18ff" +checksum = "246dc32e2ea9f419cee43e213a58a23ab302eaea492487a3fc2d9684b5cf03d0" dependencies = [ "cairo-lang-sierra", "cairo-lang-utils", @@ -372,15 +404,15 @@ dependencies = [ [[package]] name = "cairo-lang-starknet-classes" -version = "2.11.4" +version = "2.12.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e1d950413579e309fc2952c263281dc0dfce8491c1480f84d8d8a4376b2d960" +checksum = "49c34bd8d894d9412b2a632c337bfbc5d3726e620fa732e086478939bb240101" dependencies = [ "cairo-lang-casm", "cairo-lang-sierra", "cairo-lang-sierra-to-casm", "cairo-lang-utils", - "convert_case 0.7.1", + "convert_case", "itertools", "num-bigint", "num-integer", @@ -395,9 +427,9 @@ dependencies = [ [[package]] name = "cairo-lang-syntax" -version = "2.11.4" +version = "2.12.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea0e2287233244b6a49835724c932726d9e951fdfdbcc24ca5402f667d745209" +checksum = "7ffb74953193cd56cfb71527c69e7dabce90b7550823e18bf3ea54474fe2209e" dependencies = [ "cairo-lang-debug", "cairo-lang-filesystem", @@ -413,9 +445,9 @@ dependencies = [ [[package]] name = "cairo-lang-syntax-codegen" -version = "2.11.4" +version = "2.12.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c69eb6919b69a9a7bb92f79d73c568d09ef77efa0b5d265efb763234ec979d4" +checksum = "a36fad6859a594f62c1dcdb7a65cd1360461a79162f07a1f74beeee3617a42c6" dependencies = [ "genco", "xshell", @@ -423,9 +455,9 @@ dependencies = [ [[package]] name = "cairo-lang-utils" -version = "2.11.4" +version = "2.12.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c387a696a29cea52ddedb3097706dd8168958ef5388157d6e5b388a2c0de061" +checksum = "07f5f439b336d78c4d0e4f11e07dca9622f88ad08dac09252c4212d4bb24629d" dependencies = [ "hashbrown 0.15.2", "indexmap 2.8.0", @@ -434,6 +466,7 @@ dependencies = [ "num-traits", "schemars", "serde", + "smol_str", ] [[package]] @@ -442,6 +475,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "colored" version = "3.0.0" @@ -489,15 +528,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "convert_case" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb402b8d4c85569410425650ce3eddc7d698ed96d39a73f941b08fb63082f1e7" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "convert_case" version = "0.8.0" @@ -620,13 +650,24 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "erased-serde" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7" +dependencies = [ + "serde", + "typeid", +] + [[package]] name = "fancy-regex" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e24cb5a94bcae1e5408b0effca5cd7172ea3c5755049c5f3af4cd283a165298" +checksum = "d6215aee357f8c7c989ebb4b8466ca4d7dc93b3957039f2fc3ea2ade8ea5f279" dependencies = [ "bit-set", + "derivative", "regex-automata", "regex-syntax", ] @@ -674,7 +715,7 @@ checksum = "43eaff6bbc0b3a878361aced5ec6a2818ee7c541c5b33b5880dfa9a86c23e9e7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.104", ] [[package]] @@ -767,7 +808,7 @@ checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.104", ] [[package]] @@ -816,6 +857,15 @@ dependencies = [ "similar", ] +[[package]] +name = "inventory" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab08d7cd2c5897f2c949e5383ea7c7db03fb19130ffcfbf7eda795137ae3cb83" +dependencies = [ + "rustversion", +] + [[package]] name = "itertools" version = "0.14.0" @@ -929,7 +979,7 @@ checksum = "edbe595006d355eaf9ae11db92707d4338cd2384d16866131cc1afdbdd35d8d9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.104", ] [[package]] @@ -1065,11 +1115,12 @@ dependencies = [ "cairo-lang-plugins", "cairo-lang-starknet-classes", "cairo-lang-syntax", - "convert_case 0.8.0", + "convert_case", "fancy-regex", "indoc", "insta", "regex", + "syn 2.0.104", ] [[package]] @@ -1097,7 +1148,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.104", ] [[package]] @@ -1290,7 +1341,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.104", ] [[package]] @@ -1352,7 +1403,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.90", + "syn 2.0.104", ] [[package]] @@ -1387,7 +1438,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.104", ] [[package]] @@ -1398,7 +1449,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.104", ] [[package]] @@ -1463,10 +1514,11 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "smol_str" -version = "0.2.2" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" +checksum = "9676b89cd56310a87b93dec47b11af744f34d5fc9f367b829474eec0a891350d" dependencies = [ + "borsh", "serde", ] @@ -1528,9 +1580,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.90" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -1579,7 +1631,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.104", ] [[package]] @@ -1590,7 +1642,7 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.104", ] [[package]] @@ -1646,7 +1698,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.104", ] [[package]] @@ -1668,12 +1720,42 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + [[package]] name = "typenum" version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +[[package]] +name = "typetag" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f22b40dd7bfe8c14230cf9702081366421890435b2d625fa92b4acc4c3de6f" +dependencies = [ + "erased-serde", + "inventory", + "once_cell", + "serde", + "typetag-impl", +] + +[[package]] +name = "typetag-impl" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35f5380909ffc31b4de4f4bdf96b877175a016aa2ca98cee39fcfd8c4d53d952" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + [[package]] name = "unescaper" version = "0.1.5" @@ -1701,12 +1783,24 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "unty" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" + [[package]] name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "virtue" +version = "0.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "051eb1abcf10076295e815102942cc58f9d5e3b4560e46e53c21e8ff6f3af7b1" + [[package]] name = "walkdir" version = "2.5.0" diff --git a/packages/macros/Cargo.toml b/packages/macros/Cargo.toml index 0236496ca..136a9f4b3 100644 --- a/packages/macros/Cargo.toml +++ b/packages/macros/Cargo.toml @@ -8,14 +8,15 @@ crate-type = ["cdylib"] [dependencies] cairo-lang-macro = "0.1" -cairo-lang-parser = "2.11" -cairo-lang-plugins = "2.11" -cairo-lang-syntax = "2.11" -cairo-lang-defs = "2.11" -cairo-lang-formatter = "2.11" -cairo-lang-starknet-classes = "2.11" +cairo-lang-parser = "2.12.0-dev.1" +cairo-lang-plugins = "2.12.0-dev.1" +cairo-lang-syntax = "2.12.0-dev.1" +cairo-lang-defs = "2.12.0-dev.1" +cairo-lang-formatter = "2.12.0-dev.1" +cairo-lang-starknet-classes = "2.12.0-dev.1" indoc = "2.0.5" regex = "1.11.1" insta = "1.42.0" convert_case = "0.8.0" -fancy-regex = "0.14.0" +fancy-regex = "0.15.0" +syn = "2.0.104" diff --git a/packages/macros/src/attribute/type_hash/definition.rs b/packages/macros/src/attribute/type_hash/definition.rs index b868aee0a..a8965d66f 100644 --- a/packages/macros/src/attribute/type_hash/definition.rs +++ b/packages/macros/src/attribute/type_hash/definition.rs @@ -147,9 +147,9 @@ fn handle_node( args: &TypeHashArgs, ) -> Result { let typed = ast::SyntaxFile::from_syntax_node(db, node); - let items = typed.items(db).elements(db); + let mut items = typed.items(db).elements(db); - let Some(item_ast) = items.first() else { + let Some(item_ast) = items.next() else { let error = Diagnostic::error(errors::EMPTY_TYPE_FOUND); return Err(error); }; @@ -158,7 +158,7 @@ fn handle_node( match item_ast { ast::ModuleItem::Struct(_) | ast::ModuleItem::Enum(_) => { // It is safe to unwrap here because we know the item is a struct - let plugin_type_info = PluginTypeInfo::new(db, item_ast).unwrap(); + let plugin_type_info = PluginTypeInfo::new(db, &item_ast).unwrap(); generate_code(db, &plugin_type_info, args) } _ => { diff --git a/packages/macros/src/attribute/type_hash/parser.rs b/packages/macros/src/attribute/type_hash/parser.rs index 3c9f86123..8a7a5261c 100644 --- a/packages/macros/src/attribute/type_hash/parser.rs +++ b/packages/macros/src/attribute/type_hash/parser.rs @@ -52,7 +52,7 @@ impl<'a> TypeHashParser<'a> { .members_info .iter() .map(|member| { - let attributes = member.attributes.elements(db); + let attributes = member.attributes.elements(db).collect::>(); let args = match get_name_and_type_from_attributes(db, &attributes) { Ok(args) => args, Err(e) => { diff --git a/packages/macros/src/attribute/with_components/parser.rs b/packages/macros/src/attribute/with_components/parser.rs index 14ce8a5a3..0806c6378 100644 --- a/packages/macros/src/attribute/with_components/parser.rs +++ b/packages/macros/src/attribute/with_components/parser.rs @@ -9,7 +9,7 @@ use crate::{ }; use cairo_lang_defs::patcher::{PatchBuilder, RewriteNode}; use cairo_lang_macro::{Diagnostic, Diagnostics}; -use cairo_lang_syntax::node::helpers::{BodyItems, QueryAttrs}; +use cairo_lang_syntax::node::helpers::QueryAttrs; use cairo_lang_syntax::node::{ ast::{self, MaybeModuleBody}, db::SyntaxGroup, @@ -119,7 +119,7 @@ fn validate_contract_module( .collect::>(); if !components_with_initializer.is_empty() { - let constructor = body.items_vec(db).into_iter().find(|item| { + let constructor = body.items(db).elements(db).find(|item| { matches!(item, ast::ModuleItem::FreeFunction(function_ast) if function_ast.has_attr(db, CONSTRUCTOR_ATTRIBUTE)) }); let constructor_code = if let Some(constructor) = constructor { diff --git a/packages/macros/src/lib.rs b/packages/macros/src/lib.rs index c3b94f223..0aab98af3 100644 --- a/packages/macros/src/lib.rs +++ b/packages/macros/src/lib.rs @@ -1,8 +1,10 @@ pub(crate) mod attribute; pub(crate) mod constants; +pub(crate) mod inline; pub(crate) mod utils; -pub(crate) use attribute::type_hash; +pub(crate) use attribute::{type_hash, with_components}; +pub(crate) use inline::generate_event_spy_helpers; #[cfg(test)] mod tests; diff --git a/packages/macros/src/tests/test_with_components.rs b/packages/macros/src/tests/test_with_components.rs index b4bbccb87..110018aba 100644 --- a/packages/macros/src/tests/test_with_components.rs +++ b/packages/macros/src/tests/test_with_components.rs @@ -1,4 +1,4 @@ -use crate::attribute::with_components::definition::with_components_avevetedp5blk as with_components; +use crate::with_components::definition::with_components_avevetedp5blk as with_components; use cairo_lang_macro::TokenStream; use indoc::indoc; use insta::assert_snapshot; diff --git a/packages/macros/src/with_components.rs b/packages/macros/src/with_components.rs deleted file mode 100644 index 1fa07acde..000000000 --- a/packages/macros/src/with_components.rs +++ /dev/null @@ -1,851 +0,0 @@ -use crate::constants::{ - CONSTRUCTOR_ATTRIBUTE, CONTRACT_ATTRIBUTE, EVENT_ENUM_NAME, FLAT_ATTRIBUTE, - STORAGE_STRUCT_NAME, SUBSTORAGE_ATTRIBUTE, -}; -use crate::utils::tabs; -use cairo_lang_defs::patcher::{PatchBuilder, RewriteNode}; -use cairo_lang_formatter::format_string; -use cairo_lang_macro::{attribute_macro, Diagnostic, Diagnostics, ProcMacroResult, TokenStream}; -use cairo_lang_parser::utils::SimpleParserDatabase; -use cairo_lang_syntax::node::ast::MaybeModuleBody; -use cairo_lang_syntax::node::db::SyntaxGroup; -use cairo_lang_syntax::node::helpers::{BodyItems, QueryAttrs}; -use cairo_lang_syntax::node::{ast, SyntaxNode, Terminal, TypedSyntaxNode}; -use indoc::{formatdoc, indoc}; -use regex::Regex; - -const ALLOWED_COMPONENTS: [&str; 22] = [ - "Account", - "EthAccount", - "SRC9", - "AccessControl", - "Ownable", - "Vesting", - "SRC5", - "Initializable", - "Pausable", - "ReentrancyGuard", - "ERC20", - "ERC721", - "ERC721Enumerable", - "ERC721Receiver", - "ERC1155", - "ERC1155Receiver", - "ERC2981", - "Upgradeable", - "Nonces", - "Multisig", - "TimelockController", - "Votes", - // "TODO:Governor", - // "TODO:GovernorCoreExecution", - // "TODO:GovernorCountingSimple", - // "TODO:GovernorSettings", - // "TODO:GovernorTimelockExecution", - // "TODO:GovernorVotesQuorumFraction", - // "TODO:GovernorVotes", -]; - -/// Inserts multiple component dependencies into a modules codebase. -#[attribute_macro] -pub fn with_components(attribute_stream: TokenStream, item_stream: TokenStream) -> ProcMacroResult { - let args = parse_args(&attribute_stream.to_string()); - - // 1. Get the components info (if valid) - let mut components_info = vec![]; - for arg in args { - let component_info_result = get_component_info(&arg); - if let Ok(info) = component_info_result { - components_info.push(info); - } else { - return ProcMacroResult::new(TokenStream::empty()) - .with_diagnostics(component_info_result.unwrap_err()); - } - } - - // 2. Parse the item stream - let db = SimpleParserDatabase::default(); - let (content, mut diagnostics) = match db.parse_virtual(item_stream.to_string()) { - Ok(node) => build_patch(&db, node, components_info.clone()), - Err(err) => { - let error = Diagnostic::error(err.format(&db)); - return ProcMacroResult::new(TokenStream::empty()).with_diagnostics(error.into()); - } - }; - - // 4. Add warnings for each component - for component_info in components_info.iter() { - let component_warnings = add_per_component_warnings(&content, component_info); - diagnostics.extend(component_warnings); - } - - let formatted_content = if !content.is_empty() { - format_string(&db, content) - } else { - content - }; - - ProcMacroResult::new(TokenStream::new(formatted_content)).with_diagnostics(diagnostics) -} - -/// Parses the arguments from the attribute stream. -fn parse_args(text: &str) -> Vec { - let re = Regex::new(r"(\w+)").unwrap(); - let matches = re.find_iter(text); - matches.map(|m| m.as_str().to_string()).collect() -} - -/// Builds the patch for a given node and component info. -fn build_patch( - db: &dyn SyntaxGroup, - node: SyntaxNode, - components_info: Vec, -) -> (String, Diagnostics) { - let mut builder = PatchBuilder::new_ex(db, &node); - - let typed = ast::SyntaxFile::from_syntax_node(db, node); - let mut base_rnode = RewriteNode::from_ast(&typed); - let module_rnode = base_rnode - .modify_child(db, ast::SyntaxFile::INDEX_ITEMS) - .modify_child(db, 0); - - // Validate the contract module - let (errors, warnings) = validate_contract_module(db, module_rnode, &components_info); - if !errors.is_empty() { - return (String::new(), errors.into()); - } - - let body_rnode = module_rnode.modify_child(db, ast::ItemModule::INDEX_BODY); - - process_module_items(body_rnode, db, &components_info); - add_use_clauses_and_macros(body_rnode, db, &components_info); - - builder.add_modified(base_rnode); - let (content, _) = builder.build(); - - (content, warnings.into()) -} - -/// Validates that the contract module: -/// -/// - Has the `#[starknet::contract]` attribute. -/// - Has a constructor calling the corresponding initializers. -/// - Has the corresponding immutable configs. -/// -/// NOTE: Missing initializers and configs are added as Warnings. -/// NOTE: When an error is found, the functions doesn't return any warnings to avoid noise. -/// -/// # Returns -/// -/// * `errors` - The errors that arose during the validation. -/// * `warnings` - The warnings that arose during the validation. -fn validate_contract_module( - db: &dyn SyntaxGroup, - node: &mut RewriteNode, - components_info: &[ComponentInfo], -) -> (Vec, Vec) { - let mut warnings = vec![]; - - if let RewriteNode::Copied(copied) = node { - let item = ast::ItemModule::from_syntax_node(db, copied.clone()); - - // 1. Check that the module has a body (error) - let MaybeModuleBody::Some(body) = item.body(db) else { - let error = Diagnostic::error(indoc! {" - Contract module must have a body. - "}); - return (vec![error], vec![]); - }; - - // 2. Check that the module has the `#[starknet::contract]` attribute (error) - if !item.has_attr(db, CONTRACT_ATTRIBUTE) { - let error = Diagnostic::error(formatdoc! {" - Contract module must have the `#[{CONTRACT_ATTRIBUTE}]` attribute. - "}); - return (vec![error], vec![]); - } - - // 3. Check that the module has the corresponding initializers (warning) - let components_with_initializer = components_info - .iter() - .filter(|c| c.has_initializer) - .collect::>(); - - if !components_with_initializer.is_empty() { - let constructor = body.items_vec(db).into_iter().find(|item| { - matches!(item, ast::ModuleItem::FreeFunction(function_ast) if function_ast.has_attr(db, CONSTRUCTOR_ATTRIBUTE)) - }); - let constructor_code = if let Some(constructor) = constructor { - // Get the constructor code (maybe we can do this without the builder) - let constructor_ast = constructor.as_syntax_node(); - let typed = ast::ModuleItem::from_syntax_node(db, constructor_ast.clone()); - let constructor_rnode = RewriteNode::from_ast(&typed); - let mut builder = PatchBuilder::new_ex(db, &constructor_ast); - builder.add_modified(constructor_rnode); - let (code, _) = builder.build(); - code - } else { - String::new() - }; - let mut components_with_initializer_missing = vec![]; - for component in components_with_initializer.iter() { - if !constructor_code.contains(&format!("self.{}.initializer(", component.storage)) { - components_with_initializer_missing.push(component.short_name()); - } - } - - if !components_with_initializer_missing.is_empty() { - let components_with_initializer_missing_str = - components_with_initializer_missing.join(", "); - let warning = Diagnostic::warn(formatdoc! {" - It looks like the initializers for the following components are missing: - - {components_with_initializer_missing_str} - - This may lead to unexpected behavior. We recommend adding the corresponding initializer calls to the constructor. - "}); - warnings.push(warning); - } - } - - // 4. Check that the contract has the corresponding immutable configs - for component in components_info.iter().filter(|c| c.has_immutable_config) { - // Get the body code (maybe we can do this without the builder) - let body_ast = body.as_syntax_node(); - let typed = ast::ModuleBody::from_syntax_node(db, body_ast.clone()); - let body_rnode = RewriteNode::from_ast(&typed); - - let mut builder = PatchBuilder::new_ex(db, &body_ast); - builder.add_modified(body_rnode); - let (code, _) = builder.build(); - - // Check if the DefaultConfig is used - let component_parent_path = component - .path - .strip_suffix(&component.name) - .expect("Component path must end with the component name"); - let default_config_path = format!("{component_parent_path}DefaultConfig"); - let default_config_used = code.contains(&default_config_path); - if !default_config_used { - // Check if the ImmutableConfig is implemented - let immutable_config_implemented = - code.contains(&format!("of {}::ImmutableConfig", component.name)); - if !immutable_config_implemented { - let warning = Diagnostic::warn(formatdoc! {" - The {} component requires an ImmutableConfig implementation in scope. It looks like this implementation is missing. - - You can use the default implementation by importing: - - `use {};` - ", component.short_name(), default_config_path}); - warnings.push(warning); - } - } - } - } - - (vec![], warnings) -} - -/// Adds warnings that may be helpful for users. -fn add_per_component_warnings(code: &str, component_info: &ComponentInfo) -> Vec { - let mut warnings = vec![]; - - match component_info.short_name() { - "Vesting" => { - // 1. Check that the VestingScheduleTrait is implemented - let linear_impl_used = code.contains("LinearVestingSchedule"); - let vesting_trait_used = code.contains("VestingScheduleTrait"); - if !linear_impl_used && !vesting_trait_used { - let warning = Diagnostic::warn(indoc! {" - The Vesting component requires an implementation of the VestingScheduleTrait in scope. It looks like this implementation is missing. - - You can use the LinearVestingSchedule implementation by importing it: - - `use openzeppelin_finance::vesting::LinearVestingSchedule;` - "}); - warnings.push(warning); - } - } - "Initializable" => { - // 1. Check that the initialize internal function is called - let initialize_internal_function_called = - code.contains("self.initializable.initialize()"); - if !initialize_internal_function_called { - let warning = Diagnostic::warn(indoc! {" - It looks like the `self.initializable.initialize()` function is not used in the contract. If - this is intentional, you may consider removing the Initializable component. - "}); - warnings.push(warning); - } - } - "Pausable" => { - // 1. Check that the pause and unpause functions are called - let pause_function_called = code.contains("self.pausable.pause()"); - let unpause_function_called = code.contains("self.pausable.unpause()"); - if !pause_function_called || !unpause_function_called { - let warning = Diagnostic::warn(indoc! {" - It looks like either the `self.pausable.pause()` or `self.pausable.unpause()` mechanisms are not implemented in the contract. If - this is intentional, you may consider removing the Pausable component. - "}); - warnings.push(warning); - } - } - "ERC20" => { - // 1. Check that the ERC20HooksTrait is implemented - let hooks_trait_used = code.contains("ERC20HooksTrait"); - let hooks_empty_impl_used = code.contains("ERC20HooksEmptyImpl"); - if !hooks_trait_used && !hooks_empty_impl_used { - let warning = Diagnostic::warn(indoc! {" - The ERC20 component requires an implementation of the ERC20HooksTrait in scope. It looks like this implementation is missing. - - You can use the ERC20HooksEmptyImpl implementation by importing it: - - `use openzeppelin_token::erc20::ERC20HooksEmptyImpl;` - "}); - warnings.push(warning); - } - } - "ERC721" => { - // 1. Check that the ERC721HooksTrait is implemented - let hooks_trait_used = code.contains("ERC721HooksTrait"); - let hooks_empty_impl_used = code.contains("ERC721HooksEmptyImpl"); - if !hooks_trait_used && !hooks_empty_impl_used { - let warning = Diagnostic::warn(indoc! {" - The ERC721 component requires an implementation of the ERC721HooksTrait in scope. It looks like this implementation is missing. - - You can use the ERC721HooksEmptyImpl implementation by importing it: - - `use openzeppelin_token::erc721::ERC721HooksEmptyImpl;` - "}); - warnings.push(warning); - } - } - "ERC1155" => { - // 1. Check that the ERC1155HooksTrait is implemented - let hooks_trait_used = code.contains("ERC1155HooksTrait"); - let hooks_empty_impl_used = code.contains("ERC1155HooksEmptyImpl"); - if !hooks_trait_used && !hooks_empty_impl_used { - let warning = Diagnostic::warn(indoc! {" - The ERC1155 component requires an implementation of the ERC1155HooksTrait in scope. It looks like this implementation is missing. - - You can use the ERC1155HooksEmptyImpl implementation by importing it: - - `use openzeppelin_token::erc1155::ERC1155HooksEmptyImpl;` - "}); - warnings.push(warning); - } - } - "Upgradeable" => { - // 1. Check that the upgrade function is called - let upgrade_function_called = code.contains("self.upgradeable.upgrade"); - if !upgrade_function_called { - let warning = Diagnostic::warn(indoc! {" - It looks like the `self.upgradeable.upgrade(new_class_hash)` function is not used in the contract. If - this is intentional, you may consider removing the Upgradeable component. - "}); - warnings.push(warning); - } - } - "Votes" => { - // 1. Check that the SNIP12Metadata is implemented - let snip12_metadata_implemented = code.contains("of SNIP12Metadata"); - if !snip12_metadata_implemented { - let warning = Diagnostic::warn(indoc! {" - The Votes component requires an implementation of the SNIP12Metadata trait. It looks like this implementation is missing. - "}); - warnings.push(warning); - } - } - _ => {} - } - warnings -} - -/// Iterates over the items in the body node and processes them. -fn process_module_items( - body_rnode: &mut RewriteNode, - db: &dyn SyntaxGroup, - components_info: &Vec, -) { - let items_rnode = body_rnode.modify_child(db, ast::ModuleBody::INDEX_ITEMS); - let items_mnode = items_rnode.modify(db); - let mut event_enum_found = false; - - for item_rnode in items_mnode.children.as_mut().unwrap() { - if let RewriteNode::Copied(copied) = item_rnode { - let item = ast::ModuleItem::from_syntax_node(db, copied.clone()); - - match item { - ast::ModuleItem::Struct(item_struct) - if item_struct.name(db).text(db) == STORAGE_STRUCT_NAME => - { - process_storage_struct(item_rnode, db, components_info); - } - ast::ModuleItem::Enum(item_enum) - if item_enum.name(db).text(db) == EVENT_ENUM_NAME => - { - process_event_enum(item_rnode, db, components_info); - event_enum_found = true; - } - _ => {} - } - } - } - - // If the event enum is not found, add it. - if !event_enum_found { - add_event_enum(body_rnode, db, components_info); - } -} - -/// Modifies the storage struct to add the component entries. -fn process_storage_struct( - item_struct: &mut RewriteNode, - db: &dyn SyntaxGroup, - components_info: &Vec, -) { - let item_struct_mnode = item_struct.modify(db); - let item_struct_children = item_struct_mnode.children.as_mut().unwrap(); - let components_rnode = - ComponentsGenerationData(components_info).generate_for_storage_struct(db); - - // Insert the components at the beginning of the struct body. - item_struct_children.insert(ast::ItemStruct::INDEX_LBRACE + 1, components_rnode); -} - -/// Modifies the event enum to add the component events. -fn process_event_enum( - item_enum: &mut RewriteNode, - db: &dyn SyntaxGroup, - components_info: &Vec, -) { - let item_enum_mnode = item_enum.modify(db); - let item_enum_children = item_enum_mnode.children.as_mut().unwrap(); - let components_rnode = ComponentsGenerationData(components_info).generate_for_event_enum(db); - - // Insert the components at the beginning of the enum body. - item_enum_children.insert(ast::ItemEnum::INDEX_LBRACE + 1, components_rnode); -} - -fn add_event_enum( - body_rnode: &mut RewriteNode, - db: &dyn SyntaxGroup, - components_info: &Vec, -) { - let body_mnode = body_rnode.modify(db); - let event_enum_rnode = ComponentsGenerationData(components_info).generate_event_enum(db); - - // It is safe to unwrap here because we know that the node has at least the storage struct children - body_mnode - .children - .as_mut() - .unwrap() - .insert(ast::ModuleBody::INDEX_RBRACE, event_enum_rnode); -} - -/// Modifies the body node to add the use clauses and the `component!` macros to the module. -fn add_use_clauses_and_macros( - body_rnode: &mut RewriteNode, - db: &dyn SyntaxGroup, - components_info: &Vec, -) { - let body_mnode = body_rnode.modify(db); - let components_rnode = ComponentsGenerationData(components_info).generate_for_module(db); - - // It is safe to unwrap here because we know that the node has at least the storage struct children - body_mnode - .children - .as_mut() - .unwrap() - .insert(ast::ModuleBody::INDEX_RBRACE, components_rnode); -} - -/// Information about a component. -/// -/// # Members -/// -/// * `name` - The name of the component (e.g. `ERC20Component`) -/// * `path` - The path from where the component is imported (e.g. `openzeppelin_token::erc20::ERC20Component`) -/// * `storage` - The path to reference the component in storage (e.g. `erc20`) -/// * `event` - The path to reference the component events (e.g. `ERC20Event`) -/// * `has_initializer` - Whether the component requires an initializer (e.g. `true`) -/// * `internal_impls` - The internal implementations of the component to be added to -/// the module by default (e.g. `["InternalImpl1", "InternalImpl2"]`) -#[derive(Debug, Clone)] -pub struct ComponentInfo<'a> { - pub name: &'a str, - pub path: &'a str, - pub storage: &'a str, - pub event: &'a str, - pub has_initializer: bool, - pub has_immutable_config: bool, - pub internal_impls: Vec<&'a str>, -} - -impl<'a> ComponentInfo<'a> { - fn short_name(&self) -> &'a str { - self.name - .split("Component") - .next() - .expect("Component name must end with 'Component'") - } -} - -/// Returns the component info for a given component name. -/// -/// # Arguments -/// -/// * `name` - The name of the component (e.g. `ERC20`). -fn get_component_info<'a>(name: &str) -> Result, Diagnostics> { - match name { - "Account" => Ok(ComponentInfo { - name: "AccountComponent", - path: "openzeppelin_account::AccountComponent", - storage: "account", - event: "AccountEvent", - has_initializer: true, - has_immutable_config: false, - internal_impls: vec!["InternalImpl"], - }), - "EthAccount" => Ok(ComponentInfo { - name: "EthAccountComponent", - path: "openzeppelin_account::EthAccountComponent", - storage: "eth_account", - event: "EthAccountEvent", - has_initializer: true, - has_immutable_config: false, - internal_impls: vec!["InternalImpl"], - }), - "SRC9" => Ok(ComponentInfo { - name: "SRC9Component", - path: "openzeppelin_account::extensions::SRC9Component", - storage: "src9", - event: "SRC9Event", - has_initializer: true, - has_immutable_config: false, - internal_impls: vec!["InternalImpl"], - }), - "Ownable" => Ok(ComponentInfo { - name: "OwnableComponent", - path: "openzeppelin_access::ownable::OwnableComponent", - storage: "ownable", - event: "OwnableEvent", - has_initializer: true, - has_immutable_config: false, - internal_impls: vec!["InternalImpl"], - }), - "AccessControl" => Ok(ComponentInfo { - name: "AccessControlComponent", - path: "openzeppelin_access::accesscontrol::AccessControlComponent", - storage: "access_control", - event: "AccessControlEvent", - has_initializer: true, - has_immutable_config: false, - internal_impls: vec!["InternalImpl"], - }), - "Vesting" => Ok(ComponentInfo { - name: "VestingComponent", - path: "openzeppelin_finance::vesting::VestingComponent", - storage: "vesting", - event: "VestingEvent", - has_initializer: true, - has_immutable_config: false, - internal_impls: vec!["InternalImpl"], - }), - "SRC5" => Ok(ComponentInfo { - name: "SRC5Component", - path: "openzeppelin_introspection::src5::SRC5Component", - storage: "src5", - event: "SRC5Event", - has_initializer: false, - has_immutable_config: false, - internal_impls: vec!["InternalImpl"], - }), - "Initializable" => Ok(ComponentInfo { - name: "InitializableComponent", - path: "openzeppelin_security::InitializableComponent", - storage: "initializable", - event: "InitializableEvent", - has_initializer: false, - has_immutable_config: false, - internal_impls: vec!["InternalImpl"], - }), - "Pausable" => Ok(ComponentInfo { - name: "PausableComponent", - path: "openzeppelin_security::PausableComponent", - storage: "pausable", - event: "PausableEvent", - has_initializer: false, - has_immutable_config: false, - internal_impls: vec!["InternalImpl"], - }), - "ReentrancyGuard" => Ok(ComponentInfo { - name: "ReentrancyGuardComponent", - path: "openzeppelin_security::ReentrancyGuardComponent", - storage: "reentrancy_guard", - event: "ReentrancyGuardEvent", - has_initializer: false, - has_immutable_config: false, - internal_impls: vec!["InternalImpl"], - }), - "ERC20" => Ok(ComponentInfo { - name: "ERC20Component", - path: "openzeppelin_token::erc20::ERC20Component", - storage: "erc20", - event: "ERC20Event", - has_initializer: true, - has_immutable_config: false, - internal_impls: vec!["InternalImpl"], - }), - "ERC721" => Ok(ComponentInfo { - name: "ERC721Component", - path: "openzeppelin_token::erc721::ERC721Component", - storage: "erc721", - event: "ERC721Event", - has_initializer: true, - has_immutable_config: false, - internal_impls: vec!["InternalImpl"], - }), - "ERC721Enumerable" => Ok(ComponentInfo { - name: "ERC721EnumerableComponent", - path: "openzeppelin_token::erc721::extensions::ERC721EnumerableComponent", - storage: "erc721_enumerable", - event: "ERC721EnumerableEvent", - has_initializer: true, - has_immutable_config: false, - internal_impls: vec!["InternalImpl"], - }), - "ERC721Receiver" => Ok(ComponentInfo { - name: "ERC721ReceiverComponent", - path: "openzeppelin_token::erc721::ERC721ReceiverComponent", - storage: "erc721_receiver", - event: "ERC721ReceiverEvent", - has_initializer: true, - has_immutable_config: false, - internal_impls: vec!["InternalImpl"], - }), - "ERC1155" => Ok(ComponentInfo { - name: "ERC1155Component", - path: "openzeppelin_token::erc1155::ERC1155Component", - storage: "erc1155", - event: "ERC1155Event", - has_initializer: true, - has_immutable_config: false, - internal_impls: vec!["InternalImpl"], - }), - "ERC1155Receiver" => Ok(ComponentInfo { - name: "ERC1155ReceiverComponent", - path: "openzeppelin_token::erc1155::ERC1155ReceiverComponent", - storage: "erc1155_receiver", - event: "ERC1155ReceiverEvent", - has_initializer: true, - has_immutable_config: false, - internal_impls: vec!["InternalImpl"], - }), - "ERC2981" => Ok(ComponentInfo { - name: "ERC2981Component", - path: "openzeppelin_token::common::erc2981::ERC2981Component", - storage: "erc2981", - event: "ERC2981Event", - has_initializer: true, - has_immutable_config: true, - internal_impls: vec!["InternalImpl"], - }), - "Upgradeable" => Ok(ComponentInfo { - name: "UpgradeableComponent", - path: "openzeppelin_upgrades::UpgradeableComponent", - storage: "upgradeable", - event: "UpgradeableEvent", - has_initializer: false, - has_immutable_config: false, - internal_impls: vec!["InternalImpl"], - }), - "Nonces" => Ok(ComponentInfo { - name: "NoncesComponent", - path: "openzeppelin_utils::nonces::NoncesComponent", - storage: "nonces", - event: "NoncesEvent", - has_initializer: false, - has_immutable_config: false, - internal_impls: vec!["InternalImpl"], - }), - "Multisig" => Ok(ComponentInfo { - name: "MultisigComponent", - path: "openzeppelin_governance::multisig::MultisigComponent", - storage: "multisig", - event: "MultisigEvent", - has_initializer: true, - has_immutable_config: false, - internal_impls: vec!["InternalImpl"], - }), - "TimelockController" => Ok(ComponentInfo { - name: "TimelockControllerComponent", - path: "openzeppelin_governance::timelock::TimelockControllerComponent", - storage: "timelock_controller", - event: "TimelockControllerEvent", - has_initializer: true, - has_immutable_config: false, - internal_impls: vec!["InternalImpl"], - }), - "Votes" => Ok(ComponentInfo { - name: "VotesComponent", - path: "openzeppelin_governance::votes::VotesComponent", - storage: "votes", - event: "VotesEvent", - has_initializer: false, - has_immutable_config: false, - internal_impls: vec!["InternalImpl"], - }), - _ => { - let allowed_components = ALLOWED_COMPONENTS.join(", "); - let error_message = formatdoc! {" - Invalid component: {name} - - Allowed components are: - {allowed_components} - "}; - let error = Diagnostic::error(error_message); - Err(error.into()) - } - } -} - -/// Set of component information to be used for code generation. -struct ComponentsGenerationData<'a>(&'a Vec>); - -impl ComponentsGenerationData<'_> { - fn generate_for_module(self, _db: &dyn SyntaxGroup) -> RewriteNode { - RewriteNode::interpolate_patched( - indoc! {" - - $component_use_clause_entries$ - - $component_macro_entries$ - - $component_internal_impls_entries$ - "}, - &[ - ( - "component_use_clause_entries".to_string(), - self.component_use_clause_entries(), - ), - ( - "component_macro_entries".to_string(), - self.component_macro_entries(), - ), - ( - "component_internal_impls_entries".to_string(), - self.component_internal_impls_entries(), - ), - ] - .into(), - ) - } - - fn generate_for_storage_struct(self, _db: &dyn SyntaxGroup) -> RewriteNode { - let mut entries = vec![]; - for component in self.0.iter() { - entries.push(format!("{}#[{}]", tabs(2), SUBSTORAGE_ATTRIBUTE)); - entries.push(format!( - "{}pub {}: {}::Storage,", - tabs(2), - component.storage, - component.name - )); - } - RewriteNode::Text(entries.join("\n") + "\n") - } - - fn generate_for_event_enum(self, _db: &dyn SyntaxGroup) -> RewriteNode { - let mut entries = vec![]; - for component in self.0.iter() { - entries.push(format!("{}#[{}]", tabs(2), FLAT_ATTRIBUTE)); - entries.push(format!( - "{}{}: {}::Event,", - tabs(2), - component.event, - component.name - )); - } - RewriteNode::Text(entries.join("\n") + "\n") - } - - fn generate_event_enum(self, _db: &dyn SyntaxGroup) -> RewriteNode { - let mut entries = vec![]; - - entries.push(format!("\n{}#[event]", tabs(1))); - entries.push(format!("{}#[derive(Drop, starknet::Event)]", tabs(1))); - entries.push(format!("{}enum {} {{", tabs(1), EVENT_ENUM_NAME)); - for component in self.0.iter() { - entries.push(format!("{}#[{}]", tabs(2), FLAT_ATTRIBUTE)); - entries.push(format!( - "{}{}: {}::Event,", - tabs(2), - component.event, - component.name - )); - } - entries.push(format!("{}}}", tabs(1))); - RewriteNode::Text(entries.join("\n")) - } - - fn component_use_clause_entries(&self) -> RewriteNode { - let mut entries = vec![]; - for component in self.0.iter() { - entries.push(format!("{}use {};", tabs(1), component.path)); - } - RewriteNode::Text(entries.join("\n")) - } - - fn component_macro_entries(&self) -> RewriteNode { - let mut entries = vec![]; - for component in self.0.iter() { - entries.push(format!( - "{}component!(path: {}, storage: {}, event: {});", - tabs(1), - component.name, - component.storage, - component.event - )); - } - RewriteNode::Text(entries.join("\n")) - } - - fn component_internal_impls_entries(&self) -> RewriteNode { - let mut entries = vec![]; - for component in self.0.iter() { - for implementation in component.internal_impls.iter() { - entries.push(format!( - "{}impl {}{} = {}::{};", - tabs(1), - component.short_name(), - implementation, - component.name, - implementation - )); - } - } - RewriteNode::Text(entries.join("\n")) - } -} - -#[cfg(test)] -mod tests { - use super::parse_args; - - #[test] - fn test_parse_args() { - let attribute = "(ERC20, Ownable)"; - let result = parse_args(attribute); - assert_eq!(result, vec!["ERC20", "Ownable"]); - - let attribute = "ERC20"; - let result = parse_args(attribute); - assert_eq!(result, vec!["ERC20"]); - - let attribute = "(Ownable, ERC20, Other, Another)"; - let result = parse_args(attribute); - assert_eq!(result, vec!["Ownable", "ERC20", "Other", "Another"]); - } -} From 0640f63ec86baa2d531d6878bada0d60ddba70eb Mon Sep 17 00:00:00 2001 From: Eric Nordelo Date: Mon, 28 Jul 2025 12:45:02 +0200 Subject: [PATCH 15/29] feat: format files --- Scarb.toml | 8 +++--- .../governance/src/governor/governor.cairo | 7 ++--- .../governance/src/tests/test_multisig.cairo | 27 +++++++------------ packages/utils/src/tests/test_math.cairo | 12 +++------ packages/utils/src/tests/test_snip12.cairo | 5 +--- sncast_scripts/Scarb.lock | 10 +++---- sncast_scripts/src/declare_presets.cairo | 8 ++---- 7 files changed, 27 insertions(+), 50 deletions(-) diff --git a/Scarb.toml b/Scarb.toml index 572a83f9c..27f10e056 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -26,8 +26,8 @@ edition.workspace = true [workspace.package] version = "3.0.0-alpha.0" edition = "2024_07" -cairo-version = "2.11.4" -scarb-version = "2.11.4" +cairo-version = "2.12.0-rc.2" +scarb-version = "2.12.0-rc.2" authors = ["OpenZeppelin Community "] description = "OpenZeppelin Contracts written in Cairo for Starknet, a decentralized ZK Rollup" documentation = "https://docs.openzeppelin.com/contracts-cairo" @@ -42,8 +42,8 @@ keywords = [ ] [workspace.dependencies] -assert_macros = "2.11.4" -starknet = "2.11.4" +assert_macros = "2.12.0-rc.2" +starknet = "2.12.0-rc.2" snforge_std = "0.46.0" [dependencies] diff --git a/packages/governance/src/governor/governor.cairo b/packages/governance/src/governor/governor.cairo index 63dc5b87b..3757e3b75 100644 --- a/packages/governance/src/governor/governor.cairo +++ b/packages/governance/src/governor/governor.cairo @@ -965,11 +965,8 @@ pub mod GovernorComponent { description_hash: felt252, ) { let valid_states = array![ - ProposalState::Pending, - ProposalState::Active, - ProposalState::Defeated, - ProposalState::Succeeded, - ProposalState::Queued, + ProposalState::Pending, ProposalState::Active, ProposalState::Defeated, + ProposalState::Succeeded, ProposalState::Queued, ]; self.validate_state(proposal_id, valid_states.span()); diff --git a/packages/governance/src/tests/test_multisig.cairo b/packages/governance/src/tests/test_multisig.cairo index c32ff4b29..03f674ddb 100644 --- a/packages/governance/src/tests/test_multisig.cairo +++ b/packages/governance/src/tests/test_multisig.cairo @@ -146,8 +146,7 @@ fn test_submit_tx_batch() { let contract_address = test_address(); let calls = array![ - build_call(MockCall::AddNumber(42)), - build_call(MockCall::AddNumber(18)), + build_call(MockCall::AddNumber(42)), build_call(MockCall::AddNumber(18)), build_call(MockCall::AddNumber(40)), ] .span(); @@ -173,8 +172,7 @@ fn test_submit_tx_batch_with_salt() { let contract_address = test_address(); let calls = array![ - build_call(MockCall::AddNumber(42)), - build_call(MockCall::AddNumber(18)), + build_call(MockCall::AddNumber(42)), build_call(MockCall::AddNumber(18)), build_call(MockCall::AddNumber(40)), ] .span(); @@ -201,8 +199,7 @@ fn test_submit_same_tx_batch_different_salt() { let contract_address = test_address(); let calls = array![ - build_call(MockCall::AddNumber(42)), - build_call(MockCall::AddNumber(18)), + build_call(MockCall::AddNumber(42)), build_call(MockCall::AddNumber(18)), build_call(MockCall::AddNumber(40)), ] .span(); @@ -246,8 +243,7 @@ fn test_cannot_submit_tx_batch_unauthorized() { let mut state = setup_component(quorum, signers); let calls = array![ - build_call(MockCall::AddNumber(42)), - build_call(MockCall::AddNumber(18)), + build_call(MockCall::AddNumber(42)), build_call(MockCall::AddNumber(18)), build_call(MockCall::AddNumber(40)), ] .span(); @@ -276,8 +272,7 @@ fn test_cannot_submit_tx_batch_twice() { let mut state = setup_component(quorum, signers); let calls = array![ - build_call(MockCall::AddNumber(42)), - build_call(MockCall::AddNumber(18)), + build_call(MockCall::AddNumber(42)), build_call(MockCall::AddNumber(18)), build_call(MockCall::AddNumber(40)), ] .span(); @@ -375,8 +370,7 @@ fn test_confirm_tx_batch() { let contract_address = test_address(); let calls = array![ - build_call(MockCall::AddNumber(42)), - build_call(MockCall::AddNumber(18)), + build_call(MockCall::AddNumber(42)), build_call(MockCall::AddNumber(18)), build_call(MockCall::AddNumber(40)), ] .span(); @@ -636,8 +630,7 @@ fn test_execute_tx_batch() { let mut spy = spy_events(); let mock = deploy_mock(); let calls = array![ - build_call(MockCall::AddNumber(42)), - build_call(MockCall::AddNumber(18)), + build_call(MockCall::AddNumber(42)), build_call(MockCall::AddNumber(18)), build_call(MockCall::AddNumber(40)), ] .span(); @@ -713,8 +706,7 @@ fn test_cannot_execute_batch_unauthorized() { let mut state = setup_component(quorum, signers); let contract_address = test_address(); let calls = array![ - build_call(MockCall::AddNumber(42)), - build_call(MockCall::AddNumber(18)), + build_call(MockCall::AddNumber(42)), build_call(MockCall::AddNumber(18)), build_call(MockCall::AddNumber(40)), ] .span(); @@ -856,8 +848,7 @@ fn test_tx_batch_hash_depends_on_salt() { let (quorum, signers) = DEFAULT_DATA(); let mut state = setup_component(quorum, signers); let calls = array![ - build_call(MockCall::AddNumber(42)), - build_call(MockCall::AddNumber(18)), + build_call(MockCall::AddNumber(42)), build_call(MockCall::AddNumber(18)), build_call(MockCall::AddNumber(40)), ] .span(); diff --git a/packages/utils/src/tests/test_math.cairo b/packages/utils/src/tests/test_math.cairo index bd1045a25..c81d98bc4 100644 --- a/packages/utils/src/tests/test_math.cairo +++ b/packages/utils/src/tests/test_math.cairo @@ -136,11 +136,9 @@ fn test_mul_div_round_down_large_values() { let u256_max: u256 = Bounded::MAX; let args_list = array![ // (x, y, denominator, expected result) - (42, u256_max - 1, u256_max, 41), - (17, u256_max, u256_max, 17), + (42, u256_max - 1, u256_max, 41), (17, u256_max, u256_max, 17), (u256_max - 1, u256_max - 1, u256_max, u256_max - 2), - (u256_max, u256_max - 1, u256_max, u256_max - 1), - (u256_max, u256_max, u256_max, u256_max), + (u256_max, u256_max - 1, u256_max, u256_max - 1), (u256_max, u256_max, u256_max, u256_max), ] .span(); @@ -173,11 +171,9 @@ fn test_mul_div_round_up_large_values() { let u256_max: u256 = Bounded::MAX; let args_list = array![ // (x, y, denominator, expected result) - (42, u256_max - 1, u256_max, 42), - (17, u256_max, u256_max, 17), + (42, u256_max - 1, u256_max, 42), (17, u256_max, u256_max, 17), (u256_max - 1, u256_max - 1, u256_max, u256_max - 1), - (u256_max, u256_max - 1, u256_max, u256_max - 1), - (u256_max, u256_max, u256_max, u256_max), + (u256_max, u256_max - 1, u256_max, u256_max - 1), (u256_max, u256_max, u256_max, u256_max), ] .span(); diff --git a/packages/utils/src/tests/test_snip12.cairo b/packages/utils/src/tests/test_snip12.cairo index e6f987471..c7143f273 100644 --- a/packages/utils/src/tests/test_snip12.cairo +++ b/packages/utils/src/tests/test_snip12.cairo @@ -60,10 +60,7 @@ fn test_StructHashStarknetDomainImpl() { let expected = poseidon_hash_span( array![ - STARKNET_DOMAIN_TYPE_HASH, - domain.name, - domain.version, - domain.chain_id, + STARKNET_DOMAIN_TYPE_HASH, domain.name, domain.version, domain.chain_id, domain.revision, ] .span(), diff --git a/sncast_scripts/Scarb.lock b/sncast_scripts/Scarb.lock index 700574248..949ae3316 100644 --- a/sncast_scripts/Scarb.lock +++ b/sncast_scripts/Scarb.lock @@ -43,7 +43,7 @@ dependencies = [ [[package]] name = "openzeppelin_testing" -version = "4.2.0" +version = "4.3.0" dependencies = [ "snforge_std", ] @@ -83,15 +83,15 @@ checksum = "sha256:cfd7c73a6f9984880249babfa8664b69c5f7209c737b1081156a284061ccd [[package]] name = "snforge_scarb_plugin" -version = "0.44.0" +version = "0.46.0" source = "registry+https://scarbs.xyz/" -checksum = "sha256:ec8c7637b33392a53153c1e5b87a4617ddcb1981951b233ea043cad5136697e2" +checksum = "sha256:6ffa10fe0ff525678138afd584fc2012e7b248f9c8e7b44aeae033cef3ee7826" [[package]] name = "snforge_std" -version = "0.44.0" +version = "0.46.0" source = "registry+https://scarbs.xyz/" -checksum = "sha256:d4affedfb90715b1ac417b915c0a63377ae6dd69432040e5d933130d65114702" +checksum = "sha256:a4d4b4d3e8506a3907d1eabacb058c390aa13a70132f475cba5e3dcd7a60d0bb" dependencies = [ "snforge_scarb_plugin", ] diff --git a/sncast_scripts/src/declare_presets.cairo b/sncast_scripts/src/declare_presets.cairo index 6650c96e1..d2b897e56 100644 --- a/sncast_scripts/src/declare_presets.cairo +++ b/sncast_scripts/src/declare_presets.cairo @@ -5,12 +5,8 @@ const MAX_FEE: felt252 = 99_999_999_999_999_999; fn main() { let contracts = array![ - "AccountUpgradeable", - "ERC20Upgradeable", - "ERC721Upgradeable", - "ERC1155Upgradeable", - "EthAccountUpgradeable", - "VestingWallet", + "AccountUpgradeable", "ERC20Upgradeable", "ERC721Upgradeable", "ERC1155Upgradeable", + "EthAccountUpgradeable", "VestingWallet", ]; let mut consumed_latest_nonce = false; From 651bc90278008ec854021f3f9881d1270594a481 Mon Sep 17 00:00:00 2001 From: Eric Nordelo Date: Mon, 28 Jul 2025 13:04:35 +0200 Subject: [PATCH 16/29] feat: test keys in access --- .../access/src/tests/test_accesscontrol.cairo | 70 ++++++++++++++----- ...st_accesscontrol_default_admin_rules.cairo | 11 ++- .../src/tests/test_ownable_twostep.cairo | 12 ++-- .../governance/src/governor/governor.cairo | 7 +- .../governance/src/tests/test_multisig.cairo | 27 +++---- packages/test_common/src/ownable.cairo | 11 ++- packages/utils/src/tests/test_math.cairo | 12 ++-- packages/utils/src/tests/test_snip12.cairo | 5 +- sncast_scripts/Scarb.lock | 10 +-- sncast_scripts/src/declare_presets.cairo | 8 +-- 10 files changed, 95 insertions(+), 78 deletions(-) diff --git a/packages/access/src/tests/test_accesscontrol.cairo b/packages/access/src/tests/test_accesscontrol.cairo index 8397c9b58..5986c74a2 100644 --- a/packages/access/src/tests/test_accesscontrol.cairo +++ b/packages/access/src/tests/test_accesscontrol.cairo @@ -4,11 +4,12 @@ use openzeppelin_testing::constants::{ ADMIN, AUTHORIZED, OTHER, OTHER_ADMIN, OTHER_ROLE, ROLE, TIMESTAMP, ZERO, }; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; -use snforge_std::{start_cheat_block_timestamp_global, start_cheat_caller_address, test_address}; -use starknet::ContractAddress; -use crate::accesscontrol::AccessControlComponent::{ - InternalImpl, RoleAdminChanged, RoleGranted, RoleGrantedWithDelay, RoleRevoked, +use openzeppelin_utils::serde::SerializedAppend; +use snforge_std::{ + Event, start_cheat_block_timestamp_global, start_cheat_caller_address, test_address, }; +use starknet::ContractAddress; +use crate::accesscontrol::AccessControlComponent::InternalImpl; use crate::accesscontrol::interface::{ IACCESSCONTROL_ID, IAccessControl, IAccessControlCamel, IAccessControlWithDelay, RoleStatus, }; @@ -700,9 +701,15 @@ pub impl AccessControlSpyHelpersImpl of AccessControlSpyHelpers { account: ContractAddress, sender: ContractAddress, ) { - let expected = AccessControlComponent::Event::RoleRevoked( - RoleRevoked { role, account, sender }, - ); + let mut keys = array![]; + keys.append_serde(selector!("RoleRevoked")); + + let mut data = array![]; + data.append_serde(role); + data.append_serde(account); + data.append_serde(sender); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } @@ -713,9 +720,15 @@ pub impl AccessControlSpyHelpersImpl of AccessControlSpyHelpers { account: ContractAddress, sender: ContractAddress, ) { - let expected = AccessControlComponent::Event::RoleRevoked( - RoleRevoked { role, account, sender }, - ); + let mut keys = array![]; + keys.append_serde(selector!("RoleRevoked")); + + let mut data = array![]; + data.append_serde(role); + data.append_serde(account); + data.append_serde(sender); + + let expected = Event { keys, data }; self.assert_only_event(contract, expected); } @@ -726,9 +739,15 @@ pub impl AccessControlSpyHelpersImpl of AccessControlSpyHelpers { account: ContractAddress, sender: ContractAddress, ) { - let expected = AccessControlComponent::Event::RoleGranted( - RoleGranted { role, account, sender }, - ); + let mut keys = array![]; + keys.append_serde(selector!("RoleGranted")); + + let mut data = array![]; + data.append_serde(role); + data.append_serde(account); + data.append_serde(sender); + + let expected = Event { keys, data }; self.assert_only_event(contract, expected); } @@ -740,9 +759,16 @@ pub impl AccessControlSpyHelpersImpl of AccessControlSpyHelpers { sender: ContractAddress, delay: u64, ) { - let expected = AccessControlComponent::Event::RoleGrantedWithDelay( - RoleGrantedWithDelay { role, account, sender, delay }, - ); + let mut keys = array![]; + keys.append_serde(selector!("RoleGrantedWithDelay")); + + let mut data = array![]; + data.append_serde(role); + data.append_serde(account); + data.append_serde(sender); + data.append_serde(delay); + + let expected = Event { keys, data }; self.assert_only_event(contract, expected); } @@ -753,9 +779,15 @@ pub impl AccessControlSpyHelpersImpl of AccessControlSpyHelpers { previous_admin_role: felt252, new_admin_role: felt252, ) { - let expected = AccessControlComponent::Event::RoleAdminChanged( - RoleAdminChanged { role, previous_admin_role, new_admin_role }, - ); + let mut keys = array![]; + keys.append_serde(selector!("RoleAdminChanged")); + + let mut data = array![]; + data.append_serde(role); + data.append_serde(previous_admin_role); + data.append_serde(new_admin_role); + + let expected = Event { keys, data }; self.assert_only_event(from_address, expected); } } diff --git a/packages/access/src/tests/test_accesscontrol_default_admin_rules.cairo b/packages/access/src/tests/test_accesscontrol_default_admin_rules.cairo index 98c34eb76..2a41c9334 100644 --- a/packages/access/src/tests/test_accesscontrol_default_admin_rules.cairo +++ b/packages/access/src/tests/test_accesscontrol_default_admin_rules.cairo @@ -5,12 +5,12 @@ use openzeppelin_testing::constants::{ ADMIN, AUTHORIZED, OTHER, OTHER_ADMIN, OTHER_ROLE, ROLE, TIMESTAMP, ZERO, }; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; -use snforge_std::{Event, start_cheat_block_timestamp_global, start_cheat_caller_address, test_address}; -use starknet::ContractAddress; -use crate::accesscontrol::extensions::AccessControlDefaultAdminRulesComponent::{ - DefaultAdminDelayChangeCanceled, DefaultAdminDelayChangeScheduled, DefaultAdminTransferCanceled, - DefaultAdminTransferScheduled, InternalTrait, +use openzeppelin_utils::serde::SerializedAppend; +use snforge_std::{ + Event, start_cheat_block_timestamp_global, start_cheat_caller_address, test_address, }; +use starknet::ContractAddress; +use crate::accesscontrol::extensions::AccessControlDefaultAdminRulesComponent::InternalTrait; use crate::accesscontrol::extensions::interface::{ IACCESSCONTROL_DEFAULT_ADMIN_RULES_ID, IAccessControlDefaultAdminRules, }; @@ -21,7 +21,6 @@ use crate::accesscontrol::interface::{ IACCESSCONTROL_ID, IAccessControl, IAccessControlCamel, IAccessControlWithDelay, RoleStatus, }; use crate::tests::test_accesscontrol::AccessControlSpyHelpers; -use openzeppelin_utils::serde::SerializedAppend; // // Setup diff --git a/packages/access/src/tests/test_ownable_twostep.cairo b/packages/access/src/tests/test_ownable_twostep.cairo index 0fc408d0f..bbbc76c4b 100644 --- a/packages/access/src/tests/test_ownable_twostep.cairo +++ b/packages/access/src/tests/test_ownable_twostep.cairo @@ -3,7 +3,8 @@ use openzeppelin_test_common::mocks::access::DualCaseTwoStepOwnableMock; use openzeppelin_test_common::ownable::OwnableSpyHelpers; use openzeppelin_testing::constants::{NEW_OWNER, OTHER, OWNER, ZERO}; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; -use snforge_std::{start_cheat_caller_address, test_address}; +use openzeppelin_utils::serde::SerializedAppend; +use snforge_std::{Event, start_cheat_caller_address, test_address}; use starknet::ContractAddress; use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; use crate::ownable::OwnableComponent; @@ -291,9 +292,12 @@ impl TwoStepSpyHelpersImpl of TwoStepSpyHelpers { previous_owner: ContractAddress, new_owner: ContractAddress, ) { - let expected = OwnableComponent::Event::OwnershipTransferStarted( - OwnershipTransferStarted { previous_owner, new_owner }, - ); + let mut keys = array![]; + keys.append_serde(selector!("OwnershipTransferStarted")); + keys.append_serde(previous_owner); + keys.append_serde(new_owner); + + let expected = Event { keys, data: array![] }; self.assert_emitted_single(from_address, expected); } } diff --git a/packages/governance/src/governor/governor.cairo b/packages/governance/src/governor/governor.cairo index 17ed38239..1899ef4aa 100644 --- a/packages/governance/src/governor/governor.cairo +++ b/packages/governance/src/governor/governor.cairo @@ -965,11 +965,8 @@ pub mod GovernorComponent { description_hash: felt252, ) { let valid_states = array![ - ProposalState::Pending, - ProposalState::Active, - ProposalState::Defeated, - ProposalState::Succeeded, - ProposalState::Queued, + ProposalState::Pending, ProposalState::Active, ProposalState::Defeated, + ProposalState::Succeeded, ProposalState::Queued, ]; self.validate_state(proposal_id, valid_states.span()); diff --git a/packages/governance/src/tests/test_multisig.cairo b/packages/governance/src/tests/test_multisig.cairo index ef9c701c8..9eed7ea09 100644 --- a/packages/governance/src/tests/test_multisig.cairo +++ b/packages/governance/src/tests/test_multisig.cairo @@ -146,8 +146,7 @@ fn test_submit_tx_batch() { let contract_address = test_address(); let calls = array![ - build_call(MockCall::AddNumber(42)), - build_call(MockCall::AddNumber(18)), + build_call(MockCall::AddNumber(42)), build_call(MockCall::AddNumber(18)), build_call(MockCall::AddNumber(40)), ] .span(); @@ -173,8 +172,7 @@ fn test_submit_tx_batch_with_salt() { let contract_address = test_address(); let calls = array![ - build_call(MockCall::AddNumber(42)), - build_call(MockCall::AddNumber(18)), + build_call(MockCall::AddNumber(42)), build_call(MockCall::AddNumber(18)), build_call(MockCall::AddNumber(40)), ] .span(); @@ -201,8 +199,7 @@ fn test_submit_same_tx_batch_different_salt() { let contract_address = test_address(); let calls = array![ - build_call(MockCall::AddNumber(42)), - build_call(MockCall::AddNumber(18)), + build_call(MockCall::AddNumber(42)), build_call(MockCall::AddNumber(18)), build_call(MockCall::AddNumber(40)), ] .span(); @@ -246,8 +243,7 @@ fn test_cannot_submit_tx_batch_unauthorized() { let mut state = setup_component(quorum, signers); let calls = array![ - build_call(MockCall::AddNumber(42)), - build_call(MockCall::AddNumber(18)), + build_call(MockCall::AddNumber(42)), build_call(MockCall::AddNumber(18)), build_call(MockCall::AddNumber(40)), ] .span(); @@ -276,8 +272,7 @@ fn test_cannot_submit_tx_batch_twice() { let mut state = setup_component(quorum, signers); let calls = array![ - build_call(MockCall::AddNumber(42)), - build_call(MockCall::AddNumber(18)), + build_call(MockCall::AddNumber(42)), build_call(MockCall::AddNumber(18)), build_call(MockCall::AddNumber(40)), ] .span(); @@ -375,8 +370,7 @@ fn test_confirm_tx_batch() { let contract_address = test_address(); let calls = array![ - build_call(MockCall::AddNumber(42)), - build_call(MockCall::AddNumber(18)), + build_call(MockCall::AddNumber(42)), build_call(MockCall::AddNumber(18)), build_call(MockCall::AddNumber(40)), ] .span(); @@ -636,8 +630,7 @@ fn test_execute_tx_batch() { let mut spy = spy_events(); let mock = deploy_mock(); let calls = array![ - build_call(MockCall::AddNumber(42)), - build_call(MockCall::AddNumber(18)), + build_call(MockCall::AddNumber(42)), build_call(MockCall::AddNumber(18)), build_call(MockCall::AddNumber(40)), ] .span(); @@ -713,8 +706,7 @@ fn test_cannot_execute_batch_unauthorized() { let mut state = setup_component(quorum, signers); let contract_address = test_address(); let calls = array![ - build_call(MockCall::AddNumber(42)), - build_call(MockCall::AddNumber(18)), + build_call(MockCall::AddNumber(42)), build_call(MockCall::AddNumber(18)), build_call(MockCall::AddNumber(40)), ] .span(); @@ -856,8 +848,7 @@ fn test_tx_batch_hash_depends_on_salt() { let (quorum, signers) = DEFAULT_DATA(); let mut state = setup_component(quorum, signers); let calls = array![ - build_call(MockCall::AddNumber(42)), - build_call(MockCall::AddNumber(18)), + build_call(MockCall::AddNumber(42)), build_call(MockCall::AddNumber(18)), build_call(MockCall::AddNumber(40)), ] .span(); diff --git a/packages/test_common/src/ownable.cairo b/packages/test_common/src/ownable.cairo index d5fe76b84..a3df83856 100644 --- a/packages/test_common/src/ownable.cairo +++ b/packages/test_common/src/ownable.cairo @@ -1,6 +1,8 @@ use openzeppelin_access::ownable::OwnableComponent; use openzeppelin_access::ownable::OwnableComponent::OwnershipTransferred; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy}; +use openzeppelin_utils::serde::SerializedAppend; +use snforge_std::Event; use starknet::ContractAddress; #[generate_trait] @@ -21,9 +23,12 @@ pub impl OwnableSpyHelpersImpl of OwnableSpyHelpers { previous_owner: ContractAddress, new_owner: ContractAddress, ) { - let expected = OwnableComponent::Event::OwnershipTransferred( - OwnershipTransferred { previous_owner, new_owner }, - ); + let mut keys = array![]; + keys.append_serde(selector!("OwnershipTransferred")); + keys.append_serde(previous_owner); + keys.append_serde(new_owner); + + let expected = Event { keys, data: array![] }; self.assert_emitted_single(contract, expected); } } diff --git a/packages/utils/src/tests/test_math.cairo b/packages/utils/src/tests/test_math.cairo index bd1045a25..c81d98bc4 100644 --- a/packages/utils/src/tests/test_math.cairo +++ b/packages/utils/src/tests/test_math.cairo @@ -136,11 +136,9 @@ fn test_mul_div_round_down_large_values() { let u256_max: u256 = Bounded::MAX; let args_list = array![ // (x, y, denominator, expected result) - (42, u256_max - 1, u256_max, 41), - (17, u256_max, u256_max, 17), + (42, u256_max - 1, u256_max, 41), (17, u256_max, u256_max, 17), (u256_max - 1, u256_max - 1, u256_max, u256_max - 2), - (u256_max, u256_max - 1, u256_max, u256_max - 1), - (u256_max, u256_max, u256_max, u256_max), + (u256_max, u256_max - 1, u256_max, u256_max - 1), (u256_max, u256_max, u256_max, u256_max), ] .span(); @@ -173,11 +171,9 @@ fn test_mul_div_round_up_large_values() { let u256_max: u256 = Bounded::MAX; let args_list = array![ // (x, y, denominator, expected result) - (42, u256_max - 1, u256_max, 42), - (17, u256_max, u256_max, 17), + (42, u256_max - 1, u256_max, 42), (17, u256_max, u256_max, 17), (u256_max - 1, u256_max - 1, u256_max, u256_max - 1), - (u256_max, u256_max - 1, u256_max, u256_max - 1), - (u256_max, u256_max, u256_max, u256_max), + (u256_max, u256_max - 1, u256_max, u256_max - 1), (u256_max, u256_max, u256_max, u256_max), ] .span(); diff --git a/packages/utils/src/tests/test_snip12.cairo b/packages/utils/src/tests/test_snip12.cairo index e6f987471..c7143f273 100644 --- a/packages/utils/src/tests/test_snip12.cairo +++ b/packages/utils/src/tests/test_snip12.cairo @@ -60,10 +60,7 @@ fn test_StructHashStarknetDomainImpl() { let expected = poseidon_hash_span( array![ - STARKNET_DOMAIN_TYPE_HASH, - domain.name, - domain.version, - domain.chain_id, + STARKNET_DOMAIN_TYPE_HASH, domain.name, domain.version, domain.chain_id, domain.revision, ] .span(), diff --git a/sncast_scripts/Scarb.lock b/sncast_scripts/Scarb.lock index b2c564e72..3c066a293 100644 --- a/sncast_scripts/Scarb.lock +++ b/sncast_scripts/Scarb.lock @@ -43,7 +43,7 @@ dependencies = [ [[package]] name = "openzeppelin_testing" -version = "4.2.0" +version = "4.3.0" dependencies = [ "snforge_std", ] @@ -83,15 +83,15 @@ checksum = "sha256:cfd7c73a6f9984880249babfa8664b69c5f7209c737b1081156a284061ccd [[package]] name = "snforge_scarb_plugin" -version = "0.44.0" +version = "0.46.0" source = "registry+https://scarbs.xyz/" -checksum = "sha256:ec8c7637b33392a53153c1e5b87a4617ddcb1981951b233ea043cad5136697e2" +checksum = "sha256:6ffa10fe0ff525678138afd584fc2012e7b248f9c8e7b44aeae033cef3ee7826" [[package]] name = "snforge_std" -version = "0.44.0" +version = "0.46.0" source = "registry+https://scarbs.xyz/" -checksum = "sha256:d4affedfb90715b1ac417b915c0a63377ae6dd69432040e5d933130d65114702" +checksum = "sha256:a4d4b4d3e8506a3907d1eabacb058c390aa13a70132f475cba5e3dcd7a60d0bb" dependencies = [ "snforge_scarb_plugin", ] diff --git a/sncast_scripts/src/declare_presets.cairo b/sncast_scripts/src/declare_presets.cairo index 6650c96e1..d2b897e56 100644 --- a/sncast_scripts/src/declare_presets.cairo +++ b/sncast_scripts/src/declare_presets.cairo @@ -5,12 +5,8 @@ const MAX_FEE: felt252 = 99_999_999_999_999_999; fn main() { let contracts = array![ - "AccountUpgradeable", - "ERC20Upgradeable", - "ERC721Upgradeable", - "ERC1155Upgradeable", - "EthAccountUpgradeable", - "VestingWallet", + "AccountUpgradeable", "ERC20Upgradeable", "ERC721Upgradeable", "ERC1155Upgradeable", + "EthAccountUpgradeable", "VestingWallet", ]; let mut consumed_latest_nonce = false; From ded320293341acb1002cc18159c73c142d6c92f0 Mon Sep 17 00:00:00 2001 From: Eric Nordelo Date: Mon, 28 Jul 2025 13:27:55 +0200 Subject: [PATCH 17/29] feat: add key tests for governance --- .../src/governor/proposal_core.cairo | 1 - .../block_number/test_governor_settings.cairo | 40 ++++++--- .../test_governor_votes_quorum_fraction.cairo | 18 ++-- .../src/tests/governor/common.cairo | 87 ++++++++++++------- .../timestamp/test_governor_settings.cairo | 39 ++++++--- .../test_governor_timelock_execution.cairo | 14 +-- .../test_governor_votes_quorum_fraction.cairo | 17 ++-- .../governance/src/tests/test_multisig.cairo | 65 +++++++++++--- .../governance/src/tests/test_timelock.cairo | 59 +++++++++---- .../governance/src/tests/votes/common.cairo | 26 ++++-- packages/test_common/src/account.cairo | 14 ++- packages/test_common/src/eth_account.cairo | 16 +++- packages/test_common/src/vesting.cairo | 11 ++- 13 files changed, 287 insertions(+), 120 deletions(-) diff --git a/packages/governance/src/governor/proposal_core.cairo b/packages/governance/src/governor/proposal_core.cairo index 64f7b1cdf..baa932219 100644 --- a/packages/governance/src/governor/proposal_core.cairo +++ b/packages/governance/src/governor/proposal_core.cairo @@ -84,7 +84,6 @@ mod tests { use core::num::traits::Bounded; use openzeppelin_testing::constants::ALICE; use openzeppelin_testing::{FuzzableBool, FuzzableContractAddress}; - use starknet::ContractAddress; use super::{ProposalCore, ProposalCoreStorePacking as StorePacking}; #[test] diff --git a/packages/governance/src/tests/governor/block_number/test_governor_settings.cairo b/packages/governance/src/tests/governor/block_number/test_governor_settings.cairo index 31da16fb6..dbf18fb6e 100644 --- a/packages/governance/src/tests/governor/block_number/test_governor_settings.cairo +++ b/packages/governance/src/tests/governor/block_number/test_governor_settings.cairo @@ -1,12 +1,12 @@ use openzeppelin_test_common::mocks::governor::GovernorTimelockedMock::SNIP12MetadataImpl; use openzeppelin_testing::constants::OTHER; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; -use snforge_std::{start_cheat_caller_address, test_address}; +use openzeppelin_utils::serde::SerializedAppend; +use snforge_std::{Event, start_cheat_caller_address, test_address}; use starknet::ContractAddress; use starknet::storage::StoragePointerWriteAccess; use crate::governor::DefaultConfig; use crate::governor::GovernorComponent::InternalImpl; -use crate::governor::extensions::GovernorSettingsComponent; use crate::governor::extensions::GovernorSettingsComponent::{ GovernorSettings, GovernorSettingsAdminImpl, InternalImpl as GovernorSettingsInternalImpl, }; @@ -15,6 +15,7 @@ use crate::tests::governor::block_number::common::{ set_executor, }; + // // Extensions // @@ -395,9 +396,14 @@ pub(crate) impl GovernorSettingsSpyHelpersImpl of GovernorSettingsSpyHelpers { fn assert_event_voting_delay_updated( ref self: EventSpy, contract: ContractAddress, old_voting_delay: u64, new_voting_delay: u64, ) { - let expected = GovernorSettingsComponent::Event::VotingDelayUpdated( - GovernorSettingsComponent::VotingDelayUpdated { old_voting_delay, new_voting_delay }, - ); + let mut keys = array![]; + keys.append_serde(selector!("VotingDelayUpdated")); + + let mut data = array![]; + data.append_serde(old_voting_delay); + data.append_serde(new_voting_delay); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } @@ -414,9 +420,14 @@ pub(crate) impl GovernorSettingsSpyHelpersImpl of GovernorSettingsSpyHelpers { old_voting_period: u64, new_voting_period: u64, ) { - let expected = GovernorSettingsComponent::Event::VotingPeriodUpdated( - GovernorSettingsComponent::VotingPeriodUpdated { old_voting_period, new_voting_period }, - ); + let mut keys = array![]; + keys.append_serde(selector!("VotingPeriodUpdated")); + + let mut data = array![]; + data.append_serde(old_voting_period); + data.append_serde(new_voting_period); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } @@ -436,11 +447,14 @@ pub(crate) impl GovernorSettingsSpyHelpersImpl of GovernorSettingsSpyHelpers { old_proposal_threshold: u256, new_proposal_threshold: u256, ) { - let expected = GovernorSettingsComponent::Event::ProposalThresholdUpdated( - GovernorSettingsComponent::ProposalThresholdUpdated { - old_proposal_threshold, new_proposal_threshold, - }, - ); + let mut keys = array![]; + keys.append_serde(selector!("ProposalThresholdUpdated")); + + let mut data = array![]; + data.append_serde(old_proposal_threshold); + data.append_serde(new_proposal_threshold); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } diff --git a/packages/governance/src/tests/governor/block_number/test_governor_votes_quorum_fraction.cairo b/packages/governance/src/tests/governor/block_number/test_governor_votes_quorum_fraction.cairo index 23c4f5a37..86438fb21 100644 --- a/packages/governance/src/tests/governor/block_number/test_governor_votes_quorum_fraction.cairo +++ b/packages/governance/src/tests/governor/block_number/test_governor_votes_quorum_fraction.cairo @@ -2,16 +2,17 @@ use openzeppelin_test_common::mocks::governor::GovernorQuorumFractionMock; use openzeppelin_test_common::mocks::governor::GovernorQuorumFractionMock::SNIP12MetadataImpl; use openzeppelin_testing::constants::{OTHER, VOTES_TOKEN, ZERO}; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; -use snforge_std::{start_cheat_block_number_global, start_mock_call, test_address}; +use openzeppelin_utils::serde::SerializedAppend; +use snforge_std::{Event, start_cheat_block_number_global, start_mock_call, test_address}; use starknet::ContractAddress; use crate::governor::GovernorComponent::InternalImpl; -use crate::governor::extensions::GovernorVotesQuorumFractionComponent; use crate::governor::extensions::GovernorVotesQuorumFractionComponent::{ GovernorQuorum, GovernorVotes, InternalTrait, QuorumFractionImpl, }; use crate::governor::{DefaultConfig, GovernorComponent}; use crate::tests::governor::block_number::common::deploy_votes_token; + pub type ComponentState = GovernorComponent::ComponentState; @@ -240,11 +241,14 @@ pub(crate) impl GovernorSettingsSpyHelpersImpl of GovernorSettingsSpyHelpers { old_quorum_numerator: u256, new_quorum_numerator: u256, ) { - let expected = GovernorVotesQuorumFractionComponent::Event::QuorumNumeratorUpdated( - GovernorVotesQuorumFractionComponent::QuorumNumeratorUpdated { - old_quorum_numerator, new_quorum_numerator, - }, - ); + let mut keys = array![]; + keys.append_serde(selector!("QuorumNumeratorUpdated")); + + let mut data = array![]; + data.append_serde(old_quorum_numerator); + data.append_serde(new_quorum_numerator); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } diff --git a/packages/governance/src/tests/governor/common.cairo b/packages/governance/src/tests/governor/common.cairo index 8c3539c03..e79b03375 100644 --- a/packages/governance/src/tests/governor/common.cairo +++ b/packages/governance/src/tests/governor/common.cairo @@ -1,7 +1,8 @@ use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy}; +use openzeppelin_utils::serde::SerializedAppend; +use snforge_std::Event; use starknet::ContractAddress; use starknet::account::Call; -use crate::governor::GovernorComponent; // // Event helpers @@ -20,17 +21,19 @@ pub(crate) impl GovernorSpyHelpersImpl of GovernorSpyHelpers { vote_end: u64, description: @ByteArray, ) { - let expected = GovernorComponent::Event::ProposalCreated( - GovernorComponent::ProposalCreated { - proposal_id, - proposer, - calls, - signatures, - vote_start, - vote_end, - description: description.clone(), - }, - ); + let mut keys = array![]; + keys.append_serde(selector!("ProposalCreated")); + keys.append_serde(proposal_id); + keys.append_serde(proposer); + + let mut data = array![]; + data.append_serde(calls); + data.append_serde(signatures); + data.append_serde(vote_start); + data.append_serde(vote_end); + data.append_serde(description.clone()); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } @@ -68,11 +71,17 @@ pub(crate) impl GovernorSpyHelpersImpl of GovernorSpyHelpers { weight: u256, reason: @ByteArray, ) { - let expected = GovernorComponent::Event::VoteCast( - GovernorComponent::VoteCast { - voter, proposal_id, support, weight, reason: reason.clone(), - }, - ); + let mut keys = array![]; + keys.append_serde(selector!("VoteCast")); + keys.append_serde(voter); + + let mut data = array![]; + data.append_serde(proposal_id); + data.append_serde(support); + data.append_serde(weight); + data.append_serde(reason.clone()); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } @@ -99,11 +108,18 @@ pub(crate) impl GovernorSpyHelpersImpl of GovernorSpyHelpers { reason: @ByteArray, params: Span, ) { - let expected = GovernorComponent::Event::VoteCastWithParams( - GovernorComponent::VoteCastWithParams { - voter, proposal_id, support, weight, reason: reason.clone(), params, - }, - ); + let mut keys = array![]; + keys.append_serde(selector!("VoteCastWithParams")); + keys.append_serde(voter); + + let mut data = array![]; + data.append_serde(proposal_id); + data.append_serde(support); + data.append_serde(weight); + data.append_serde(reason.clone()); + data.append_serde(params); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } @@ -127,9 +143,14 @@ pub(crate) impl GovernorSpyHelpersImpl of GovernorSpyHelpers { fn assert_event_proposal_queued( ref self: EventSpy, contract: ContractAddress, proposal_id: felt252, eta_seconds: u64, ) { - let expected = GovernorComponent::Event::ProposalQueued( - GovernorComponent::ProposalQueued { proposal_id, eta_seconds }, - ); + let mut keys = array![]; + keys.append_serde(selector!("ProposalQueued")); + keys.append_serde(proposal_id); + + let mut data = array![]; + data.append_serde(eta_seconds); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } @@ -143,9 +164,11 @@ pub(crate) impl GovernorSpyHelpersImpl of GovernorSpyHelpers { fn assert_event_proposal_executed( ref self: EventSpy, contract: ContractAddress, proposal_id: felt252, ) { - let expected = GovernorComponent::Event::ProposalExecuted( - GovernorComponent::ProposalExecuted { proposal_id }, - ); + let mut keys = array![]; + keys.append_serde(selector!("ProposalExecuted")); + keys.append_serde(proposal_id); + + let expected = Event { keys, data: array![] }; self.assert_emitted_single(contract, expected); } @@ -159,9 +182,11 @@ pub(crate) impl GovernorSpyHelpersImpl of GovernorSpyHelpers { fn assert_event_proposal_canceled( ref self: EventSpy, contract: ContractAddress, proposal_id: felt252, ) { - let expected = GovernorComponent::Event::ProposalCanceled( - GovernorComponent::ProposalCanceled { proposal_id }, - ); + let mut keys = array![]; + keys.append_serde(selector!("ProposalCanceled")); + keys.append_serde(proposal_id); + + let expected = Event { keys, data: array![] }; self.assert_emitted_single(contract, expected); } diff --git a/packages/governance/src/tests/governor/timestamp/test_governor_settings.cairo b/packages/governance/src/tests/governor/timestamp/test_governor_settings.cairo index fcbb3228d..2bc190874 100644 --- a/packages/governance/src/tests/governor/timestamp/test_governor_settings.cairo +++ b/packages/governance/src/tests/governor/timestamp/test_governor_settings.cairo @@ -1,12 +1,12 @@ use openzeppelin_test_common::mocks::governor::GovernorTimelockedMock::SNIP12MetadataImpl; use openzeppelin_testing::constants::OTHER; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; -use snforge_std::{start_cheat_caller_address, test_address}; +use openzeppelin_utils::serde::SerializedAppend; +use snforge_std::{Event, start_cheat_caller_address, test_address}; use starknet::ContractAddress; use starknet::storage::StoragePointerWriteAccess; use crate::governor::DefaultConfig; use crate::governor::GovernorComponent::InternalImpl; -use crate::governor::extensions::GovernorSettingsComponent; use crate::governor::extensions::GovernorSettingsComponent::{ GovernorSettings, GovernorSettingsAdminImpl, InternalImpl as GovernorSettingsInternalImpl, }; @@ -395,9 +395,14 @@ pub(crate) impl GovernorSettingsSpyHelpersImpl of GovernorSettingsSpyHelpers { fn assert_event_voting_delay_updated( ref self: EventSpy, contract: ContractAddress, old_voting_delay: u64, new_voting_delay: u64, ) { - let expected = GovernorSettingsComponent::Event::VotingDelayUpdated( - GovernorSettingsComponent::VotingDelayUpdated { old_voting_delay, new_voting_delay }, - ); + let mut keys = array![]; + keys.append_serde(selector!("VotingDelayUpdated")); + + let mut data = array![]; + data.append_serde(old_voting_delay); + data.append_serde(new_voting_delay); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } @@ -414,9 +419,14 @@ pub(crate) impl GovernorSettingsSpyHelpersImpl of GovernorSettingsSpyHelpers { old_voting_period: u64, new_voting_period: u64, ) { - let expected = GovernorSettingsComponent::Event::VotingPeriodUpdated( - GovernorSettingsComponent::VotingPeriodUpdated { old_voting_period, new_voting_period }, - ); + let mut keys = array![]; + keys.append_serde(selector!("VotingPeriodUpdated")); + + let mut data = array![]; + data.append_serde(old_voting_period); + data.append_serde(new_voting_period); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } @@ -436,11 +446,14 @@ pub(crate) impl GovernorSettingsSpyHelpersImpl of GovernorSettingsSpyHelpers { old_proposal_threshold: u256, new_proposal_threshold: u256, ) { - let expected = GovernorSettingsComponent::Event::ProposalThresholdUpdated( - GovernorSettingsComponent::ProposalThresholdUpdated { - old_proposal_threshold, new_proposal_threshold, - }, - ); + let mut keys = array![]; + keys.append_serde(selector!("ProposalThresholdUpdated")); + + let mut data = array![]; + data.append_serde(old_proposal_threshold); + data.append_serde(new_proposal_threshold); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } diff --git a/packages/governance/src/tests/governor/timestamp/test_governor_timelock_execution.cairo b/packages/governance/src/tests/governor/timestamp/test_governor_timelock_execution.cairo index f5d3a9764..aef47a203 100644 --- a/packages/governance/src/tests/governor/timestamp/test_governor_timelock_execution.cairo +++ b/packages/governance/src/tests/governor/timestamp/test_governor_timelock_execution.cairo @@ -12,14 +12,13 @@ use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; use openzeppelin_utils::bytearray::ByteArrayExtTrait; use openzeppelin_utils::serde::SerializedAppend; use snforge_std::{ - start_cheat_block_timestamp_global, start_cheat_caller_address, start_mock_call, store, + Event, start_cheat_block_timestamp_global, start_cheat_caller_address, start_mock_call, store, }; use starknet::ContractAddress; use starknet::account::Call; use starknet::storage::{StorageMapWriteAccess, StoragePathEntry, StoragePointerWriteAccess}; use crate::governor::DefaultConfig; use crate::governor::GovernorComponent::{InternalExtendedImpl, InternalImpl}; -use crate::governor::extensions::GovernorTimelockExecutionComponent; use crate::governor::extensions::GovernorTimelockExecutionComponent::GovernorExecution; use crate::governor::extensions::GovernorVotesComponent::InternalTrait; use crate::governor::extensions::interface::{ITimelockedDispatcher, ITimelockedDispatcherTrait}; @@ -829,9 +828,14 @@ pub(crate) impl GovernorTimelockExecutionSpyHelpersImpl of GovernorTimelockExecu old_timelock: ContractAddress, new_timelock: ContractAddress, ) { - let expected = GovernorTimelockExecutionComponent::Event::TimelockUpdated( - GovernorTimelockExecutionComponent::TimelockUpdated { old_timelock, new_timelock }, - ); + let mut keys = array![]; + keys.append_serde(selector!("TimelockUpdated")); + + let mut data = array![]; + data.append_serde(old_timelock); + data.append_serde(new_timelock); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } diff --git a/packages/governance/src/tests/governor/timestamp/test_governor_votes_quorum_fraction.cairo b/packages/governance/src/tests/governor/timestamp/test_governor_votes_quorum_fraction.cairo index edac75311..9c9718edf 100644 --- a/packages/governance/src/tests/governor/timestamp/test_governor_votes_quorum_fraction.cairo +++ b/packages/governance/src/tests/governor/timestamp/test_governor_votes_quorum_fraction.cairo @@ -2,10 +2,10 @@ use openzeppelin_test_common::mocks::governor::GovernorQuorumFractionMock; use openzeppelin_test_common::mocks::governor::GovernorQuorumFractionMock::SNIP12MetadataImpl; use openzeppelin_testing::constants::{OTHER, VOTES_TOKEN, ZERO}; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; -use snforge_std::{start_cheat_block_timestamp_global, start_mock_call, test_address}; +use openzeppelin_utils::serde::SerializedAppend; +use snforge_std::{Event, start_cheat_block_timestamp_global, start_mock_call, test_address}; use starknet::ContractAddress; use crate::governor::GovernorComponent::InternalImpl; -use crate::governor::extensions::GovernorVotesQuorumFractionComponent; use crate::governor::extensions::GovernorVotesQuorumFractionComponent::{ GovernorQuorum, GovernorVotes, InternalTrait, QuorumFractionImpl, }; @@ -262,11 +262,14 @@ pub(crate) impl GovernorSettingsSpyHelpersImpl of GovernorSettingsSpyHelpers { old_quorum_numerator: u256, new_quorum_numerator: u256, ) { - let expected = GovernorVotesQuorumFractionComponent::Event::QuorumNumeratorUpdated( - GovernorVotesQuorumFractionComponent::QuorumNumeratorUpdated { - old_quorum_numerator, new_quorum_numerator, - }, - ); + let mut keys = array![]; + keys.append_serde(selector!("QuorumNumeratorUpdated")); + + let mut data = array![]; + data.append_serde(old_quorum_numerator); + data.append_serde(new_quorum_numerator); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } diff --git a/packages/governance/src/tests/test_multisig.cairo b/packages/governance/src/tests/test_multisig.cairo index 03f674ddb..86fbf04ea 100644 --- a/packages/governance/src/tests/test_multisig.cairo +++ b/packages/governance/src/tests/test_multisig.cairo @@ -6,14 +6,12 @@ use openzeppelin_test_common::mocks::multisig::{ use openzeppelin_testing as utils; use openzeppelin_testing::constants::{ALICE, BLOCK_NUMBER, BOB, CHARLIE, OTHER, SALT, ZERO}; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; -use snforge_std::{start_cheat_block_number_global, start_cheat_caller_address, test_address}; +use openzeppelin_utils::serde::SerializedAppend; +use snforge_std::{Event, start_cheat_block_number_global, start_cheat_caller_address, test_address}; use starknet::ContractAddress; use starknet::account::Call; use starknet::storage_access::StorePacking; -use crate::multisig::MultisigComponent::{ - CallSalt, ConfirmationRevoked, Event, InternalImpl, MultisigImpl, QuorumUpdated, SignerAdded, - SignerRemoved, TransactionConfirmed, TransactionExecuted, TransactionSubmitted, -}; +use crate::multisig::MultisigComponent::{InternalImpl, MultisigImpl}; use crate::multisig::storage_utils::{SignersInfo, SignersInfoStorePackingV2}; use crate::multisig::{MultisigComponent, TransactionID, TransactionState}; @@ -1553,7 +1551,11 @@ impl MultisigSpyHelpersImpl of MultisigSpyHelpers { fn assert_event_signer_added( ref self: EventSpy, contract: ContractAddress, signer: ContractAddress, ) { - let expected = Event::SignerAdded(SignerAdded { signer }); + let mut keys = array![]; + keys.append_serde(selector!("SignerAdded")); + keys.append_serde(signer); + + let expected = Event { keys, data: array![] }; self.assert_emitted_single(contract, expected); } @@ -1571,7 +1573,11 @@ impl MultisigSpyHelpersImpl of MultisigSpyHelpers { fn assert_event_signer_removed( ref self: EventSpy, contract: ContractAddress, signer: ContractAddress, ) { - let expected = Event::SignerRemoved(SignerRemoved { signer }); + let mut keys = array![]; + keys.append_serde(selector!("SignerRemoved")); + keys.append_serde(signer); + + let expected = Event { keys, data: array![] }; self.assert_emitted_single(contract, expected); } @@ -1589,7 +1595,14 @@ impl MultisigSpyHelpersImpl of MultisigSpyHelpers { fn assert_event_quorum_updated( ref self: EventSpy, contract: ContractAddress, old_quorum: u32, new_quorum: u32, ) { - let expected = Event::QuorumUpdated(QuorumUpdated { old_quorum, new_quorum }); + let mut keys = array![]; + keys.append_serde(selector!("QuorumUpdated")); + + let mut data = array![]; + data.append_serde(old_quorum); + data.append_serde(new_quorum); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } @@ -1607,7 +1620,12 @@ impl MultisigSpyHelpersImpl of MultisigSpyHelpers { fn assert_event_tx_submitted( ref self: EventSpy, contract: ContractAddress, id: TransactionID, signer: ContractAddress, ) { - let expected = Event::TransactionSubmitted(TransactionSubmitted { id, signer }); + let mut keys = array![]; + keys.append_serde(selector!("TransactionSubmitted")); + keys.append_serde(id); + keys.append_serde(signer); + + let expected = Event { keys, data: array![] }; self.assert_emitted_single(contract, expected); } @@ -1625,7 +1643,12 @@ impl MultisigSpyHelpersImpl of MultisigSpyHelpers { fn assert_event_tx_confirmed( ref self: EventSpy, contract: ContractAddress, id: TransactionID, signer: ContractAddress, ) { - let expected = Event::TransactionConfirmed(TransactionConfirmed { id, signer }); + let mut keys = array![]; + keys.append_serde(selector!("TransactionConfirmed")); + keys.append_serde(id); + keys.append_serde(signer); + + let expected = Event { keys, data: array![] }; self.assert_emitted_single(contract, expected); } @@ -1643,7 +1666,12 @@ impl MultisigSpyHelpersImpl of MultisigSpyHelpers { fn assert_event_confirmation_revoked( ref self: EventSpy, contract: ContractAddress, id: TransactionID, signer: ContractAddress, ) { - let expected = Event::ConfirmationRevoked(ConfirmationRevoked { id, signer }); + let mut keys = array![]; + keys.append_serde(selector!("ConfirmationRevoked")); + keys.append_serde(id); + keys.append_serde(signer); + + let expected = Event { keys, data: array![] }; self.assert_emitted_single(contract, expected); } @@ -1659,7 +1687,11 @@ impl MultisigSpyHelpersImpl of MultisigSpyHelpers { // fn assert_event_tx_executed(ref self: EventSpy, contract: ContractAddress, id: TransactionID) { - let expected = Event::TransactionExecuted(TransactionExecuted { id }); + let mut keys = array![]; + keys.append_serde(selector!("TransactionExecuted")); + keys.append_serde(id); + + let expected = Event { keys, data: array![] }; self.assert_emitted_single(contract, expected); } @@ -1677,7 +1709,14 @@ impl MultisigSpyHelpersImpl of MultisigSpyHelpers { fn assert_event_call_salt( ref self: EventSpy, contract: ContractAddress, id: TransactionID, salt: felt252, ) { - let expected = Event::CallSalt(CallSalt { id, salt }); + let mut keys = array![]; + keys.append_serde(selector!("CallSalt")); + keys.append_serde(id); + + let mut data = array![]; + data.append_serde(salt); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } } diff --git a/packages/governance/src/tests/test_timelock.cairo b/packages/governance/src/tests/test_timelock.cairo index bbdf79dc5..21b4db95d 100644 --- a/packages/governance/src/tests/test_timelock.cairo +++ b/packages/governance/src/tests/test_timelock.cairo @@ -17,15 +17,14 @@ use openzeppelin_testing::{AsAddressTrait, EventSpyExt, EventSpyQueue as EventSp use openzeppelin_utils::contract_clock::ERC6372TimestampClock; use openzeppelin_utils::serde::SerializedAppend; use snforge_std::{ - CheatSpan, cheat_caller_address, start_cheat_block_timestamp_global, start_cheat_caller_address, - test_address, + CheatSpan, Event, cheat_caller_address, start_cheat_block_timestamp_global, + start_cheat_caller_address, test_address, }; use starknet::ContractAddress; use starknet::account::Call; use starknet::storage::{StorageMapReadAccess, StorageMapWriteAccess, StoragePointerWriteAccess}; use crate::timelock::TimelockControllerComponent::{ - CallCancelled, CallExecuted, CallSalt, CallScheduled, InternalImpl as TimelockInternalImpl, - MinDelayChanged, TimelockImpl, + InternalImpl as TimelockInternalImpl, TimelockImpl, }; use crate::timelock::interface::{TimelockABIDispatcher, TimelockABIDispatcherTrait}; use crate::timelock::{ @@ -1654,9 +1653,17 @@ pub(crate) impl TimelockSpyHelpersImpl of TimelockSpyHelpers { predecessor: felt252, delay: u64, ) { - let expected = TimelockControllerComponent::Event::CallScheduled( - CallScheduled { id, index, call, predecessor, delay }, - ); + let mut keys = array![]; + keys.append_serde(selector!("CallScheduled")); + keys.append_serde(id); + keys.append_serde(index); + + let mut data = array![]; + data.append_serde(call); + data.append_serde(predecessor); + data.append_serde(delay); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } @@ -1710,7 +1717,14 @@ pub(crate) impl TimelockSpyHelpersImpl of TimelockSpyHelpers { fn assert_event_call_salt( ref self: EventSpy, contract: ContractAddress, id: felt252, salt: felt252, ) { - let expected = TimelockControllerComponent::Event::CallSalt(CallSalt { id, salt }); + let mut keys = array![]; + keys.append_serde(selector!("CallSalt")); + keys.append_serde(id); + + let mut data = array![]; + data.append_serde(salt); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } @@ -1726,7 +1740,11 @@ pub(crate) impl TimelockSpyHelpersImpl of TimelockSpyHelpers { // fn assert_event_call_cancelled(ref self: EventSpy, contract: ContractAddress, id: felt252) { - let expected = TimelockControllerComponent::Event::CallCancelled(CallCancelled { id }); + let mut keys = array![]; + keys.append_serde(selector!("CallCancelled")); + keys.append_serde(id); + + let expected = Event { keys, data: array![] }; self.assert_emitted_single(contract, expected); } @@ -1744,9 +1762,15 @@ pub(crate) impl TimelockSpyHelpersImpl of TimelockSpyHelpers { fn assert_event_call_executed( ref self: EventSpy, contract: ContractAddress, id: felt252, index: felt252, call: Call, ) { - let expected = TimelockControllerComponent::Event::CallExecuted( - CallExecuted { id, index, call }, - ); + let mut keys = array![]; + keys.append_serde(selector!("CallExecuted")); + keys.append_serde(id); + keys.append_serde(index); + + let mut data = array![]; + data.append_serde(call); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } @@ -1781,9 +1805,14 @@ pub(crate) impl TimelockSpyHelpersImpl of TimelockSpyHelpers { fn assert_event_delay_changed( ref self: EventSpy, contract: ContractAddress, old_duration: u64, new_duration: u64, ) { - let expected = TimelockControllerComponent::Event::MinDelayChanged( - MinDelayChanged { old_duration, new_duration }, - ); + let mut keys = array![]; + keys.append_serde(selector!("MinDelayChanged")); + + let mut data = array![]; + data.append_serde(old_duration); + data.append_serde(new_duration); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } diff --git a/packages/governance/src/tests/votes/common.cairo b/packages/governance/src/tests/votes/common.cairo index b7193ad88..b684c03e0 100644 --- a/packages/governance/src/tests/votes/common.cairo +++ b/packages/governance/src/tests/votes/common.cairo @@ -1,7 +1,7 @@ use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy}; +use openzeppelin_utils::serde::SerializedAppend; +use snforge_std::Event; use starknet::ContractAddress; -use crate::votes::VotesComponent; -use crate::votes::VotesComponent::{DelegateChanged, DelegateVotesChanged}; #[generate_trait] pub(crate) impl VotesSpyHelpersImpl of VotesSpyHelpers { @@ -12,9 +12,13 @@ pub(crate) impl VotesSpyHelpersImpl of VotesSpyHelpers { from_delegate: ContractAddress, to_delegate: ContractAddress, ) { - let expected = VotesComponent::Event::DelegateChanged( - DelegateChanged { delegator, from_delegate, to_delegate }, - ); + let mut keys = array![]; + keys.append_serde(selector!("DelegateChanged")); + keys.append_serde(delegator); + keys.append_serde(from_delegate); + keys.append_serde(to_delegate); + + let expected = Event { keys, data: array![] }; self.assert_emitted_single(contract, expected); } @@ -25,9 +29,15 @@ pub(crate) impl VotesSpyHelpersImpl of VotesSpyHelpers { previous_votes: u256, new_votes: u256, ) { - let expected = VotesComponent::Event::DelegateVotesChanged( - DelegateVotesChanged { delegate, previous_votes, new_votes }, - ); + let mut keys = array![]; + keys.append_serde(selector!("DelegateVotesChanged")); + keys.append_serde(delegate); + + let mut data = array![]; + data.append_serde(previous_votes); + data.append_serde(new_votes); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } diff --git a/packages/test_common/src/account.cairo b/packages/test_common/src/account.cairo index 0a83b0316..12b88a86a 100644 --- a/packages/test_common/src/account.cairo +++ b/packages/test_common/src/account.cairo @@ -5,6 +5,8 @@ use openzeppelin_account::AccountComponent::{OwnerAdded, OwnerRemoved}; use openzeppelin_testing::constants::TRANSACTION_HASH; use openzeppelin_testing::signing::StarkKeyPair; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy}; +use openzeppelin_utils::serde::SerializedAppend; +use snforge_std::Event; use snforge_std::signature::stark_curve::StarkCurveSignerImpl; use starknet::ContractAddress; @@ -39,14 +41,22 @@ pub impl AccountSpyHelpersImpl of AccountSpyHelpers { fn assert_event_owner_removed( ref self: EventSpy, contract: ContractAddress, removed_owner_guid: felt252, ) { - let expected = AccountComponent::Event::OwnerRemoved(OwnerRemoved { removed_owner_guid }); + let mut keys = array![]; + keys.append_serde(selector!("OwnerRemoved")); + keys.append_serde(removed_owner_guid); + + let expected = Event { keys, data: array![] }; self.assert_emitted_single(contract, expected); } fn assert_event_owner_added( ref self: EventSpy, contract: ContractAddress, new_owner_guid: felt252, ) { - let expected = AccountComponent::Event::OwnerAdded(OwnerAdded { new_owner_guid }); + let mut keys = array![]; + keys.append_serde(selector!("OwnerAdded")); + keys.append_serde(new_owner_guid); + + let expected = Event { keys, data: array![] }; self.assert_emitted_single(contract, expected); } diff --git a/packages/test_common/src/eth_account.cairo b/packages/test_common/src/eth_account.cairo index c52820c2a..ecb8ff49b 100644 --- a/packages/test_common/src/eth_account.cairo +++ b/packages/test_common/src/eth_account.cairo @@ -7,6 +7,8 @@ use openzeppelin_account::utils::signature::Secp256Signature; use openzeppelin_testing::constants::TRANSACTION_HASH; use openzeppelin_testing::signing::{Secp256k1KeyPair, Secp256k1SerializedSigning}; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy}; +use openzeppelin_utils::serde::SerializedAppend; +use snforge_std::Event; use snforge_std::signature::secp256k1_curve::Secp256k1CurveSignerImpl; use starknet::secp256_trait::Secp256PointTrait; use starknet::{ContractAddress, SyscallResultTrait}; @@ -50,9 +52,11 @@ pub impl EthAccountSpyHelpersImpl of EthAccountSpyHelpers { ref self: EventSpy, contract: ContractAddress, public_key: EthPublicKey, ) { let removed_owner_guid = get_guid_from_public_key(public_key); - let expected = EthAccountComponent::Event::OwnerRemoved( - OwnerRemoved { removed_owner_guid }, - ); + let mut keys = array![]; + keys.append_serde(selector!("OwnerRemoved")); + keys.append_serde(removed_owner_guid); + + let expected = Event { keys, data: array![] }; self.assert_emitted_single(contract, expected); } @@ -60,7 +64,11 @@ pub impl EthAccountSpyHelpersImpl of EthAccountSpyHelpers { ref self: EventSpy, contract: ContractAddress, public_key: EthPublicKey, ) { let new_owner_guid = get_guid_from_public_key(public_key); - let expected = EthAccountComponent::Event::OwnerAdded(OwnerAdded { new_owner_guid }); + let mut keys = array![]; + keys.append_serde(selector!("OwnerAdded")); + keys.append_serde(new_owner_guid); + + let expected = Event { keys, data: array![] }; self.assert_emitted_single(contract, expected); } diff --git a/packages/test_common/src/vesting.cairo b/packages/test_common/src/vesting.cairo index 44861ae95..355603e5e 100644 --- a/packages/test_common/src/vesting.cairo +++ b/packages/test_common/src/vesting.cairo @@ -1,6 +1,8 @@ use openzeppelin_finance::vesting::VestingComponent; use openzeppelin_finance::vesting::VestingComponent::AmountReleased; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy}; +use openzeppelin_utils::serde::SerializedAppend; +use snforge_std::Event; use starknet::ContractAddress; #[generate_trait] @@ -8,7 +10,14 @@ pub impl VestingSpyHelpersImpl of VestingSpyHelpers { fn assert_only_event_amount_released( ref self: EventSpy, contract: ContractAddress, token: ContractAddress, amount: u256, ) { - let expected = VestingComponent::Event::AmountReleased(AmountReleased { token, amount }); + let mut keys = array![]; + keys.append_serde(selector!("AmountReleased")); + keys.append_serde(token); + + let mut data = array![]; + data.append_serde(amount); + + let expected = Event { keys, data }; self.assert_only_event(contract, expected); } } From 4c13e4b8cb785f9a7e093df903e024b350dc88dc Mon Sep 17 00:00:00 2001 From: Eric Nordelo Date: Mon, 28 Jul 2025 13:43:43 +0200 Subject: [PATCH 18/29] feat: add key tests for token --- Scarb.lock | 1 + .../src/tests/test_universal_deployer.cairo | 19 +++-- packages/security/Scarb.toml | 1 + .../security/src/tests/test_pausable.cairo | 21 ++++- packages/test_common/src/erc1155.cairo | 44 ++++++++--- packages/test_common/src/erc20.cairo | 23 +++++- packages/test_common/src/erc721.cairo | 32 ++++++-- packages/test_common/src/upgrades.cairo | 12 ++- .../src/tests/erc1155/test_erc1155.cairo | 29 +++++-- .../token/src/tests/erc20/test_erc20.cairo | 27 +++++-- .../src/tests/erc4626/test_erc4626.cairo | 77 ++++++++++++++----- .../token/src/tests/erc721/test_erc721.cairo | 27 +++++-- 12 files changed, 236 insertions(+), 77 deletions(-) diff --git a/Scarb.lock b/Scarb.lock index fa700ee79..7f1decf44 100644 --- a/Scarb.lock +++ b/Scarb.lock @@ -111,6 +111,7 @@ version = "3.0.0-alpha.0" dependencies = [ "openzeppelin_test_common", "openzeppelin_testing", + "openzeppelin_utils", "snforge_std", ] diff --git a/packages/presets/src/tests/test_universal_deployer.cairo b/packages/presets/src/tests/test_universal_deployer.cairo index e2185a2bf..11a9b3ecd 100644 --- a/packages/presets/src/tests/test_universal_deployer.cairo +++ b/packages/presets/src/tests/test_universal_deployer.cairo @@ -7,10 +7,8 @@ use openzeppelin_utils::interfaces::{ UniversalDeployerABIDispatcher, UniversalDeployerABIDispatcherTrait, }; use openzeppelin_utils::serde::SerializedAppend; -use snforge_std::start_cheat_caller_address; +use snforge_std::{Event, start_cheat_caller_address}; use starknet::{ClassHash, ContractAddress}; -use crate::universal_deployer::UniversalDeployer; -use crate::universal_deployer::UniversalDeployer::ContractDeployed; fn ERC20_CLASS_HASH() -> ClassHash { utils::declare_class("DualCaseERC20Mock").class_hash @@ -157,9 +155,18 @@ impl UniversalDeployerHelpersImpl of UniversalDeployerSpyHelpers { calldata: Span, salt: felt252, ) { - let expected = UniversalDeployer::Event::ContractDeployed( - ContractDeployed { address, deployer, not_from_zero, class_hash, calldata, salt }, - ); + let mut keys = array![]; + keys.append_serde(selector!("ContractDeployed")); + + let mut data = array![]; + data.append_serde(address); + data.append_serde(deployer); + data.append_serde(not_from_zero); + data.append_serde(class_hash); + data.append_serde(calldata); + data.append_serde(salt); + + let expected = Event { keys, data }; self.assert_only_event(contract, expected); } } diff --git a/packages/security/Scarb.toml b/packages/security/Scarb.toml index 5929a9462..7029f3821 100644 --- a/packages/security/Scarb.toml +++ b/packages/security/Scarb.toml @@ -30,6 +30,7 @@ assert_macros.workspace = true snforge_std.workspace = true openzeppelin_testing = { path = "../testing" } openzeppelin_test_common = { path = "../test_common" } +openzeppelin_utils = { path = "../utils" } [lib] diff --git a/packages/security/src/tests/test_pausable.cairo b/packages/security/src/tests/test_pausable.cairo index 7f5d70c7d..d07a772b3 100644 --- a/packages/security/src/tests/test_pausable.cairo +++ b/packages/security/src/tests/test_pausable.cairo @@ -1,10 +1,11 @@ use openzeppelin_test_common::mocks::security::PausableMock; use openzeppelin_testing::constants::CALLER; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; -use snforge_std::{start_cheat_caller_address, test_address}; +use openzeppelin_utils::serde::SerializedAppend; +use snforge_std::{Event, start_cheat_caller_address, test_address}; use starknet::ContractAddress; use crate::PausableComponent; -use crate::PausableComponent::{InternalImpl, PausableImpl, Paused, Unpaused}; +use crate::PausableComponent::{InternalImpl, PausableImpl}; type ComponentState = PausableComponent::ComponentState; @@ -125,7 +126,13 @@ impl PausableSpyHelpersImpl of PausableSpyHelpers { fn assert_event_paused( ref self: EventSpy, contract: ContractAddress, account: ContractAddress, ) { - let expected = PausableComponent::Event::Paused(Paused { account }); + let mut keys = array![]; + keys.append_serde(selector!("Paused")); + + let mut data = array![]; + data.append_serde(account); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } @@ -139,7 +146,13 @@ impl PausableSpyHelpersImpl of PausableSpyHelpers { fn assert_event_unpaused( ref self: EventSpy, contract: ContractAddress, account: ContractAddress, ) { - let expected = PausableComponent::Event::Unpaused(Unpaused { account }); + let mut keys = array![]; + keys.append_serde(selector!("Unpaused")); + + let mut data = array![]; + data.append_serde(account); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } diff --git a/packages/test_common/src/erc1155.cairo b/packages/test_common/src/erc1155.cairo index 2cedfbaa6..8f66df42e 100644 --- a/packages/test_common/src/erc1155.cairo +++ b/packages/test_common/src/erc1155.cairo @@ -1,8 +1,8 @@ use openzeppelin_testing as utils; use openzeppelin_testing::constants::{PUBKEY, TOKEN_ID, TOKEN_ID_2, TOKEN_VALUE, TOKEN_VALUE_2}; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy}; -use openzeppelin_token::erc1155::ERC1155Component; -use openzeppelin_token::erc1155::ERC1155Component::{ApprovalForAll, TransferBatch, TransferSingle}; +use openzeppelin_utils::serde::SerializedAppend; +use snforge_std::Event; use starknet::ContractAddress; pub fn setup_receiver() -> ContractAddress { @@ -44,9 +44,15 @@ pub impl ERC1155SpyHelpersImpl of ERC1155SpyHelpers { operator: ContractAddress, approved: bool, ) { - let expected = ERC1155Component::Event::ApprovalForAll( - ApprovalForAll { owner, operator, approved }, - ); + let mut keys = array![]; + keys.append_serde(selector!("ApprovalForAll")); + keys.append_serde(owner); + keys.append_serde(operator); + + let mut data = array![]; + data.append_serde(approved); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } @@ -70,9 +76,17 @@ pub impl ERC1155SpyHelpersImpl of ERC1155SpyHelpers { token_id: u256, value: u256, ) { - let expected = ERC1155Component::Event::TransferSingle( - TransferSingle { operator, from, to, id: token_id, value }, - ); + let mut keys = array![]; + keys.append_serde(selector!("TransferSingle")); + keys.append_serde(operator); + keys.append_serde(from); + keys.append_serde(to); + + let mut data = array![]; + data.append_serde(token_id); + data.append_serde(value); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } @@ -98,9 +112,17 @@ pub impl ERC1155SpyHelpersImpl of ERC1155SpyHelpers { token_ids: Span, values: Span, ) { - let expected = ERC1155Component::Event::TransferBatch( - TransferBatch { operator, from, to, ids: token_ids, values }, - ); + let mut keys = array![]; + keys.append_serde(selector!("TransferBatch")); + keys.append_serde(operator); + keys.append_serde(from); + keys.append_serde(to); + + let mut data = array![]; + data.append_serde(token_ids); + data.append_serde(values); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } diff --git a/packages/test_common/src/erc20.cairo b/packages/test_common/src/erc20.cairo index c1acd0cec..aa0942995 100644 --- a/packages/test_common/src/erc20.cairo +++ b/packages/test_common/src/erc20.cairo @@ -1,10 +1,9 @@ use openzeppelin_testing as utils; use openzeppelin_testing::constants::{NAME, SYMBOL}; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy}; -use openzeppelin_token::erc20::ERC20Component; -use openzeppelin_token::erc20::ERC20Component::{Approval, Transfer}; use openzeppelin_token::erc20::interface::IERC20Dispatcher; use openzeppelin_utils::serde::SerializedAppend; +use snforge_std::Event; use starknet::ContractAddress; pub fn deploy_erc20(recipient: ContractAddress, initial_supply: u256) -> IERC20Dispatcher { @@ -27,7 +26,15 @@ pub impl ERC20SpyHelpersImpl of ERC20SpyHelpers { spender: ContractAddress, value: u256, ) { - let expected = ERC20Component::Event::Approval(Approval { owner, spender, value }); + let mut keys = array![]; + keys.append_serde(selector!("Approval")); + keys.append_serde(owner); + keys.append_serde(spender); + + let mut data = array![]; + data.append_serde(value); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } @@ -49,7 +56,15 @@ pub impl ERC20SpyHelpersImpl of ERC20SpyHelpers { to: ContractAddress, value: u256, ) { - let expected = ERC20Component::Event::Transfer(Transfer { from, to, value }); + let mut keys = array![]; + keys.append_serde(selector!("Transfer")); + keys.append_serde(from); + keys.append_serde(to); + + let mut data = array![]; + data.append_serde(value); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } diff --git a/packages/test_common/src/erc721.cairo b/packages/test_common/src/erc721.cairo index 9a710cb96..bca70feba 100644 --- a/packages/test_common/src/erc721.cairo +++ b/packages/test_common/src/erc721.cairo @@ -1,6 +1,6 @@ use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy}; -use openzeppelin_token::erc721::ERC721Component; -use openzeppelin_token::erc721::ERC721Component::{Approval, ApprovalForAll, Transfer}; +use openzeppelin_utils::serde::SerializedAppend; +use snforge_std::Event; use starknet::ContractAddress; #[generate_trait] @@ -12,9 +12,15 @@ pub impl ERC721SpyHelpersImpl of ERC721SpyHelpers { operator: ContractAddress, approved: bool, ) { - let expected = ERC721Component::Event::ApprovalForAll( - ApprovalForAll { owner, operator, approved }, - ); + let mut keys = array![]; + keys.append_serde(selector!("ApprovalForAll")); + keys.append_serde(owner); + keys.append_serde(operator); + + let mut data = array![]; + data.append_serde(approved); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } @@ -36,7 +42,13 @@ pub impl ERC721SpyHelpersImpl of ERC721SpyHelpers { approved: ContractAddress, token_id: u256, ) { - let expected = ERC721Component::Event::Approval(Approval { owner, approved, token_id }); + let mut keys = array![]; + keys.append_serde(selector!("Approval")); + keys.append_serde(owner); + keys.append_serde(approved); + keys.append_serde(token_id); + + let expected = Event { keys, data: array![] }; self.assert_emitted_single(contract, expected); } @@ -58,7 +70,13 @@ pub impl ERC721SpyHelpersImpl of ERC721SpyHelpers { to: ContractAddress, token_id: u256, ) { - let expected = ERC721Component::Event::Transfer(Transfer { from, to, token_id }); + let mut keys = array![]; + keys.append_serde(selector!("Transfer")); + keys.append_serde(from); + keys.append_serde(to); + keys.append_serde(token_id); + + let expected = Event { keys, data: array![] }; self.assert_emitted_single(contract, expected); } diff --git a/packages/test_common/src/upgrades.cairo b/packages/test_common/src/upgrades.cairo index 2a2576df8..65cfd405f 100644 --- a/packages/test_common/src/upgrades.cairo +++ b/packages/test_common/src/upgrades.cairo @@ -1,12 +1,18 @@ use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy}; -use openzeppelin_upgrades::UpgradeableComponent; -use openzeppelin_upgrades::UpgradeableComponent::Upgraded; +use openzeppelin_utils::serde::SerializedAppend; +use snforge_std::Event; use starknet::{ClassHash, ContractAddress}; #[generate_trait] pub impl UpgradeableSpyHelpersImpl of UpgradeableSpyHelpers { fn assert_event_upgraded(ref self: EventSpy, contract: ContractAddress, class_hash: ClassHash) { - let expected = UpgradeableComponent::Event::Upgraded(Upgraded { class_hash }); + let mut keys = array![]; + keys.append_serde(selector!("Upgraded")); + + let mut data = array![]; + data.append_serde(class_hash); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } diff --git a/packages/token/src/tests/erc1155/test_erc1155.cairo b/packages/token/src/tests/erc1155/test_erc1155.cairo index 579515701..564aa67bb 100644 --- a/packages/token/src/tests/erc1155/test_erc1155.cairo +++ b/packages/token/src/tests/erc1155/test_erc1155.cairo @@ -10,7 +10,8 @@ use openzeppelin_testing::constants::{ ZERO, }; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; -use snforge_std::{start_cheat_caller_address, test_address}; +use openzeppelin_utils::serde::SerializedAppend; +use snforge_std::{Event, start_cheat_caller_address, test_address}; use starknet::ContractAddress; use starknet::storage::StoragePointerReadAccess; use crate::erc1155; @@ -1392,9 +1393,16 @@ impl ERC1155HooksSpyHelpersImpl of ERC1155HooksSpyHelpers { token_ids: Span, values: Span, ) { - let expected = SnakeERC1155MockWithHooks::Event::BeforeUpdate( - SnakeERC1155MockWithHooks::BeforeUpdate { from, to, token_ids, values }, - ); + let mut keys = array![]; + keys.append_serde(selector!("BeforeUpdate")); + + let mut data = array![]; + data.append_serde(from); + data.append_serde(to); + data.append_serde(token_ids); + data.append_serde(values); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } @@ -1406,9 +1414,16 @@ impl ERC1155HooksSpyHelpersImpl of ERC1155HooksSpyHelpers { token_ids: Span, values: Span, ) { - let expected = SnakeERC1155MockWithHooks::Event::AfterUpdate( - SnakeERC1155MockWithHooks::AfterUpdate { from, to, token_ids, values }, - ); + let mut keys = array![]; + keys.append_serde(selector!("AfterUpdate")); + + let mut data = array![]; + data.append_serde(from); + data.append_serde(to); + data.append_serde(token_ids); + data.append_serde(values); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } } diff --git a/packages/token/src/tests/erc20/test_erc20.cairo b/packages/token/src/tests/erc20/test_erc20.cairo index 3b0c9fcfe..d020692c1 100644 --- a/packages/token/src/tests/erc20/test_erc20.cairo +++ b/packages/token/src/tests/erc20/test_erc20.cairo @@ -3,7 +3,8 @@ use openzeppelin_test_common::erc20::ERC20SpyHelpers; use openzeppelin_test_common::mocks::erc20::{DualCaseERC20Mock, SnakeERC20MockWithHooks}; use openzeppelin_testing::constants::{NAME, OWNER, RECIPIENT, SPENDER, SUPPLY, SYMBOL, VALUE, ZERO}; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; -use snforge_std::{start_cheat_caller_address, test_address}; +use openzeppelin_utils::serde::SerializedAppend; +use snforge_std::{Event, start_cheat_caller_address, test_address}; use starknet::ContractAddress; use crate::erc20::ERC20Component; use crate::erc20::ERC20Component::{ERC20CamelOnlyImpl, ERC20Impl, ERC20MetadataImpl, InternalImpl}; @@ -668,9 +669,15 @@ impl ERC20HooksSpyHelpersImpl of ERC20HooksSpyHelpers { recipient: ContractAddress, amount: u256, ) { - let expected = SnakeERC20MockWithHooks::Event::BeforeUpdate( - SnakeERC20MockWithHooks::BeforeUpdate { from, recipient, amount }, - ); + let mut keys = array![]; + keys.append_serde(selector!("BeforeUpdate")); + + let mut data = array![]; + data.append_serde(from); + data.append_serde(recipient); + data.append_serde(amount); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } @@ -681,9 +688,15 @@ impl ERC20HooksSpyHelpersImpl of ERC20HooksSpyHelpers { recipient: ContractAddress, amount: u256, ) { - let expected = SnakeERC20MockWithHooks::Event::AfterUpdate( - SnakeERC20MockWithHooks::AfterUpdate { from, recipient, amount }, - ); + let mut keys = array![]; + keys.append_serde(selector!("AfterUpdate")); + + let mut data = array![]; + data.append_serde(from); + data.append_serde(recipient); + data.append_serde(amount); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } } diff --git a/packages/token/src/tests/erc4626/test_erc4626.cairo b/packages/token/src/tests/erc4626/test_erc4626.cairo index 56ec64bec..9749b3948 100644 --- a/packages/token/src/tests/erc4626/test_erc4626.cairo +++ b/packages/token/src/tests/erc4626/test_erc4626.cairo @@ -3,18 +3,16 @@ use openzeppelin_test_common::erc20::ERC20SpyHelpers; use openzeppelin_test_common::mocks::erc20::{ IERC20ReentrantDispatcher, IERC20ReentrantDispatcherTrait, Type, }; -use openzeppelin_test_common::mocks::erc4626::{ - ERC4626LimitsMock, ERC4626Mock, ERC4626MockWithHooks, -}; +use openzeppelin_test_common::mocks::erc4626::{ERC4626LimitsMock, ERC4626Mock}; use openzeppelin_testing as utils; use openzeppelin_testing::constants::{ALICE, BOB, NAME, OTHER, RECIPIENT, SPENDER, SYMBOL, ZERO}; use openzeppelin_testing::{AsAddressTrait, EventSpyExt, EventSpyQueue as EventSpy, spy_events}; use openzeppelin_utils::serde::SerializedAppend; -use snforge_std::{CheatSpan, cheat_caller_address}; +use snforge_std::{CheatSpan, Event, cheat_caller_address}; use starknet::ContractAddress; use crate::erc20::ERC20Component::InternalImpl as ERC20InternalImpl; use crate::erc20::extensions::erc4626::ERC4626Component::{ - Deposit, ERC4626Impl, ERC4626MetadataImpl, InternalImpl, Withdraw, + ERC4626Impl, ERC4626MetadataImpl, InternalImpl, }; use crate::erc20::extensions::erc4626::interface::{ERC4626ABIDispatcher, ERC4626ABIDispatcherTrait}; use crate::erc20::extensions::erc4626::{DefaultConfig, ERC4626Component}; @@ -1723,7 +1721,16 @@ pub impl ERC4626SpyHelpersImpl of ERC4626SpyHelpers { assets: u256, shares: u256, ) { - let expected = ERC4626Component::Event::Deposit(Deposit { sender, owner, assets, shares }); + let mut keys = array![]; + keys.append_serde(selector!("Deposit")); + keys.append_serde(sender); + keys.append_serde(owner); + + let mut data = array![]; + data.append_serde(assets); + data.append_serde(shares); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } @@ -1748,9 +1755,17 @@ pub impl ERC4626SpyHelpersImpl of ERC4626SpyHelpers { assets: u256, shares: u256, ) { - let expected = ERC4626Component::Event::Withdraw( - Withdraw { sender, receiver, owner, assets, shares }, - ); + let mut keys = array![]; + keys.append_serde(selector!("Withdraw")); + keys.append_serde(sender); + keys.append_serde(receiver); + keys.append_serde(owner); + + let mut data = array![]; + data.append_serde(assets); + data.append_serde(shares); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } @@ -1773,36 +1788,56 @@ impl ERC4626HooksSpyHelpersImpl of ERC4626HooksSpyHelpers { fn assert_event_before_deposit( ref self: EventSpy, contract: ContractAddress, assets: u256, shares: u256, ) { - let expected = ERC4626MockWithHooks::Event::BeforeDeposit( - ERC4626MockWithHooks::BeforeDeposit { assets, shares }, - ); + let mut keys = array![]; + keys.append_serde(selector!("BeforeDeposit")); + + let mut data = array![]; + data.append_serde(assets); + data.append_serde(shares); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } fn assert_event_after_deposit( ref self: EventSpy, contract: ContractAddress, assets: u256, shares: u256, ) { - let expected = ERC4626MockWithHooks::Event::AfterDeposit( - ERC4626MockWithHooks::AfterDeposit { assets, shares }, - ); + let mut keys = array![]; + keys.append_serde(selector!("AfterDeposit")); + + let mut data = array![]; + data.append_serde(assets); + data.append_serde(shares); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } fn assert_event_before_withdraw( ref self: EventSpy, contract: ContractAddress, assets: u256, shares: u256, ) { - let expected = ERC4626MockWithHooks::Event::BeforeWithdraw( - ERC4626MockWithHooks::BeforeWithdraw { assets, shares }, - ); + let mut keys = array![]; + keys.append_serde(selector!("BeforeWithdraw")); + + let mut data = array![]; + data.append_serde(assets); + data.append_serde(shares); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } fn assert_event_after_withdraw( ref self: EventSpy, contract: ContractAddress, assets: u256, shares: u256, ) { - let expected = ERC4626MockWithHooks::Event::AfterWithdraw( - ERC4626MockWithHooks::AfterWithdraw { assets, shares }, - ); + let mut keys = array![]; + keys.append_serde(selector!("AfterWithdraw")); + + let mut data = array![]; + data.append_serde(assets); + data.append_serde(shares); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } } diff --git a/packages/token/src/tests/erc721/test_erc721.cairo b/packages/token/src/tests/erc721/test_erc721.cairo index 53ff3023e..819c551d0 100644 --- a/packages/token/src/tests/erc721/test_erc721.cairo +++ b/packages/token/src/tests/erc721/test_erc721.cairo @@ -8,7 +8,8 @@ use openzeppelin_testing::constants::{ SYMBOL, TOKEN_ID, TOKEN_ID_2, ZERO, }; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; -use snforge_std::{start_cheat_caller_address, test_address}; +use openzeppelin_utils::serde::SerializedAppend; +use snforge_std::{Event, start_cheat_caller_address, test_address}; use starknet::ContractAddress; use starknet::storage::StorageMapReadAccess; use crate::erc721; @@ -1489,9 +1490,15 @@ impl ERC721HooksSpyHelpersImpl of ERC721HooksSpyHelpers { token_id: u256, auth: ContractAddress, ) { - let expected = SnakeERC721MockWithHooks::Event::BeforeUpdate( - SnakeERC721MockWithHooks::BeforeUpdate { to, token_id, auth }, - ); + let mut keys = array![]; + keys.append_serde(selector!("BeforeUpdate")); + + let mut data = array![]; + data.append_serde(to); + data.append_serde(token_id); + data.append_serde(auth); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } @@ -1502,9 +1509,15 @@ impl ERC721HooksSpyHelpersImpl of ERC721HooksSpyHelpers { token_id: u256, auth: ContractAddress, ) { - let expected = SnakeERC721MockWithHooks::Event::AfterUpdate( - SnakeERC721MockWithHooks::AfterUpdate { to, token_id, auth }, - ); + let mut keys = array![]; + keys.append_serde(selector!("AfterUpdate")); + + let mut data = array![]; + data.append_serde(to); + data.append_serde(token_id); + data.append_serde(auth); + + let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } } From 34480a104e46379b3139ebd2a2b2a615e52f80f9 Mon Sep 17 00:00:00 2001 From: Eric Nordelo Date: Mon, 28 Jul 2025 13:47:18 +0200 Subject: [PATCH 19/29] feat: remove inline macro --- packages/macros/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/macros/src/lib.rs b/packages/macros/src/lib.rs index 0aab98af3..bd4c26a8c 100644 --- a/packages/macros/src/lib.rs +++ b/packages/macros/src/lib.rs @@ -1,6 +1,5 @@ pub(crate) mod attribute; pub(crate) mod constants; -pub(crate) mod inline; pub(crate) mod utils; pub(crate) use attribute::{type_hash, with_components}; From 661529e39af7405730afd8ea8d11242245770b5e Mon Sep 17 00:00:00 2001 From: Eric Nordelo Date: Mon, 28 Jul 2025 13:47:42 +0200 Subject: [PATCH 20/29] feat: remove argument --- packages/macros/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/macros/src/lib.rs b/packages/macros/src/lib.rs index bd4c26a8c..1ddaf3bc5 100644 --- a/packages/macros/src/lib.rs +++ b/packages/macros/src/lib.rs @@ -3,7 +3,6 @@ pub(crate) mod constants; pub(crate) mod utils; pub(crate) use attribute::{type_hash, with_components}; -pub(crate) use inline::generate_event_spy_helpers; #[cfg(test)] mod tests; From c800abfa3eae664e521d1be69a407f70f82783f1 Mon Sep 17 00:00:00 2001 From: Eric Nordelo Date: Mon, 28 Jul 2025 13:54:57 +0200 Subject: [PATCH 21/29] feat: add missing import --- packages/governance/src/governor/proposal_core.cairo | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/governance/src/governor/proposal_core.cairo b/packages/governance/src/governor/proposal_core.cairo index baa932219..64f7b1cdf 100644 --- a/packages/governance/src/governor/proposal_core.cairo +++ b/packages/governance/src/governor/proposal_core.cairo @@ -84,6 +84,7 @@ mod tests { use core::num::traits::Bounded; use openzeppelin_testing::constants::ALICE; use openzeppelin_testing::{FuzzableBool, FuzzableContractAddress}; + use starknet::ContractAddress; use super::{ProposalCore, ProposalCoreStorePacking as StorePacking}; #[test] From 78df7c5b0f6418feb4647bffe48f98e5075e9f90 Mon Sep 17 00:00:00 2001 From: Eric Nordelo Date: Tue, 29 Jul 2025 17:58:35 +0200 Subject: [PATCH 22/29] feat: added new macro --- packages/macros/Cargo.lock | 17 +- packages/macros/Cargo.toml | 4 +- .../src/attribute/with_components/parser.rs | 10 +- .../generate_event_spy_helpers/definition.rs | 172 ++++++++++++++++++ .../inline/generate_event_spy_helpers/mod.rs | 2 + .../generate_event_spy_helpers/parser.rs | 152 ++++++++++++++++ packages/macros/src/inline/mod.rs | 3 + packages/macros/src/lib.rs | 2 + packages/macros/src/tests/mod.rs | 1 + ...nerate_event_spy_helpers__empty_event.snap | 30 +++ ...enerate_event_spy_helpers__empty_impl.snap | 18 ++ ...__event_with_invalid_non_default_attr.snap | 17 ++ ...ate_event_spy_helpers__event_with_key.snap | 30 +++ ...te_event_spy_helpers__event_with_only.snap | 31 ++++ ..._spy_helpers__event_with_only_and_key.snap | 36 ++++ ...vent_spy_helpers__event_without_attrs.snap | 27 +++ ...e_event_spy_helpers__impl_without_pub.snap | 27 +++ ...te_event_spy_helpers__multiple_events.snap | 39 ++++ .../tests/test_generate_event_spy_helpers.rs | 162 +++++++++++++++++ packages/macros/src/utils.rs | 20 ++ packages/test_common/src/account.cairo | 2 - 21 files changed, 791 insertions(+), 11 deletions(-) create mode 100644 packages/macros/src/inline/generate_event_spy_helpers/definition.rs create mode 100644 packages/macros/src/inline/generate_event_spy_helpers/mod.rs create mode 100644 packages/macros/src/inline/generate_event_spy_helpers/parser.rs create mode 100644 packages/macros/src/inline/mod.rs create mode 100644 packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__empty_event.snap create mode 100644 packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__empty_impl.snap create mode 100644 packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__event_with_invalid_non_default_attr.snap create mode 100644 packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__event_with_key.snap create mode 100644 packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__event_with_only.snap create mode 100644 packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__event_with_only_and_key.snap create mode 100644 packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__event_without_attrs.snap create mode 100644 packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__impl_without_pub.snap create mode 100644 packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__multiple_events.snap create mode 100644 packages/macros/src/tests/test_generate_event_spy_helpers.rs diff --git a/packages/macros/Cargo.lock b/packages/macros/Cargo.lock index afab07997..1827cace5 100644 --- a/packages/macros/Cargo.lock +++ b/packages/macros/Cargo.lock @@ -1045,6 +1045,15 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" +[[package]] +name = "nom" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405" +dependencies = [ + "memchr", +] + [[package]] name = "nu-ansi-term" version = "0.50.1" @@ -1119,8 +1128,10 @@ dependencies = [ "fancy-regex", "indoc", "insta", + "nom", + "proc-macro2", + "quote", "regex", - "syn 2.0.104", ] [[package]] @@ -1243,9 +1254,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] diff --git a/packages/macros/Cargo.toml b/packages/macros/Cargo.toml index efc1f7bff..96ffea179 100644 --- a/packages/macros/Cargo.toml +++ b/packages/macros/Cargo.toml @@ -19,4 +19,6 @@ regex = "1.11.1" insta = "1.42.0" convert_case = "0.8.0" fancy-regex = "0.15.0" -syn = "2.0.104" +nom = "8" +quote = "1.0.40" +proc-macro2 = "1.0.95" diff --git a/packages/macros/src/attribute/with_components/parser.rs b/packages/macros/src/attribute/with_components/parser.rs index 0806c6378..bef550c01 100644 --- a/packages/macros/src/attribute/with_components/parser.rs +++ b/packages/macros/src/attribute/with_components/parser.rs @@ -42,7 +42,7 @@ impl<'a> WithComponentsParser<'a> { /// Parses the module and returns the patched code. pub fn parse(&mut self, db: &dyn SyntaxGroup) -> (String, Diagnostics) { - let base_node = self.base_node.clone(); + let base_node = self.base_node; let mut builder = PatchBuilder::new_ex(db, &base_node); let typed = ast::SyntaxFile::from_syntax_node(db, base_node); @@ -98,7 +98,7 @@ fn validate_contract_module( let mut warnings = vec![]; if let RewriteNode::Copied(copied) = node { - let item = ast::ItemModule::from_syntax_node(db, copied.clone()); + let item = ast::ItemModule::from_syntax_node(db, *copied); // 1. Check that the module has a body (error) let MaybeModuleBody::Some(body) = item.body(db) else { @@ -125,7 +125,7 @@ fn validate_contract_module( let constructor_code = if let Some(constructor) = constructor { // Get the constructor code (maybe we can do this without the builder) let constructor_ast = constructor.as_syntax_node(); - let typed = ast::ModuleItem::from_syntax_node(db, constructor_ast.clone()); + let typed = ast::ModuleItem::from_syntax_node(db, constructor_ast); let constructor_rnode = RewriteNode::from_ast(&typed); let mut builder = PatchBuilder::new_ex(db, &constructor_ast); builder.add_modified(constructor_rnode); @@ -155,7 +155,7 @@ fn validate_contract_module( for component in components_info.iter().filter(|c| c.has_immutable_config) { // Get the body code (maybe we can do this without the builder) let body_ast = body.as_syntax_node(); - let typed = ast::ModuleBody::from_syntax_node(db, body_ast.clone()); + let typed = ast::ModuleBody::from_syntax_node(db, body_ast); let body_rnode = RewriteNode::from_ast(&typed); let mut builder = PatchBuilder::new_ex(db, &body_ast); @@ -282,7 +282,7 @@ fn process_module_items( for item_rnode in items_mnode.children.as_mut().unwrap() { if let RewriteNode::Copied(copied) = item_rnode { - let item = ast::ModuleItem::from_syntax_node(db, copied.clone()); + let item = ast::ModuleItem::from_syntax_node(db, *copied); match item { ast::ModuleItem::Struct(item_struct) diff --git a/packages/macros/src/inline/generate_event_spy_helpers/definition.rs b/packages/macros/src/inline/generate_event_spy_helpers/definition.rs new file mode 100644 index 000000000..410a2b52f --- /dev/null +++ b/packages/macros/src/inline/generate_event_spy_helpers/definition.rs @@ -0,0 +1,172 @@ +use cairo_lang_formatter::format_string; +use cairo_lang_macro::{inline_macro, Diagnostic, ProcMacroResult, TokenStream}; +use cairo_lang_parser::utils::SimpleParserDatabase; +use proc_macro2::TokenStream as ProcTokenStream; +use quote::{format_ident, quote}; + +use crate::{generate_event_spy_helpers::parser, utils::camel_to_snake}; + +/// Generates helper functions for spying on events in tests. +/// +/// Example: +/// ``` +/// generate_event_spy_helpers! { +/// impl AccessControlDefaultAdminRulesSpyHelpers { +/// event DefaultAdminTransferScheduled( +/// #[key] +/// new_admin: ContractAddress, +/// accept_schedule: u64 +/// ); +/// } +/// } +/// ``` +/// +/// // Generated code: +/// #[generate_trait] +/// impl AccessControlDefaultAdminRulesSpyHelpers of AccessControlDefaultAdminRulesSpyHelpersTrait { +/// fn assert_event_default_admin_transfer_scheduled( +/// ref self: EventSpy, +/// contract: ContractAddress, +/// new_admin: ContractAddress, +/// accept_schedule: u64, +/// ) { +/// let mut keys = array![]; +/// keys.append_serde(selector!("DefaultAdminTransferScheduled")); +/// keys.append_serde(new_admin); +/// +/// let mut data = array![]; +/// data.append_serde(accept_schedule); +/// +/// let expected = Event { keys, data }; +/// self.assert_only_event(contract, expected); +/// } +/// +/// fn assert_only_event_default_admin_transfer_scheduled( +/// ref self: EventSpy, +/// contract: ContractAddress, +/// new_admin: ContractAddress, +/// accept_schedule: u64, +/// ) { +/// self.assert_event_default_admin_transfer_scheduled(contract, new_admin, accept_schedule); +/// self.assert_no_events_left_from(contract); +/// } +/// } +/// ``` +#[inline_macro] +pub fn generate_event_spy_helpers(args_stream: TokenStream) -> ProcMacroResult { + // Parse the arguments + let impl_block = match parser::parse_dsl(&args_stream.to_string()) { + Ok((_, impl_block)) => impl_block, + Err(e) => { + let error = Diagnostic::error(e.to_string()); + let empty_result = ProcMacroResult::new(TokenStream::empty()); + return empty_result.with_diagnostics(error.into()); + } + }; + + // Generate the helper functions + let expanded = generate_code(&impl_block).to_string(); + + // Format the code + let db = SimpleParserDatabase::default(); + let formatted_code = format_string(&db, expanded); + + // Return the result + ProcMacroResult::new(TokenStream::new(formatted_code)) +} + +/// Generates the code for event spy helper functions based on the provided implementation block. +/// +/// # Arguments +/// +/// * `impl_block` - The parsed implementation block containing event definitions +/// +/// # Returns +/// +/// A `ProcTokenStream` containing the generated code for event spy helper functions +pub fn generate_code(impl_block: &parser::ImplBlock) -> ProcTokenStream { + let impl_name = format_ident!("{}", impl_block.name); + let trait_name = format_ident!("{}Trait", impl_block.name); + + let methods: Vec = impl_block + .events + .iter() + .map(|event| { + let event_name = &event.name; + let fn_suffix = format_ident!("{}", camel_to_snake(event_name)); + let selector = event_name.to_string(); + + let mut key_fields = vec![]; + let mut data_fields = vec![]; + + let mut fn_args = vec![]; + for param in &event.fields { + let name = format_ident!("{}", param.name); + let ty = format_ident!("{}", param.ty); + fn_args.push(quote! { #name: #ty }); + + if param.is_key { + key_fields.push(quote! { keys.append_serde(#name); }); + } else { + data_fields.push(quote! { data.append_serde(#name); }); + } + } + + let assert_fn_name = format_ident!("assert_event_{}", fn_suffix); + let only_fn_name = format_ident!("assert_only_event_{}", fn_suffix); + let fields = event + .fields + .iter() + .map(|p| format_ident!("{}", p.name)) + .collect::>(); + + let assert_only_fn = if event.is_only { + quote! { + fn #only_fn_name( + ref self: EventSpy, + contract: ContractAddress, + #(#fn_args),* + ) { + self.#assert_fn_name(contract, #(#fields),*); + self.assert_no_events_left_from(contract); + } + } + } else { + quote! {} + }; + + quote! { + fn #assert_fn_name( + ref self: EventSpy, + contract: ContractAddress, + #(#fn_args),* + ) { + let mut keys = array![]; + keys.append_serde(selector!(#selector)); + #(#key_fields)* + + let mut data = array![]; + #(#data_fields)* + + let expected = Event { keys, data }; + self.assert_only_event(contract, expected); + } + + #assert_only_fn + } + }) + .collect(); + + let maybe_pub = if impl_block.is_public { + quote! { pub } + } else { + quote! {} + }; + + quote! { + #[generate_trait] + #maybe_pub impl #impl_name of #trait_name { + #(#methods)* + } + } +} diff --git a/packages/macros/src/inline/generate_event_spy_helpers/mod.rs b/packages/macros/src/inline/generate_event_spy_helpers/mod.rs new file mode 100644 index 000000000..ec83ad179 --- /dev/null +++ b/packages/macros/src/inline/generate_event_spy_helpers/mod.rs @@ -0,0 +1,2 @@ +pub mod definition; +pub mod parser; diff --git a/packages/macros/src/inline/generate_event_spy_helpers/parser.rs b/packages/macros/src/inline/generate_event_spy_helpers/parser.rs new file mode 100644 index 000000000..76aa5c3a2 --- /dev/null +++ b/packages/macros/src/inline/generate_event_spy_helpers/parser.rs @@ -0,0 +1,152 @@ +use nom::{ + branch::alt, + bytes::complete::tag, + character::complete::{alpha1, alphanumeric1, char, multispace0, multispace1}, + combinator::{map, opt}, + multi::{many0, separated_list0}, + sequence::{delimited, pair}, + IResult, Parser, +}; + +#[derive(Debug)] +pub struct ImplBlock { + pub is_public: bool, + pub name: String, + pub events: Vec, +} + +#[derive(Debug)] +pub struct Event { + pub name: String, + pub fields: Vec, + pub is_only: bool, +} + +#[derive(Debug)] +pub struct Parameter { + pub is_key: bool, + pub name: String, + pub ty: String, +} + +// Parses an identifier like `AccessControlDefaultAdminRulesSpyHelpers` +fn identifier(input: &str) -> IResult<&str, String> { + map( + pair(alpha1, many0(alt((alphanumeric1, tag("_"))))), + |(first, rest)| format!("{}{}", first, rest.concat()), + ) + .parse(input) +} + +// #[key] (optional) +fn key_attribute(input: &str) -> IResult<&str, bool> { + map(opt(delimited(tag("#["), tag("key"), tag("]"))), |opt_key| { + opt_key.is_some() + }) + .parse(input) +} + +// new_admin: ContractAddress +fn parameter(input: &str) -> IResult<&str, Parameter> { + map( + ( + multispace0, + key_attribute, + multispace0, + identifier, + multispace0, + char(':'), + multispace0, + identifier, + multispace0, + ), + |(_, is_key, _, name, _, _, _, ty, _)| Parameter { is_key, name, ty }, + ) + .parse(input) +} + +// event DefaultAdminTransferScheduled(...) +fn event(input: &str) -> IResult<&str, Event> { + let (input, _) = multispace0(input)?; + let (input, is_only) = event_attributes(input)?; + let (input, _) = multispace0(input)?; + let (input, _) = tag("event")(input)?; + let (input, _) = multispace1(input)?; + let (input, name) = identifier(input)?; + let (input, fields) = delimited( + delimited(multispace0, char('('), multispace0), + separated_list0(char(','), parameter), + delimited(multispace0, char(')'), multispace0), + ) + .parse(input)?; + let (input, _) = char(';').parse(input)?; + Ok(( + input, + Event { + name, + fields, + is_only, + }, + )) +} + +fn event_attributes(input: &str) -> IResult<&str, bool> { + let (input, _) = multispace0(input)?; + + // Parse #[...] if present + let (input, maybe_attrs): (&str, Option>) = opt(delimited( + tag("#["), + separated_list0(delimited(multispace0, char(','), multispace0), alpha1), + tag("]"), + )) + .parse(input)?; + + let attrs = maybe_attrs.unwrap_or_default(); + + for attr in &attrs { + if *attr != "only" { + return Err(nom::Err::Failure(nom::error::Error::new( + input, + nom::error::ErrorKind::Verify, + ))); + } + } + + let is_only = attrs.contains(&"only"); + Ok((input, is_only)) +} + +// impl AccessControlDefaultAdminRulesSpyHelpers { ... } +fn impl_block(input: &str) -> IResult<&str, ImplBlock> { + let (input, _) = multispace0(input)?; + let (input, is_public) = opt(tag("pub")).parse(input)?; + let (input, _) = multispace0(input)?; + let (input, _) = tag("impl")(input)?; + let (input, _) = multispace1(input)?; + let (input, name) = identifier(input)?; + let (input, events) = delimited( + delimited(multispace0, char('{'), multispace0), + many0(event), + delimited(multispace0, char('}'), multispace0), + ) + .parse(input)?; + let is_public = is_public.is_some(); + Ok(( + input, + ImplBlock { + is_public, + name, + events, + }, + )) +} + +// Outer {} +pub fn parse_dsl(input: &str) -> IResult<&str, ImplBlock> { + delimited( + delimited(multispace0, char('{'), multispace0), + impl_block, + delimited(multispace0, char('}'), multispace0), + ) + .parse(input) +} diff --git a/packages/macros/src/inline/mod.rs b/packages/macros/src/inline/mod.rs new file mode 100644 index 000000000..9dcf32811 --- /dev/null +++ b/packages/macros/src/inline/mod.rs @@ -0,0 +1,3 @@ +//! OpenZeppelin inline macros. + +pub mod generate_event_spy_helpers; diff --git a/packages/macros/src/lib.rs b/packages/macros/src/lib.rs index 1ddaf3bc5..0aab98af3 100644 --- a/packages/macros/src/lib.rs +++ b/packages/macros/src/lib.rs @@ -1,8 +1,10 @@ pub(crate) mod attribute; pub(crate) mod constants; +pub(crate) mod inline; pub(crate) mod utils; pub(crate) use attribute::{type_hash, with_components}; +pub(crate) use inline::generate_event_spy_helpers; #[cfg(test)] mod tests; diff --git a/packages/macros/src/tests/mod.rs b/packages/macros/src/tests/mod.rs index 881107cd0..970c4ea80 100644 --- a/packages/macros/src/tests/mod.rs +++ b/packages/macros/src/tests/mod.rs @@ -1,3 +1,4 @@ mod common; +mod test_generate_event_spy_helpers; mod test_type_hash; mod test_with_components; diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__empty_event.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__empty_event.snap new file mode 100644 index 000000000..6cb4d6d04 --- /dev/null +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__empty_event.snap @@ -0,0 +1,30 @@ +--- +source: src/tests/test_generate_event_spy_helpers.rs +expression: get_string_result(input) +snapshot_kind: text +--- +TokenStream: + +#[generate_trait] +impl MockContractSpyHelpers of MockContractSpyHelpersTrait { + fn assert_event_empty_event(ref self: EventSpy, contract: ContractAddress) { + let mut keys = array![]; + keys.append_serde(selector!("EmptyEvent")); + let mut data = array![]; + let expected = Event { keys, data }; + self.assert_only_event(contract, expected); + } + fn assert_only_event_empty_event(ref self: EventSpy, contract: ContractAddress) { + self.assert_event_empty_event(contract); + self.assert_no_events_left_from(contract); + } +} + + +Diagnostics: + +None + +AuxData: + +None diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__empty_impl.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__empty_impl.snap new file mode 100644 index 000000000..40e06cdd3 --- /dev/null +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__empty_impl.snap @@ -0,0 +1,18 @@ +--- +source: src/tests/test_generate_event_spy_helpers.rs +expression: get_string_result(input) +snapshot_kind: text +--- +TokenStream: + +#[generate_trait] +impl MockContractSpyHelpers of MockContractSpyHelpersTrait {} + + +Diagnostics: + +None + +AuxData: + +None diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__event_with_invalid_non_default_attr.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__event_with_invalid_non_default_attr.snap new file mode 100644 index 000000000..acfa6213d --- /dev/null +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__event_with_invalid_non_default_attr.snap @@ -0,0 +1,17 @@ +--- +source: src/tests/test_generate_event_spy_helpers.rs +expression: get_string_result(input) +snapshot_kind: text +--- +TokenStream: + +None + +Diagnostics: + +==== +Error: Parsing Error: Error { input: "#[non_default]\n event InvalidEvent(\n field: u64\n );\n }\n}\n", code: Char }==== + +AuxData: + +None diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__event_with_key.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__event_with_key.snap new file mode 100644 index 000000000..e5fe4f91a --- /dev/null +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__event_with_key.snap @@ -0,0 +1,30 @@ +--- +source: src/tests/test_generate_event_spy_helpers.rs +expression: get_string_result(input) +snapshot_kind: text +--- +TokenStream: + +#[generate_trait] +pub impl ContrMockContractSpyHelpersactSpy of ContrMockContractSpyHelpersactSpyTrait { + fn assert_event_keyed_event( + ref self: EventSpy, contract: ContractAddress, user: ContractAddress, value: u64, + ) { + let mut keys = array![]; + keys.append_serde(selector!("KeyedEvent")); + keys.append_serde(user); + let mut data = array![]; + data.append_serde(value); + let expected = Event { keys, data }; + self.assert_only_event(contract, expected); + } +} + + +Diagnostics: + +None + +AuxData: + +None diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__event_with_only.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__event_with_only.snap new file mode 100644 index 000000000..745865651 --- /dev/null +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__event_with_only.snap @@ -0,0 +1,31 @@ +--- +source: src/tests/test_generate_event_spy_helpers.rs +expression: get_string_result(input) +snapshot_kind: text +--- +TokenStream: + +#[generate_trait] +pub impl MockContractSpyHelpers of MockContractSpyHelpersTrait { + fn assert_event_only_event(ref self: EventSpy, contract: ContractAddress, field: u64) { + let mut keys = array![]; + keys.append_serde(selector!("OnlyEvent")); + let mut data = array![]; + data.append_serde(field); + let expected = Event { keys, data }; + self.assert_only_event(contract, expected); + } + fn assert_only_event_only_event(ref self: EventSpy, contract: ContractAddress, field: u64) { + self.assert_event_only_event(contract, field); + self.assert_no_events_left_from(contract); + } +} + + +Diagnostics: + +None + +AuxData: + +None diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__event_with_only_and_key.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__event_with_only_and_key.snap new file mode 100644 index 000000000..0cfe8705a --- /dev/null +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__event_with_only_and_key.snap @@ -0,0 +1,36 @@ +--- +source: src/tests/test_generate_event_spy_helpers.rs +expression: get_string_result(input) +snapshot_kind: text +--- +TokenStream: + +#[generate_trait] +pub impl MockContractSpyHelpers of MockContractSpyHelpersTrait { + fn assert_event_only_keyed_event( + ref self: EventSpy, contract: ContractAddress, user: ContractAddress, value: u64, + ) { + let mut keys = array![]; + keys.append_serde(selector!("OnlyKeyedEvent")); + keys.append_serde(user); + let mut data = array![]; + data.append_serde(value); + let expected = Event { keys, data }; + self.assert_only_event(contract, expected); + } + fn assert_only_event_only_keyed_event( + ref self: EventSpy, contract: ContractAddress, user: ContractAddress, value: u64, + ) { + self.assert_event_only_keyed_event(contract, user, value); + self.assert_no_events_left_from(contract); + } +} + + +Diagnostics: + +None + +AuxData: + +None diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__event_without_attrs.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__event_without_attrs.snap new file mode 100644 index 000000000..7fc9b0a1e --- /dev/null +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__event_without_attrs.snap @@ -0,0 +1,27 @@ +--- +source: src/tests/test_generate_event_spy_helpers.rs +expression: get_string_result(input) +snapshot_kind: text +--- +TokenStream: + +#[generate_trait] +pub impl MockContractSpyHelpers of MockContractSpyHelpersTrait { + fn assert_event_simple_event(ref self: EventSpy, contract: ContractAddress, field: u64) { + let mut keys = array![]; + keys.append_serde(selector!("SimpleEvent")); + let mut data = array![]; + data.append_serde(field); + let expected = Event { keys, data }; + self.assert_only_event(contract, expected); + } +} + + +Diagnostics: + +None + +AuxData: + +None diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__impl_without_pub.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__impl_without_pub.snap new file mode 100644 index 000000000..7e2e23c8d --- /dev/null +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__impl_without_pub.snap @@ -0,0 +1,27 @@ +--- +source: src/tests/test_generate_event_spy_helpers.rs +expression: get_string_result(input) +snapshot_kind: text +--- +TokenStream: + +#[generate_trait] +impl MockContractSpyHelpers of MockContractSpyHelpersTrait { + fn assert_event_mock_event(ref self: EventSpy, contract: ContractAddress, field: u64) { + let mut keys = array![]; + keys.append_serde(selector!("MockEvent")); + let mut data = array![]; + data.append_serde(field); + let expected = Event { keys, data }; + self.assert_only_event(contract, expected); + } +} + + +Diagnostics: + +None + +AuxData: + +None diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__multiple_events.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__multiple_events.snap new file mode 100644 index 000000000..5f8dd7c3a --- /dev/null +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__multiple_events.snap @@ -0,0 +1,39 @@ +--- +source: src/tests/test_generate_event_spy_helpers.rs +expression: get_string_result(input) +snapshot_kind: text +--- +TokenStream: + +#[generate_trait] +impl MockContractSpyHelpers of MockContractSpyHelpersTrait { + fn assert_event_mock_event(ref self: EventSpy, contract: ContractAddress, field: u64) { + let mut keys = array![]; + keys.append_serde(selector!("MockEvent")); + let mut data = array![]; + data.append_serde(field); + let expected = Event { keys, data }; + self.assert_only_event(contract, expected); + } + fn assert_event_mock_event2(ref self: EventSpy, contract: ContractAddress, field: u64) { + let mut keys = array![]; + keys.append_serde(selector!("MockEvent2")); + let mut data = array![]; + data.append_serde(field); + let expected = Event { keys, data }; + self.assert_only_event(contract, expected); + } + fn assert_only_event_mock_event2(ref self: EventSpy, contract: ContractAddress, field: u64) { + self.assert_event_mock_event2(contract, field); + self.assert_no_events_left_from(contract); + } +} + + +Diagnostics: + +None + +AuxData: + +None diff --git a/packages/macros/src/tests/test_generate_event_spy_helpers.rs b/packages/macros/src/tests/test_generate_event_spy_helpers.rs new file mode 100644 index 000000000..5a6294a20 --- /dev/null +++ b/packages/macros/src/tests/test_generate_event_spy_helpers.rs @@ -0,0 +1,162 @@ +use cairo_lang_macro::TokenStream; +use indoc::indoc; +use insta::assert_snapshot; + +use super::common::format_proc_macro_result; +use crate::generate_event_spy_helpers::definition::generate_event_spy_helpers_q2hsv6hnhh3ug as generate_event_spy_helpers; + +#[test] +fn test_event_without_attrs() { + let input = indoc!( + " + { + pub impl MockContractSpyHelpers { + event SimpleEvent( + field: u64 + ); + } + } + " + ); + assert_snapshot!(get_string_result(input)); +} + +#[test] +fn test_event_with_only() { + let input = indoc!( + " + { + pub impl MockContractSpyHelpers { + #[only] + event OnlyEvent( + field: u64 + ); + } + } + " + ); + assert_snapshot!(get_string_result(input)); +} + +#[test] +fn test_event_with_key() { + let input = indoc!( + " + { + pub impl ContrMockContractSpyHelpersactSpy { + event KeyedEvent( + #[key] + user: ContractAddress, + value: u64 + ); + } + } + " + ); + assert_snapshot!(get_string_result(input)); +} + +#[test] +fn test_event_with_only_and_key() { + let input = indoc!( + " + { + pub impl MockContractSpyHelpers { + #[only] + event OnlyKeyedEvent( + #[key] user: ContractAddress, + value: u64 + ); + } + } + " + ); + assert_snapshot!(get_string_result(input)); +} + +#[test] +fn test_event_with_invalid_non_default_attr() { + let input = indoc!( + " + { + pub impl MockContractSpyHelpers { + #[non_default] + event InvalidEvent( + field: u64 + ); + } + } + " + ); + assert_snapshot!(get_string_result(input)); +} + +#[test] +fn test_impl_without_pub() { + let input = indoc!( + " + { + impl MockContractSpyHelpers { + event MockEvent( + field: u64 + ); + } + } + " + ); + assert_snapshot!(get_string_result(input)); +} + +#[test] +fn test_empty_impl() { + let input = indoc!( + " + { + impl MockContractSpyHelpers {} + } + " + ); + assert_snapshot!(get_string_result(input)); +} + +#[test] +fn test_multiple_events() { + let input = indoc!( + " + { + impl MockContractSpyHelpers { + event MockEvent( + field: u64 + ); + + #[only] + event MockEvent2( + field: u64 + ); + } + } + " + ); + assert_snapshot!(get_string_result(input)); +} + +#[test] +fn test_empty_event() { + let input = indoc!( + " + { + impl MockContractSpyHelpers { + #[only] + event EmptyEvent(); + } + } + " + ); + assert_snapshot!(get_string_result(input)); +} + +fn get_string_result(args_stream: &str) -> String { + let args_stream = TokenStream::new(args_stream.to_string()); + let raw_result = generate_event_spy_helpers(args_stream); + format_proc_macro_result(raw_result) +} diff --git a/packages/macros/src/utils.rs b/packages/macros/src/utils.rs index f79bda3cc..0199e9438 100644 --- a/packages/macros/src/utils.rs +++ b/packages/macros/src/utils.rs @@ -4,3 +4,23 @@ use crate::constants::TAB; pub fn tabs(n: usize) -> String { TAB.repeat(n) } + +/// Converts a camelCase string to a snake_case string. +pub fn camel_to_snake(input: &str) -> String { + let mut snake = String::with_capacity(input.len()); + + for (i, ch) in input.chars().enumerate() { + if ch.is_uppercase() { + if i != 0 { + snake.push('_'); + } + for lc in ch.to_lowercase() { + snake.push(lc); + } + } else { + snake.push(ch); + } + } + + snake +} diff --git a/packages/test_common/src/account.cairo b/packages/test_common/src/account.cairo index 12b88a86a..b7bfaed48 100644 --- a/packages/test_common/src/account.cairo +++ b/packages/test_common/src/account.cairo @@ -1,7 +1,5 @@ use core::hash::{HashStateExTrait, HashStateTrait}; use core::poseidon::PoseidonTrait; -use openzeppelin_account::AccountComponent; -use openzeppelin_account::AccountComponent::{OwnerAdded, OwnerRemoved}; use openzeppelin_testing::constants::TRANSACTION_HASH; use openzeppelin_testing::signing::StarkKeyPair; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy}; From ffb2cae6f02da6b76c9b7650fc18511b9af6c5ec Mon Sep 17 00:00:00 2001 From: Eric Nordelo Date: Wed, 30 Jul 2025 13:01:30 +0200 Subject: [PATCH 23/29] feat: rename trait --- Scarb.toml | 8 ++++---- packages/finance/src/tests/test_vesting_linear.cairo | 2 +- packages/finance/src/tests/test_vesting_steps.cairo | 2 +- .../macros/src/attribute/with_components/definition.rs | 3 +-- .../src/inline/generate_event_spy_helpers/definition.rs | 6 +++--- packages/presets/src/tests/test_vesting.cairo | 2 +- packages/test_common/src/vesting.cairo | 4 +--- 7 files changed, 12 insertions(+), 15 deletions(-) diff --git a/Scarb.toml b/Scarb.toml index 27f10e056..651dc86e4 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -26,8 +26,8 @@ edition.workspace = true [workspace.package] version = "3.0.0-alpha.0" edition = "2024_07" -cairo-version = "2.12.0-rc.2" -scarb-version = "2.12.0-rc.2" +cairo-version = "2.12.0-rc.3" +scarb-version = "2.12.0-rc.3" authors = ["OpenZeppelin Community "] description = "OpenZeppelin Contracts written in Cairo for Starknet, a decentralized ZK Rollup" documentation = "https://docs.openzeppelin.com/contracts-cairo" @@ -42,8 +42,8 @@ keywords = [ ] [workspace.dependencies] -assert_macros = "2.12.0-rc.2" -starknet = "2.12.0-rc.2" +assert_macros = "2.12.0-rc.3" +starknet = "2.12.0-rc.3" snforge_std = "0.46.0" [dependencies] diff --git a/packages/finance/src/tests/test_vesting_linear.cairo b/packages/finance/src/tests/test_vesting_linear.cairo index da911e2a1..561822b22 100644 --- a/packages/finance/src/tests/test_vesting_linear.cairo +++ b/packages/finance/src/tests/test_vesting_linear.cairo @@ -1,6 +1,6 @@ use openzeppelin_access::ownable::interface::{IOwnableDispatcher, IOwnableDispatcherTrait}; use openzeppelin_test_common::mocks::vesting::LinearVestingMock; -use openzeppelin_test_common::vesting::VestingSpyHelpers; +use openzeppelin_test_common::vesting::VestingSpyHelpersTrait; use openzeppelin_testing::constants::{OTHER, OWNER}; use openzeppelin_testing::{EventSpyExt, spy_events}; use openzeppelin_token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; diff --git a/packages/finance/src/tests/test_vesting_steps.cairo b/packages/finance/src/tests/test_vesting_steps.cairo index c7f56da09..51ed75c0c 100644 --- a/packages/finance/src/tests/test_vesting_steps.cairo +++ b/packages/finance/src/tests/test_vesting_steps.cairo @@ -1,6 +1,6 @@ use openzeppelin_access::ownable::interface::{IOwnableDispatcher, IOwnableDispatcherTrait}; use openzeppelin_test_common::mocks::vesting::StepsVestingMock; -use openzeppelin_test_common::vesting::VestingSpyHelpers; +use openzeppelin_test_common::vesting::VestingSpyHelpersTrait; use openzeppelin_testing::constants::{OTHER, OWNER}; use openzeppelin_testing::spy_events; use openzeppelin_token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; diff --git a/packages/macros/src/attribute/with_components/definition.rs b/packages/macros/src/attribute/with_components/definition.rs index f3947f4eb..0dd086382 100644 --- a/packages/macros/src/attribute/with_components/definition.rs +++ b/packages/macros/src/attribute/with_components/definition.rs @@ -1,10 +1,9 @@ +use crate::with_components::{components::AllowedComponents, parser::WithComponentsParser}; use cairo_lang_formatter::format_string; use cairo_lang_macro::{attribute_macro, Diagnostic, ProcMacroResult, TokenStream}; use cairo_lang_parser::utils::SimpleParserDatabase; use regex::Regex; -use super::{components::AllowedComponents, parser::WithComponentsParser}; - /// Inserts multiple component dependencies into a modules codebase. #[attribute_macro] pub fn with_components(attribute_stream: TokenStream, item_stream: TokenStream) -> ProcMacroResult { diff --git a/packages/macros/src/inline/generate_event_spy_helpers/definition.rs b/packages/macros/src/inline/generate_event_spy_helpers/definition.rs index 410a2b52f..e40c6bfb6 100644 --- a/packages/macros/src/inline/generate_event_spy_helpers/definition.rs +++ b/packages/macros/src/inline/generate_event_spy_helpers/definition.rs @@ -53,9 +53,9 @@ use crate::{generate_event_spy_helpers::parser, utils::camel_to_snake}; /// } /// ``` #[inline_macro] -pub fn generate_event_spy_helpers(args_stream: TokenStream) -> ProcMacroResult { +pub fn generate_event_spy_helpers(token_stream: TokenStream) -> ProcMacroResult { // Parse the arguments - let impl_block = match parser::parse_dsl(&args_stream.to_string()) { + let impl_block = match parser::parse_dsl(&token_stream.to_string()) { Ok((_, impl_block)) => impl_block, Err(e) => { let error = Diagnostic::error(e.to_string()); @@ -84,7 +84,7 @@ pub fn generate_event_spy_helpers(args_stream: TokenStream) -> ProcMacroResult { /// # Returns /// /// A `ProcTokenStream` containing the generated code for event spy helper functions -pub fn generate_code(impl_block: &parser::ImplBlock) -> ProcTokenStream { +fn generate_code(impl_block: &parser::ImplBlock) -> ProcTokenStream { let impl_name = format_ident!("{}", impl_block.name); let trait_name = format_ident!("{}Trait", impl_block.name); diff --git a/packages/presets/src/tests/test_vesting.cairo b/packages/presets/src/tests/test_vesting.cairo index f24b36e70..4a1e217ae 100644 --- a/packages/presets/src/tests/test_vesting.cairo +++ b/packages/presets/src/tests/test_vesting.cairo @@ -2,7 +2,7 @@ use core::num::traits::Zero; use openzeppelin_finance::vesting::VestingComponent::InternalImpl; use openzeppelin_test_common::erc20::deploy_erc20; use openzeppelin_test_common::ownable::OwnableSpyHelpers; -use openzeppelin_test_common::vesting::VestingSpyHelpers; +use openzeppelin_test_common::vesting::VestingSpyHelpersTrait; use openzeppelin_testing as utils; use openzeppelin_testing::constants::{OTHER, OWNER, ZERO}; use openzeppelin_testing::spy_events; diff --git a/packages/test_common/src/vesting.cairo b/packages/test_common/src/vesting.cairo index 355603e5e..eac1af8fd 100644 --- a/packages/test_common/src/vesting.cairo +++ b/packages/test_common/src/vesting.cairo @@ -1,12 +1,10 @@ -use openzeppelin_finance::vesting::VestingComponent; -use openzeppelin_finance::vesting::VestingComponent::AmountReleased; use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy}; use openzeppelin_utils::serde::SerializedAppend; use snforge_std::Event; use starknet::ContractAddress; #[generate_trait] -pub impl VestingSpyHelpersImpl of VestingSpyHelpers { +pub impl VestingSpyHelpersImpl of VestingSpyHelpersTrait { fn assert_only_event_amount_released( ref self: EventSpy, contract: ContractAddress, token: ContractAddress, amount: u256, ) { From 784173421133ac5471c27b91a52a4ea97f60b4fe Mon Sep 17 00:00:00 2001 From: Eric Nordelo Date: Tue, 5 Aug 2025 12:18:46 +0200 Subject: [PATCH 24/29] feat: use scarb 2.12 --- Scarb.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Scarb.toml b/Scarb.toml index 27f10e056..28615dd10 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -26,8 +26,8 @@ edition.workspace = true [workspace.package] version = "3.0.0-alpha.0" edition = "2024_07" -cairo-version = "2.12.0-rc.2" -scarb-version = "2.12.0-rc.2" +cairo-version = "2.12.0" +scarb-version = "2.12.0" authors = ["OpenZeppelin Community "] description = "OpenZeppelin Contracts written in Cairo for Starknet, a decentralized ZK Rollup" documentation = "https://docs.openzeppelin.com/contracts-cairo" @@ -42,8 +42,8 @@ keywords = [ ] [workspace.dependencies] -assert_macros = "2.12.0-rc.2" -starknet = "2.12.0-rc.2" +assert_macros = "2.12.0" +starknet = "2.12.0" snforge_std = "0.46.0" [dependencies] From a947c2cb0c5ac3c8c4c4ae8114e83ea123be61d1 Mon Sep 17 00:00:00 2001 From: Eric Nordelo Date: Tue, 5 Aug 2025 12:59:39 +0200 Subject: [PATCH 25/29] feat: format files --- .../access/src/tests/test_accesscontrol.cairo | 74 ++++++---------- ...st_accesscontrol_default_admin_rules.cairo | 37 +++----- .../src/tests/test_ownable_twostep.cairo | 2 +- .../src/governor/proposal_core.cairo | 1 - .../timestamp/test_governor_settings.cairo | 41 +++------ .../test_governor_timelock_execution.cairo | 16 ++-- .../test_governor_votes_quorum_fraction.cairo | 17 ++-- .../attribute/with_components/definition.rs | 2 +- .../src/tests/test_universal_deployer.cairo | 25 +++--- .../security/src/tests/test_pausable.cairo | 21 +---- packages/test_common/src/account.cairo | 18 +--- packages/test_common/src/erc1155.cairo | 54 +++++------- packages/test_common/src/erc20.cairo | 29 +++--- packages/test_common/src/erc721.cairo | 42 ++++----- packages/test_common/src/eth_account.cairo | 18 +--- packages/test_common/src/ownable.cairo | 16 ++-- packages/test_common/src/upgrades.cairo | 12 +-- packages/test_common/src/vesting.cairo | 18 ++-- packages/testing/CHANGELOG.md | 6 ++ packages/testing/src/events.cairo | 62 +++++++++++++ packages/testing/src/lib.cairo | 2 +- .../src/tests/erc1155/test_erc1155.cairo | 37 +++----- .../token/src/tests/erc20/test_erc20.cairo | 33 +++---- .../src/tests/erc4626/test_erc4626.cairo | 88 +++++++------------ .../token/src/tests/erc721/test_erc721.cairo | 33 +++---- 25 files changed, 288 insertions(+), 416 deletions(-) diff --git a/packages/access/src/tests/test_accesscontrol.cairo b/packages/access/src/tests/test_accesscontrol.cairo index 5986c74a2..aea9aee75 100644 --- a/packages/access/src/tests/test_accesscontrol.cairo +++ b/packages/access/src/tests/test_accesscontrol.cairo @@ -3,11 +3,8 @@ use openzeppelin_test_common::mocks::access::DualCaseAccessControlMock; use openzeppelin_testing::constants::{ ADMIN, AUTHORIZED, OTHER, OTHER_ADMIN, OTHER_ROLE, ROLE, TIMESTAMP, ZERO, }; -use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; -use openzeppelin_utils::serde::SerializedAppend; -use snforge_std::{ - Event, start_cheat_block_timestamp_global, start_cheat_caller_address, test_address, -}; +use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, ExpectedEvent, spy_events}; +use snforge_std::{start_cheat_block_timestamp_global, start_cheat_caller_address, test_address}; use starknet::ContractAddress; use crate::accesscontrol::AccessControlComponent::InternalImpl; use crate::accesscontrol::interface::{ @@ -701,15 +698,12 @@ pub impl AccessControlSpyHelpersImpl of AccessControlSpyHelpers { account: ContractAddress, sender: ContractAddress, ) { - let mut keys = array![]; - keys.append_serde(selector!("RoleRevoked")); - - let mut data = array![]; - data.append_serde(role); - data.append_serde(account); - data.append_serde(sender); + let expected = ExpectedEvent::new() + .key(selector!("RoleRevoked")) + .data(role) + .data(account) + .data(sender); - let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } @@ -720,15 +714,12 @@ pub impl AccessControlSpyHelpersImpl of AccessControlSpyHelpers { account: ContractAddress, sender: ContractAddress, ) { - let mut keys = array![]; - keys.append_serde(selector!("RoleRevoked")); - - let mut data = array![]; - data.append_serde(role); - data.append_serde(account); - data.append_serde(sender); + let expected = ExpectedEvent::new() + .key(selector!("RoleRevoked")) + .data(role) + .data(account) + .data(sender); - let expected = Event { keys, data }; self.assert_only_event(contract, expected); } @@ -739,15 +730,12 @@ pub impl AccessControlSpyHelpersImpl of AccessControlSpyHelpers { account: ContractAddress, sender: ContractAddress, ) { - let mut keys = array![]; - keys.append_serde(selector!("RoleGranted")); + let expected = ExpectedEvent::new() + .key(selector!("RoleGranted")) + .data(role) + .data(account) + .data(sender); - let mut data = array![]; - data.append_serde(role); - data.append_serde(account); - data.append_serde(sender); - - let expected = Event { keys, data }; self.assert_only_event(contract, expected); } @@ -759,16 +747,13 @@ pub impl AccessControlSpyHelpersImpl of AccessControlSpyHelpers { sender: ContractAddress, delay: u64, ) { - let mut keys = array![]; - keys.append_serde(selector!("RoleGrantedWithDelay")); - - let mut data = array![]; - data.append_serde(role); - data.append_serde(account); - data.append_serde(sender); - data.append_serde(delay); + let expected = ExpectedEvent::new() + .key(selector!("RoleGrantedWithDelay")) + .data(role) + .data(account) + .data(sender) + .data(delay); - let expected = Event { keys, data }; self.assert_only_event(contract, expected); } @@ -779,15 +764,12 @@ pub impl AccessControlSpyHelpersImpl of AccessControlSpyHelpers { previous_admin_role: felt252, new_admin_role: felt252, ) { - let mut keys = array![]; - keys.append_serde(selector!("RoleAdminChanged")); - - let mut data = array![]; - data.append_serde(role); - data.append_serde(previous_admin_role); - data.append_serde(new_admin_role); + let expected = ExpectedEvent::new() + .key(selector!("RoleAdminChanged")) + .data(role) + .data(previous_admin_role) + .data(new_admin_role); - let expected = Event { keys, data }; self.assert_only_event(from_address, expected); } } diff --git a/packages/access/src/tests/test_accesscontrol_default_admin_rules.cairo b/packages/access/src/tests/test_accesscontrol_default_admin_rules.cairo index 2a41c9334..c328202b5 100644 --- a/packages/access/src/tests/test_accesscontrol_default_admin_rules.cairo +++ b/packages/access/src/tests/test_accesscontrol_default_admin_rules.cairo @@ -4,11 +4,8 @@ use openzeppelin_test_common::mocks::access::DualCaseAccessControlDefaultAdminRu use openzeppelin_testing::constants::{ ADMIN, AUTHORIZED, OTHER, OTHER_ADMIN, OTHER_ROLE, ROLE, TIMESTAMP, ZERO, }; -use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; -use openzeppelin_utils::serde::SerializedAppend; -use snforge_std::{ - Event, start_cheat_block_timestamp_global, start_cheat_caller_address, test_address, -}; +use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, ExpectedEvent, spy_events}; +use snforge_std::{start_cheat_block_timestamp_global, start_cheat_caller_address, test_address}; use starknet::ContractAddress; use crate::accesscontrol::extensions::AccessControlDefaultAdminRulesComponent::InternalTrait; use crate::accesscontrol::extensions::interface::{ @@ -1169,48 +1166,38 @@ impl AccessControlDefaultAdminRulesSpyHelpersImpl of AccessControlDefaultAdminRu new_admin: ContractAddress, accept_schedule: u64, ) { - let mut keys = array![]; - keys.append_serde(selector!("DefaultAdminTransferScheduled")); - keys.append_serde(new_admin); - - let mut data = array![]; - data.append_serde(accept_schedule); + let expected = ExpectedEvent::new() + .key(selector!("DefaultAdminTransferScheduled")) + .key(new_admin) + .data(accept_schedule); - let expected = Event { keys, data }; self.assert_only_event(contract, expected); } fn assert_only_event_default_admin_transfer_canceled( ref self: EventSpy, contract: ContractAddress, ) { - let mut keys = array![]; - keys.append_serde(selector!("DefaultAdminTransferCanceled")); + let expected = ExpectedEvent::new().key(selector!("DefaultAdminTransferCanceled")); - let expected = Event { keys, data: array![] }; self.assert_only_event(contract, expected); } fn assert_only_event_default_admin_delay_change_scheduled( ref self: EventSpy, contract: ContractAddress, new_delay: u64, effect_schedule: u64, ) { - let mut keys = array![]; - keys.append_serde(selector!("DefaultAdminDelayChangeScheduled")); - - let mut data = array![]; - data.append_serde(new_delay); - data.append_serde(effect_schedule); + let expected = ExpectedEvent::new() + .key(selector!("DefaultAdminDelayChangeScheduled")) + .data(new_delay) + .data(effect_schedule); - let expected = Event { keys, data }; self.assert_only_event(contract, expected); } fn assert_only_event_default_admin_delay_change_canceled( ref self: EventSpy, contract: ContractAddress, ) { - let mut keys = array![]; - keys.append_serde(selector!("DefaultAdminDelayChangeCanceled")); + let expected = ExpectedEvent::new().key(selector!("DefaultAdminDelayChangeCanceled")); - let expected = Event { keys, data: array![] }; self.assert_only_event(contract, expected); } } diff --git a/packages/access/src/tests/test_ownable_twostep.cairo b/packages/access/src/tests/test_ownable_twostep.cairo index bbbc76c4b..56cc4d443 100644 --- a/packages/access/src/tests/test_ownable_twostep.cairo +++ b/packages/access/src/tests/test_ownable_twostep.cairo @@ -8,7 +8,7 @@ use snforge_std::{Event, start_cheat_caller_address, test_address}; use starknet::ContractAddress; use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; use crate::ownable::OwnableComponent; -use crate::ownable::OwnableComponent::{InternalTrait, OwnershipTransferStarted}; +use crate::ownable::OwnableComponent::InternalTrait; use crate::ownable::interface::{IOwnableTwoStep, IOwnableTwoStepCamelOnly}; // diff --git a/packages/governance/src/governor/proposal_core.cairo b/packages/governance/src/governor/proposal_core.cairo index 64f7b1cdf..baa932219 100644 --- a/packages/governance/src/governor/proposal_core.cairo +++ b/packages/governance/src/governor/proposal_core.cairo @@ -84,7 +84,6 @@ mod tests { use core::num::traits::Bounded; use openzeppelin_testing::constants::ALICE; use openzeppelin_testing::{FuzzableBool, FuzzableContractAddress}; - use starknet::ContractAddress; use super::{ProposalCore, ProposalCoreStorePacking as StorePacking}; #[test] diff --git a/packages/governance/src/tests/governor/timestamp/test_governor_settings.cairo b/packages/governance/src/tests/governor/timestamp/test_governor_settings.cairo index 2bc190874..871dfa0f7 100644 --- a/packages/governance/src/tests/governor/timestamp/test_governor_settings.cairo +++ b/packages/governance/src/tests/governor/timestamp/test_governor_settings.cairo @@ -1,8 +1,7 @@ use openzeppelin_test_common::mocks::governor::GovernorTimelockedMock::SNIP12MetadataImpl; use openzeppelin_testing::constants::OTHER; -use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; -use openzeppelin_utils::serde::SerializedAppend; -use snforge_std::{Event, start_cheat_caller_address, test_address}; +use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, ExpectedEvent, spy_events}; +use snforge_std::{start_cheat_caller_address, test_address}; use starknet::ContractAddress; use starknet::storage::StoragePointerWriteAccess; use crate::governor::DefaultConfig; @@ -395,14 +394,10 @@ pub(crate) impl GovernorSettingsSpyHelpersImpl of GovernorSettingsSpyHelpers { fn assert_event_voting_delay_updated( ref self: EventSpy, contract: ContractAddress, old_voting_delay: u64, new_voting_delay: u64, ) { - let mut keys = array![]; - keys.append_serde(selector!("VotingDelayUpdated")); - - let mut data = array![]; - data.append_serde(old_voting_delay); - data.append_serde(new_voting_delay); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new() + .key(selector!("VotingDelayUpdated")) + .data(old_voting_delay) + .data(new_voting_delay); self.assert_emitted_single(contract, expected); } @@ -419,14 +414,10 @@ pub(crate) impl GovernorSettingsSpyHelpersImpl of GovernorSettingsSpyHelpers { old_voting_period: u64, new_voting_period: u64, ) { - let mut keys = array![]; - keys.append_serde(selector!("VotingPeriodUpdated")); - - let mut data = array![]; - data.append_serde(old_voting_period); - data.append_serde(new_voting_period); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new() + .key(selector!("VotingPeriodUpdated")) + .data(old_voting_period) + .data(new_voting_period); self.assert_emitted_single(contract, expected); } @@ -446,14 +437,10 @@ pub(crate) impl GovernorSettingsSpyHelpersImpl of GovernorSettingsSpyHelpers { old_proposal_threshold: u256, new_proposal_threshold: u256, ) { - let mut keys = array![]; - keys.append_serde(selector!("ProposalThresholdUpdated")); - - let mut data = array![]; - data.append_serde(old_proposal_threshold); - data.append_serde(new_proposal_threshold); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new() + .key(selector!("ProposalThresholdUpdated")) + .data(old_proposal_threshold) + .data(new_proposal_threshold); self.assert_emitted_single(contract, expected); } diff --git a/packages/governance/src/tests/governor/timestamp/test_governor_timelock_execution.cairo b/packages/governance/src/tests/governor/timestamp/test_governor_timelock_execution.cairo index aef47a203..0c855fdab 100644 --- a/packages/governance/src/tests/governor/timestamp/test_governor_timelock_execution.cairo +++ b/packages/governance/src/tests/governor/timestamp/test_governor_timelock_execution.cairo @@ -8,11 +8,11 @@ use openzeppelin_test_common::mocks::timelock::{ }; use openzeppelin_testing as utils; use openzeppelin_testing::constants::{OTHER, TIMELOCK, VOTES_TOKEN}; -use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; +use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, ExpectedEvent, spy_events}; use openzeppelin_utils::bytearray::ByteArrayExtTrait; use openzeppelin_utils::serde::SerializedAppend; use snforge_std::{ - Event, start_cheat_block_timestamp_global, start_cheat_caller_address, start_mock_call, store, + start_cheat_block_timestamp_global, start_cheat_caller_address, start_mock_call, store, }; use starknet::ContractAddress; use starknet::account::Call; @@ -828,14 +828,10 @@ pub(crate) impl GovernorTimelockExecutionSpyHelpersImpl of GovernorTimelockExecu old_timelock: ContractAddress, new_timelock: ContractAddress, ) { - let mut keys = array![]; - keys.append_serde(selector!("TimelockUpdated")); - - let mut data = array![]; - data.append_serde(old_timelock); - data.append_serde(new_timelock); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new() + .key(selector!("TimelockUpdated")) + .data(old_timelock) + .data(new_timelock); self.assert_emitted_single(contract, expected); } diff --git a/packages/governance/src/tests/governor/timestamp/test_governor_votes_quorum_fraction.cairo b/packages/governance/src/tests/governor/timestamp/test_governor_votes_quorum_fraction.cairo index 9c9718edf..215b09db1 100644 --- a/packages/governance/src/tests/governor/timestamp/test_governor_votes_quorum_fraction.cairo +++ b/packages/governance/src/tests/governor/timestamp/test_governor_votes_quorum_fraction.cairo @@ -1,9 +1,8 @@ use openzeppelin_test_common::mocks::governor::GovernorQuorumFractionMock; use openzeppelin_test_common::mocks::governor::GovernorQuorumFractionMock::SNIP12MetadataImpl; use openzeppelin_testing::constants::{OTHER, VOTES_TOKEN, ZERO}; -use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; -use openzeppelin_utils::serde::SerializedAppend; -use snforge_std::{Event, start_cheat_block_timestamp_global, start_mock_call, test_address}; +use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, ExpectedEvent, spy_events}; +use snforge_std::{start_cheat_block_timestamp_global, start_mock_call, test_address}; use starknet::ContractAddress; use crate::governor::GovernorComponent::InternalImpl; use crate::governor::extensions::GovernorVotesQuorumFractionComponent::{ @@ -262,14 +261,10 @@ pub(crate) impl GovernorSettingsSpyHelpersImpl of GovernorSettingsSpyHelpers { old_quorum_numerator: u256, new_quorum_numerator: u256, ) { - let mut keys = array![]; - keys.append_serde(selector!("QuorumNumeratorUpdated")); - - let mut data = array![]; - data.append_serde(old_quorum_numerator); - data.append_serde(new_quorum_numerator); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new() + .key(selector!("QuorumNumeratorUpdated")) + .data(old_quorum_numerator) + .data(new_quorum_numerator); self.assert_emitted_single(contract, expected); } diff --git a/packages/macros/src/attribute/with_components/definition.rs b/packages/macros/src/attribute/with_components/definition.rs index f3947f4eb..7f91f3337 100644 --- a/packages/macros/src/attribute/with_components/definition.rs +++ b/packages/macros/src/attribute/with_components/definition.rs @@ -3,7 +3,7 @@ use cairo_lang_macro::{attribute_macro, Diagnostic, ProcMacroResult, TokenStream use cairo_lang_parser::utils::SimpleParserDatabase; use regex::Regex; -use super::{components::AllowedComponents, parser::WithComponentsParser}; +use crate::with_components::{components::AllowedComponents, parser::WithComponentsParser}; /// Inserts multiple component dependencies into a modules codebase. #[attribute_macro] diff --git a/packages/presets/src/tests/test_universal_deployer.cairo b/packages/presets/src/tests/test_universal_deployer.cairo index 11a9b3ecd..45b9b0b6b 100644 --- a/packages/presets/src/tests/test_universal_deployer.cairo +++ b/packages/presets/src/tests/test_universal_deployer.cairo @@ -1,13 +1,13 @@ use openzeppelin_testing as utils; use openzeppelin_testing::constants::{CALLER, NAME, RECIPIENT, SALT, SUPPLY, SYMBOL}; -use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; +use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, ExpectedEvent, spy_events}; use openzeppelin_token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; use openzeppelin_utils::deployments::{DeployerInfo, calculate_contract_address_from_udc}; use openzeppelin_utils::interfaces::{ UniversalDeployerABIDispatcher, UniversalDeployerABIDispatcherTrait, }; use openzeppelin_utils::serde::SerializedAppend; -use snforge_std::{Event, start_cheat_caller_address}; +use snforge_std::start_cheat_caller_address; use starknet::{ClassHash, ContractAddress}; fn ERC20_CLASS_HASH() -> ClassHash { @@ -155,18 +155,15 @@ impl UniversalDeployerHelpersImpl of UniversalDeployerSpyHelpers { calldata: Span, salt: felt252, ) { - let mut keys = array![]; - keys.append_serde(selector!("ContractDeployed")); - - let mut data = array![]; - data.append_serde(address); - data.append_serde(deployer); - data.append_serde(not_from_zero); - data.append_serde(class_hash); - data.append_serde(calldata); - data.append_serde(salt); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new() + .key(selector!("ContractDeployed")) + .data(address) + .data(deployer) + .data(not_from_zero) + .data(class_hash) + .data(calldata) + .data(salt); + self.assert_only_event(contract, expected); } } diff --git a/packages/security/src/tests/test_pausable.cairo b/packages/security/src/tests/test_pausable.cairo index d07a772b3..76ad2ba2d 100644 --- a/packages/security/src/tests/test_pausable.cairo +++ b/packages/security/src/tests/test_pausable.cairo @@ -1,8 +1,7 @@ use openzeppelin_test_common::mocks::security::PausableMock; use openzeppelin_testing::constants::CALLER; -use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; -use openzeppelin_utils::serde::SerializedAppend; -use snforge_std::{Event, start_cheat_caller_address, test_address}; +use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, ExpectedEvent, spy_events}; +use snforge_std::{start_cheat_caller_address, test_address}; use starknet::ContractAddress; use crate::PausableComponent; use crate::PausableComponent::{InternalImpl, PausableImpl}; @@ -126,13 +125,7 @@ impl PausableSpyHelpersImpl of PausableSpyHelpers { fn assert_event_paused( ref self: EventSpy, contract: ContractAddress, account: ContractAddress, ) { - let mut keys = array![]; - keys.append_serde(selector!("Paused")); - - let mut data = array![]; - data.append_serde(account); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new().key(selector!("Paused")).data(account); self.assert_emitted_single(contract, expected); } @@ -146,13 +139,7 @@ impl PausableSpyHelpersImpl of PausableSpyHelpers { fn assert_event_unpaused( ref self: EventSpy, contract: ContractAddress, account: ContractAddress, ) { - let mut keys = array![]; - keys.append_serde(selector!("Unpaused")); - - let mut data = array![]; - data.append_serde(account); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new().key(selector!("Unpaused")).data(account); self.assert_emitted_single(contract, expected); } diff --git a/packages/test_common/src/account.cairo b/packages/test_common/src/account.cairo index 12b88a86a..09d5d6785 100644 --- a/packages/test_common/src/account.cairo +++ b/packages/test_common/src/account.cairo @@ -1,12 +1,8 @@ use core::hash::{HashStateExTrait, HashStateTrait}; use core::poseidon::PoseidonTrait; -use openzeppelin_account::AccountComponent; -use openzeppelin_account::AccountComponent::{OwnerAdded, OwnerRemoved}; use openzeppelin_testing::constants::TRANSACTION_HASH; use openzeppelin_testing::signing::StarkKeyPair; -use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy}; -use openzeppelin_utils::serde::SerializedAppend; -use snforge_std::Event; +use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, ExpectedEvent}; use snforge_std::signature::stark_curve::StarkCurveSignerImpl; use starknet::ContractAddress; @@ -41,22 +37,14 @@ pub impl AccountSpyHelpersImpl of AccountSpyHelpers { fn assert_event_owner_removed( ref self: EventSpy, contract: ContractAddress, removed_owner_guid: felt252, ) { - let mut keys = array![]; - keys.append_serde(selector!("OwnerRemoved")); - keys.append_serde(removed_owner_guid); - - let expected = Event { keys, data: array![] }; + let expected = ExpectedEvent::new().key(selector!("OwnerRemoved")).key(removed_owner_guid); self.assert_emitted_single(contract, expected); } fn assert_event_owner_added( ref self: EventSpy, contract: ContractAddress, new_owner_guid: felt252, ) { - let mut keys = array![]; - keys.append_serde(selector!("OwnerAdded")); - keys.append_serde(new_owner_guid); - - let expected = Event { keys, data: array![] }; + let expected = ExpectedEvent::new().key(selector!("OwnerAdded")).key(new_owner_guid); self.assert_emitted_single(contract, expected); } diff --git a/packages/test_common/src/erc1155.cairo b/packages/test_common/src/erc1155.cairo index 8f66df42e..ca6673a1a 100644 --- a/packages/test_common/src/erc1155.cairo +++ b/packages/test_common/src/erc1155.cairo @@ -1,8 +1,6 @@ use openzeppelin_testing as utils; use openzeppelin_testing::constants::{PUBKEY, TOKEN_ID, TOKEN_ID_2, TOKEN_VALUE, TOKEN_VALUE_2}; -use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy}; -use openzeppelin_utils::serde::SerializedAppend; -use snforge_std::Event; +use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, ExpectedEvent}; use starknet::ContractAddress; pub fn setup_receiver() -> ContractAddress { @@ -44,15 +42,11 @@ pub impl ERC1155SpyHelpersImpl of ERC1155SpyHelpers { operator: ContractAddress, approved: bool, ) { - let mut keys = array![]; - keys.append_serde(selector!("ApprovalForAll")); - keys.append_serde(owner); - keys.append_serde(operator); - - let mut data = array![]; - data.append_serde(approved); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new() + .key(selector!("ApprovalForAll")) + .key(owner) + .key(operator) + .data(approved); self.assert_emitted_single(contract, expected); } @@ -76,17 +70,13 @@ pub impl ERC1155SpyHelpersImpl of ERC1155SpyHelpers { token_id: u256, value: u256, ) { - let mut keys = array![]; - keys.append_serde(selector!("TransferSingle")); - keys.append_serde(operator); - keys.append_serde(from); - keys.append_serde(to); - - let mut data = array![]; - data.append_serde(token_id); - data.append_serde(value); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new() + .key(selector!("TransferSingle")) + .key(operator) + .key(from) + .key(to) + .data(token_id) + .data(value); self.assert_emitted_single(contract, expected); } @@ -112,17 +102,13 @@ pub impl ERC1155SpyHelpersImpl of ERC1155SpyHelpers { token_ids: Span, values: Span, ) { - let mut keys = array![]; - keys.append_serde(selector!("TransferBatch")); - keys.append_serde(operator); - keys.append_serde(from); - keys.append_serde(to); - - let mut data = array![]; - data.append_serde(token_ids); - data.append_serde(values); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new() + .key(selector!("TransferBatch")) + .key(operator) + .key(from) + .key(to) + .data(token_ids) + .data(values); self.assert_emitted_single(contract, expected); } diff --git a/packages/test_common/src/erc20.cairo b/packages/test_common/src/erc20.cairo index aa0942995..e3746737f 100644 --- a/packages/test_common/src/erc20.cairo +++ b/packages/test_common/src/erc20.cairo @@ -1,9 +1,8 @@ use openzeppelin_testing as utils; use openzeppelin_testing::constants::{NAME, SYMBOL}; -use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy}; +use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, ExpectedEvent}; use openzeppelin_token::erc20::interface::IERC20Dispatcher; use openzeppelin_utils::serde::SerializedAppend; -use snforge_std::Event; use starknet::ContractAddress; pub fn deploy_erc20(recipient: ContractAddress, initial_supply: u256) -> IERC20Dispatcher { @@ -26,15 +25,12 @@ pub impl ERC20SpyHelpersImpl of ERC20SpyHelpers { spender: ContractAddress, value: u256, ) { - let mut keys = array![]; - keys.append_serde(selector!("Approval")); - keys.append_serde(owner); - keys.append_serde(spender); + let expected = ExpectedEvent::new() + .key(selector!("Approval")) + .key(owner) + .key(spender) + .data(value); - let mut data = array![]; - data.append_serde(value); - - let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } @@ -56,15 +52,12 @@ pub impl ERC20SpyHelpersImpl of ERC20SpyHelpers { to: ContractAddress, value: u256, ) { - let mut keys = array![]; - keys.append_serde(selector!("Transfer")); - keys.append_serde(from); - keys.append_serde(to); - - let mut data = array![]; - data.append_serde(value); + let expected = ExpectedEvent::new() + .key(selector!("Transfer")) + .key(from) + .key(to) + .data(value); - let expected = Event { keys, data }; self.assert_emitted_single(contract, expected); } diff --git a/packages/test_common/src/erc721.cairo b/packages/test_common/src/erc721.cairo index bca70feba..61fc52d96 100644 --- a/packages/test_common/src/erc721.cairo +++ b/packages/test_common/src/erc721.cairo @@ -1,6 +1,4 @@ -use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy}; -use openzeppelin_utils::serde::SerializedAppend; -use snforge_std::Event; +use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, ExpectedEvent}; use starknet::ContractAddress; #[generate_trait] @@ -12,15 +10,11 @@ pub impl ERC721SpyHelpersImpl of ERC721SpyHelpers { operator: ContractAddress, approved: bool, ) { - let mut keys = array![]; - keys.append_serde(selector!("ApprovalForAll")); - keys.append_serde(owner); - keys.append_serde(operator); - - let mut data = array![]; - data.append_serde(approved); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new() + .key(selector!("ApprovalForAll")) + .key(owner) + .key(operator) + .data(approved); self.assert_emitted_single(contract, expected); } @@ -42,13 +36,11 @@ pub impl ERC721SpyHelpersImpl of ERC721SpyHelpers { approved: ContractAddress, token_id: u256, ) { - let mut keys = array![]; - keys.append_serde(selector!("Approval")); - keys.append_serde(owner); - keys.append_serde(approved); - keys.append_serde(token_id); - - let expected = Event { keys, data: array![] }; + let expected = ExpectedEvent::new() + .key(selector!("Approval")) + .key(owner) + .key(approved) + .key(token_id); self.assert_emitted_single(contract, expected); } @@ -70,13 +62,11 @@ pub impl ERC721SpyHelpersImpl of ERC721SpyHelpers { to: ContractAddress, token_id: u256, ) { - let mut keys = array![]; - keys.append_serde(selector!("Transfer")); - keys.append_serde(from); - keys.append_serde(to); - keys.append_serde(token_id); - - let expected = Event { keys, data: array![] }; + let expected = ExpectedEvent::new() + .key(selector!("Transfer")) + .key(from) + .key(to) + .key(token_id); self.assert_emitted_single(contract, expected); } diff --git a/packages/test_common/src/eth_account.cairo b/packages/test_common/src/eth_account.cairo index ecb8ff49b..64dd4ca8e 100644 --- a/packages/test_common/src/eth_account.cairo +++ b/packages/test_common/src/eth_account.cairo @@ -1,14 +1,10 @@ use core::hash::{HashStateExTrait, HashStateTrait}; use core::poseidon::{PoseidonTrait, poseidon_hash_span}; -use openzeppelin_account::EthAccountComponent; -use openzeppelin_account::EthAccountComponent::{OwnerAdded, OwnerRemoved}; use openzeppelin_account::interface::EthPublicKey; use openzeppelin_account::utils::signature::Secp256Signature; use openzeppelin_testing::constants::TRANSACTION_HASH; use openzeppelin_testing::signing::{Secp256k1KeyPair, Secp256k1SerializedSigning}; -use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy}; -use openzeppelin_utils::serde::SerializedAppend; -use snforge_std::Event; +use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, ExpectedEvent}; use snforge_std::signature::secp256k1_curve::Secp256k1CurveSignerImpl; use starknet::secp256_trait::Secp256PointTrait; use starknet::{ContractAddress, SyscallResultTrait}; @@ -52,11 +48,7 @@ pub impl EthAccountSpyHelpersImpl of EthAccountSpyHelpers { ref self: EventSpy, contract: ContractAddress, public_key: EthPublicKey, ) { let removed_owner_guid = get_guid_from_public_key(public_key); - let mut keys = array![]; - keys.append_serde(selector!("OwnerRemoved")); - keys.append_serde(removed_owner_guid); - - let expected = Event { keys, data: array![] }; + let expected = ExpectedEvent::new().key(selector!("OwnerRemoved")).key(removed_owner_guid); self.assert_emitted_single(contract, expected); } @@ -64,11 +56,7 @@ pub impl EthAccountSpyHelpersImpl of EthAccountSpyHelpers { ref self: EventSpy, contract: ContractAddress, public_key: EthPublicKey, ) { let new_owner_guid = get_guid_from_public_key(public_key); - let mut keys = array![]; - keys.append_serde(selector!("OwnerAdded")); - keys.append_serde(new_owner_guid); - - let expected = Event { keys, data: array![] }; + let expected = ExpectedEvent::new().key(selector!("OwnerAdded")).key(new_owner_guid); self.assert_emitted_single(contract, expected); } diff --git a/packages/test_common/src/ownable.cairo b/packages/test_common/src/ownable.cairo index a3df83856..e9ef3f70b 100644 --- a/packages/test_common/src/ownable.cairo +++ b/packages/test_common/src/ownable.cairo @@ -1,8 +1,4 @@ -use openzeppelin_access::ownable::OwnableComponent; -use openzeppelin_access::ownable::OwnableComponent::OwnershipTransferred; -use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy}; -use openzeppelin_utils::serde::SerializedAppend; -use snforge_std::Event; +use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, ExpectedEvent}; use starknet::ContractAddress; #[generate_trait] @@ -23,12 +19,10 @@ pub impl OwnableSpyHelpersImpl of OwnableSpyHelpers { previous_owner: ContractAddress, new_owner: ContractAddress, ) { - let mut keys = array![]; - keys.append_serde(selector!("OwnershipTransferred")); - keys.append_serde(previous_owner); - keys.append_serde(new_owner); - - let expected = Event { keys, data: array![] }; + let expected = ExpectedEvent::new() + .key(selector!("OwnershipTransferred")) + .key(previous_owner) + .key(new_owner); self.assert_emitted_single(contract, expected); } } diff --git a/packages/test_common/src/upgrades.cairo b/packages/test_common/src/upgrades.cairo index 65cfd405f..50376ae4a 100644 --- a/packages/test_common/src/upgrades.cairo +++ b/packages/test_common/src/upgrades.cairo @@ -1,18 +1,10 @@ -use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy}; -use openzeppelin_utils::serde::SerializedAppend; -use snforge_std::Event; +use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, ExpectedEvent}; use starknet::{ClassHash, ContractAddress}; #[generate_trait] pub impl UpgradeableSpyHelpersImpl of UpgradeableSpyHelpers { fn assert_event_upgraded(ref self: EventSpy, contract: ContractAddress, class_hash: ClassHash) { - let mut keys = array![]; - keys.append_serde(selector!("Upgraded")); - - let mut data = array![]; - data.append_serde(class_hash); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new().key(selector!("Upgraded")).data(class_hash); self.assert_emitted_single(contract, expected); } diff --git a/packages/test_common/src/vesting.cairo b/packages/test_common/src/vesting.cairo index 355603e5e..121eeacfe 100644 --- a/packages/test_common/src/vesting.cairo +++ b/packages/test_common/src/vesting.cairo @@ -1,8 +1,4 @@ -use openzeppelin_finance::vesting::VestingComponent; -use openzeppelin_finance::vesting::VestingComponent::AmountReleased; -use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy}; -use openzeppelin_utils::serde::SerializedAppend; -use snforge_std::Event; +use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, ExpectedEvent}; use starknet::ContractAddress; #[generate_trait] @@ -10,14 +6,10 @@ pub impl VestingSpyHelpersImpl of VestingSpyHelpers { fn assert_only_event_amount_released( ref self: EventSpy, contract: ContractAddress, token: ContractAddress, amount: u256, ) { - let mut keys = array![]; - keys.append_serde(selector!("AmountReleased")); - keys.append_serde(token); - - let mut data = array![]; - data.append_serde(amount); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new() + .key(selector!("AmountReleased")) + .key(token) + .data(amount); self.assert_only_event(contract, expected); } } diff --git a/packages/testing/CHANGELOG.md b/packages/testing/CHANGELOG.md index 4ea0a19df..362a88362 100644 --- a/packages/testing/CHANGELOG.md +++ b/packages/testing/CHANGELOG.md @@ -7,6 +7,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Added + +- The `ExpectedEvent` trait and impl (#1472) + ## 4.4.0 (2025-07-31) ### Changed diff --git a/packages/testing/src/events.cairo b/packages/testing/src/events.cairo index b871a1a46..ebfd6cb33 100644 --- a/packages/testing/src/events.cairo +++ b/packages/testing/src/events.cairo @@ -90,6 +90,68 @@ pub impl EventSpyQueueImpl of EventSpyExt { } } +/// The `ExpectedEventImpl` trait provides a convenient API for constructing +/// expected events in tests. +/// +/// This implementation is generated by the `#[generate_trait]` macro and offers +/// three methods: +/// +/// * `new()`: creates a fresh `Event` with empty `keys` and `data` fields. +/// * `key(value)`: serializes the given value and appends it to the `keys` field. +/// * `data(value)`: serializes the given value and appends it to the `data` field. +/// +/// By using these methods, you can construct events in a fluent style without +/// manually managing the `keys` and `data` arrays. For example, instead of: +/// +/// ```cairo +/// let mut keys = array![]; +/// keys.append_serde(selector!("Transfer")); // event selector +/// keys.append_serde(from); // key #1 +/// keys.append_serde(to); // key #2 +/// +/// let mut data = array![]; +/// data.append_serde(value); // non-key data +/// let expected = Event { keys, data }; +/// +/// spy.assert_emitted( +/// @array![(contract_address, expected)], +/// ); +/// ``` +/// +/// you can now write: +/// +/// ```cairo +/// let expected = ExpectedEvent::new() +/// .key(selector!("Transfer")) +/// .key(from) +/// .key(to) +/// .data(value); +/// spy.assert_emitted( +/// @array![(contract_address, expected)] +/// ); +/// ``` +#[generate_trait] +pub impl ExpectedEvent of ExpectedEventTrait { + /// Creates a new `Event` with empty `keys` and `data` fields. + fn new() -> Event { + Event { keys: array![], data: array![] } + } + + /// Serializes the given value and appends it to the `keys` field. + fn key, +Drop>(self: Event, value: T) -> Event { + let Event { mut keys, data } = self; + value.serialize(ref keys); + Event { keys, data } + } + + /// Serializes the given value and appends it to the `data` field. + fn data, +Drop>(self: Event, value: T) -> Event { + let Event { keys, mut data } = self; + value.serialize(ref data); + Event { keys, data } + } +} + #[generate_trait] pub impl EventSpyQueueDebugImpl of EventSpyQueueDebug { /// Prints out all events remaining on the queue. diff --git a/packages/testing/src/lib.cairo b/packages/testing/src/lib.cairo index 74137a380..557c3b3cc 100644 --- a/packages/testing/src/lib.cairo +++ b/packages/testing/src/lib.cairo @@ -13,4 +13,4 @@ pub use deployment::{ declare_and_deploy, declare_and_deploy_at, declare_class, deploy, deploy_another_at, deploy_at, }; -pub use events::{EventSpyExt, EventSpyQueue, spy_events}; +pub use events::{EventSpyExt, EventSpyQueue, ExpectedEvent, spy_events}; diff --git a/packages/token/src/tests/erc1155/test_erc1155.cairo b/packages/token/src/tests/erc1155/test_erc1155.cairo index 564aa67bb..4f04297e5 100644 --- a/packages/token/src/tests/erc1155/test_erc1155.cairo +++ b/packages/token/src/tests/erc1155/test_erc1155.cairo @@ -9,9 +9,8 @@ use openzeppelin_testing::constants::{ EMPTY_DATA, OPERATOR, OTHER, OWNER, RECIPIENT, TOKEN_ID, TOKEN_ID_2, TOKEN_VALUE, TOKEN_VALUE_2, ZERO, }; -use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; -use openzeppelin_utils::serde::SerializedAppend; -use snforge_std::{Event, start_cheat_caller_address, test_address}; +use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, ExpectedEvent, spy_events}; +use snforge_std::{start_cheat_caller_address, test_address}; use starknet::ContractAddress; use starknet::storage::StoragePointerReadAccess; use crate::erc1155; @@ -1393,16 +1392,12 @@ impl ERC1155HooksSpyHelpersImpl of ERC1155HooksSpyHelpers { token_ids: Span, values: Span, ) { - let mut keys = array![]; - keys.append_serde(selector!("BeforeUpdate")); - - let mut data = array![]; - data.append_serde(from); - data.append_serde(to); - data.append_serde(token_ids); - data.append_serde(values); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new() + .key(selector!("BeforeUpdate")) + .data(from) + .data(to) + .data(token_ids) + .data(values); self.assert_emitted_single(contract, expected); } @@ -1414,16 +1409,12 @@ impl ERC1155HooksSpyHelpersImpl of ERC1155HooksSpyHelpers { token_ids: Span, values: Span, ) { - let mut keys = array![]; - keys.append_serde(selector!("AfterUpdate")); - - let mut data = array![]; - data.append_serde(from); - data.append_serde(to); - data.append_serde(token_ids); - data.append_serde(values); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new() + .key(selector!("AfterUpdate")) + .data(from) + .data(to) + .data(token_ids) + .data(values); self.assert_emitted_single(contract, expected); } } diff --git a/packages/token/src/tests/erc20/test_erc20.cairo b/packages/token/src/tests/erc20/test_erc20.cairo index d020692c1..31500a46e 100644 --- a/packages/token/src/tests/erc20/test_erc20.cairo +++ b/packages/token/src/tests/erc20/test_erc20.cairo @@ -2,9 +2,8 @@ use core::num::traits::Bounded; use openzeppelin_test_common::erc20::ERC20SpyHelpers; use openzeppelin_test_common::mocks::erc20::{DualCaseERC20Mock, SnakeERC20MockWithHooks}; use openzeppelin_testing::constants::{NAME, OWNER, RECIPIENT, SPENDER, SUPPLY, SYMBOL, VALUE, ZERO}; -use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; -use openzeppelin_utils::serde::SerializedAppend; -use snforge_std::{Event, start_cheat_caller_address, test_address}; +use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, ExpectedEvent, spy_events}; +use snforge_std::{start_cheat_caller_address, test_address}; use starknet::ContractAddress; use crate::erc20::ERC20Component; use crate::erc20::ERC20Component::{ERC20CamelOnlyImpl, ERC20Impl, ERC20MetadataImpl, InternalImpl}; @@ -669,15 +668,11 @@ impl ERC20HooksSpyHelpersImpl of ERC20HooksSpyHelpers { recipient: ContractAddress, amount: u256, ) { - let mut keys = array![]; - keys.append_serde(selector!("BeforeUpdate")); - - let mut data = array![]; - data.append_serde(from); - data.append_serde(recipient); - data.append_serde(amount); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new() + .key(selector!("BeforeUpdate")) + .data(from) + .data(recipient) + .data(amount); self.assert_emitted_single(contract, expected); } @@ -688,15 +683,11 @@ impl ERC20HooksSpyHelpersImpl of ERC20HooksSpyHelpers { recipient: ContractAddress, amount: u256, ) { - let mut keys = array![]; - keys.append_serde(selector!("AfterUpdate")); - - let mut data = array![]; - data.append_serde(from); - data.append_serde(recipient); - data.append_serde(amount); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new() + .key(selector!("AfterUpdate")) + .data(from) + .data(recipient) + .data(amount); self.assert_emitted_single(contract, expected); } } diff --git a/packages/token/src/tests/erc4626/test_erc4626.cairo b/packages/token/src/tests/erc4626/test_erc4626.cairo index 9749b3948..3f3987532 100644 --- a/packages/token/src/tests/erc4626/test_erc4626.cairo +++ b/packages/token/src/tests/erc4626/test_erc4626.cairo @@ -6,9 +6,11 @@ use openzeppelin_test_common::mocks::erc20::{ use openzeppelin_test_common::mocks::erc4626::{ERC4626LimitsMock, ERC4626Mock}; use openzeppelin_testing as utils; use openzeppelin_testing::constants::{ALICE, BOB, NAME, OTHER, RECIPIENT, SPENDER, SYMBOL, ZERO}; -use openzeppelin_testing::{AsAddressTrait, EventSpyExt, EventSpyQueue as EventSpy, spy_events}; +use openzeppelin_testing::{ + AsAddressTrait, EventSpyExt, EventSpyQueue as EventSpy, ExpectedEvent, spy_events, +}; use openzeppelin_utils::serde::SerializedAppend; -use snforge_std::{CheatSpan, Event, cheat_caller_address}; +use snforge_std::{CheatSpan, cheat_caller_address}; use starknet::ContractAddress; use crate::erc20::ERC20Component::InternalImpl as ERC20InternalImpl; use crate::erc20::extensions::erc4626::ERC4626Component::{ @@ -1721,16 +1723,12 @@ pub impl ERC4626SpyHelpersImpl of ERC4626SpyHelpers { assets: u256, shares: u256, ) { - let mut keys = array![]; - keys.append_serde(selector!("Deposit")); - keys.append_serde(sender); - keys.append_serde(owner); - - let mut data = array![]; - data.append_serde(assets); - data.append_serde(shares); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new() + .key(selector!("Deposit")) + .key(sender) + .key(owner) + .data(assets) + .data(shares); self.assert_emitted_single(contract, expected); } @@ -1755,17 +1753,13 @@ pub impl ERC4626SpyHelpersImpl of ERC4626SpyHelpers { assets: u256, shares: u256, ) { - let mut keys = array![]; - keys.append_serde(selector!("Withdraw")); - keys.append_serde(sender); - keys.append_serde(receiver); - keys.append_serde(owner); - - let mut data = array![]; - data.append_serde(assets); - data.append_serde(shares); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new() + .key(selector!("Withdraw")) + .key(sender) + .key(receiver) + .key(owner) + .data(assets) + .data(shares); self.assert_emitted_single(contract, expected); } @@ -1788,56 +1782,40 @@ impl ERC4626HooksSpyHelpersImpl of ERC4626HooksSpyHelpers { fn assert_event_before_deposit( ref self: EventSpy, contract: ContractAddress, assets: u256, shares: u256, ) { - let mut keys = array![]; - keys.append_serde(selector!("BeforeDeposit")); - - let mut data = array![]; - data.append_serde(assets); - data.append_serde(shares); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new() + .key(selector!("BeforeDeposit")) + .data(assets) + .data(shares); self.assert_emitted_single(contract, expected); } fn assert_event_after_deposit( ref self: EventSpy, contract: ContractAddress, assets: u256, shares: u256, ) { - let mut keys = array![]; - keys.append_serde(selector!("AfterDeposit")); - - let mut data = array![]; - data.append_serde(assets); - data.append_serde(shares); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new() + .key(selector!("AfterDeposit")) + .data(assets) + .data(shares); self.assert_emitted_single(contract, expected); } fn assert_event_before_withdraw( ref self: EventSpy, contract: ContractAddress, assets: u256, shares: u256, ) { - let mut keys = array![]; - keys.append_serde(selector!("BeforeWithdraw")); - - let mut data = array![]; - data.append_serde(assets); - data.append_serde(shares); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new() + .key(selector!("BeforeWithdraw")) + .data(assets) + .data(shares); self.assert_emitted_single(contract, expected); } fn assert_event_after_withdraw( ref self: EventSpy, contract: ContractAddress, assets: u256, shares: u256, ) { - let mut keys = array![]; - keys.append_serde(selector!("AfterWithdraw")); - - let mut data = array![]; - data.append_serde(assets); - data.append_serde(shares); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new() + .key(selector!("AfterWithdraw")) + .data(assets) + .data(shares); self.assert_emitted_single(contract, expected); } } diff --git a/packages/token/src/tests/erc721/test_erc721.cairo b/packages/token/src/tests/erc721/test_erc721.cairo index 819c551d0..2b9c61b20 100644 --- a/packages/token/src/tests/erc721/test_erc721.cairo +++ b/packages/token/src/tests/erc721/test_erc721.cairo @@ -7,9 +7,8 @@ use openzeppelin_testing::constants::{ BASE_URI, BASE_URI_2, CALLER, DATA, NAME, OPERATOR, OTHER, OWNER, PUBKEY, RECIPIENT, SPENDER, SYMBOL, TOKEN_ID, TOKEN_ID_2, ZERO, }; -use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, spy_events}; -use openzeppelin_utils::serde::SerializedAppend; -use snforge_std::{Event, start_cheat_caller_address, test_address}; +use openzeppelin_testing::{EventSpyExt, EventSpyQueue as EventSpy, ExpectedEvent, spy_events}; +use snforge_std::{start_cheat_caller_address, test_address}; use starknet::ContractAddress; use starknet::storage::StorageMapReadAccess; use crate::erc721; @@ -1490,15 +1489,11 @@ impl ERC721HooksSpyHelpersImpl of ERC721HooksSpyHelpers { token_id: u256, auth: ContractAddress, ) { - let mut keys = array![]; - keys.append_serde(selector!("BeforeUpdate")); - - let mut data = array![]; - data.append_serde(to); - data.append_serde(token_id); - data.append_serde(auth); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new() + .key(selector!("BeforeUpdate")) + .data(to) + .data(token_id) + .data(auth); self.assert_emitted_single(contract, expected); } @@ -1509,15 +1504,11 @@ impl ERC721HooksSpyHelpersImpl of ERC721HooksSpyHelpers { token_id: u256, auth: ContractAddress, ) { - let mut keys = array![]; - keys.append_serde(selector!("AfterUpdate")); - - let mut data = array![]; - data.append_serde(to); - data.append_serde(token_id); - data.append_serde(auth); - - let expected = Event { keys, data }; + let expected = ExpectedEvent::new() + .key(selector!("AfterUpdate")) + .data(to) + .data(token_id) + .data(auth); self.assert_emitted_single(contract, expected); } } From a57a5bb2e75d882c3cf4f89885bf4e6e430aede0 Mon Sep 17 00:00:00 2001 From: Eric Nordelo Date: Wed, 6 Aug 2025 12:51:43 +0200 Subject: [PATCH 26/29] feat: bump foundry --- Scarb.lock | 8 ++++---- Scarb.toml | 2 +- packages/testing/CHANGELOG.md | 4 ++++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Scarb.lock b/Scarb.lock index 6c7076508..6bd3f984e 100644 --- a/Scarb.lock +++ b/Scarb.lock @@ -191,15 +191,15 @@ dependencies = [ [[package]] name = "snforge_scarb_plugin" -version = "0.47.0" +version = "0.48.0" source = "registry+https://scarbs.xyz/" -checksum = "sha256:3525e4502541043571678531fced28f753746cb59a8aa79811811218abef6c05" +checksum = "sha256:8630dcf3fa4df36a3d45e6a2d053cf84c548ab154e829fece99373ae5852921c" [[package]] name = "snforge_std" -version = "0.47.0" +version = "0.48.0" source = "registry+https://scarbs.xyz/" -checksum = "sha256:b8647adcd0f5c9631f88b5a523b2653a82f2349dde2af7213c75f1006fa3f71b" +checksum = "sha256:981139c83359089540652c44f4a1a888c77409eedaa148377927cc63a604b67b" dependencies = [ "snforge_scarb_plugin", ] diff --git a/Scarb.toml b/Scarb.toml index e23928b0b..d28514941 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -45,7 +45,7 @@ keywords = [ [workspace.dependencies] assert_macros = "2.12.0" starknet = "2.12.0" -snforge_std = "0.47.0" +snforge_std = "0.48.0" [dependencies] starknet.workspace = true diff --git a/packages/testing/CHANGELOG.md b/packages/testing/CHANGELOG.md index 362a88362..7b5ef86f4 100644 --- a/packages/testing/CHANGELOG.md +++ b/packages/testing/CHANGELOG.md @@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The `ExpectedEvent` trait and impl (#1472) +### Changed + +- Bump snforge to v0.48.0 (#1472) + ## 4.4.0 (2025-07-31) ### Changed From 7976b642cb561d825a56d2ddb91b04b544da47e3 Mon Sep 17 00:00:00 2001 From: Eric Nordelo Date: Wed, 13 Aug 2025 14:10:01 +0200 Subject: [PATCH 27/29] feat: finish refactor into v2 --- packages/macros/Cargo.lock | 230 +++++-- packages/macros/Cargo.toml | 17 +- .../src/attribute/type_hash/definition.rs | 33 +- .../macros/src/attribute/type_hash/parser.rs | 2 +- .../attribute/with_components/definition.rs | 7 +- .../src/attribute/with_components/parser.rs | 14 +- packages/macros/src/tests/common.rs | 16 +- ..._tests__test_type_hash__doc_example_2.snap | 2 +- ...s__tests__test_type_hash__empty_input.snap | 2 +- ..._type_hash__potential_duplicate_types.snap | 2 - ..._hash__potential_duplicate_types_enum.snap | 2 - ...est_type_hash__with_inner_custom_type.snap | 9 +- ..._test_type_hash__with_inner_u256_type.snap | 2 - ..._type_hash__with_inner_u256_type_enum.snap | 2 - ..._with_components__with_access_control.snap | 3 - ...s__with_access_control_no_initializer.snap | 2 - ...s__test_with_components__with_account.snap | 1 - ...s__test_with_components__with_erc1155.snap | 2 - ...omponents__with_erc1155_no_hooks_impl.snap | 1 - ...mponents__with_erc1155_no_initializer.snap | 1 - ...ith_components__with_erc1155_receiver.snap | 1 - ...sts__test_with_components__with_erc20.snap | 2 - ...with_components__with_erc20_no_config.snap | 2 - ..._components__with_erc20_no_hooks_impl.snap | 2 - ...components__with_erc20_no_initializer.snap | 2 - ...s__test_with_components__with_erc2981.snap | 2 - ...th_components__with_erc2981_no_config.snap | 2 - ...mponents__with_erc2981_no_initializer.snap | 1 - ...with_erc2981_no_initializer_no_config.snap | 2 - ...s__test_with_components__with_erc4626.snap | 7 - ...ts__test_with_components__with_erc721.snap | 2 - ...th_components__with_erc721_enumerable.snap | 1 - ...components__with_erc721_no_hooks_impl.snap | 1 - ...omponents__with_erc721_no_initializer.snap | 1 - ...with_components__with_erc721_receiver.snap | 1 - ...est_with_components__with_eth_account.snap | 2 - ...st_with_components__with_event_struct.snap | 5 - ...__test_with_components__with_governor.snap | 2 - ...components__with_governor_integration.snap | 29 +- ...h_components__with_governor_no_config.snap | 1 - ...ponents__with_governor_no_initializer.snap | 2 - ...th_components__with_governor_settings.snap | 6 +- ...with_governor_settings_no_initializer.snap | 1 - ...nts__with_governor_timelock_execution.snap | 2 - ...nor_timelock_execution_no_initializer.snap | 1 - ..._with_components__with_governor_votes.snap | 2 - ...__with_governor_votes_quorum_fraction.snap | 5 +- ...t_with_components__with_initializable.snap | 1 - ...__test_with_components__with_multisig.snap | 2 - ...s__test_with_components__with_ownable.snap | 2 - ...mponents__with_ownable_no_initializer.snap | 2 - ...__test_with_components__with_pausable.snap | 2 - ...mponents__with_pausable_no_pause_call.snap | 1 - ...onents__with_pausable_no_unpause_call.snap | 1 - ...ests__test_with_components__with_src9.snap | 1 - ..._components__with_timelock_controller.snap | 2 - ..._with_components__with_two_components.snap | 2 - ...s__with_two_components_no_constructor.snap | 1 - ...s__with_two_components_no_initializer.snap | 2 - ...est_with_components__with_upgradeable.snap | 1 - ...nts__with_upgradeable_no_upgrade_call.snap | 1 - ...s__test_with_components__with_vesting.snap | 2 - ...mponents__with_vesting_no_initializer.snap | 2 - ..._components__with_vesting_no_schedule.snap | 2 - ...sts__test_with_components__with_votes.snap | 7 +- packages/macros/src/tests/test_type_hash.rs | 410 +++++------- .../macros/src/tests/test_with_components.rs | 623 +++++++----------- 67 files changed, 637 insertions(+), 867 deletions(-) diff --git a/packages/macros/Cargo.lock b/packages/macros/Cargo.lock index f3bfc86a1..0366e3887 100644 --- a/packages/macros/Cargo.lock +++ b/packages/macros/Cargo.lock @@ -50,6 +50,26 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "bincode" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36eaf5d7b090263e8150820482d5d93cd964a81e4019913c972f4edcc6edb740" +dependencies = [ + "bincode_derive", + "serde", + "unty", +] + +[[package]] +name = "bincode_derive" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf95709a440f45e986983918d0e8a1f30a9b1df04918fc828670606804ac3c09" +dependencies = [ + "virtue", +] + [[package]] name = "bit-set" version = "0.8.0" @@ -92,6 +112,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "borsh" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce" +dependencies = [ + "cfg_aliases", +] + [[package]] name = "bstr" version = "1.11.3" @@ -102,6 +131,12 @@ dependencies = [ "serde", ] +[[package]] +name = "bumpalo" +version = "3.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" + [[package]] name = "byte-slice-cast" version = "1.2.3" @@ -110,9 +145,9 @@ checksum = "7575182f7272186991736b70173b0ea045398f984bf5ebbb3804736ce1330c9d" [[package]] name = "cairo-lang-casm" -version = "2.11.4" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34f666086bfda27b0b1c708d4c9aca097508870381ddfcc1c97f442b2430d079" +checksum = "5fcb67fa250ab8eb216e626dc58ed04081286885005519875bfbcfbb66485f33" dependencies = [ "cairo-lang-utils", "indoc", @@ -124,19 +159,20 @@ dependencies = [ [[package]] name = "cairo-lang-debug" -version = "2.11.4" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94e438aea97ef0d360b0e1eff98c9bd7077407993fae735ac450031faf0a7cb1" +checksum = "87be3c3a2351b0931ce482c70b407e042c8cf952fdd4751c739c50078edad67b" dependencies = [ "cairo-lang-utils", ] [[package]] name = "cairo-lang-defs" -version = "2.11.4" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f9c075e393b2e120ab32e981a2af9c36e9ec78405e86d6c8a2c4c11a3df9257" +checksum = "db0dce1e9c902b91ec11d6baf0478537db91be457e7b0b03b1395f8daa3c7fe6" dependencies = [ + "bincode", "cairo-lang-debug", "cairo-lang-diagnostics", "cairo-lang-filesystem", @@ -145,14 +181,17 @@ dependencies = [ "cairo-lang-utils", "itertools", "rust-analyzer-salsa", + "serde", "smol_str", + "typetag", + "xxhash-rust", ] [[package]] name = "cairo-lang-diagnostics" -version = "2.11.4" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0366f2ba4f0d523e1da8bae918566bb67a0030b15958b7185a889df58475dc7" +checksum = "d4a040088f9b8ec09ad7e2a461490276b17b9abd0eb4c5e95b8d87d66ca04255" dependencies = [ "cairo-lang-debug", "cairo-lang-filesystem", @@ -162,9 +201,9 @@ dependencies = [ [[package]] name = "cairo-lang-eq-solver" -version = "2.11.4" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b540174610928874781672632c2a84a7352201a6a12f635362468b98e71050" +checksum = "fe2a4ed344b143eceaf818d7212a45a5d6dc9e50ebfc5afabb30ff05d8298261" dependencies = [ "cairo-lang-utils", "good_lp", @@ -172,9 +211,9 @@ dependencies = [ [[package]] name = "cairo-lang-filesystem" -version = "2.11.4" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de819fdd43ea61c051c7a876d0ea44626c7ee7447a72ef63f48672c7745c86b5" +checksum = "694930930f52a131a0f82fa92d213874ac24aad2638cd73e43790e4339cd42c6" dependencies = [ "cairo-lang-debug", "cairo-lang-utils", @@ -188,9 +227,9 @@ dependencies = [ [[package]] name = "cairo-lang-formatter" -version = "2.11.4" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3f5327e5cc48880249d8bc9edc8f5ab534a18e002b5069f1a67f4a8f3f2003a" +checksum = "c006f5a9342e77da68b07962ba419c20dfb6e0ba8f9e3b16a49cc131f3fbe709" dependencies = [ "anyhow", "cairo-lang-diagnostics", @@ -201,27 +240,29 @@ dependencies = [ "diffy", "ignore", "itertools", - "rust-analyzer-salsa", "serde", "thiserror 2.0.12", ] [[package]] name = "cairo-lang-macro" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dda77fe9404e438edaa80c9acaf0d72260aa883ba433812d0a745f5a72f31881" +checksum = "221e399ef5d91483e1ff3be9860a7e74b91ba37d95f1211704cd330baa6a28fe" dependencies = [ + "bumpalo", "cairo-lang-macro-attributes", "cairo-lang-macro-stable", + "cairo-lang-primitive-token", + "cairo-lang-quote", "linkme", ] [[package]] name = "cairo-lang-macro-attributes" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e32e958decd95ae122ee64daa26721da2f76e83231047f947fd9cdc5d3c90cc6" +checksum = "a13b61d5054ecc80a7a034f0cafc94abe20748741cfd3cd1efb69a893c7234da" dependencies = [ "quote", "scarb-stable-hash", @@ -230,15 +271,15 @@ dependencies = [ [[package]] name = "cairo-lang-macro-stable" -version = "1.0.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c49906d6b1c215e5814be7c5c65ecf2328898b335bee8c2409ec07cfb5530daf" +checksum = "414b7ba40b5ec3f26101b5c76df5739190832834b95689a723f3f88ec1695fe3" [[package]] name = "cairo-lang-parser" -version = "2.11.4" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0154b6c5bf6e75cc672a5a47775829f4248946c96855a2483e0b41f7e43c0248" +checksum = "a3f75b0baca6666107c47d9d8d40684c99c82c930924eb85a13db90bc795928c" dependencies = [ "cairo-lang-diagnostics", "cairo-lang-filesystem", @@ -257,9 +298,9 @@ dependencies = [ [[package]] name = "cairo-lang-plugins" -version = "2.11.4" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aed019a1665d85930366bd2cc76a9c5bedb6052dbc82c55a141c3066077c00cb" +checksum = "1ac54f473248dfb00311b35b809e043e2e6ca3e288e63f3876c6ac3509d3c433" dependencies = [ "cairo-lang-defs", "cairo-lang-diagnostics", @@ -280,16 +321,26 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "123ac0ecadf31bacae77436d72b88fa9caef2b8e92c89ce63a125ae911a12fae" +[[package]] +name = "cairo-lang-quote" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3112c71b991ab1617d95737c32193873b63ff6a11926f8e38271a70eb260ed31" +dependencies = [ + "proc-macro2", + "quote", +] + [[package]] name = "cairo-lang-sierra" -version = "2.11.4" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "461500d262ac78744c7b39087b033c36a448e047390c71f5c92ac27ef6a6edda" +checksum = "104eba8e6509ecd4e96cac9cd3dee9f0c698bfc8cba0097b32f6378eaac3edd8" dependencies = [ "anyhow", "cairo-lang-utils", "const-fnv1a-hash", - "convert_case 0.7.1", + "convert_case", "derivative", "itertools", "lalrpop", @@ -309,9 +360,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-ap-change" -version = "2.11.4" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7153bdd6d3f46c3045c0b3e23c9f5e8458fe4da673864f95ddfc5ff9f4ef981c" +checksum = "9131235c4854d3c483a3d363cbfa70b6c2e8b5ca05e37ecbb9edc4a5dfc2e186" dependencies = [ "cairo-lang-eq-solver", "cairo-lang-sierra", @@ -325,9 +376,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-gas" -version = "2.11.4" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0330f6846da0d59b32feae23dfc97887e81b4f51cf9fe17a39ef493ed8cabe23" +checksum = "b6d9d0fed2440c8ea6717e9580d0efa4b10e07415ca9508afe2d9cb9be8aca64" dependencies = [ "cairo-lang-eq-solver", "cairo-lang-sierra", @@ -341,9 +392,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-to-casm" -version = "2.11.4" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a91e32d7eeac0e4c7837e87bb75375c2d42eaa05dd314a636b162c68f5326e56" +checksum = "4a47906641d467f18f2035c5017bee4afd6e118eba80e217b82a03b678764919" dependencies = [ "assert_matches", "cairo-lang-casm", @@ -362,9 +413,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-type-size" -version = "2.11.4" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40197fac8db5540008ae6c4e9ba40ebf0e402f8cf7c709e9959b48913ebd18ff" +checksum = "1a7cc6bb50cc23e0252a48a1b2ee9b17edcb74d2dab86c70b095bcd287ecfd66" dependencies = [ "cairo-lang-sierra", "cairo-lang-utils", @@ -372,15 +423,15 @@ dependencies = [ [[package]] name = "cairo-lang-starknet-classes" -version = "2.11.4" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e1d950413579e309fc2952c263281dc0dfce8491c1480f84d8d8a4376b2d960" +checksum = "0d46f87d7dc5ee23ff1e67cb88210f3273ee97b82efc84e30f5abf17a96d7510" dependencies = [ "cairo-lang-casm", "cairo-lang-sierra", "cairo-lang-sierra-to-casm", "cairo-lang-utils", - "convert_case 0.7.1", + "convert_case", "itertools", "num-bigint", "num-integer", @@ -395,9 +446,9 @@ dependencies = [ [[package]] name = "cairo-lang-syntax" -version = "2.11.4" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea0e2287233244b6a49835724c932726d9e951fdfdbcc24ca5402f667d745209" +checksum = "0638177321676b1ffc6350e3d7a62cd3d48df46d90bfc561b32a38589f0eeee0" dependencies = [ "cairo-lang-debug", "cairo-lang-filesystem", @@ -413,9 +464,9 @@ dependencies = [ [[package]] name = "cairo-lang-syntax-codegen" -version = "2.11.4" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c69eb6919b69a9a7bb92f79d73c568d09ef77efa0b5d265efb763234ec979d4" +checksum = "882f1bad365ffa5ad353e6ae727cbaf7ad51420787f1c4211c9f0bf847e55cb4" dependencies = [ "genco", "xshell", @@ -423,9 +474,9 @@ dependencies = [ [[package]] name = "cairo-lang-utils" -version = "2.11.4" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c387a696a29cea52ddedb3097706dd8168958ef5388157d6e5b388a2c0de061" +checksum = "3443f4fc17986f362f5b87cd8c37dafeadf5e0a0909a19f2541cd55baae25a74" dependencies = [ "hashbrown 0.15.2", "indexmap 2.8.0", @@ -434,6 +485,7 @@ dependencies = [ "num-traits", "schemars", "serde", + "smol_str", ] [[package]] @@ -442,6 +494,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "colored" version = "3.0.0" @@ -489,15 +547,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "convert_case" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb402b8d4c85569410425650ce3eddc7d698ed96d39a73f941b08fb63082f1e7" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "convert_case" version = "0.8.0" @@ -620,11 +669,21 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "erased-serde" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7" +dependencies = [ + "serde", + "typeid", +] + [[package]] name = "fancy-regex" -version = "0.14.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e24cb5a94bcae1e5408b0effca5cd7172ea3c5755049c5f3af4cd283a165298" +checksum = "bf04c5ec15464ace8355a7b440a33aece288993475556d461154d7a62ad9947c" dependencies = [ "bit-set", "regex-automata", @@ -816,6 +875,15 @@ dependencies = [ "similar", ] +[[package]] +name = "inventory" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab08d7cd2c5897f2c949e5383ea7c7db03fb19130ffcfbf7eda795137ae3cb83" +dependencies = [ + "rustversion", +] + [[package]] name = "itertools" version = "0.14.0" @@ -1063,9 +1131,10 @@ dependencies = [ "cairo-lang-macro", "cairo-lang-parser", "cairo-lang-plugins", + "cairo-lang-primitive-token", "cairo-lang-starknet-classes", "cairo-lang-syntax", - "convert_case 0.8.0", + "convert_case", "fancy-regex", "indoc", "insta", @@ -1463,10 +1532,11 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "smol_str" -version = "0.2.2" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" +checksum = "9676b89cd56310a87b93dec47b11af744f34d5fc9f367b829474eec0a891350d" dependencies = [ + "borsh", "serde", ] @@ -1668,12 +1738,42 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + [[package]] name = "typenum" version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +[[package]] +name = "typetag" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f22b40dd7bfe8c14230cf9702081366421890435b2d625fa92b4acc4c3de6f" +dependencies = [ + "erased-serde", + "inventory", + "once_cell", + "serde", + "typetag-impl", +] + +[[package]] +name = "typetag-impl" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35f5380909ffc31b4de4f4bdf96b877175a016aa2ca98cee39fcfd8c4d53d952" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "unescaper" version = "0.1.5" @@ -1701,12 +1801,24 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "unty" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" + [[package]] name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "virtue" +version = "0.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "051eb1abcf10076295e815102942cc58f9d5e3b4560e46e53c21e8ff6f3af7b1" + [[package]] name = "walkdir" version = "2.5.0" diff --git a/packages/macros/Cargo.toml b/packages/macros/Cargo.toml index 1f9eb69b4..38c636cd6 100644 --- a/packages/macros/Cargo.toml +++ b/packages/macros/Cargo.toml @@ -7,15 +7,16 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -cairo-lang-macro = "0.1" -cairo-lang-parser = "2.11" -cairo-lang-plugins = "2.11" -cairo-lang-syntax = "2.11" -cairo-lang-defs = "2.11" -cairo-lang-formatter = "2.11" -cairo-lang-starknet-classes = "2.11" +cairo-lang-macro = "0.2" +cairo-lang-primitive-token = "1.0.0" +cairo-lang-parser = "2.12" +cairo-lang-plugins = "2.12" +cairo-lang-syntax = "2.12" +cairo-lang-defs = "2.12" +cairo-lang-formatter = "2.12" +cairo-lang-starknet-classes = "2.12" indoc = "2.0.5" regex = "1.11.1" insta = "1.42.0" convert_case = "0.8.0" -fancy-regex = "0.14.0" +fancy-regex = "0.16.0" diff --git a/packages/macros/src/attribute/type_hash/definition.rs b/packages/macros/src/attribute/type_hash/definition.rs index b868aee0a..5724cf519 100644 --- a/packages/macros/src/attribute/type_hash/definition.rs +++ b/packages/macros/src/attribute/type_hash/definition.rs @@ -1,8 +1,9 @@ use cairo_lang_formatter::format_string; -use cairo_lang_macro::{attribute_macro, Diagnostic, Diagnostics, ProcMacroResult, TokenStream}; +use cairo_lang_macro::{attribute_macro, quote, Diagnostic, ProcMacroResult, TokenStream}; use cairo_lang_parser::utils::SimpleParserDatabase; use cairo_lang_plugins::plugins::utils::PluginTypeInfo; use cairo_lang_starknet_classes::keccak::starknet_keccak; +use cairo_lang_syntax::node::with_db::SyntaxNodeWithDb; use cairo_lang_syntax::node::{ast, TypedSyntaxNode}; use cairo_lang_syntax::node::{db::SyntaxGroup, SyntaxNode}; use convert_case::{Case, Casing}; @@ -38,7 +39,8 @@ pub fn type_hash(attr_stream: TokenStream, item_stream: TokenStream) -> ProcMacr // 2. Parse the item stream let db = SimpleParserDatabase::default(); - let content = match db.parse_virtual(item_stream.to_string()) { + let formatted_item_stream = format_string(&db, item_stream.to_string()); + let content = match db.parse_virtual(formatted_item_stream) { Ok(node) => handle_node(&db, node, &config), Err(err) => { let error = Diagnostic::error(err.format(&db)); @@ -46,15 +48,20 @@ pub fn type_hash(attr_stream: TokenStream, item_stream: TokenStream) -> ProcMacr } }; - // 3. Format the expanded content - let (formatted_content, diagnostics) = match content { - Ok(content) => (format_string(&db, content), Diagnostics::new(vec![])), - Err(err) => (String::new(), err.into()), + let generated = match content { + Ok(generated) => generated, + Err(err) => { + return ProcMacroResult::new(TokenStream::empty()).with_diagnostics(err.into()); + } }; - // 4. Return the result - let result = TokenStream::new(item_stream.to_string() + &formatted_content); - ProcMacroResult::new(result).with_diagnostics(diagnostics) + // 3. Return the result + let syntax_node = db.parse_virtual(generated).unwrap(); + let content_node = SyntaxNodeWithDb::new(&syntax_node, &db); + + let mut result = item_stream; + result.extend(quote! {#content_node}); + ProcMacroResult::new(result) } /// This attribute macro is used to specify an override for the SNIP-12 type. @@ -115,7 +122,7 @@ fn parse_args(s: &str) -> Result { let allowed_args_re = allowed_args.join("|"); let re = Regex::new(&format!( - r#"^\(({allowed_args_re}): ([\w"' ])+(?:, ({allowed_args_re}): ([\w"' ])+)*\)$"# + r#"^\(({allowed_args_re}):\s?([\w"' ])+(?:,\s?({allowed_args_re}):\s?([\w"' ])+)*\)$"# )) .unwrap(); @@ -147,9 +154,9 @@ fn handle_node( args: &TypeHashArgs, ) -> Result { let typed = ast::SyntaxFile::from_syntax_node(db, node); - let items = typed.items(db).elements(db); + let mut items = typed.items(db).elements(db); - let Some(item_ast) = items.first() else { + let Some(item_ast) = items.next() else { let error = Diagnostic::error(errors::EMPTY_TYPE_FOUND); return Err(error); }; @@ -158,7 +165,7 @@ fn handle_node( match item_ast { ast::ModuleItem::Struct(_) | ast::ModuleItem::Enum(_) => { // It is safe to unwrap here because we know the item is a struct - let plugin_type_info = PluginTypeInfo::new(db, item_ast).unwrap(); + let plugin_type_info = PluginTypeInfo::new(db, &item_ast).unwrap(); generate_code(db, &plugin_type_info, args) } _ => { diff --git a/packages/macros/src/attribute/type_hash/parser.rs b/packages/macros/src/attribute/type_hash/parser.rs index 3c9f86123..8a7a5261c 100644 --- a/packages/macros/src/attribute/type_hash/parser.rs +++ b/packages/macros/src/attribute/type_hash/parser.rs @@ -52,7 +52,7 @@ impl<'a> TypeHashParser<'a> { .members_info .iter() .map(|member| { - let attributes = member.attributes.elements(db); + let attributes = member.attributes.elements(db).collect::>(); let args = match get_name_and_type_from_attributes(db, &attributes) { Ok(args) => args, Err(e) => { diff --git a/packages/macros/src/attribute/with_components/definition.rs b/packages/macros/src/attribute/with_components/definition.rs index f3947f4eb..a9eea5b09 100644 --- a/packages/macros/src/attribute/with_components/definition.rs +++ b/packages/macros/src/attribute/with_components/definition.rs @@ -1,6 +1,7 @@ use cairo_lang_formatter::format_string; -use cairo_lang_macro::{attribute_macro, Diagnostic, ProcMacroResult, TokenStream}; +use cairo_lang_macro::{attribute_macro, quote, Diagnostic, ProcMacroResult, TokenStream}; use cairo_lang_parser::utils::SimpleParserDatabase; +use cairo_lang_syntax::node::with_db::SyntaxNodeWithDb; use regex::Regex; use super::{components::AllowedComponents, parser::WithComponentsParser}; @@ -41,7 +42,9 @@ pub fn with_components(attribute_stream: TokenStream, item_stream: TokenStream) content }; - ProcMacroResult::new(TokenStream::new(formatted_content)).with_diagnostics(diagnostics) + let syntax_node = db.parse_virtual(formatted_content).unwrap(); + let formatted_content_node = SyntaxNodeWithDb::new(&syntax_node, &db); + ProcMacroResult::new(quote! {#formatted_content_node}).with_diagnostics(diagnostics) } /// Parses the arguments from the attribute stream. diff --git a/packages/macros/src/attribute/with_components/parser.rs b/packages/macros/src/attribute/with_components/parser.rs index 14ce8a5a3..bef550c01 100644 --- a/packages/macros/src/attribute/with_components/parser.rs +++ b/packages/macros/src/attribute/with_components/parser.rs @@ -9,7 +9,7 @@ use crate::{ }; use cairo_lang_defs::patcher::{PatchBuilder, RewriteNode}; use cairo_lang_macro::{Diagnostic, Diagnostics}; -use cairo_lang_syntax::node::helpers::{BodyItems, QueryAttrs}; +use cairo_lang_syntax::node::helpers::QueryAttrs; use cairo_lang_syntax::node::{ ast::{self, MaybeModuleBody}, db::SyntaxGroup, @@ -42,7 +42,7 @@ impl<'a> WithComponentsParser<'a> { /// Parses the module and returns the patched code. pub fn parse(&mut self, db: &dyn SyntaxGroup) -> (String, Diagnostics) { - let base_node = self.base_node.clone(); + let base_node = self.base_node; let mut builder = PatchBuilder::new_ex(db, &base_node); let typed = ast::SyntaxFile::from_syntax_node(db, base_node); @@ -98,7 +98,7 @@ fn validate_contract_module( let mut warnings = vec![]; if let RewriteNode::Copied(copied) = node { - let item = ast::ItemModule::from_syntax_node(db, copied.clone()); + let item = ast::ItemModule::from_syntax_node(db, *copied); // 1. Check that the module has a body (error) let MaybeModuleBody::Some(body) = item.body(db) else { @@ -119,13 +119,13 @@ fn validate_contract_module( .collect::>(); if !components_with_initializer.is_empty() { - let constructor = body.items_vec(db).into_iter().find(|item| { + let constructor = body.items(db).elements(db).find(|item| { matches!(item, ast::ModuleItem::FreeFunction(function_ast) if function_ast.has_attr(db, CONSTRUCTOR_ATTRIBUTE)) }); let constructor_code = if let Some(constructor) = constructor { // Get the constructor code (maybe we can do this without the builder) let constructor_ast = constructor.as_syntax_node(); - let typed = ast::ModuleItem::from_syntax_node(db, constructor_ast.clone()); + let typed = ast::ModuleItem::from_syntax_node(db, constructor_ast); let constructor_rnode = RewriteNode::from_ast(&typed); let mut builder = PatchBuilder::new_ex(db, &constructor_ast); builder.add_modified(constructor_rnode); @@ -155,7 +155,7 @@ fn validate_contract_module( for component in components_info.iter().filter(|c| c.has_immutable_config) { // Get the body code (maybe we can do this without the builder) let body_ast = body.as_syntax_node(); - let typed = ast::ModuleBody::from_syntax_node(db, body_ast.clone()); + let typed = ast::ModuleBody::from_syntax_node(db, body_ast); let body_rnode = RewriteNode::from_ast(&typed); let mut builder = PatchBuilder::new_ex(db, &body_ast); @@ -282,7 +282,7 @@ fn process_module_items( for item_rnode in items_mnode.children.as_mut().unwrap() { if let RewriteNode::Copied(copied) = item_rnode { - let item = ast::ModuleItem::from_syntax_node(db, copied.clone()); + let item = ast::ModuleItem::from_syntax_node(db, *copied); match item { ast::ModuleItem::Struct(item_struct) diff --git a/packages/macros/src/tests/common.rs b/packages/macros/src/tests/common.rs index 28365cb76..481e21a2a 100644 --- a/packages/macros/src/tests/common.rs +++ b/packages/macros/src/tests/common.rs @@ -1,17 +1,23 @@ +use cairo_lang_formatter::format_string; use cairo_lang_macro::ProcMacroResult; +use cairo_lang_parser::utils::SimpleParserDatabase; use indoc::formatdoc; pub(crate) fn format_proc_macro_result(raw_result: ProcMacroResult) -> String { let none = "None"; let mut token_stream = raw_result.token_stream.to_string(); - let mut diagnostics = String::new(); - for d in raw_result.diagnostics { - diagnostics += format!("====\n{:?}: {}====", d.severity, d.message).as_str(); - } - if token_stream.is_empty() { token_stream = none.to_string(); + } else { + let db = SimpleParserDatabase::default(); + let formatted_token_stream = format_string(&db, token_stream); + token_stream = formatted_token_stream; + } + + let mut diagnostics = String::new(); + for d in raw_result.diagnostics { + diagnostics += format!("====\n{:?}: {}====", d.severity(), d.message()).as_str(); } if diagnostics.is_empty() { diagnostics = none.to_string(); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__doc_example_2.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__doc_example_2.snap index c34109b16..540e5367e 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__doc_example_2.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__doc_example_2.snap @@ -6,7 +6,7 @@ snapshot_kind: text TokenStream: pub struct MyStruct { - #[snip12(name: "Simple Felt")] // Optional custom name + #[snip12(name: "Simple Felt")] pub simple_felt: felt252, #[snip12(name: "Class Hash")] pub class_hash: ClassHash, diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__empty_input.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__empty_input.snap index e5c858552..7c1e63dfd 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__empty_input.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__empty_input.snap @@ -5,7 +5,7 @@ snapshot_kind: text --- TokenStream: - +None Diagnostics: diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__potential_duplicate_types.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__potential_duplicate_types.snap index ef686e24b..00db2da14 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__potential_duplicate_types.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__potential_duplicate_types.snap @@ -6,8 +6,6 @@ snapshot_kind: text TokenStream: pub struct MyType { - // TokenAmount type contains u256, which should be resolved - // and appended to the final type hash. pub token_amount: TokenAmount, pub token_amount_2: TokenAmount, pub number: u256, diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__potential_duplicate_types_enum.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__potential_duplicate_types_enum.snap index 425465e53..53fd0404c 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__potential_duplicate_types_enum.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__potential_duplicate_types_enum.snap @@ -6,8 +6,6 @@ snapshot_kind: text TokenStream: pub enum MyEnum { - // TokenAmount type contains u256, which should be resolved - // and appended to the final type hash. Variant1: TokenAmount, Variant2: TokenAmount, Variant3: u256, diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__with_inner_custom_type.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__with_inner_custom_type.snap index f88e42391..d864faf83 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__with_inner_custom_type.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__with_inner_custom_type.snap @@ -5,14 +5,7 @@ snapshot_kind: text --- TokenStream: -pub struct MyType { - pub name: felt252, - pub version: felt252, - pub chain_id: felt252, - pub revision: felt252, - pub member: InnerCustomType, -} - +None Diagnostics: diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__with_inner_u256_type.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__with_inner_u256_type.snap index 7264cc5b0..946202911 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__with_inner_u256_type.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__with_inner_u256_type.snap @@ -6,8 +6,6 @@ snapshot_kind: text TokenStream: pub struct MyType { - // TokenAmount type contains u256, which should be resolved - // and appended to the final type hash. pub token_amount: TokenAmount, } pub fn __MY_TYPE_encoded_type() { diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__with_inner_u256_type_enum.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__with_inner_u256_type_enum.snap index 8dfb37a91..69c650ca9 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__with_inner_u256_type_enum.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_type_hash__with_inner_u256_type_enum.snap @@ -6,8 +6,6 @@ snapshot_kind: text TokenStream: pub enum MyEnum { - // TokenAmount type contains u256, which should be resolved - // and appended to the final type hash. Variant1: TokenAmount, } pub fn __MY_ENUM_encoded_type() { diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_access_control.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_access_control.snap index 881c3f544..6d6967b37 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_access_control.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_access_control.snap @@ -9,17 +9,14 @@ TokenStream: pub mod Contract { use openzeppelin_access::accesscontrol::DEFAULT_ADMIN_ROLE; use starknet::ContractAddress; - #[storage] pub struct Storage { #[substorage(v0)] pub access_control: AccessControlComponent::Storage, } - #[constructor] fn constructor(ref self: ContractState, default_admin: ContractAddress) { self.access_control.initializer(); - self.access_control._grant_role(DEFAULT_ADMIN_ROLE, default_admin); } use openzeppelin_access::accesscontrol::AccessControlComponent; diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_access_control_no_initializer.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_access_control_no_initializer.snap index dd38be288..87417bbe9 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_access_control_no_initializer.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_access_control_no_initializer.snap @@ -9,13 +9,11 @@ TokenStream: pub mod Contract { use openzeppelin_access::accesscontrol::DEFAULT_ADMIN_ROLE; use starknet::ContractAddress; - #[storage] pub struct Storage { #[substorage(v0)] pub access_control: AccessControlComponent::Storage, } - #[constructor] fn constructor(ref self: ContractState) {} use openzeppelin_access::accesscontrol::AccessControlComponent; diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_account.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_account.snap index c54e85606..3f641ab92 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_account.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_account.snap @@ -12,7 +12,6 @@ pub mod MyContract { #[substorage(v0)] pub account: AccountComponent::Storage, } - #[constructor] fn constructor(ref self: ContractState, public_key: felt252) { self.account.initializer(public_key); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc1155.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc1155.snap index 2da4b2a54..e97502125 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc1155.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc1155.snap @@ -8,13 +8,11 @@ TokenStream: #[starknet::contract] pub mod MyContract { use openzeppelin_token::erc1155::ERC1155HooksEmptyImpl; - #[storage] pub struct Storage { #[substorage(v0)] pub erc1155: ERC1155Component::Storage, } - #[constructor] fn constructor(ref self: ContractState) { self.erc1155.initializer(""); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc1155_no_hooks_impl.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc1155_no_hooks_impl.snap index ccbf568c8..de81b7338 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc1155_no_hooks_impl.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc1155_no_hooks_impl.snap @@ -12,7 +12,6 @@ pub mod MyContract { #[substorage(v0)] pub erc1155: ERC1155Component::Storage, } - #[constructor] fn constructor(ref self: ContractState) { self.erc1155.initializer(""); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc1155_no_initializer.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc1155_no_initializer.snap index 39f1a319d..e70719d80 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc1155_no_initializer.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc1155_no_initializer.snap @@ -8,7 +8,6 @@ TokenStream: #[starknet::contract] pub mod MyContract { use openzeppelin_token::erc1155::ERC1155HooksEmptyImpl; - #[storage] pub struct Storage { #[substorage(v0)] diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc1155_receiver.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc1155_receiver.snap index e4afe9cec..0c3d59762 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc1155_receiver.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc1155_receiver.snap @@ -12,7 +12,6 @@ pub mod MyContract { #[substorage(v0)] pub erc1155_receiver: ERC1155ReceiverComponent::Storage, } - #[constructor] fn constructor(ref self: ContractState) { self.erc1155_receiver.initializer(); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc20.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc20.snap index 4ce8a30bc..53f9e70eb 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc20.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc20.snap @@ -9,13 +9,11 @@ TokenStream: pub mod MyToken { use openzeppelin_token::erc20::{DefaultConfig, ERC20HooksEmptyImpl}; use starknet::ContractAddress; - #[storage] pub struct Storage { #[substorage(v0)] pub erc20: ERC20Component::Storage, } - #[constructor] fn constructor(ref self: ContractState) { self.erc20.initializer("MyToken", "MTK"); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc20_no_config.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc20_no_config.snap index 458ebd923..89c567fc4 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc20_no_config.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc20_no_config.snap @@ -9,13 +9,11 @@ TokenStream: pub mod MyToken { use openzeppelin_token::erc20::ERC20HooksEmptyImpl; use starknet::ContractAddress; - #[storage] pub struct Storage { #[substorage(v0)] pub erc20: ERC20Component::Storage, } - #[constructor] fn constructor(ref self: ContractState) { self.erc20.initializer("MyToken", "MTK"); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc20_no_hooks_impl.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc20_no_hooks_impl.snap index ad2b0683f..3c46d288d 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc20_no_hooks_impl.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc20_no_hooks_impl.snap @@ -9,13 +9,11 @@ TokenStream: pub mod MyToken { use openzeppelin_token::erc20::DefaultConfig; use starknet::ContractAddress; - #[storage] pub struct Storage { #[substorage(v0)] pub erc20: ERC20Component::Storage, } - #[constructor] fn constructor(ref self: ContractState) { self.erc20.initializer("MyToken", "MTK"); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc20_no_initializer.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc20_no_initializer.snap index 3f77e08b0..4bc33e743 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc20_no_initializer.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc20_no_initializer.snap @@ -9,13 +9,11 @@ TokenStream: pub mod MyToken { use openzeppelin_token::erc20::{DefaultConfig, ERC20HooksEmptyImpl}; use starknet::ContractAddress; - #[storage] pub struct Storage { #[substorage(v0)] pub erc20: ERC20Component::Storage, } - #[constructor] fn constructor(ref self: ContractState) {} use openzeppelin_token::erc20::ERC20Component; diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc2981.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc2981.snap index 396f12691..179af2d83 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc2981.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc2981.snap @@ -9,13 +9,11 @@ TokenStream: pub mod MyContract { use openzeppelin_token::common::erc2981::DefaultConfig; use starknet::ContractAddress; - #[storage] pub struct Storage { #[substorage(v0)] pub erc2981: ERC2981Component::Storage, } - #[constructor] fn constructor(ref self: ContractState, default_royalty_receiver: ContractAddress) { self.erc2981.initializer(default_royalty_receiver, 0); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc2981_no_config.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc2981_no_config.snap index 646898d82..1e1cb1308 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc2981_no_config.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc2981_no_config.snap @@ -8,13 +8,11 @@ TokenStream: #[starknet::contract] pub mod MyContract { use starknet::ContractAddress; - #[storage] pub struct Storage { #[substorage(v0)] pub erc2981: ERC2981Component::Storage, } - #[constructor] fn constructor(ref self: ContractState, default_royalty_receiver: ContractAddress) { self.erc2981.initializer(default_royalty_receiver, 0); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc2981_no_initializer.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc2981_no_initializer.snap index b413dc978..11d42796b 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc2981_no_initializer.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc2981_no_initializer.snap @@ -8,7 +8,6 @@ TokenStream: #[starknet::contract] pub mod MyContract { use openzeppelin_token::common::erc2981::DefaultConfig; - #[storage] pub struct Storage { #[substorage(v0)] diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc2981_no_initializer_no_config.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc2981_no_initializer_no_config.snap index 1d405279f..5f58b6b86 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc2981_no_initializer_no_config.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc2981_no_initializer_no_config.snap @@ -8,13 +8,11 @@ TokenStream: #[starknet::contract] pub mod MyContract { use starknet::ContractAddress; - #[storage] pub struct Storage { #[substorage(v0)] pub erc2981: ERC2981Component::Storage, } - #[constructor] fn constructor(ref self: ContractState, default_royalty_receiver: ContractAddress) {} use openzeppelin_token::common::erc2981::ERC2981Component; diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc4626.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc4626.snap index d1a5ddc6b..234c14b75 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc4626.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc4626.snap @@ -12,20 +12,14 @@ pub mod ERC4626Mock { DefaultConfig, ERC4626DefaultLimits, ERC4626DefaultNoFees, ERC4626HooksEmptyImpl, }; use starknet::ContractAddress; - - // ERC4626 #[abi(embed_v0)] impl ERC4626ComponentImpl = ERC4626Component::ERC4626Impl; - // ERC4626MetadataImpl is a custom impl of IERC20Metadata #[abi(embed_v0)] impl ERC4626MetadataImpl = ERC4626Component::ERC4626MetadataImpl; - - // ERC20 #[abi(embed_v0)] impl ERC20Impl = ERC20Component::ERC20Impl; #[abi(embed_v0)] impl ERC20CamelOnlyImpl = ERC20Component::ERC20CamelOnlyImpl; - #[storage] pub struct Storage { #[substorage(v0)] @@ -33,7 +27,6 @@ pub mod ERC4626Mock { #[substorage(v0)] pub erc4626: ERC4626Component::Storage, } - #[constructor] fn constructor( ref self: ContractState, diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc721.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc721.snap index afa44fef8..d3120a546 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc721.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc721.snap @@ -8,13 +8,11 @@ TokenStream: #[starknet::contract] pub mod MyContract { use openzeppelin_token::erc721::ERC721HooksEmptyImpl; - #[storage] pub struct Storage { #[substorage(v0)] pub erc721: ERC721Component::Storage, } - #[constructor] fn constructor(ref self: ContractState) { self.erc721.initializer("MyToken", "MTK", ""); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc721_enumerable.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc721_enumerable.snap index c1f734641..5907e24ae 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc721_enumerable.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc721_enumerable.snap @@ -12,7 +12,6 @@ pub mod MyContract { #[substorage(v0)] pub erc721_enumerable: ERC721EnumerableComponent::Storage, } - #[constructor] fn constructor(ref self: ContractState) { self.erc721_enumerable.initializer(); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc721_no_hooks_impl.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc721_no_hooks_impl.snap index 4317a5683..adea13a0d 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc721_no_hooks_impl.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc721_no_hooks_impl.snap @@ -12,7 +12,6 @@ pub mod MyContract { #[substorage(v0)] pub erc721: ERC721Component::Storage, } - #[constructor] fn constructor(ref self: ContractState) { self.erc721.initializer("MyToken", "MTK", ""); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc721_no_initializer.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc721_no_initializer.snap index 208e1164e..b4fc31f58 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc721_no_initializer.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc721_no_initializer.snap @@ -8,7 +8,6 @@ TokenStream: #[starknet::contract] pub mod MyContract { use openzeppelin_token::erc721::ERC721HooksEmptyImpl; - #[storage] pub struct Storage { #[substorage(v0)] diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc721_receiver.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc721_receiver.snap index 72d74ef8f..8f1aad788 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc721_receiver.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_erc721_receiver.snap @@ -12,7 +12,6 @@ pub mod MyContract { #[substorage(v0)] pub erc721_receiver: ERC721ReceiverComponent::Storage, } - #[constructor] fn constructor(ref self: ContractState) { self.erc721_receiver.initializer(); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_eth_account.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_eth_account.snap index d3079efbf..817b837a8 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_eth_account.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_eth_account.snap @@ -8,13 +8,11 @@ TokenStream: #[starknet::contract(account)] pub mod MyContract { use openzeppelin_interfaces::accounts::EthPublicKey; - #[storage] pub struct Storage { #[substorage(v0)] pub eth_account: EthAccountComponent::Storage, } - #[constructor] fn constructor(ref self: ContractState, public_key: EthPublicKey) { self.eth_account.initializer(public_key); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_event_struct.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_event_struct.snap index c317e4116..b228dd356 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_event_struct.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_event_struct.snap @@ -8,13 +8,11 @@ TokenStream: #[starknet::contract] pub mod Owned { use starknet::ContractAddress; - #[storage] pub struct Storage { #[substorage(v0)] pub ownable: OwnableComponent::Storage, } - #[event] #[derive(Drop, starknet::Event)] enum Event { @@ -22,8 +20,6 @@ pub mod Owned { OwnableEvent: OwnableComponent::Event, Transfer: Transfer, } - - /// Emitted when tokens are moved from address `from` to address `to`. #[derive(Drop, starknet::Event)] pub struct Transfer { #[key] @@ -32,7 +28,6 @@ pub mod Owned { pub to: ContractAddress, pub value: u256, } - #[constructor] fn constructor(ref self: ContractState, owner: ContractAddress) { self.ownable.initializer(owner); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor.snap index 3b6c48d19..4c2345552 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor.snap @@ -8,13 +8,11 @@ TokenStream: #[starknet::contract] pub mod MyContract { use openzeppelin_governance::governor::DefaultConfig; - #[storage] pub struct Storage { #[substorage(v0)] pub governor: GovernorComponent::Storage, } - #[constructor] fn constructor(ref self: ContractState) { self.governor.initializer(); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_integration.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_integration.snap index d70b3dbd1..3aee8d571 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_integration.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_integration.snap @@ -10,17 +10,12 @@ pub mod GovernorTimelockedMock { use openzeppelin_governance::governor::DefaultConfig; use openzeppelin_utils::cryptography::snip12::SNIP12Metadata; use starknet::ContractAddress; - - pub const VOTING_DELAY: u64 = 86400; // 1 day - pub const VOTING_PERIOD: u64 = 604800; // 1 week + pub const VOTING_DELAY: u64 = 86400; + pub const VOTING_PERIOD: u64 = 604800; pub const PROPOSAL_THRESHOLD: u256 = 10; pub const QUORUM: u256 = 100_000_000; - - // Governor #[abi(embed_v0)] impl GovernorImpl = GovernorComponent::GovernorImpl; - - // Extensions external #[abi(embed_v0)] impl VotesTokenImpl = GovernorVotesComponent::VotesTokenImpl; #[abi(embed_v0)] @@ -29,11 +24,8 @@ pub mod GovernorTimelockedMock { #[abi(embed_v0)] impl TimelockedImpl = GovernorTimelockExecutionComponent::TimelockedImpl; - - // SRC5 #[abi(embed_v0)] impl SRC5Impl = SRC5Component::SRC5Impl; - #[storage] struct Storage { #[substorage(v0)] @@ -49,7 +41,6 @@ pub mod GovernorTimelockedMock { #[substorage(v0)] pub src5: SRC5Component::Storage, } - #[constructor] fn constructor( ref self: ContractState, votes_token: ContractAddress, timelock_controller: ContractAddress, @@ -59,27 +50,15 @@ pub mod GovernorTimelockedMock { self.governor_settings.initializer(VOTING_DELAY, VOTING_PERIOD, PROPOSAL_THRESHOLD); self.governor_timelock_execution.initializer(timelock_controller); } - - // - // SNIP12 Metadata - // - pub impl SNIP12MetadataImpl of SNIP12Metadata { fn name() -> felt252 { - 'DAPP_NAME' + "DAPP_NAME" } - fn version() -> felt252 { - 'DAPP_VERSION' + "DAPP_VERSION" } } - - // - // Locally implemented extensions - // - impl GovernorQuorum of GovernorComponent::GovernorQuorumTrait { - /// See `GovernorComponent::GovernorQuorumTrait::quorum`. fn quorum(self: @GovernorComponent::ComponentState, timepoint: u64) -> u256 { QUORUM } diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_no_config.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_no_config.snap index 3f51dcc04..1484099c1 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_no_config.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_no_config.snap @@ -12,7 +12,6 @@ pub mod MyContract { #[substorage(v0)] pub governor: GovernorComponent::Storage, } - #[constructor] fn constructor(ref self: ContractState) { self.governor.initializer(); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_no_initializer.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_no_initializer.snap index f95b1ef9e..59b2cb7bb 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_no_initializer.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_no_initializer.snap @@ -8,13 +8,11 @@ TokenStream: #[starknet::contract] pub mod MyContract { use openzeppelin_governance::governor::DefaultConfig; - #[storage] pub struct Storage { #[substorage(v0)] pub governor: GovernorComponent::Storage, } - #[constructor] fn constructor(ref self: ContractState) {} use openzeppelin_governance::governor::GovernorComponent; diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_settings.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_settings.snap index d946291ae..d5f72e28a 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_settings.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_settings.snap @@ -7,16 +7,14 @@ TokenStream: #[starknet::contract] pub mod MyContract { - pub const VOTING_DELAY: u64 = 86400; // 1 day - pub const VOTING_PERIOD: u64 = 604800; // 1 week + pub const VOTING_DELAY: u64 = 86400; + pub const VOTING_PERIOD: u64 = 604800; pub const PROPOSAL_THRESHOLD: u256 = 10; - #[storage] pub struct Storage { #[substorage(v0)] pub governor_settings: GovernorSettingsComponent::Storage, } - #[constructor] fn constructor(ref self: ContractState) { self.governor_settings.initializer(VOTING_DELAY, VOTING_PERIOD, PROPOSAL_THRESHOLD); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_settings_no_initializer.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_settings_no_initializer.snap index 731035461..44263c388 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_settings_no_initializer.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_settings_no_initializer.snap @@ -12,7 +12,6 @@ pub mod MyContract { #[substorage(v0)] pub governor_settings: GovernorSettingsComponent::Storage, } - #[constructor] fn constructor(ref self: ContractState) {} use openzeppelin_governance::governor::extensions::GovernorSettingsComponent; diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_timelock_execution.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_timelock_execution.snap index 779c95d85..3c3760a4d 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_timelock_execution.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_timelock_execution.snap @@ -8,13 +8,11 @@ TokenStream: #[starknet::contract] pub mod MyContract { use starknet::ContractAddress; - #[storage] pub struct Storage { #[substorage(v0)] pub governor_timelock_execution: GovernorTimelockExecutionComponent::Storage, } - #[constructor] fn constructor(ref self: ContractState, timelock_controller: ContractAddress) { self.governor_timelock_execution.initializer(timelock_controller); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_timelock_execution_no_initializer.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_timelock_execution_no_initializer.snap index c23e0a7eb..d945b99ec 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_timelock_execution_no_initializer.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_timelock_execution_no_initializer.snap @@ -12,7 +12,6 @@ pub mod MyContract { #[substorage(v0)] pub governor_timelock_execution: GovernorTimelockExecutionComponent::Storage, } - #[constructor] fn constructor(ref self: ContractState) {} use openzeppelin_governance::governor::extensions::GovernorTimelockExecutionComponent; diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_votes.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_votes.snap index ae29fa6f2..37a1da5af 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_votes.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_votes.snap @@ -8,13 +8,11 @@ TokenStream: #[starknet::contract] pub mod MyContract { use starknet::ContractAddress; - #[storage] pub struct Storage { #[substorage(v0)] pub governor_votes: GovernorVotesComponent::Storage, } - #[constructor] fn constructor(ref self: ContractState, votes_token: ContractAddress) { self.governor_votes.initializer(votes_token); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_votes_quorum_fraction.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_votes_quorum_fraction.snap index 600d6a200..3576feb84 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_votes_quorum_fraction.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_governor_votes_quorum_fraction.snap @@ -8,15 +8,12 @@ TokenStream: #[starknet::contract] pub mod MyContract { use starknet::ContractAddress; - - pub const QUORUM_NUMERATOR: u256 = 600; // 60% - + pub const QUORUM_NUMERATOR: u256 = 600; #[storage] pub struct Storage { #[substorage(v0)] pub governor_votes_quorum_fraction: GovernorVotesQuorumFractionComponent::Storage, } - #[constructor] fn constructor(ref self: ContractState, votes_token: ContractAddress) { self.governor_votes_quorum_fraction.initializer(votes_token, QUORUM_NUMERATOR); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_initializable.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_initializable.snap index a6f7f7694..9333946ca 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_initializable.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_initializable.snap @@ -12,7 +12,6 @@ pub mod MyContract { #[substorage(v0)] pub initializable: InitializableComponent::Storage, } - #[generate_trait] #[abi(per_item)] impl ExternalImpl of ExternalTrait { diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_multisig.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_multisig.snap index 782005e07..2d7d0f940 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_multisig.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_multisig.snap @@ -8,13 +8,11 @@ TokenStream: #[starknet::contract] pub mod MyContract { use starknet::ContractAddress; - #[storage] pub struct Storage { #[substorage(v0)] pub multisig: MultisigComponent::Storage, } - #[constructor] fn constructor(ref self: ContractState, quorum: u32, signers: Span) { self.multisig.initializer(quorum, signers); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_ownable.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_ownable.snap index df79c46c6..12525b648 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_ownable.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_ownable.snap @@ -8,13 +8,11 @@ TokenStream: #[starknet::contract] pub mod Owned { use starknet::ContractAddress; - #[storage] pub struct Storage { #[substorage(v0)] pub ownable: OwnableComponent::Storage, } - #[constructor] fn constructor(ref self: ContractState, owner: ContractAddress) { self.ownable.initializer(owner); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_ownable_no_initializer.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_ownable_no_initializer.snap index cca30c544..0a9dd1264 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_ownable_no_initializer.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_ownable_no_initializer.snap @@ -8,13 +8,11 @@ TokenStream: #[starknet::contract] pub mod Owned { use starknet::ContractAddress; - #[storage] pub struct Storage { #[substorage(v0)] pub ownable: OwnableComponent::Storage, } - #[constructor] fn constructor(ref self: ContractState) {} use openzeppelin_access::ownable::OwnableComponent; diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_pausable.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_pausable.snap index d52b4ca72..a91e07728 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_pausable.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_pausable.snap @@ -12,7 +12,6 @@ pub mod MyContract { #[substorage(v0)] pub pausable: PausableComponent::Storage, } - #[generate_trait] #[abi(per_item)] impl ExternalImpl of ExternalTrait { @@ -20,7 +19,6 @@ pub mod MyContract { fn pause(ref self: ContractState) { self.pausable.pause(); } - #[external(v0)] fn unpause(ref self: ContractState) { self.pausable.unpause(); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_pausable_no_pause_call.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_pausable_no_pause_call.snap index 7dfc3b098..0bb08ae6a 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_pausable_no_pause_call.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_pausable_no_pause_call.snap @@ -12,7 +12,6 @@ pub mod MyContract { #[substorage(v0)] pub pausable: PausableComponent::Storage, } - #[generate_trait] #[abi(per_item)] impl ExternalImpl of ExternalTrait { diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_pausable_no_unpause_call.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_pausable_no_unpause_call.snap index c363e6c02..22cedfb83 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_pausable_no_unpause_call.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_pausable_no_unpause_call.snap @@ -12,7 +12,6 @@ pub mod MyContract { #[substorage(v0)] pub pausable: PausableComponent::Storage, } - #[generate_trait] #[abi(per_item)] impl ExternalImpl of ExternalTrait { diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_src9.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_src9.snap index d36bd70e0..2617b8876 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_src9.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_src9.snap @@ -12,7 +12,6 @@ pub mod MyContract { #[substorage(v0)] pub src9: SRC9Component::Storage, } - #[constructor] fn constructor(ref self: ContractState) { self.src9.initializer(); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_timelock_controller.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_timelock_controller.snap index 6c9b15a34..7cd684669 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_timelock_controller.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_timelock_controller.snap @@ -8,13 +8,11 @@ TokenStream: #[starknet::contract] pub mod MyContract { use starknet::ContractAddress; - #[storage] pub struct Storage { #[substorage(v0)] pub timelock_controller: TimelockControllerComponent::Storage, } - #[constructor] fn constructor( ref self: ContractState, diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_two_components.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_two_components.snap index 01b950242..7b0d6c82e 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_two_components.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_two_components.snap @@ -9,7 +9,6 @@ TokenStream: pub mod MyToken { use openzeppelin_token::erc20::{DefaultConfig, ERC20HooksEmptyImpl}; use starknet::ContractAddress; - #[storage] pub struct Storage { #[substorage(v0)] @@ -17,7 +16,6 @@ pub mod MyToken { #[substorage(v0)] pub ownable: OwnableComponent::Storage, } - #[constructor] fn constructor(ref self: ContractState, owner: ContractAddress) { self.ownable.initializer(owner); diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_two_components_no_constructor.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_two_components_no_constructor.snap index 6b43e9ea4..2a80b8307 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_two_components_no_constructor.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_two_components_no_constructor.snap @@ -9,7 +9,6 @@ TokenStream: pub mod MyToken { use openzeppelin_token::erc20::{DefaultConfig, ERC20HooksEmptyImpl}; use starknet::ContractAddress; - #[storage] pub struct Storage { #[substorage(v0)] diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_two_components_no_initializer.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_two_components_no_initializer.snap index 9c49d55b3..fc02d505a 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_two_components_no_initializer.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_two_components_no_initializer.snap @@ -9,7 +9,6 @@ TokenStream: pub mod MyToken { use openzeppelin_token::erc20::{DefaultConfig, ERC20HooksEmptyImpl}; use starknet::ContractAddress; - #[storage] pub struct Storage { #[substorage(v0)] @@ -17,7 +16,6 @@ pub mod MyToken { #[substorage(v0)] pub ownable: OwnableComponent::Storage, } - #[constructor] fn constructor(ref self: ContractState) {} use openzeppelin_access::ownable::OwnableComponent; diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_upgradeable.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_upgradeable.snap index de5660a0b..3f484ec2e 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_upgradeable.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_upgradeable.snap @@ -12,7 +12,6 @@ pub mod MyContract { #[substorage(v0)] pub upgradeable: UpgradeableComponent::Storage, } - #[abi(embed_v0)] impl UpgradeableImpl of IUpgradeable { fn upgrade(ref self: ContractState, new_class_hash: ClassHash) { diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_upgradeable_no_upgrade_call.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_upgradeable_no_upgrade_call.snap index c170d3b57..049fa5e25 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_upgradeable_no_upgrade_call.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_upgradeable_no_upgrade_call.snap @@ -12,7 +12,6 @@ pub mod MyContract { #[substorage(v0)] pub upgradeable: UpgradeableComponent::Storage, } - #[abi(embed_v0)] impl UpgradeableImpl of IUpgradeable { fn upgrade(ref self: ContractState, new_class_hash: ClassHash) {} diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_vesting.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_vesting.snap index 25a8df428..c5822dc67 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_vesting.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_vesting.snap @@ -9,7 +9,6 @@ TokenStream: pub mod VestingWallet { use openzeppelin_finance::vesting::LinearVestingSchedule; use starknet::ContractAddress; - #[storage] pub struct Storage { #[substorage(v0)] @@ -17,7 +16,6 @@ pub mod VestingWallet { #[substorage(v0)] pub ownable: OwnableComponent::Storage, } - #[constructor] fn constructor( ref self: ContractState, diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_vesting_no_initializer.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_vesting_no_initializer.snap index 0ab787673..ff1a4944f 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_vesting_no_initializer.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_vesting_no_initializer.snap @@ -9,7 +9,6 @@ TokenStream: pub mod VestingWallet { use openzeppelin_finance::vesting::LinearVestingSchedule; use starknet::ContractAddress; - #[storage] pub struct Storage { #[substorage(v0)] @@ -17,7 +16,6 @@ pub mod VestingWallet { #[substorage(v0)] pub ownable: OwnableComponent::Storage, } - #[constructor] fn constructor( ref self: ContractState, diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_vesting_no_schedule.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_vesting_no_schedule.snap index b1091204f..322cc178a 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_vesting_no_schedule.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_vesting_no_schedule.snap @@ -8,7 +8,6 @@ TokenStream: #[starknet::contract] pub mod VestingWallet { use starknet::ContractAddress; - #[storage] pub struct Storage { #[substorage(v0)] @@ -16,7 +15,6 @@ pub mod VestingWallet { #[substorage(v0)] pub ownable: OwnableComponent::Storage, } - #[constructor] fn constructor( ref self: ContractState, diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_votes.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_votes.snap index 46a100f85..cbc883c14 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_votes.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_with_components__with_votes.snap @@ -8,20 +8,17 @@ TokenStream: #[starknet::contract] pub mod MyContract { use openzeppelin_utils::cryptography::snip12::SNIP12Metadata; - #[storage] pub struct Storage { #[substorage(v0)] pub votes: VotesComponent::Storage, } - - /// Required for hash computation. pub impl SNIP12MetadataImpl of SNIP12Metadata { fn name() -> felt252 { - 'DAPP_NAME' + "DAPP_NAME" } fn version() -> felt252 { - 'DAPP_VERSION' + "DAPP_VERSION" } } use openzeppelin_governance::votes::VotesComponent; diff --git a/packages/macros/src/tests/test_type_hash.rs b/packages/macros/src/tests/test_type_hash.rs index 5e8ea6e3b..ff57d655d 100644 --- a/packages/macros/src/tests/test_type_hash.rs +++ b/packages/macros/src/tests/test_type_hash.rs @@ -1,5 +1,4 @@ -use cairo_lang_macro::TokenStream; -use indoc::indoc; +use cairo_lang_macro::{quote, TokenStream}; use insta::assert_snapshot; use crate::type_hash::definition::type_hash_jgjpoopqerqnq as type_hash; @@ -8,51 +7,42 @@ use super::common::format_proc_macro_result; #[test] fn test_empty_input() { - let item = indoc!( - " - " - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + let item = quote! {}; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_empty_struct() { - let item = indoc!( - " + let item = quote! { pub struct MyType {} - " - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_empty_enum() { - let item = indoc!( - " + let item = quote! { pub enum MyEnum {} - " - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_snip12_attribute_empty() { - let item = indoc!( - " + let item = quote! { pub struct MyType { #[snip12()] pub name: felt252, } - " - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } @@ -67,8 +57,7 @@ fn test_basic_types() { // - Selector // - U128 // - I128 - let item = indoc!( - r#" + let item = quote! { pub struct MyType { pub name: felt252, #[snip12(kind: "shortstring")] @@ -82,17 +71,15 @@ fn test_basic_types() { pub u128_member: u128, pub i128_member: i128, } - "# - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_basic_types_enum() { - let item = indoc!( - r#" + let item = quote! { pub enum MyEnum { Variant1: felt252, Variant2: ClassHash, @@ -106,10 +93,9 @@ fn test_basic_types_enum() { #[snip12(kind: "selector")] Variant8: felt252, } - "# - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } @@ -119,85 +105,74 @@ fn test_preset_types() { // - TokenAmount // - NftId // - U256 - let item = indoc!( - " + let item = quote! { pub struct MyType { pub token_amount: TokenAmount, pub nft_id: NftId, pub u256: u256, } - " - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_preset_types_enum() { - let item = indoc!( - " + let item = quote! { pub enum MyEnum { Variant1: TokenAmount, Variant2: NftId, Variant3: u256, } - " - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_with_inner_starknet_domain() { - let item = indoc!( - " + let item = quote! { pub struct MyType { pub starknet_domain: StarknetDomain, } - " - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_with_inner_u256_type() { - let item = indoc!( - " + let item = quote! { pub struct MyType { // TokenAmount type contains u256, which should be resolved // and appended to the final type hash. pub token_amount: TokenAmount, } - " - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_with_inner_u256_type_enum() { - let item = indoc!( - " + let item = quote! { pub enum MyEnum { // TokenAmount type contains u256, which should be resolved // and appended to the final type hash. Variant1: TokenAmount, } - " - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_potential_duplicate_types() { - let item = indoc!( - " + let item = quote! { pub struct MyType { // TokenAmount type contains u256, which should be resolved // and appended to the final type hash. @@ -205,17 +180,15 @@ fn test_potential_duplicate_types() { pub token_amount_2: TokenAmount, pub number: u256, } - " - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_potential_duplicate_types_enum() { - let item = indoc!( - " + let item = quote! { pub enum MyEnum { // TokenAmount type contains u256, which should be resolved // and appended to the final type hash. @@ -223,17 +196,15 @@ fn test_potential_duplicate_types_enum() { Variant2: TokenAmount, Variant3: u256, } - " - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_complex_struct_type() { - let item = indoc!( - r#" + let item = quote! { pub struct MyType { pub token_amount: TokenAmount, pub token_amount_2: TokenAmount, @@ -249,17 +220,15 @@ fn test_complex_struct_type() { pub u128_member: u128, pub i128_member: i128, } - "# - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_complex_enum_type() { - let item = indoc!( - r#" + let item = quote! { pub enum MyEnum { Variant1: TokenAmount, Variant2: TokenAmount, @@ -275,17 +244,15 @@ fn test_complex_enum_type() { Variant9: u128, Variant10: i128, } - "# - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_with_inner_custom_type() { - let item = indoc!( - " + let item = quote! { pub struct MyType { pub name: felt252, pub version: felt252, @@ -293,77 +260,67 @@ fn test_with_inner_custom_type() { pub revision: felt252, pub member: InnerCustomType, } - " - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_with_tuple() { - let item = indoc!( - " + let item = quote! { pub struct MyType { pub member: (felt252, felt252, ClassHash, NftId), } - " - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_with_tuple_enum() { - let item = indoc!( - " + let item = quote! { pub enum MyEnum { Variant1: (felt252, felt252, ClassHash, NftId), Variant2: TokenAmount, Variant3: (ContractAddress,), } - " - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_with_empty_tuple() { // This doesn't make sense, but it's a valid type. - let item = indoc!( - " + let item = quote! { pub struct MyType { pub member: (), } - " - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_with_empty_tuple_enum() { - let item = indoc!( - " + let item = quote! { pub enum MyEnum { Variant1: TokenAmount, Variant2: (), } - " - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_with_array() { - let item = indoc!( - " + let item = quote! { pub struct MyType { pub member1: Array, pub member2: Array, @@ -372,17 +329,15 @@ fn test_with_array() { pub member5: Array, pub member6: Array, } - " - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_with_span() { - let item = indoc!( - " + let item = quote! { pub struct MyType { pub member1: Span, pub member2: Span, @@ -391,32 +346,28 @@ fn test_with_span() { pub member5: Span, pub member6: Span, } - " - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_with_tuple_and_attribute() { - let item = indoc!( - r#" + let item = quote! { pub struct MyType { #[snip12(kind: "(shortstring, felt252, ClassHash, NftId)")] pub member: (felt252, felt252, ClassHash, NftId), } - "# - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_starknet_domain() { - let item = indoc!( - r#" + let item = quote! { pub struct StarknetDomain { #[snip12(kind: "shortstring")] pub name: felt252, @@ -427,17 +378,15 @@ fn test_starknet_domain() { #[snip12(kind: "shortstring")] pub revision: felt252, } - "# - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_complex_struct_with_collection_types() { - let item = indoc!( - r#" + let item = quote! { pub struct MyType { pub member1: (felt252, felt252, ClassHash, NftId), pub member2: Array, @@ -453,17 +402,15 @@ fn test_complex_struct_with_collection_types() { pub member11: Array<(TokenAmount, ContractAddress, Array)>, pub member12: Array, Array, Array)>>, } - "# - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_complex_struct_with_collection_types_custom_names() { - let item = indoc!( - r#" + let item = quote! { pub struct MyType { #[snip12(name: "Member 1")] pub member1: (felt252, felt252, ClassHash, NftId), @@ -490,17 +437,15 @@ fn test_complex_struct_with_collection_types_custom_names() { #[snip12(name: "Member 12")] pub member12: Array, Array, Array)>>, } - "# - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_complex_enum_with_collection_types() { - let item = indoc!( - r#" + let item = quote! { pub enum MyEnum { Variant1: (felt252, felt252, ClassHash, NftId), Variant2: Array, @@ -516,17 +461,15 @@ fn test_complex_enum_with_collection_types() { Variant11: Array<(TokenAmount, ContractAddress, Array)>, Variant12: Array, Array, Array)>>, } - "# - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_complex_enum_with_collection_types_custom_names() { - let item = indoc!( - r#" + let item = quote! { pub enum MyEnum { #[snip12(name: "Variant 1")] Variant1: (felt252, felt252, ClassHash, NftId), @@ -553,17 +496,15 @@ fn test_complex_enum_with_collection_types_custom_names() { #[snip12(name: "Variant 12")] Variant12: Array, Array, Array)>>, } - "# - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_name_attribute() { - let item = indoc!( - r#" + let item = quote! { pub enum MyEnum { #[snip12(name: "Variant 1")] Variant1: (felt252, felt252, ClassHash, NftId), @@ -576,68 +517,59 @@ fn test_name_attribute() { #[snip12(name: "Variant 5")] Variant5: Array, } - "# - ); - let attr_stream = r#"(name: "My Enum")"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (name: "My Enum") }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_debug_attribute() { - let item = indoc!( - " + let item = quote! { pub struct MyType { pub member: felt252, } - " - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_invalid_type_hash_attribute() { - let item = indoc!( - " + let item = quote! { pub struct MyType { pub member: felt252, } - " - ); - let attr_stream = r#"(other: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (other: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_enum_without_explicit_variant_type() { - let item = indoc!( - " + let item = quote! { pub enum MyEnum { Variant1, Variant2, } - " - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_merkletree_type() { - let item = indoc!( - r#" + let item = quote! { pub struct MyType { #[snip12(kind: "merkletree")] pub member: felt252, } - "# - ); - let attr_stream = r#"(debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } @@ -647,23 +579,20 @@ fn test_merkletree_type() { #[test] fn test_doc_example_1() { - let item = indoc!( - r#" + let item = quote! { struct MyStruct { #[snip12(name: "My Field")] my_field: felt252, } - "# - ); - let attr_stream = r#"(name: "My Struct", debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (name: "My Struct", debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_doc_example_2() { - let item = indoc!( - r#" + let item = quote! { pub struct MyStruct { #[snip12(name: "Simple Felt")] // Optional custom name pub simple_felt: felt252, @@ -676,17 +605,15 @@ fn test_doc_example_2() { #[snip12(name: "Selector", kind: "selector")] pub selector: felt252, } - "# - ); - let attr_stream = r#"(name: "My Struct", debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (name: "My Struct", debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_doc_example_3() { - let item = indoc!( - r#" + let item = quote! { pub enum MyEnum { #[snip12(name: "Simple Felt")] SimpleFelt: felt252, @@ -699,17 +626,15 @@ fn test_doc_example_3() { #[snip12(name: "Selector", kind: "selector")] Selector: felt252, } - "# - ); - let attr_stream = r#"(name: "My Enum", debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (name: "My Enum", debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_doc_example_4() { - let item = indoc!( - r#" + let item = quote! { pub struct MyStruct { #[snip12(name: "Member 1")] pub member1: Array, @@ -718,17 +643,15 @@ fn test_doc_example_4() { #[snip12(name: "Timestamps", kind: "Array")] pub timestamps: Array, } - "# - ); - let attr_stream = r#"(name: "My Struct", debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (name: "My Struct", debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_doc_example_5() { - let item = indoc!( - r#" + let item = quote! { pub enum MyEnum { #[snip12(name: "Member 1")] Member1: Array, @@ -739,17 +662,15 @@ fn test_doc_example_5() { #[snip12(name: "Name and Last Name", kind: "(shortstring, shortstring)")] NameAndLastName: (felt252, felt252), } - "# - ); - let attr_stream = r#"(name: "My Enum", debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (name: "My Enum", debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_doc_example_6() { - let item = indoc!( - r#" + let item = quote! { pub struct MyStruct { #[snip12(name: "Token Amount")] pub token_amount: TokenAmount, @@ -758,17 +679,15 @@ fn test_doc_example_6() { #[snip12(name: "Number")] pub number: u256, } - "# - ); - let attr_stream = r#"(name: "My Struct", debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { (name: "My Struct", debug: true) }; + let result = get_string_result(attr_stream, item); assert_snapshot!(result); } #[test] fn test_doc_example_7() { - let item = indoc!( - r#" + let item_stream = quote! { pub enum MyEnum { #[snip12(name: "Token Amount")] TokenAmount: TokenAmount, @@ -777,16 +696,15 @@ fn test_doc_example_7() { #[snip12(name: "Number")] Number: u256, } - "# - ); - let attr_stream = r#"(name: "My Enum", debug: true)"#; - let result = get_string_result(item, attr_stream); + }; + let attr_stream = quote! { + (name: "My Enum", debug: true) + }; + let result = get_string_result(attr_stream, item_stream); assert_snapshot!(result); } -fn get_string_result(item: &str, attr_stream: &str) -> String { - let attr_stream = TokenStream::new(attr_stream.to_string()); - let item = TokenStream::new(item.to_string()); - let raw_result = type_hash(attr_stream, item); +fn get_string_result(attr_stream: TokenStream, item_stream: TokenStream) -> String { + let raw_result = type_hash(attr_stream, item_stream); format_proc_macro_result(raw_result) } diff --git a/packages/macros/src/tests/test_with_components.rs b/packages/macros/src/tests/test_with_components.rs index dfd5089c5..3d2d02e4d 100644 --- a/packages/macros/src/tests/test_with_components.rs +++ b/packages/macros/src/tests/test_with_components.rs @@ -1,15 +1,13 @@ use crate::attribute::with_components::definition::with_components_avevetedp5blk as with_components; -use cairo_lang_macro::TokenStream; -use indoc::indoc; +use cairo_lang_macro::{quote, TokenStream}; use insta::assert_snapshot; use super::common::format_proc_macro_result; #[test] fn test_with_account() { - let attribute = "(Account)"; - let item = indoc!( - " + let attribute = quote! { (Account) }; + let item = quote! { #[starknet::contract(account)] pub mod MyContract { #[storage] @@ -20,33 +18,29 @@ fn test_with_account() { self.account.initializer(public_key); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_account_no_initializer() { - let attribute = "(Account)"; - let item = indoc!( - " + let attribute = quote! { (Account) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] pub struct Storage {} } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_eth_account() { - let attribute = "(EthAccount)"; - let item = indoc!( - " + let attribute = quote! { (EthAccount) }; + let item = quote! { #[starknet::contract(account)] pub mod MyContract { use openzeppelin_interfaces::accounts::EthPublicKey; @@ -59,33 +53,29 @@ fn test_with_eth_account() { self.eth_account.initializer(public_key); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_eth_account_no_initializer() { - let attribute = "(EthAccount)"; - let item = indoc!( - " + let attribute = quote! { (EthAccount) }; + let item = quote! { #[starknet::contract(account)] pub mod MyContract { #[storage] pub struct Storage {} } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_src9() { - let attribute = "(SRC9)"; - let item = indoc!( - " + let attribute = quote! { (SRC9) }; + let item = quote! { #[starknet::contract(src9)] pub mod MyContract { #[storage] @@ -96,33 +86,29 @@ fn test_with_src9() { self.src9.initializer(); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_src9_no_initializer() { - let attribute = "(SRC9)"; - let item = indoc!( - " + let attribute = quote! { (SRC9) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] pub struct Storage {} } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_erc20() { - let attribute = "(ERC20)"; - let item = indoc!( - " + let attribute = quote! { (ERC20) }; + let item = quote! { #[starknet::contract] pub mod MyToken { use openzeppelin_token::erc20::{ERC20HooksEmptyImpl, DefaultConfig}; @@ -133,20 +119,18 @@ fn test_with_erc20() { #[constructor] fn constructor(ref self: ContractState) { - self.erc20.initializer(\"MyToken\", \"MTK\"); + self.erc20.initializer("MyToken", "MTK"); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_erc20_no_initializer() { - let attribute = "(ERC20)"; - let item = indoc!( - " + let attribute = quote! { (ERC20) }; + let item = quote! { #[starknet::contract] pub mod MyToken { use openzeppelin_token::erc20::{ERC20HooksEmptyImpl, DefaultConfig}; @@ -159,17 +143,15 @@ fn test_with_erc20_no_initializer() { fn constructor(ref self: ContractState) { } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_erc20_no_hooks_impl() { - let attribute = "(ERC20)"; - let item = indoc!( - " + let attribute = quote! { (ERC20) }; + let item = quote! { #[starknet::contract] pub mod MyToken { use openzeppelin_token::erc20::DefaultConfig; @@ -180,20 +162,18 @@ fn test_with_erc20_no_hooks_impl() { #[constructor] fn constructor(ref self: ContractState) { - self.erc20.initializer(\"MyToken\", \"MTK\"); + self.erc20.initializer("MyToken", "MTK"); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_erc20_no_config() { - let attribute = "(ERC20)"; - let item = indoc!( - " + let attribute = quote! { (ERC20) }; + let item = quote! { #[starknet::contract] pub mod MyToken { use openzeppelin_token::erc20::ERC20HooksEmptyImpl; @@ -204,20 +184,18 @@ fn test_with_erc20_no_config() { #[constructor] fn constructor(ref self: ContractState) { - self.erc20.initializer(\"MyToken\", \"MTK\"); + self.erc20.initializer("MyToken", "MTK"); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_ownable() { - let attribute = "(Ownable)"; - let item = indoc!( - " + let attribute = quote! { (Ownable) }; + let item = quote! { #[starknet::contract] pub mod Owned { use starknet::ContractAddress; @@ -230,17 +208,15 @@ fn test_with_ownable() { self.ownable.initializer(owner); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_ownable_no_initializer() { - let attribute = "(Ownable)"; - let item = indoc!( - " + let attribute = quote! { (Ownable) }; + let item = quote! { #[starknet::contract] pub mod Owned { use starknet::ContractAddress; @@ -252,17 +228,15 @@ fn test_with_ownable_no_initializer() { fn constructor(ref self: ContractState) { } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_two_components() { - let attribute = "(ERC20, Ownable)"; - let item = indoc!( - " + let attribute = quote! { (ERC20, Ownable) }; + let item = quote! { #[starknet::contract] pub mod MyToken { use openzeppelin_token::erc20::{ERC20HooksEmptyImpl, DefaultConfig}; @@ -274,20 +248,18 @@ fn test_with_two_components() { #[constructor] fn constructor(ref self: ContractState, owner: ContractAddress) { self.ownable.initializer(owner); - self.erc20.initializer(\"MyToken\", \"MTK\"); + self.erc20.initializer("MyToken", "MTK"); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_two_components_no_initializer() { - let attribute = "(ERC20, Ownable)"; - let item = indoc!( - " + let attribute = quote! { (ERC20, Ownable) }; + let item = quote! { #[starknet::contract] pub mod MyToken { use openzeppelin_token::erc20::{ERC20HooksEmptyImpl, DefaultConfig}; @@ -300,17 +272,15 @@ fn test_with_two_components_no_initializer() { fn constructor(ref self: ContractState) { } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_two_components_no_constructor() { - let attribute = "(ERC20, Ownable)"; - let item = indoc!( - " + let attribute = quote! { (ERC20, Ownable) }; + let item = quote! { #[starknet::contract] pub mod MyToken { use openzeppelin_token::erc20::{ERC20HooksEmptyImpl, DefaultConfig}; @@ -319,17 +289,15 @@ fn test_with_two_components_no_constructor() { #[storage] pub struct Storage {} } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_access_control() { - let attribute = "(AccessControl)"; - let item = indoc!( - " + let attribute = quote! { (AccessControl) }; + let item = quote! { #[starknet::contract] pub mod Contract { use openzeppelin_access::accesscontrol::DEFAULT_ADMIN_ROLE; @@ -345,17 +313,15 @@ fn test_with_access_control() { self.access_control._grant_role(DEFAULT_ADMIN_ROLE, default_admin); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_access_control_no_initializer() { - let attribute = "(AccessControl)"; - let item = indoc!( - " + let attribute = quote! { (AccessControl) }; + let item = quote! { #[starknet::contract] pub mod Contract { use openzeppelin_access::accesscontrol::DEFAULT_ADMIN_ROLE; @@ -368,17 +334,15 @@ fn test_with_access_control_no_initializer() { fn constructor(ref self: ContractState) { } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_vesting() { - let attribute = "(Vesting, Ownable)"; - let item = indoc!( - " + let attribute = quote! { (Vesting, Ownable) }; + let item = quote! { #[starknet::contract] pub mod VestingWallet { use openzeppelin_finance::vesting::LinearVestingSchedule; @@ -399,17 +363,15 @@ fn test_with_vesting() { self.vesting.initializer(start, duration, cliff_duration); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_vesting_no_initializer() { - let attribute = "(Vesting, Ownable)"; - let item = indoc!( - " + let attribute = quote! { (Vesting, Ownable) }; + let item = quote! { #[starknet::contract] pub mod VestingWallet { use openzeppelin_finance::vesting::LinearVestingSchedule; @@ -429,17 +391,15 @@ fn test_with_vesting_no_initializer() { self.ownable.initializer(beneficiary); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_vesting_no_schedule() { - let attribute = "(Vesting, Ownable)"; - let item = indoc!( - " + let attribute = quote! { (Vesting, Ownable) }; + let item = quote! { #[starknet::contract] pub mod VestingWallet { use starknet::ContractAddress; @@ -459,17 +419,15 @@ fn test_with_vesting_no_schedule() { self.vesting.initializer(start, duration, cliff_duration); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_no_contract_attribute() { - let attribute = "(Ownable)"; - let item = indoc!( - " + let attribute = quote! { (Ownable) }; + let item = quote! { pub mod Owned { use starknet::ContractAddress; @@ -481,77 +439,67 @@ fn test_with_no_contract_attribute() { self.ownable.initializer(owner); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_no_body() { - let attribute = "(ERC20, Ownable)"; - let item = indoc!( - " + let attribute = quote! { (ERC20, Ownable) }; + let item = quote! { pub mod MyContract; - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_no_components() { - let attribute = "()"; - let item = indoc!( - " + let attribute = quote! { () }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] pub struct Storage {} } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_invalid_component() { - let attribute = "(ERC6000, Ownable)"; - let item = indoc!( - " + let attribute = quote! { (ERC6000, Ownable) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] pub struct Storage {} } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_src5() { - let attribute = "(SRC5)"; - let item = indoc!( - " + let attribute = quote! { (SRC5) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] pub struct Storage {} } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_initializable() { - let attribute = "(Initializable)"; - let item = indoc!( - " + let attribute = quote! { (Initializable) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] @@ -566,33 +514,29 @@ fn test_with_initializable() { } } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_initializable_no_initialize_call() { - let attribute = "(Initializable)"; - let item = indoc!( - " + let attribute = quote! { (Initializable) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] pub struct Storage {} } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_pausable() { - let attribute = "(Pausable)"; - let item = indoc!( - " + let attribute = quote! { (Pausable) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] @@ -612,17 +556,15 @@ fn test_with_pausable() { } } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_pausable_no_pause_call() { - let attribute = "(Pausable)"; - let item = indoc!( - " + let attribute = quote! { (Pausable) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] @@ -637,17 +579,15 @@ fn test_with_pausable_no_pause_call() { } } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_pausable_no_unpause_call() { - let attribute = "(Pausable)"; - let item = indoc!( - " + let attribute = quote! { (Pausable) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] @@ -662,49 +602,43 @@ fn test_with_pausable_no_unpause_call() { } } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_pausable_no_pause_or_unpause_call() { - let attribute = "(Pausable)"; - let item = indoc!( - " + let attribute = quote! { (Pausable) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] pub struct Storage {} } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_reentrancy_guard() { - let attribute = "(ReentrancyGuard)"; - let item = indoc!( - " + let attribute = quote! { (ReentrancyGuard) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] pub struct Storage {} } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_erc721() { - let attribute = "(ERC721)"; - let item = indoc!( - " + let attribute = quote! { (ERC721) }; + let item = quote! { #[starknet::contract] pub mod MyContract { use openzeppelin_token::erc721::ERC721HooksEmptyImpl; @@ -714,20 +648,18 @@ fn test_with_erc721() { #[constructor] fn constructor(ref self: ContractState) { - self.erc721.initializer(\"MyToken\", \"MTK\", \"\"); + self.erc721.initializer("MyToken", "MTK", ""); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_erc721_no_initializer() { - let attribute = "(ERC721)"; - let item = indoc!( - " + let attribute = quote! { (ERC721) }; + let item = quote! { #[starknet::contract] pub mod MyContract { use openzeppelin_token::erc721::ERC721HooksEmptyImpl; @@ -735,17 +667,15 @@ fn test_with_erc721_no_initializer() { #[storage] pub struct Storage {} } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_erc721_no_hooks_impl() { - let attribute = "(ERC721)"; - let item = indoc!( - " + let attribute = quote! { (ERC721) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] @@ -753,20 +683,18 @@ fn test_with_erc721_no_hooks_impl() { #[constructor] fn constructor(ref self: ContractState) { - self.erc721.initializer(\"MyToken\", \"MTK\", \"\"); + self.erc721.initializer("MyToken", "MTK", ""); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_erc1155() { - let attribute = "(ERC1155)"; - let item = indoc!( - " + let attribute = quote! { (ERC1155) }; + let item = quote! { #[starknet::contract] pub mod MyContract { use openzeppelin_token::erc1155::ERC1155HooksEmptyImpl; @@ -776,20 +704,18 @@ fn test_with_erc1155() { #[constructor] fn constructor(ref self: ContractState) { - self.erc1155.initializer(\"\"); + self.erc1155.initializer(""); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_erc1155_no_initializer() { - let attribute = "(ERC1155)"; - let item = indoc!( - " + let attribute = quote! { (ERC1155) }; + let item = quote! { #[starknet::contract] pub mod MyContract { use openzeppelin_token::erc1155::ERC1155HooksEmptyImpl; @@ -797,17 +723,15 @@ fn test_with_erc1155_no_initializer() { #[storage] pub struct Storage {} } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_erc1155_no_hooks_impl() { - let attribute = "(ERC1155)"; - let item = indoc!( - " + let attribute = quote! { (ERC1155) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] @@ -815,20 +739,18 @@ fn test_with_erc1155_no_hooks_impl() { #[constructor] fn constructor(ref self: ContractState) { - self.erc1155.initializer(\"\"); + self.erc1155.initializer(""); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_erc721_enumerable() { - let attribute = "(ERC721Enumerable)"; - let item = indoc!( - " + let attribute = quote! { (ERC721Enumerable) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] @@ -839,33 +761,29 @@ fn test_with_erc721_enumerable() { self.erc721_enumerable.initializer(); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_erc721_enumerable_no_initializer() { - let attribute = "(ERC721Enumerable)"; - let item = indoc!( - " + let attribute = quote! { (ERC721Enumerable) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] pub struct Storage {} } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_erc721_receiver() { - let attribute = "(ERC721Receiver)"; - let item = indoc!( - " + let attribute = quote! { (ERC721Receiver) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] @@ -876,33 +794,29 @@ fn test_with_erc721_receiver() { self.erc721_receiver.initializer(); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_erc721_receiver_no_initializer() { - let attribute = "(ERC721Receiver)"; - let item = indoc!( - " + let attribute = quote! { (ERC721Receiver) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] pub struct Storage {} } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_erc1155_receiver() { - let attribute = "(ERC1155Receiver)"; - let item = indoc!( - " + let attribute = quote! { (ERC1155Receiver) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] @@ -913,33 +827,29 @@ fn test_with_erc1155_receiver() { self.erc1155_receiver.initializer(); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_erc1155_receiver_no_initializer() { - let attribute = "(ERC1155Receiver)"; - let item = indoc!( - " + let attribute = quote! { (ERC1155Receiver) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] pub struct Storage {} } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_erc2981() { - let attribute = "(ERC2981)"; - let item = indoc!( - " + let attribute = quote! { (ERC2981) }; + let item = quote! { #[starknet::contract] pub mod MyContract { use openzeppelin_token::common::erc2981::DefaultConfig; @@ -953,17 +863,15 @@ fn test_with_erc2981() { self.erc2981.initializer(default_royalty_receiver, 0); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_erc2981_no_initializer() { - let attribute = "(ERC2981)"; - let item = indoc!( - " + let attribute = quote! { (ERC2981) }; + let item = quote! { #[starknet::contract] pub mod MyContract { use openzeppelin_token::common::erc2981::DefaultConfig; @@ -971,17 +879,15 @@ fn test_with_erc2981_no_initializer() { #[storage] pub struct Storage {} } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_erc2981_no_config() { - let attribute = "(ERC2981)"; - let item = indoc!( - " + let attribute = quote! { (ERC2981) }; + let item = quote! { #[starknet::contract] pub mod MyContract { use starknet::ContractAddress; @@ -994,17 +900,15 @@ fn test_with_erc2981_no_config() { self.erc2981.initializer(default_royalty_receiver, 0); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_erc2981_no_initializer_no_config() { - let attribute = "(ERC2981)"; - let item = indoc!( - " + let attribute = quote! { (ERC2981) }; + let item = quote! { #[starknet::contract] pub mod MyContract { use starknet::ContractAddress; @@ -1016,17 +920,15 @@ fn test_with_erc2981_no_initializer_no_config() { fn constructor(ref self: ContractState, default_royalty_receiver: ContractAddress) { } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_upgradeable() { - let attribute = "(Upgradeable)"; - let item = indoc!( - " + let attribute = quote! { (Upgradeable) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] @@ -1039,17 +941,15 @@ fn test_with_upgradeable() { } } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_upgradeable_no_upgrade_call() { - let attribute = "(Upgradeable)"; - let item = indoc!( - " + let attribute = quote! { (Upgradeable) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] @@ -1061,33 +961,29 @@ fn test_with_upgradeable_no_upgrade_call() { } } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_nonces() { - let attribute = "(Nonces)"; - let item = indoc!( - " + let attribute = quote! { (Nonces) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] pub struct Storage {} } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_multisig() { - let attribute = "(Multisig)"; - let item = indoc!( - " + let attribute = quote! { (Multisig) }; + let item = quote! { #[starknet::contract] pub mod MyContract { use starknet::ContractAddress; @@ -1100,33 +996,29 @@ fn test_with_multisig() { self.multisig.initializer(quorum, signers); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_multisig_no_initializer() { - let attribute = "(Multisig)"; - let item = indoc!( - " + let attribute = quote! { (Multisig) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] pub struct Storage {} } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_timelock_controller() { - let attribute = "(TimelockController)"; - let item = indoc!( - " + let attribute = quote! { (TimelockController) }; + let item = quote! { #[starknet::contract] pub mod MyContract { use starknet::ContractAddress; @@ -1145,33 +1037,29 @@ fn test_with_timelock_controller() { self.timelock_controller.initializer(min_delay, proposers, executors, admin); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_timelock_controller_no_initializer() { - let attribute = "(TimelockController)"; - let item = indoc!( - " + let attribute = quote! { (TimelockController) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] pub struct Storage {} } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_votes() { - let attribute = "(Votes)"; - let item = indoc!( - " + let attribute = quote! { (Votes) }; + let item = quote! { #[starknet::contract] pub mod MyContract { use openzeppelin_utils::cryptography::snip12::SNIP12Metadata; @@ -1179,43 +1067,39 @@ fn test_with_votes() { #[storage] pub struct Storage {} - /// Required for hash computation. + // Required for hash computation. pub impl SNIP12MetadataImpl of SNIP12Metadata { fn name() -> felt252 { - 'DAPP_NAME' + "DAPP_NAME" // quote! fails to recognize short strings } fn version() -> felt252 { - 'DAPP_VERSION' + "DAPP_VERSION" // quote! fails to recognize short strings } } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_votes_no_metadata() { - let attribute = "(Votes)"; - let item = indoc!( - " + let attribute = quote! { (Votes) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] pub struct Storage {} } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_event_struct() { - let attribute = "(Ownable)"; - let item = indoc!( - " + let attribute = quote! { (Ownable) }; + let item = quote! { #[starknet::contract] pub mod Owned { use starknet::ContractAddress; @@ -1229,7 +1113,7 @@ fn test_with_event_struct() { Transfer: Transfer, } - /// Emitted when tokens are moved from address `from` to address `to`. + // Emitted when tokens are moved from address `from` to address `to`. #[derive(Drop, starknet::Event)] pub struct Transfer { #[key] @@ -1244,17 +1128,15 @@ fn test_with_event_struct() { self.ownable.initializer(owner); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_erc4626() { - let attribute = "(ERC20, ERC4626)"; - let item = indoc!( - " + let attribute = quote! { (ERC20, ERC4626) }; + let item = quote! { #[starknet::contract] pub mod ERC4626Mock { use openzeppelin_token::erc20::extensions::erc4626::{ @@ -1294,17 +1176,15 @@ fn test_with_erc4626() { self.erc4626.initializer(underlying_asset); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_governor() { - let attribute = "(Governor)"; - let item = indoc!( - " + let attribute = quote! { (Governor) }; + let item = quote! { #[starknet::contract] pub mod MyContract { use openzeppelin_governance::governor::DefaultConfig; @@ -1317,17 +1197,15 @@ fn test_with_governor() { self.governor.initializer(); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_governor_no_initializer() { - let attribute = "(Governor)"; - let item = indoc!( - " + let attribute = quote! { (Governor) }; + let item = quote! { #[starknet::contract] pub mod MyContract { use openzeppelin_governance::governor::DefaultConfig; @@ -1339,17 +1217,15 @@ fn test_with_governor_no_initializer() { fn constructor(ref self: ContractState) { } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_governor_no_config() { - let attribute = "(Governor)"; - let item = indoc!( - " + let attribute = quote! { (Governor) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] @@ -1360,49 +1236,43 @@ fn test_with_governor_no_config() { self.governor.initializer(); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_governor_core_execution() { - let attribute = "(GovernorCoreExecution)"; - let item = indoc!( - " + let attribute = quote! { (GovernorCoreExecution) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] pub struct Storage {} } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_governor_counting_simple() { - let attribute = "(GovernorCountingSimple)"; - let item = indoc!( - " + let attribute = quote! { (GovernorCountingSimple) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] pub struct Storage {} } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_governor_settings() { - let attribute = "(GovernorSettings)"; - let item = indoc!( - " + let attribute = quote! { (GovernorSettings) }; + let item = quote! { #[starknet::contract] pub mod MyContract { pub const VOTING_DELAY: u64 = 86400; // 1 day @@ -1417,17 +1287,15 @@ fn test_with_governor_settings() { self.governor_settings.initializer(VOTING_DELAY, VOTING_PERIOD, PROPOSAL_THRESHOLD); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_governor_settings_no_initializer() { - let attribute = "(GovernorSettings)"; - let item = indoc!( - " + let attribute = quote! { (GovernorSettings) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] @@ -1437,17 +1305,15 @@ fn test_with_governor_settings_no_initializer() { fn constructor(ref self: ContractState) { } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_governor_timelock_execution() { - let attribute = "(GovernorTimelockExecution)"; - let item = indoc!( - " + let attribute = quote! { (GovernorTimelockExecution) }; + let item = quote! { #[starknet::contract] pub mod MyContract { use starknet::ContractAddress; @@ -1460,17 +1326,15 @@ fn test_with_governor_timelock_execution() { self.governor_timelock_execution.initializer(timelock_controller); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_governor_timelock_execution_no_initializer() { - let attribute = "(GovernorTimelockExecution)"; - let item = indoc!( - " + let attribute = quote! { (GovernorTimelockExecution) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] @@ -1480,17 +1344,15 @@ fn test_with_governor_timelock_execution_no_initializer() { fn constructor(ref self: ContractState) { } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_governor_votes_quorum_fraction() { - let attribute = "(GovernorVotesQuorumFraction)"; - let item = indoc!( - " + let attribute = quote! { (GovernorVotesQuorumFraction) }; + let item = quote! { #[starknet::contract] pub mod MyContract { use starknet::ContractAddress; @@ -1505,33 +1367,29 @@ fn test_with_governor_votes_quorum_fraction() { self.governor_votes_quorum_fraction.initializer(votes_token, QUORUM_NUMERATOR); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_governor_votes_quorum_fraction_no_initializer() { - let attribute = "(GovernorVotesQuorumFraction)"; - let item = indoc!( - " + let attribute = quote! { (GovernorVotesQuorumFraction) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] pub struct Storage {} } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_governor_votes() { - let attribute = "(GovernorVotes)"; - let item = indoc!( - " + let attribute = quote! { (GovernorVotes) }; + let item = quote! { #[starknet::contract] pub mod MyContract { use starknet::ContractAddress; @@ -1544,33 +1402,29 @@ fn test_with_governor_votes() { self.governor_votes.initializer(votes_token); } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_governor_votes_no_initializer() { - let attribute = "(GovernorVotes)"; - let item = indoc!( - " + let attribute = quote! { (GovernorVotes) }; + let item = quote! { #[starknet::contract] pub mod MyContract { #[storage] pub struct Storage {} } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } #[test] fn test_with_governor_integration() { - let attribute = "(Governor, GovernorVotes, GovernorSettings, GovernorCountingSimple, GovernorTimelockExecution, SRC5)"; - let item = indoc!( - " + let attribute = quote! { (Governor, GovernorVotes, GovernorSettings, GovernorCountingSimple, GovernorTimelockExecution, SRC5) }; + let item = quote! { #[starknet::contract] pub mod GovernorTimelockedMock { use openzeppelin_governance::governor::DefaultConfig; @@ -1618,13 +1472,14 @@ fn test_with_governor_integration() { // SNIP12 Metadata // + // This should be 'DAPP_NAME' and 'DAPP_VERSION' but quote! fails to recognize short strings pub impl SNIP12MetadataImpl of SNIP12Metadata { fn name() -> felt252 { - 'DAPP_NAME' + "DAPP_NAME" // quote! fails to recognize short strings } fn version() -> felt252 { - 'DAPP_VERSION' + "DAPP_VERSION" // quote! fails to recognize short strings } } @@ -1633,14 +1488,12 @@ fn test_with_governor_integration() { // impl GovernorQuorum of GovernorComponent::GovernorQuorumTrait { - /// See `GovernorComponent::GovernorQuorumTrait::quorum`. fn quorum(self: @GovernorComponent::ComponentState, timepoint: u64) -> u256 { QUORUM } } } - " - ); + }; let result = get_string_result(attribute, item); assert_snapshot!(result); } @@ -1651,9 +1504,7 @@ fn test_with_governor_integration() { /// Returns a string representation of the result of the macro expansion, /// including the token stream, diagnostics and aux data. -fn get_string_result(attribute: &str, item: &str) -> String { - let attribute_stream = TokenStream::new(attribute.to_string()); - let item_stream = TokenStream::new(item.to_string()); - let raw_result = with_components(attribute_stream, item_stream); +fn get_string_result(attr_stream: TokenStream, item_stream: TokenStream) -> String { + let raw_result = with_components(attr_stream, item_stream); format_proc_macro_result(raw_result) } From 57f2ba0e47c160dc9cabf4477576bf5afda56798 Mon Sep 17 00:00:00 2001 From: Eric Nordelo Date: Wed, 13 Aug 2025 15:25:41 +0200 Subject: [PATCH 28/29] feat: refactor to v2 --- packages/macros/Cargo.lock | 3 +- .../generate_event_spy_helpers/definition.rs | 13 +++--- ...__event_with_invalid_non_default_attr.snap | 2 +- .../tests/test_generate_event_spy_helpers.rs | 41 +++++-------------- 4 files changed, 20 insertions(+), 39 deletions(-) diff --git a/packages/macros/Cargo.lock b/packages/macros/Cargo.lock index 32636d2e5..87dca4df1 100644 --- a/packages/macros/Cargo.lock +++ b/packages/macros/Cargo.lock @@ -686,7 +686,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf04c5ec15464ace8355a7b440a33aece288993475556d461154d7a62ad9947c" dependencies = [ "bit-set", - "derivative", "regex-automata", "regex-syntax", ] @@ -1784,7 +1783,7 @@ checksum = "35f5380909ffc31b4de4f4bdf96b877175a016aa2ca98cee39fcfd8c4d53d952" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.104", ] [[package]] diff --git a/packages/macros/src/inline/generate_event_spy_helpers/definition.rs b/packages/macros/src/inline/generate_event_spy_helpers/definition.rs index e40c6bfb6..60559c1c4 100644 --- a/packages/macros/src/inline/generate_event_spy_helpers/definition.rs +++ b/packages/macros/src/inline/generate_event_spy_helpers/definition.rs @@ -1,6 +1,7 @@ use cairo_lang_formatter::format_string; use cairo_lang_macro::{inline_macro, Diagnostic, ProcMacroResult, TokenStream}; use cairo_lang_parser::utils::SimpleParserDatabase; +use cairo_lang_syntax::node::with_db::SyntaxNodeWithDb; use proc_macro2::TokenStream as ProcTokenStream; use quote::{format_ident, quote}; @@ -54,7 +55,7 @@ use crate::{generate_event_spy_helpers::parser, utils::camel_to_snake}; /// ``` #[inline_macro] pub fn generate_event_spy_helpers(token_stream: TokenStream) -> ProcMacroResult { - // Parse the arguments + // 1. Parse the arguments let impl_block = match parser::parse_dsl(&token_stream.to_string()) { Ok((_, impl_block)) => impl_block, Err(e) => { @@ -64,15 +65,15 @@ pub fn generate_event_spy_helpers(token_stream: TokenStream) -> ProcMacroResult } }; - // Generate the helper functions + // 2. Generate the helper functions let expanded = generate_code(&impl_block).to_string(); - // Format the code + // 3. Return the result let db = SimpleParserDatabase::default(); - let formatted_code = format_string(&db, expanded); + let syntax_node = db.parse_virtual(expanded).unwrap(); + let content_node = SyntaxNodeWithDb::new(&syntax_node, &db); - // Return the result - ProcMacroResult::new(TokenStream::new(formatted_code)) + ProcMacroResult::new(cairo_lang_macro::quote! {#content_node}) } /// Generates the code for event spy helper functions based on the provided implementation block. diff --git a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__event_with_invalid_non_default_attr.snap b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__event_with_invalid_non_default_attr.snap index acfa6213d..df3d2e7a7 100644 --- a/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__event_with_invalid_non_default_attr.snap +++ b/packages/macros/src/tests/snapshots/openzeppelin_macros__tests__test_generate_event_spy_helpers__event_with_invalid_non_default_attr.snap @@ -10,7 +10,7 @@ None Diagnostics: ==== -Error: Parsing Error: Error { input: "#[non_default]\n event InvalidEvent(\n field: u64\n );\n }\n}\n", code: Char }==== +Error: Parsing Error: Error { input: "#[non_default]event InvalidEvent(field:u64);}}", code: Char }==== AuxData: diff --git a/packages/macros/src/tests/test_generate_event_spy_helpers.rs b/packages/macros/src/tests/test_generate_event_spy_helpers.rs index 5a6294a20..446968ca4 100644 --- a/packages/macros/src/tests/test_generate_event_spy_helpers.rs +++ b/packages/macros/src/tests/test_generate_event_spy_helpers.rs @@ -1,4 +1,4 @@ -use cairo_lang_macro::TokenStream; +use cairo_lang_macro::{quote, TokenStream}; use indoc::indoc; use insta::assert_snapshot; @@ -7,8 +7,7 @@ use crate::generate_event_spy_helpers::definition::generate_event_spy_helpers_q2 #[test] fn test_event_without_attrs() { - let input = indoc!( - " + let input = quote!( { pub impl MockContractSpyHelpers { event SimpleEvent( @@ -16,15 +15,13 @@ fn test_event_without_attrs() { ); } } - " ); assert_snapshot!(get_string_result(input)); } #[test] fn test_event_with_only() { - let input = indoc!( - " + let input = quote!( { pub impl MockContractSpyHelpers { #[only] @@ -33,15 +30,13 @@ fn test_event_with_only() { ); } } - " ); assert_snapshot!(get_string_result(input)); } #[test] fn test_event_with_key() { - let input = indoc!( - " + let input = quote!( { pub impl ContrMockContractSpyHelpersactSpy { event KeyedEvent( @@ -51,15 +46,13 @@ fn test_event_with_key() { ); } } - " ); assert_snapshot!(get_string_result(input)); } #[test] fn test_event_with_only_and_key() { - let input = indoc!( - " + let input = quote!( { pub impl MockContractSpyHelpers { #[only] @@ -69,15 +62,13 @@ fn test_event_with_only_and_key() { ); } } - " ); assert_snapshot!(get_string_result(input)); } #[test] fn test_event_with_invalid_non_default_attr() { - let input = indoc!( - " + let input = quote!( { pub impl MockContractSpyHelpers { #[non_default] @@ -86,15 +77,13 @@ fn test_event_with_invalid_non_default_attr() { ); } } - " ); assert_snapshot!(get_string_result(input)); } #[test] fn test_impl_without_pub() { - let input = indoc!( - " + let input = quote!( { impl MockContractSpyHelpers { event MockEvent( @@ -102,27 +91,23 @@ fn test_impl_without_pub() { ); } } - " ); assert_snapshot!(get_string_result(input)); } #[test] fn test_empty_impl() { - let input = indoc!( - " + let input = quote!( { impl MockContractSpyHelpers {} } - " ); assert_snapshot!(get_string_result(input)); } #[test] fn test_multiple_events() { - let input = indoc!( - " + let input = quote!( { impl MockContractSpyHelpers { event MockEvent( @@ -135,28 +120,24 @@ fn test_multiple_events() { ); } } - " ); assert_snapshot!(get_string_result(input)); } #[test] fn test_empty_event() { - let input = indoc!( - " + let input = quote!( { impl MockContractSpyHelpers { #[only] event EmptyEvent(); } } - " ); assert_snapshot!(get_string_result(input)); } -fn get_string_result(args_stream: &str) -> String { - let args_stream = TokenStream::new(args_stream.to_string()); +fn get_string_result(args_stream: TokenStream) -> String { let raw_result = generate_event_spy_helpers(args_stream); format_proc_macro_result(raw_result) } From 1be2abc7c32f7087875f17bf3b051a8caf2c103e Mon Sep 17 00:00:00 2001 From: Eric Nordelo Date: Wed, 13 Aug 2025 15:29:24 +0200 Subject: [PATCH 29/29] feat: fix linter issues --- .../src/inline/generate_event_spy_helpers/definition.rs | 1 - .../macros/src/tests/test_generate_event_spy_helpers.rs | 9 +++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/macros/src/inline/generate_event_spy_helpers/definition.rs b/packages/macros/src/inline/generate_event_spy_helpers/definition.rs index 60559c1c4..ecfbb6b76 100644 --- a/packages/macros/src/inline/generate_event_spy_helpers/definition.rs +++ b/packages/macros/src/inline/generate_event_spy_helpers/definition.rs @@ -1,4 +1,3 @@ -use cairo_lang_formatter::format_string; use cairo_lang_macro::{inline_macro, Diagnostic, ProcMacroResult, TokenStream}; use cairo_lang_parser::utils::SimpleParserDatabase; use cairo_lang_syntax::node::with_db::SyntaxNodeWithDb; diff --git a/packages/macros/src/tests/test_generate_event_spy_helpers.rs b/packages/macros/src/tests/test_generate_event_spy_helpers.rs index 446968ca4..0ff2cf8ff 100644 --- a/packages/macros/src/tests/test_generate_event_spy_helpers.rs +++ b/packages/macros/src/tests/test_generate_event_spy_helpers.rs @@ -1,5 +1,4 @@ use cairo_lang_macro::{quote, TokenStream}; -use indoc::indoc; use insta::assert_snapshot; use super::common::format_proc_macro_result; @@ -97,11 +96,9 @@ fn test_impl_without_pub() { #[test] fn test_empty_impl() { - let input = quote!( - { - impl MockContractSpyHelpers {} - } - ); + let input = quote!({ + impl MockContractSpyHelpers {} + }); assert_snapshot!(get_string_result(input)); }