use cucumber::{given, then, when, World}; use std::sync::Arc; use verax::{storage::SQLite, Asset}; #[derive(Debug, World)] pub struct LedgerWorld { ledger: Arc>, revisions: Vec, } impl Default for LedgerWorld { fn default() -> Self { futures::executor::block_on(async move { let settings = "sqlite://:memory:" .parse::() .expect("valid settings") .journal_mode(verax::storage::sqlite::SqliteJournalMode::Wal) .create_if_missing(true); let pool = verax::storage::sqlite::SqlitePoolOptions::new() .connect_with(settings) .await .expect("pool"); let db = SQLite::new(pool); db.setup().await.expect("setup"); Self { ledger: verax::Ledger::new(db.into()), revisions: vec![], } }) } } #[given(expr = "a {word} deposit of {word} {word} for {word}")] async fn deposit_funds( world: &mut LedgerWorld, status: String, amount: String, asset: String, account: String, ) { let asset = asset.parse::().expect("valid asset"); world.revisions.push( world .ledger .deposit( &account.parse().expect("valid account"), asset.from_human(&amount).expect("valid amount"), status.parse().expect("valid status"), vec![], "Initial deposit".to_owned(), ) .await .expect("deposit") .revision_id, ); } #[when(expr = "update last transaction set status to {word}")] async fn update_status_from_last_tx(world: &mut LedgerWorld, new_status: String) { let revision = world.revisions.pop().expect("has last revision"); let status = new_status.parse().expect("valid status"); world.revisions.push( world .ledger .change_status(revision, status, "update status".to_owned()) .await .expect("update status") .revision_id, ); } #[then(expr = "{word} has no balance")] async fn check_balance_empty(world: &mut LedgerWorld, account: String) { let balance = world .ledger .get_balance(&account.parse().expect("valid account")) .await .expect("balance") .into_iter() .filter(|b| b.cents() != 0) .collect::>(); assert_eq!(0, balance.len()) } #[then(expr = "{word} has balance of {word} {word}")] async fn check_balance(world: &mut LedgerWorld, account: String, amount: String, asset: String) { let asset = asset.parse::().expect("valid asset"); let amount = asset.from_human(&amount).expect("valid amount"); let balances = world .ledger .get_balance(&account.parse().expect("valid account")) .await .expect("balance") .into_iter() .filter(|b| b.asset() == &asset) .collect::>(); assert_eq!(1, balances.len(), "{} is found", asset); assert_eq!(balances.get(0), Some(&amount)); } #[tokio::main] async fn main() { LedgerWorld::run("tests/simple.feature").await; }