@layerzerolabs/common-utils-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.
@@ -0,0 +1,522 @@
1
+ extern crate std;
2
+
3
+ use crate::testing_utils::{
4
+ assert_contains_event, assert_contains_events, assert_eq_event, assert_eq_events, decode_event_topics_data,
5
+ };
6
+ use soroban_sdk::{
7
+ contract, contractevent, contractimpl, testutils::Address as _, testutils::Events as _, xdr, Address, Env,
8
+ TryFromVal,
9
+ };
10
+
11
+ // ============================================
12
+ // Test Fixtures
13
+ // ============================================
14
+
15
+ #[contractevent]
16
+ #[derive(Clone, Debug, Eq, PartialEq)]
17
+ pub struct TestEvent1 {
18
+ pub value: u32,
19
+ }
20
+
21
+ #[contractevent]
22
+ #[derive(Clone, Debug, Eq, PartialEq)]
23
+ pub struct TestEvent2 {
24
+ pub name: u32,
25
+ pub count: u64,
26
+ }
27
+
28
+ #[contractevent]
29
+ #[derive(Clone, Debug, Eq, PartialEq)]
30
+ pub struct TestEvent3 {
31
+ pub address: Address,
32
+ }
33
+
34
+ #[contract]
35
+ pub struct TestingUtilsContract;
36
+
37
+ #[contractimpl]
38
+ impl TestingUtilsContract {
39
+ pub fn emit_event1(env: &Env, value: u32) {
40
+ TestEvent1 { value }.publish(env);
41
+ }
42
+
43
+ pub fn emit_event2(env: &Env, name: u32, count: u64) {
44
+ TestEvent2 { name, count }.publish(env);
45
+ }
46
+
47
+ pub fn emit_event3(env: &Env, address: Address) {
48
+ TestEvent3 { address }.publish(env);
49
+ }
50
+
51
+ pub fn emit_multiple_events(env: &Env, value1: u32, value2: u32) {
52
+ TestEvent1 { value: value1 }.publish(env);
53
+ TestEvent1 { value: value2 }.publish(env);
54
+ }
55
+
56
+ pub fn emit_both_events(env: &Env, value: u32, name: u32, count: u64) {
57
+ TestEvent1 { value }.publish(env);
58
+ TestEvent2 { name, count }.publish(env);
59
+ }
60
+
61
+ pub fn emit_three_events(env: &Env, value1: u32, value2: u32, value3: u32) {
62
+ TestEvent1 { value: value1 }.publish(env);
63
+ TestEvent1 { value: value2 }.publish(env);
64
+ TestEvent1 { value: value3 }.publish(env);
65
+ }
66
+
67
+ pub fn emit_mixed_four_events(env: &Env, v1: u32, name: u32, count: u64, v2: u32, v3: u32) {
68
+ TestEvent1 { value: v1 }.publish(env);
69
+ TestEvent2 { name, count }.publish(env);
70
+ TestEvent1 { value: v2 }.publish(env);
71
+ TestEvent1 { value: v3 }.publish(env);
72
+ }
73
+
74
+ pub fn emit_mixed_three_types(env: &Env, value: u32, name: u32, count: u64, address: Address) {
75
+ TestEvent1 { value }.publish(env);
76
+ TestEvent2 { name, count }.publish(env);
77
+ TestEvent3 { address }.publish(env);
78
+ }
79
+
80
+ pub fn emit_two_plus_event2(env: &Env, value1: u32, value2: u32, name: u32, count: u64) {
81
+ TestEvent1 { value: value1 }.publish(env);
82
+ TestEvent1 { value: value2 }.publish(env);
83
+ TestEvent2 { name, count }.publish(env);
84
+ }
85
+ }
86
+
87
+ // ============================================
88
+ // assert_eq_event
89
+ // ============================================
90
+
91
+ // Basic functionality
92
+
93
+ #[test]
94
+ fn test_assert_event_found() {
95
+ let env = Env::default();
96
+ let contract_id = env.register(TestingUtilsContract, ());
97
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
98
+
99
+ client.emit_event1(&42);
100
+
101
+ assert_eq_event(&env, &contract_id, TestEvent1 { value: 42 });
102
+ }
103
+
104
+ #[test]
105
+ fn test_assert_event_with_multiple_fields() {
106
+ let env = Env::default();
107
+ let contract_id = env.register(TestingUtilsContract, ());
108
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
109
+
110
+ client.emit_event2(&123, &456);
111
+
112
+ assert_eq_event(&env, &contract_id, TestEvent2 { name: 123, count: 456 });
113
+ }
114
+
115
+ #[test]
116
+ fn test_assert_event_with_address() {
117
+ let env = Env::default();
118
+ let contract_id = env.register(TestingUtilsContract, ());
119
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
120
+
121
+ let addr = Address::generate(&env);
122
+ client.emit_event3(&addr);
123
+
124
+ assert_eq_event(&env, &contract_id, TestEvent3 { address: addr });
125
+ }
126
+
127
+ #[test]
128
+ fn test_assert_event_among_multiple() {
129
+ let env = Env::default();
130
+ let contract_id = env.register(TestingUtilsContract, ());
131
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
132
+
133
+ client.emit_multiple_events(&10, &20);
134
+
135
+ assert_contains_event(&env, &contract_id, TestEvent1 { value: 10 });
136
+ assert_contains_event(&env, &contract_id, TestEvent1 { value: 20 });
137
+ }
138
+
139
+ // Edge cases
140
+
141
+ #[test]
142
+ fn test_assert_event_finds_first_matching_event() {
143
+ let env = Env::default();
144
+ let contract_id = env.register(TestingUtilsContract, ());
145
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
146
+
147
+ client.emit_multiple_events(&42, &42);
148
+
149
+ assert_contains_event(&env, &contract_id, TestEvent1 { value: 42 });
150
+ }
151
+
152
+ #[test]
153
+ fn test_assert_event_finds_correct_event_among_many() {
154
+ let env = Env::default();
155
+ let contract_id = env.register(TestingUtilsContract, ());
156
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
157
+
158
+ // Use single contract call that emits all events (events don't accumulate across calls)
159
+ client.emit_mixed_four_events(&1, &100, &200, &2, &3);
160
+
161
+ assert_contains_event(&env, &contract_id, TestEvent1 { value: 2 });
162
+ assert_contains_event(&env, &contract_id, TestEvent2 { name: 100, count: 200 });
163
+ }
164
+
165
+ // Error cases
166
+
167
+ #[test]
168
+ #[should_panic(expected = "Expected exactly one event")]
169
+ fn test_assert_event_no_events_emitted() {
170
+ let env = Env::default();
171
+ let contract_id = env.register(TestingUtilsContract, ());
172
+
173
+ assert_eq_event(&env, &contract_id, TestEvent1 { value: 42 });
174
+ }
175
+
176
+ #[test]
177
+ #[should_panic(expected = "Expected exactly one event")]
178
+ fn test_assert_event_not_found() {
179
+ let env = Env::default();
180
+ let contract_id = env.register(TestingUtilsContract, ());
181
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
182
+
183
+ client.emit_event1(&42);
184
+
185
+ assert_eq_event(&env, &contract_id, TestEvent1 { value: 100 });
186
+ }
187
+
188
+ #[test]
189
+ #[should_panic(expected = "Expected exactly one event")]
190
+ fn test_assert_event_wrong_contract() {
191
+ let env = Env::default();
192
+ let contract_id = env.register(TestingUtilsContract, ());
193
+ let other_contract_id = env.register(TestingUtilsContract, ());
194
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
195
+
196
+ client.emit_event1(&42);
197
+
198
+ assert_eq_event(&env, &other_contract_id, TestEvent1 { value: 42 });
199
+ }
200
+
201
+ #[test]
202
+ #[should_panic(expected = "Expected exactly one event")]
203
+ fn test_assert_event_topics_length_mismatch() {
204
+ let env = Env::default();
205
+ let contract_id = env.register(TestingUtilsContract, ());
206
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
207
+
208
+ client.emit_event1(&42);
209
+
210
+ assert_eq_event(&env, &contract_id, TestEvent2 { name: 42, count: 0 });
211
+ }
212
+
213
+ #[test]
214
+ #[should_panic(expected = "Expected exactly one event")]
215
+ fn test_assert_event_data_mismatch() {
216
+ let env = Env::default();
217
+ let contract_id = env.register(TestingUtilsContract, ());
218
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
219
+
220
+ client.emit_event2(&123, &456);
221
+
222
+ assert_eq_event(&env, &contract_id, TestEvent2 { name: 123, count: 789 });
223
+ }
224
+
225
+ // ============================================
226
+ // decode_event_topics_data
227
+ // ============================================
228
+
229
+ #[test]
230
+ fn test_decode_event_topics_data_roundtrip() {
231
+ let env = Env::default();
232
+ let contract_id = env.register(TestingUtilsContract, ());
233
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
234
+
235
+ client.emit_event2(&123, &456);
236
+
237
+ let filtered = env.events().all().filter_by_contract(&contract_id);
238
+ let raw = filtered.events();
239
+ assert_eq!(raw.len(), 1);
240
+
241
+ let event = &raw[0];
242
+ let v0 = match &event.body {
243
+ xdr::ContractEventBody::V0(v0) => v0,
244
+ };
245
+
246
+ let (topics, data) = decode_event_topics_data(&env, event).expect("event should decode");
247
+
248
+ // `Val` doesn't implement `PartialEq` in this SDK version, so compare by converting back to XDR.
249
+ let topics_xdr: std::vec::Vec<xdr::ScVal> =
250
+ topics.iter().map(|t| xdr::ScVal::try_from_val(&env, &t).expect("topic Val must convert to XDR")).collect();
251
+ assert_eq!(topics_xdr.len(), v0.topics.len() as usize);
252
+ for (i, t) in v0.topics.iter().enumerate() {
253
+ assert_eq!(topics_xdr[i], *t);
254
+ }
255
+
256
+ let data_xdr = xdr::ScVal::try_from_val(&env, &data).expect("data Val must convert to XDR");
257
+ assert_eq!(data_xdr, v0.data);
258
+ }
259
+
260
+ // ============================================
261
+ // assert_eq_events
262
+ // ============================================
263
+
264
+ // Basic functionality
265
+
266
+ #[test]
267
+ fn test_assert_events_single() {
268
+ let env = Env::default();
269
+ let contract_id = env.register(TestingUtilsContract, ());
270
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
271
+
272
+ client.emit_event1(&42);
273
+
274
+ assert_eq_events(&env, &contract_id, &[&TestEvent1 { value: 42 }]);
275
+ }
276
+
277
+ #[test]
278
+ fn test_assert_events_multiple_same_type() {
279
+ let env = Env::default();
280
+ let contract_id = env.register(TestingUtilsContract, ());
281
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
282
+
283
+ client.emit_multiple_events(&10, &20);
284
+
285
+ assert_eq_events(&env, &contract_id, &[&TestEvent1 { value: 10 }, &TestEvent1 { value: 20 }]);
286
+ }
287
+
288
+ #[test]
289
+ fn test_assert_events_multiple_different_types() {
290
+ let env = Env::default();
291
+ let contract_id = env.register(TestingUtilsContract, ());
292
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
293
+
294
+ client.emit_both_events(&42, &123, &456);
295
+
296
+ assert_eq_events(&env, &contract_id, &[&TestEvent1 { value: 42 }, &TestEvent2 { name: 123, count: 456 }]);
297
+ }
298
+
299
+ #[test]
300
+ fn test_assert_events_order_independent() {
301
+ let env = Env::default();
302
+ let contract_id = env.register(TestingUtilsContract, ());
303
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
304
+
305
+ client.emit_both_events(&42, &123, &456);
306
+
307
+ assert_eq_events(&env, &contract_id, &[&TestEvent1 { value: 42 }, &TestEvent2 { name: 123, count: 456 }]);
308
+ }
309
+
310
+ #[test]
311
+ fn test_assert_events_empty_list() {
312
+ let env = Env::default();
313
+ let contract_id = env.register(TestingUtilsContract, ());
314
+
315
+ assert_eq_events(&env, &contract_id, &[]);
316
+ }
317
+
318
+ #[test]
319
+ fn test_assert_events_with_duplicates() {
320
+ let env = Env::default();
321
+ let contract_id = env.register(TestingUtilsContract, ());
322
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
323
+
324
+ client.emit_multiple_events(&42, &42);
325
+
326
+ assert_eq_events(&env, &contract_id, &[&TestEvent1 { value: 42 }, &TestEvent1 { value: 42 }]);
327
+ }
328
+
329
+ // Edge cases
330
+
331
+ #[test]
332
+ fn test_assert_events_partial_match() {
333
+ let env = Env::default();
334
+ let contract_id = env.register(TestingUtilsContract, ());
335
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
336
+
337
+ // Use single contract call that emits all events (events don't accumulate across calls)
338
+ client.emit_two_plus_event2(&10, &20, &100, &200);
339
+
340
+ assert_contains_events(&env, &contract_id, &[&TestEvent1 { value: 10 }]);
341
+ }
342
+
343
+ #[test]
344
+ fn test_assert_events_three_events() {
345
+ let env = Env::default();
346
+ let contract_id = env.register(TestingUtilsContract, ());
347
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
348
+
349
+ // Use single contract call that emits all events (events don't accumulate across calls)
350
+ client.emit_three_events(&1, &2, &3);
351
+
352
+ assert_eq_events(
353
+ &env,
354
+ &contract_id,
355
+ &[&TestEvent1 { value: 1 }, &TestEvent1 { value: 2 }, &TestEvent1 { value: 3 }],
356
+ );
357
+ }
358
+
359
+ #[test]
360
+ fn test_assert_events_mixed_event_types_three() {
361
+ let env = Env::default();
362
+ let contract_id = env.register(TestingUtilsContract, ());
363
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
364
+
365
+ let addr = Address::generate(&env);
366
+
367
+ // Use single contract call that emits all events (events don't accumulate across calls)
368
+ client.emit_mixed_three_types(&42, &100, &200, &addr);
369
+
370
+ assert_eq_events(
371
+ &env,
372
+ &contract_id,
373
+ &[&TestEvent1 { value: 42 }, &TestEvent2 { name: 100, count: 200 }, &TestEvent3 { address: addr.clone() }],
374
+ );
375
+ }
376
+
377
+ #[test]
378
+ fn test_assert_events_from_specific_contract_ignores_others() {
379
+ let env = Env::default();
380
+ let contract_id1 = env.register(TestingUtilsContract, ());
381
+ let contract_id2 = env.register(TestingUtilsContract, ());
382
+ let client1 = TestingUtilsContractClient::new(&env, &contract_id1);
383
+
384
+ // Emit events from contract1 only
385
+ // Note: Events don't accumulate across separate contract calls, so we use a single call
386
+ client1.emit_multiple_events(&10, &30);
387
+
388
+ // Assert events from contract1 are found when using contract1's address
389
+ assert_eq_events(&env, &contract_id1, &[&TestEvent1 { value: 10 }, &TestEvent1 { value: 30 }]);
390
+
391
+ // Verify that using contract2's address doesn't match contract1's events
392
+ // (this tests the filtering logic - events should not be found for wrong contract)
393
+ assert_contains_events(&env, &contract_id2, &[]);
394
+ }
395
+
396
+ // Error cases
397
+
398
+ #[test]
399
+ #[should_panic(expected = "Expected events to match exactly")]
400
+ fn test_assert_events_first_not_found() {
401
+ let env = Env::default();
402
+ let contract_id = env.register(TestingUtilsContract, ());
403
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
404
+
405
+ client.emit_event1(&42);
406
+
407
+ assert_eq_events(&env, &contract_id, &[&TestEvent1 { value: 100 }]);
408
+ }
409
+
410
+ #[test]
411
+ #[should_panic(expected = "Expected events to match exactly")]
412
+ fn test_assert_events_second_not_found() {
413
+ let env = Env::default();
414
+ let contract_id = env.register(TestingUtilsContract, ());
415
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
416
+
417
+ client.emit_event1(&42);
418
+
419
+ assert_eq_events(&env, &contract_id, &[&TestEvent1 { value: 42 }, &TestEvent1 { value: 100 }]);
420
+ }
421
+
422
+ #[test]
423
+ #[should_panic(expected = "Expected events to match exactly")]
424
+ fn test_assert_events_third_not_found() {
425
+ let env = Env::default();
426
+ let contract_id = env.register(TestingUtilsContract, ());
427
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
428
+
429
+ client.emit_multiple_events(&10, &20);
430
+
431
+ assert_eq_events(
432
+ &env,
433
+ &contract_id,
434
+ &[&TestEvent1 { value: 10 }, &TestEvent1 { value: 20 }, &TestEvent1 { value: 30 }],
435
+ );
436
+ }
437
+
438
+ #[test]
439
+ #[should_panic(expected = "Expected events to match exactly")]
440
+ fn test_assert_events_duplicate_expected_but_not_emitted() {
441
+ let env = Env::default();
442
+ let contract_id = env.register(TestingUtilsContract, ());
443
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
444
+
445
+ client.emit_event1(&42);
446
+
447
+ assert_eq_events(&env, &contract_id, &[&TestEvent1 { value: 42 }, &TestEvent1 { value: 42 }]);
448
+ }
449
+
450
+ #[test]
451
+ #[should_panic(expected = "Expected events to match exactly")]
452
+ fn test_assert_events_no_events_emitted() {
453
+ let env = Env::default();
454
+ let contract_id = env.register(TestingUtilsContract, ());
455
+
456
+ assert_eq_events(&env, &contract_id, &[&TestEvent1 { value: 42 }]);
457
+ }
458
+
459
+ #[test]
460
+ #[should_panic(expected = "Expected events to match exactly")]
461
+ fn test_assert_events_wrong_contract() {
462
+ let env = Env::default();
463
+ let contract_id1 = env.register(TestingUtilsContract, ());
464
+ let contract_id2 = env.register(TestingUtilsContract, ());
465
+ let client1 = TestingUtilsContractClient::new(&env, &contract_id1);
466
+
467
+ client1.emit_event1(&42);
468
+
469
+ assert_eq_events(&env, &contract_id2, &[&TestEvent1 { value: 42 }]);
470
+ }
471
+
472
+ #[test]
473
+ #[should_panic(expected = "Expected events to match exactly")]
474
+ fn test_assert_events_data_mismatch() {
475
+ let env = Env::default();
476
+ let contract_id = env.register(TestingUtilsContract, ());
477
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
478
+
479
+ client.emit_event2(&100, &200);
480
+
481
+ assert_eq_events(&env, &contract_id, &[&TestEvent2 { name: 100, count: 999 }]);
482
+ }
483
+
484
+ // ============================================
485
+ // assert_contains_event / assert_contains_events (multiset semantics)
486
+ // ============================================
487
+
488
+ #[test]
489
+ #[should_panic(expected = "Expected event not found")]
490
+ fn test_assert_contains_event_not_found_panics() {
491
+ let env = Env::default();
492
+ let contract_id = env.register(TestingUtilsContract, ());
493
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
494
+
495
+ client.emit_event1(&42);
496
+
497
+ assert_contains_event(&env, &contract_id, TestEvent1 { value: 999 });
498
+ }
499
+
500
+ #[test]
501
+ fn test_assert_contains_events_allows_duplicates() {
502
+ let env = Env::default();
503
+ let contract_id = env.register(TestingUtilsContract, ());
504
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
505
+
506
+ client.emit_multiple_events(&42, &42);
507
+
508
+ assert_contains_events(&env, &contract_id, &[&TestEvent1 { value: 42 }, &TestEvent1 { value: 42 }]);
509
+ }
510
+
511
+ #[test]
512
+ #[should_panic(expected = "Expected event #1 not found")]
513
+ fn test_assert_contains_events_duplicate_expected_but_not_emitted_panics() {
514
+ let env = Env::default();
515
+ let contract_id = env.register(TestingUtilsContract, ());
516
+ let client = TestingUtilsContractClient::new(&env, &contract_id);
517
+
518
+ client.emit_event1(&42);
519
+
520
+ // Only one emission, but two expectations -> must fail on the second.
521
+ assert_contains_events(&env, &contract_id, &[&TestEvent1 { value: 42 }, &TestEvent1 { value: 42 }]);
522
+ }