thalo-testing 0.3.3

Test utils for crates.io/thalo
Documentation

Testing utilities for thalo apps.

Examples

Create aggregate and events.

use thalo::{
aggregate::{Aggregate, TypeId},
event::EventType,
};
use thiserror::Error;

#[derive(Aggregate, Clone, Debug, Default, PartialEq, TypeId)]
struct BankAccount {
id: String,
opened: bool,
balance: f64,
}

#[derive(Clone, Debug, EventType)]
enum BankAccountEvent {
OpenedAccount { balance: f64 },
}

fn apply(bank_account: &mut BankAccount, event: BankAccountEvent) {
use BankAccountEvent::*;

match event {
OpenedAccount { balance } => {
bank_account.opened = true;
bank_account.balance = balance;
}
}
}

Test aggregate events.

# use thalo::{
#     aggregate::{Aggregate, TypeId},
#     event::EventType,
# };
# use thiserror::Error;
#
# #[derive(Aggregate, Clone, Debug, Default, PartialEq, TypeId)]
# struct BankAccount {
#     id: String,
#     opened: bool,
#     balance: f64,
# }
#
# #[derive(Clone, Debug, EventType)]
# enum BankAccountEvent {
#     OpenedAccount { balance: f64 },
# }
#
# fn apply(bank_account: &mut BankAccount, event: BankAccountEvent) {
#     use BankAccountEvent::*;
#
#     match event {
#         OpenedAccount { balance } => {
#             bank_account.opened = true;
#             bank_account.balance = balance;
#         }
#     }
# }
#
#[cfg(test)]
mod tests {
use thalo_testing::*;
use super::{BankAccount, BankAccountEvent};

#[test]
fn opened_account() {
BankAccount::given(
"account-123",
BankAccountEvent::OpenedAccount {
balance: 0.0,
}
)
.should_eq(BankAccount {
id: "account-123".to_string(),
opened: true,
balance: 0.0,
});
}
}

Test aggregate commands.

# use thalo::{
#     aggregate::{Aggregate, TypeId},
#     event::EventType,
# };
# use thiserror::Error;
#
# #[derive(Aggregate, Clone, Debug, Default, PartialEq, TypeId)]
# struct BankAccount {
#     id: String,
#     opened: bool,
#     balance: f64,
# }
#
# #[derive(Clone, Debug, EventType)]
# enum BankAccountEvent {
#     OpenedAccount { balance: f64 },
# }
#
# fn apply(bank_account: &mut BankAccount, event: BankAccountEvent) {
#     use BankAccountEvent::*;
#
#     match event {
#         OpenedAccount { balance } => {
#             bank_account.opened = true;
#             bank_account.balance = balance;
#         }
#     }
# }
#
impl BankAccount {
pub fn open_account(
&self,
initial_balance: f64,
) -> Result<BankAccountEvent, BankAccountError> {
if self.opened {
return Err(BankAccountError::AlreadyOpened);
}

if initial_balance < 0.0 {
return Err(BankAccountError::NegativeAmount);
}

Ok(BankAccountEvent::OpenedAccount {
balance: initial_balance,
})
}
}

#[derive(Debug, Error)]
pub enum BankAccountError {
#[error("account already opened")]
AlreadyOpened,
#[error("negative amount")]
NegativeAmount,
}

#[cfg(test)]
mod tests {
use thalo_testing::*;
use super::{BankAccount, BankAccountError, BankAccountEvent};

#[test]
fn open_account() {
BankAccount::given_no_events("account-123")
.when(|bank_account| bank_account.open_account(0.0))
.then(Ok(BankAccountEvent::OpenedAccount {
balance: 0.0,
}));
}
#[test]
fn open_account_already_opened() {
BankAccount::given(
"account-123",
BankAccountEvent::OpenedAccount {
balance: 0.0,
},
)
.when(|bank_account| bank_account.open_account(50.0))
.then(Err(BankAccountError::AlreadyOpened));
}

#[test]
fn open_account_negative_amount() {
BankAccount::given_no_events()
.when(|bank_account| bank_account.open_account(-10.0))
.then(Err(BankAccountError::NegativeAmount));
}