Skip to content

Commit 9e0492d

Browse files
committed
chore: add ContractEvent struct to improve event testing
1 parent 12904c3 commit 9e0492d

File tree

2 files changed

+71
-13
lines changed

2 files changed

+71
-13
lines changed

soroban-sdk/src/events.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,26 @@ impl Debug for Events {
5858
}
5959
}
6060

61+
#[cfg(any(test, feature = "testutils"))]
62+
use crate::{testutils, xdr, Address, TryIntoVal};
63+
6164
pub trait Event {
6265
fn topics(&self, env: &Env) -> Vec<Val>;
6366
fn data(&self, env: &Env) -> Val;
6467

6568
fn publish(&self, env: &Env) {
6669
env.events().publish_event(self);
6770
}
71+
72+
/// Convert this event into a [`testutils::ContractEvent`] object for testing purposes.
73+
#[cfg(any(test, feature = "testutils"))]
74+
fn to_contract_event(
75+
&self,
76+
env: &Env,
77+
contract_id: &crate::Address,
78+
) -> testutils::ContractEvent {
79+
testutils::ContractEvent::new(env, contract_id.clone(), self.topics(env), self.data(env))
80+
}
6881
}
6982

7083
pub trait Topics: IntoVal<Env, Vec<Val>> {}
@@ -116,15 +129,12 @@ impl Events {
116129
}
117130
}
118131

119-
#[cfg(any(test, feature = "testutils"))]
120-
use crate::{testutils, xdr, Address, TryIntoVal};
121-
122132
#[cfg(any(test, feature = "testutils"))]
123133
#[cfg_attr(feature = "docs", doc(cfg(feature = "testutils")))]
124134
impl testutils::Events for Events {
125-
fn all(&self) -> Vec<(crate::Address, Vec<Val>, Val)> {
135+
fn all(&self) -> std::vec::Vec<testutils::ContractEvent> {
126136
let env = self.env();
127-
let mut vec = Vec::new(env);
137+
let mut vec = std::vec::Vec::new();
128138
self.env()
129139
.host()
130140
.get_events()
@@ -142,7 +152,8 @@ impl testutils::Events for Events {
142152
..
143153
} = e.event
144154
{
145-
vec.push_back((
155+
vec.push(testutils::ContractEvent::new(
156+
&env,
146157
Address::from_contract_id(env, contract_id.0 .0),
147158
topics.try_into_val(env).unwrap(),
148159
data.try_into_val(env).unwrap(),

soroban-sdk/src/testutils.rs

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
pub mod arbitrary;
77

88
mod sign;
9-
use std::rc::Rc;
9+
use std::{fmt::Debug, rc::Rc};
1010

1111
pub use sign::ed25519;
1212

@@ -20,7 +20,9 @@ pub mod storage;
2020

2121
pub mod cost_estimate;
2222

23-
use crate::{xdr, ConstructorArgs, Env, Val, Vec};
23+
use crate::{
24+
env::internal::Env as _, unwrap::UnwrapInfallible, xdr, ConstructorArgs, Env, Val, Vec,
25+
};
2426
use soroban_ledger_snapshot::LedgerSnapshot;
2527

2628
pub use crate::env::EnvTestConfig;
@@ -413,15 +415,60 @@ pub mod budget {
413415
}
414416
}
415417

418+
#[derive(Clone)]
419+
pub struct ContractEvent {
420+
pub env: Env,
421+
pub contract_id: crate::Address,
422+
pub topics: Vec<Val>,
423+
pub data: Val,
424+
}
425+
426+
impl Eq for ContractEvent {}
427+
428+
impl PartialEq for ContractEvent {
429+
fn eq(&self, other: &Self) -> bool {
430+
if self.contract_id != other.contract_id || self.topics != other.topics {
431+
false
432+
} else if self.data.is_object() || other.data.is_object() {
433+
self.env.obj_cmp(self.data, other.data).unwrap_infallible() == 0
434+
} else {
435+
self.data.get_payload() == other.data.get_payload()
436+
}
437+
}
438+
}
439+
440+
impl Debug for ContractEvent {
441+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
442+
write!(
443+
f,
444+
"ContractEvent {{ contract_id: {:?}, topics: {:?}, data: {:?} }}",
445+
self.contract_id, self.topics, self.data
446+
)
447+
}
448+
}
449+
450+
impl ContractEvent {
451+
pub fn new(
452+
env: &Env,
453+
contract_id: crate::Address,
454+
topics: Vec<Val>,
455+
data: Val,
456+
) -> ContractEvent {
457+
ContractEvent {
458+
env: env.clone(),
459+
contract_id,
460+
topics,
461+
data,
462+
}
463+
}
464+
}
465+
416466
/// Test utilities for [`Events`][crate::events::Events].
417467
pub trait Events {
418468
/// Returns all events that have been published by contracts.
419469
///
420-
/// Returns a [`Vec`] of three element tuples containing:
421-
/// - Contract ID
422-
/// - Event Topics as a [`Vec<Val>`]
423-
/// - Event Data as a [`Val`]
424-
fn all(&self) -> Vec<(crate::Address, Vec<Val>, Val)>;
470+
/// Returns a [`std::vec::Vec`] of [`ContractEvent`]s
471+
fn all(&self) -> std::vec::Vec<ContractEvent>;
425472
}
426473

427474
/// Test utilities for [`Logs`][crate::logs::Logs].

0 commit comments

Comments
 (0)