litesvm_utils/assertions.rs
1//! Assertion helpers for testing account states
2//!
3//! This module provides convenient assertion methods for verifying
4//! account states in tests.
5
6use litesvm::LiteSVM;
7use solana_program::pubkey::Pubkey;
8use litesvm_token::spl_token;
9use solana_program_pack::Pack;
10
11/// Assertion helper methods for LiteSVM
12pub trait AssertionHelpers {
13 /// Assert that an account is closed (doesn't exist or has 0 lamports and 0 data)
14 ///
15 /// # Example
16 /// ```no_run
17 /// # use litesvm_utils::AssertionHelpers;
18 /// # use litesvm::LiteSVM;
19 /// # use solana_program::pubkey::Pubkey;
20 /// # let svm = LiteSVM::new();
21 /// # let account = Pubkey::new_unique();
22 /// svm.assert_account_closed(&account);
23 /// ```
24 fn assert_account_closed(&self, pubkey: &Pubkey);
25
26 /// Assert that an account exists
27 ///
28 /// # Example
29 /// ```no_run
30 /// # use litesvm_utils::AssertionHelpers;
31 /// # use litesvm::LiteSVM;
32 /// # use solana_program::pubkey::Pubkey;
33 /// # let svm = LiteSVM::new();
34 /// # let account = Pubkey::new_unique();
35 /// svm.assert_account_exists(&account);
36 /// ```
37 fn assert_account_exists(&self, pubkey: &Pubkey);
38
39 /// Assert token account balance
40 ///
41 /// # Example
42 /// ```no_run
43 /// # use litesvm_utils::AssertionHelpers;
44 /// # use litesvm::LiteSVM;
45 /// # use solana_program::pubkey::Pubkey;
46 /// # let svm = LiteSVM::new();
47 /// # let token_account = Pubkey::new_unique();
48 /// svm.assert_token_balance(&token_account, 1_000_000_000); // 1 token with 9 decimals
49 /// ```
50 fn assert_token_balance(&self, token_account: &Pubkey, expected: u64);
51
52 /// Assert SOL balance
53 ///
54 /// # Example
55 /// ```no_run
56 /// # use litesvm_utils::AssertionHelpers;
57 /// # use litesvm::LiteSVM;
58 /// # use solana_program::pubkey::Pubkey;
59 /// # let svm = LiteSVM::new();
60 /// # let account = Pubkey::new_unique();
61 /// svm.assert_sol_balance(&account, 1_000_000_000); // 1 SOL
62 /// ```
63 fn assert_sol_balance(&self, pubkey: &Pubkey, expected: u64);
64
65 /// Assert token mint supply
66 ///
67 /// # Example
68 /// ```no_run
69 /// # use litesvm_utils::AssertionHelpers;
70 /// # use litesvm::LiteSVM;
71 /// # use solana_program::pubkey::Pubkey;
72 /// # let svm = LiteSVM::new();
73 /// # let mint = Pubkey::new_unique();
74 /// svm.assert_mint_supply(&mint, 1_000_000_000);
75 /// ```
76 fn assert_mint_supply(&self, mint: &Pubkey, expected: u64);
77
78 /// Assert that an account is owned by a specific program
79 ///
80 /// # Example
81 /// ```no_run
82 /// # use litesvm_utils::AssertionHelpers;
83 /// # use litesvm::LiteSVM;
84 /// # use solana_program::pubkey::Pubkey;
85 /// # let svm = LiteSVM::new();
86 /// # let account = Pubkey::new_unique();
87 /// # let owner = Pubkey::new_unique();
88 /// svm.assert_account_owner(&account, &owner);
89 /// ```
90 fn assert_account_owner(&self, account: &Pubkey, expected_owner: &Pubkey);
91
92 /// Assert that an account has a specific data length
93 ///
94 /// # Example
95 /// ```no_run
96 /// # use litesvm_utils::AssertionHelpers;
97 /// # use litesvm::LiteSVM;
98 /// # use solana_program::pubkey::Pubkey;
99 /// # let svm = LiteSVM::new();
100 /// # let account = Pubkey::new_unique();
101 /// svm.assert_account_data_len(&account, 100);
102 /// ```
103 fn assert_account_data_len(&self, account: &Pubkey, expected_len: usize);
104}
105
106impl AssertionHelpers for LiteSVM {
107 fn assert_account_closed(&self, pubkey: &Pubkey) {
108 let account = self.get_account(pubkey);
109 assert!(
110 account.is_none() || (account.as_ref().unwrap().lamports == 0 && account.as_ref().unwrap().data.is_empty()),
111 "Expected account {} to be closed, but it exists with {} lamports and {} bytes of data",
112 pubkey,
113 account.as_ref().map_or(0, |a| a.lamports),
114 account.as_ref().map_or(0, |a| a.data.len())
115 );
116 }
117
118 fn assert_account_exists(&self, pubkey: &Pubkey) {
119 let account = self.get_account(pubkey);
120 assert!(
121 account.is_some(),
122 "Expected account {} to exist, but it doesn't",
123 pubkey
124 );
125 }
126
127 fn assert_token_balance(&self, token_account: &Pubkey, expected: u64) {
128 let account = self
129 .get_account(token_account)
130 .expect(&format!("Token account {} not found", token_account));
131
132 let token_data = spl_token::state::Account::unpack(&account.data)
133 .expect(&format!("Failed to unpack token account {}", token_account));
134
135 assert_eq!(
136 token_data.amount, expected,
137 "Token balance mismatch for account {}. Expected: {}, Actual: {}",
138 token_account, expected, token_data.amount
139 );
140 }
141
142 fn assert_sol_balance(&self, pubkey: &Pubkey, expected: u64) {
143 let account = self.get_account(pubkey);
144 let actual = account.map_or(0, |a| a.lamports);
145 assert_eq!(
146 actual, expected,
147 "SOL balance mismatch for account {}. Expected: {}, Actual: {}",
148 pubkey, expected, actual
149 );
150 }
151
152 fn assert_mint_supply(&self, mint: &Pubkey, expected: u64) {
153 let account = self
154 .get_account(mint)
155 .expect(&format!("Mint {} not found", mint));
156
157 let mint_data = spl_token::state::Mint::unpack(&account.data)
158 .expect(&format!("Failed to unpack mint {}", mint));
159
160 assert_eq!(
161 mint_data.supply, expected,
162 "Mint supply mismatch for {}. Expected: {}, Actual: {}",
163 mint, expected, mint_data.supply
164 );
165 }
166
167 fn assert_account_owner(&self, account: &Pubkey, expected_owner: &Pubkey) {
168 let acc = self
169 .get_account(account)
170 .expect(&format!("Account {} not found", account));
171
172 assert_eq!(
173 &acc.owner, expected_owner,
174 "Account owner mismatch for {}. Expected: {}, Actual: {}",
175 account, expected_owner, acc.owner
176 );
177 }
178
179 fn assert_account_data_len(&self, account: &Pubkey, expected_len: usize) {
180 let acc = self
181 .get_account(account)
182 .expect(&format!("Account {} not found", account));
183
184 assert_eq!(
185 acc.data.len(),
186 expected_len,
187 "Account data length mismatch for {}. Expected: {}, Actual: {}",
188 account,
189 expected_len,
190 acc.data.len()
191 );
192 }
193}