@layerzerolabs/common-utils-macros-stellar-contracts 0.2.122

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/Cargo.toml +21 -0
  2. package/LICENSE +23 -0
  3. package/clippy.toml +7 -0
  4. package/package.json +37 -0
  5. package/rust-toolchain.toml +4 -0
  6. package/rustfmt.toml +15 -0
  7. package/src/auth.rs +95 -0
  8. package/src/contract_ttl.rs +92 -0
  9. package/src/error.rs +43 -0
  10. package/src/lib.rs +585 -0
  11. package/src/lz_contract.rs +105 -0
  12. package/src/rbac.rs +90 -0
  13. package/src/storage.rs +522 -0
  14. package/src/tests/auth.rs +230 -0
  15. package/src/tests/contract_ttl.rs +695 -0
  16. package/src/tests/error.rs +156 -0
  17. package/src/tests/lz_contract.rs +87 -0
  18. package/src/tests/mod.rs +11 -0
  19. package/src/tests/rbac.rs +523 -0
  20. package/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_multisig_code.snap +31 -0
  21. package/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_ownable_code.snap +39 -0
  22. package/src/tests/snapshots/common_macros__tests__auth__snapshot_only_auth_preserves_function_signature.snap +19 -0
  23. package/src/tests/snapshots/common_macros__tests__contract_ttl__snapshot_generated_contractimpl_code.snap +77 -0
  24. package/src/tests/snapshots/common_macros__tests__contract_ttl__snapshot_generated_contracttrait_code.snap +46 -0
  25. package/src/tests/snapshots/common_macros__tests__error__snapshot_generated_contract_error_code.snap +20 -0
  26. package/src/tests/snapshots/common_macros__tests__lz_contract__snapshot_generated_lz_contract_code.snap +51 -0
  27. package/src/tests/snapshots/common_macros__tests__rbac__snapshot_authorizer_role.snap +21 -0
  28. package/src/tests/snapshots/common_macros__tests__rbac__snapshot_preserve_function_signature.snap +21 -0
  29. package/src/tests/snapshots/common_macros__tests__ttl_configurable__snapshot_generated_ttl_configurable_code.snap +10 -0
  30. package/src/tests/snapshots/common_macros__tests__ttl_extendable__snapshot_generated_ttl_extendable_code.snap +8 -0
  31. package/src/tests/snapshots/common_macros__tests__upgradeable__snapshot_generated_upgradeable_code.snap +28 -0
  32. package/src/tests/storage/extract_fields.rs +87 -0
  33. package/src/tests/storage/gen_accessor_methods.rs +223 -0
  34. package/src/tests/storage/gen_args.rs +65 -0
  35. package/src/tests/storage/gen_enum_variant.rs +78 -0
  36. package/src/tests/storage/gen_key.rs +108 -0
  37. package/src/tests/storage/gen_params.rs +105 -0
  38. package/src/tests/storage/generate_storage.rs +410 -0
  39. package/src/tests/storage/is_primitive_type.rs +48 -0
  40. package/src/tests/storage/mod.rs +16 -0
  41. package/src/tests/storage/parse_default.rs +164 -0
  42. package/src/tests/storage/parse_name.rs +158 -0
  43. package/src/tests/storage/parse_no_ttl_extension.rs +124 -0
  44. package/src/tests/storage/parse_storage_type.rs +174 -0
  45. package/src/tests/storage/snapshots/common_macros__tests__storage__generate_storage__snapshot_generated_storage_code.snap +412 -0
  46. package/src/tests/storage/storage_kind.rs +39 -0
  47. package/src/tests/storage/test_setup.rs +25 -0
  48. package/src/tests/storage/validate_attrs.rs +138 -0
  49. package/src/tests/storage/variant_config.rs +226 -0
  50. package/src/tests/test_helpers.rs +87 -0
  51. package/src/tests/ttl_configurable.rs +34 -0
  52. package/src/tests/ttl_extendable.rs +32 -0
  53. package/src/tests/upgradeable.rs +169 -0
  54. package/src/tests/utils.rs +267 -0
  55. package/src/ttl_configurable.rs +24 -0
  56. package/src/ttl_extendable.rs +28 -0
  57. package/src/upgradeable.rs +136 -0
  58. package/src/utils.rs +56 -0
@@ -0,0 +1,156 @@
1
+ use quote::quote;
2
+
3
+ use crate::tests::test_helpers::{assert_panics_contains, filter_item_inputs_excluding_labels};
4
+
5
+ // ============================================
6
+ // Error Cases: Invalid Inputs
7
+ // ============================================
8
+
9
+ #[test]
10
+ fn test_contract_error_rejects_non_enum_inputs() {
11
+ for (case, input) in filter_item_inputs_excluding_labels(&["enum"]) {
12
+ assert_panics_contains(case, "failed to parse enum", || {
13
+ crate::error::generate_error(input.clone());
14
+ });
15
+ }
16
+ }
17
+
18
+ #[test]
19
+ fn test_contract_error_requires_unit_variants() {
20
+ let cases = vec![("tuple variant", quote! { A(u32) }), ("struct variant", quote! { A { x: u32 } })];
21
+
22
+ for (case, variant) in cases {
23
+ let input = quote! {
24
+ pub enum MyError {
25
+ #variant,
26
+ }
27
+ };
28
+ assert_panics_contains(case, "Error enum variants must be unit variants", || {
29
+ crate::error::generate_error(input.clone());
30
+ });
31
+ }
32
+ }
33
+
34
+ #[test]
35
+ fn test_contract_error_discriminant_must_be_integer_literal() {
36
+ let cases = vec![
37
+ ("binary expr", quote! { 1 + 1 }),
38
+ ("path expr", quote! { SOME_CONST }),
39
+ ("negative integer (unary expr)", quote! { -1 }),
40
+ ("paren expr", quote! { (1) }),
41
+ ("bool literal", quote! { true }),
42
+ ("string literal", quote! { "1" }),
43
+ ("float literal", quote! { 1.0 }),
44
+ ("char literal", quote! { 'a' }),
45
+ ];
46
+
47
+ for (case, expr) in cases {
48
+ let input = quote! {
49
+ pub enum MyError {
50
+ A = #expr,
51
+ }
52
+ };
53
+ assert_panics_contains(case, "Error enum discriminant must be an integer literal", || {
54
+ crate::error::generate_error(input.clone());
55
+ });
56
+ }
57
+ }
58
+
59
+ #[test]
60
+ fn test_contract_error_discriminant_must_fit_u32() {
61
+ let input = quote! {
62
+ pub enum MyError {
63
+ A = 4294967296,
64
+ }
65
+ };
66
+
67
+ assert_panics_contains("u32::MAX + 1", "Error enum discriminant must be a valid u32 integer", || {
68
+ crate::error::generate_error(input);
69
+ });
70
+ }
71
+
72
+ #[test]
73
+ fn test_contract_error_discriminants_ordering_rejections_table_driven() {
74
+ let cases = vec![
75
+ (
76
+ "explicit value is less than previous",
77
+ quote! {
78
+ // A is assigned 1 by default; B cannot go backwards.
79
+ A,
80
+ B = 1,
81
+ },
82
+ ),
83
+ (
84
+ "explicit zero",
85
+ quote! {
86
+ A = 0,
87
+ },
88
+ ),
89
+ (
90
+ "explicit equal to previous explicit",
91
+ quote! {
92
+ A = 1,
93
+ B = 1,
94
+ },
95
+ ),
96
+ (
97
+ "explicit decreases after explicit",
98
+ quote! {
99
+ A = 5,
100
+ B = 4,
101
+ },
102
+ ),
103
+ ];
104
+
105
+ for (case, variants) in cases {
106
+ let input = quote! {
107
+ pub enum MyError {
108
+ #variants
109
+ }
110
+ };
111
+ assert_panics_contains(case, "Error enum discriminant must be greater than the previous discriminant", || {
112
+ crate::error::generate_error(input.clone());
113
+ });
114
+ }
115
+ }
116
+
117
+ #[test]
118
+ fn test_contract_error_max_not_last_panics_overflow() {
119
+ let input = quote! {
120
+ pub enum MyError {
121
+ A = 4294967295,
122
+ B,
123
+ }
124
+ };
125
+ assert_panics_contains("max not last overflows", "attempt to add with overflow", || {
126
+ crate::error::generate_error(input);
127
+ });
128
+ }
129
+
130
+ // ============================================
131
+ // Valid Cases: Snapshot Tests for Generated Code
132
+ // ============================================
133
+
134
+ #[test]
135
+ fn snapshot_generated_contract_error_code() {
136
+ let input = quote! {
137
+ /// Example error enum
138
+ pub enum MyError {
139
+ /// Implicit (should start at 1)
140
+ A,
141
+ /// Implicit (should be 2)
142
+ B,
143
+ /// Explicit (must be >= previous + 1)
144
+ C = 10,
145
+ /// Implicit (should be 11)
146
+ D,
147
+ /// Explicit max boundary (u32::MAX)
148
+ E = 4294967295,
149
+ }
150
+ };
151
+
152
+ let result = crate::error::generate_error(input);
153
+ let formatted = prettyplease::unparse(&syn::parse2::<syn::File>(result).expect("failed to parse generated code"));
154
+
155
+ insta::assert_snapshot!(formatted);
156
+ }
@@ -0,0 +1,87 @@
1
+ use proc_macro2::TokenStream;
2
+ use quote::quote;
3
+
4
+ use crate::tests::test_helpers::{assert_panics_contains, filter_item_inputs_excluding_labels};
5
+
6
+ // ============================================
7
+ // Snapshot Tests: lz_contract Code Generation
8
+ // ============================================
9
+
10
+ #[test]
11
+ fn snapshot_generated_lz_contract_code() {
12
+ let input = quote! {
13
+ pub struct MyContract;
14
+ };
15
+
16
+ let default_result = crate::lz_contract::generate_lz_contract(TokenStream::new(), input.clone());
17
+ let default_formatted =
18
+ prettyplease::unparse(&syn::parse2::<syn::File>(default_result).expect("failed to parse generated code"));
19
+
20
+ let multisig_upgradeable_result = crate::lz_contract::generate_lz_contract(quote! { multisig, upgradeable }, input);
21
+ let multisig_upgradeable_formatted = prettyplease::unparse(
22
+ &syn::parse2::<syn::File>(multisig_upgradeable_result).expect("failed to parse generated code"),
23
+ );
24
+
25
+ let upgradeable_no_migration_result = crate::lz_contract::generate_lz_contract(
26
+ quote! { upgradeable(no_migration) },
27
+ quote! { pub struct MyContract; },
28
+ );
29
+ let upgradeable_no_migration_formatted = prettyplease::unparse(
30
+ &syn::parse2::<syn::File>(upgradeable_no_migration_result).expect("failed to parse generated code"),
31
+ );
32
+
33
+ let upgradeable_rbac_result =
34
+ crate::lz_contract::generate_lz_contract(quote! { upgradeable(rbac) }, quote! { pub struct MyContract; });
35
+ let upgradeable_rbac_formatted = prettyplease::unparse(
36
+ &syn::parse2::<syn::File>(upgradeable_rbac_result).expect("failed to parse generated code"),
37
+ );
38
+
39
+ // Pass-through: order and content preserved verbatim
40
+ let upgradeable_rbac_no_migration_result = crate::lz_contract::generate_lz_contract(
41
+ quote! { upgradeable(rbac, no_migration) },
42
+ quote! { pub struct MyContract; },
43
+ );
44
+ let upgradeable_rbac_no_migration_formatted = prettyplease::unparse(
45
+ &syn::parse2::<syn::File>(upgradeable_rbac_no_migration_result).expect("failed to parse generated code"),
46
+ );
47
+
48
+ let combined = format!(
49
+ "// === Default (ownable) ===\n\n{}\n\n// === MultiSig + Upgradeable ===\n\n{}\n\n// === Upgradeable (no_migration) ===\n\n{}\n\n// === Upgradeable (rbac) ===\n\n{}\n\n// === Upgradeable (rbac, no_migration) pass-through ===\n\n{}",
50
+ default_formatted, multisig_upgradeable_formatted, upgradeable_no_migration_formatted, upgradeable_rbac_formatted, upgradeable_rbac_no_migration_formatted
51
+ );
52
+
53
+ insta::assert_snapshot!(combined);
54
+ }
55
+
56
+ // ============================================
57
+ // Error Cases: Invalid Config
58
+ // ============================================
59
+
60
+ #[test]
61
+ fn test_lz_contract_invalid_config_table_driven() {
62
+ let input = quote! { pub struct MyContract; };
63
+
64
+ let cases: Vec<(&str, TokenStream, &str)> = vec![
65
+ ("unknown option", quote! { not_a_real_option }, "expected one of `upgradeable`, `multisig`"),
66
+ ("invalid attr syntax", quote! { 123 }, "failed to parse lz_contract config"),
67
+ ];
68
+
69
+ for (case, attr, expected_substring) in cases {
70
+ assert_panics_contains(case, expected_substring, || {
71
+ crate::lz_contract::generate_lz_contract(attr.clone(), input.clone());
72
+ });
73
+ }
74
+ }
75
+
76
+ // ============================================
77
+ // Error Cases: Non-Struct Input
78
+ // ============================================
79
+
80
+ #[test]
81
+ fn test_lz_contract_rejects_non_struct_inputs() {
82
+ for (case, input) in filter_item_inputs_excluding_labels(&["struct"]) {
83
+ assert_panics_contains(case, "failed to parse struct", || {
84
+ crate::lz_contract::generate_lz_contract(TokenStream::new(), input.clone());
85
+ });
86
+ }
87
+ }
@@ -0,0 +1,11 @@
1
+ mod auth;
2
+ mod contract_ttl;
3
+ mod error;
4
+ mod lz_contract;
5
+ mod rbac;
6
+ mod storage;
7
+ mod test_helpers;
8
+ mod ttl_configurable;
9
+ mod ttl_extendable;
10
+ mod upgradeable;
11
+ mod utils;