use std::sync::atomic::{AtomicI32, Ordering};
use std::sync::Arc;
use std::time::Duration;
use acton_reactive::prelude::*;
use acton_test::prelude::*;
#[acton_test]
async fn test_complete_counter_example() -> anyhow::Result<()> {
#[acton_actor]
struct Counter {
count: i32,
}
#[acton_message]
struct Increment;
#[acton_message]
struct PrintCount;
let final_count = Arc::new(AtomicI32::new(0));
let final_count_clone = final_count.clone();
let mut runtime = ActonApp::launch_async().await;
let mut counter = runtime.new_actor::<Counter>();
counter
.mutate_on::<Increment>(|actor, _envelope| {
actor.model.count += 1;
Reply::ready()
})
.act_on::<PrintCount>(|actor, _envelope| {
assert_eq!(actor.model.count, 3);
Reply::ready()
})
.after_stop(move |actor| {
final_count_clone.store(actor.model.count, Ordering::SeqCst);
Reply::ready()
});
let handle = counter.start().await;
handle.send(Increment).await;
handle.send(Increment).await;
handle.send(Increment).await;
handle.send(PrintCount).await;
tokio::time::sleep(Duration::from_millis(50)).await;
runtime.shutdown_all().await?;
assert_eq!(final_count.load(Ordering::SeqCst), 3);
Ok(())
}
#[acton_test]
async fn test_message_with_data() -> anyhow::Result<()> {
#[acton_actor]
struct Counter {
count: i32,
}
#[acton_message]
struct IncrementBy {
amount: i32,
}
let final_count = Arc::new(AtomicI32::new(0));
let final_count_clone = final_count.clone();
let mut runtime = ActonApp::launch_async().await;
let mut counter = runtime.new_actor::<Counter>();
counter
.mutate_on::<IncrementBy>(|actor, envelope| {
actor.model.count += envelope.message().amount;
Reply::ready()
})
.after_stop(move |actor| {
final_count_clone.store(actor.model.count, Ordering::SeqCst);
Reply::ready()
});
let handle = counter.start().await;
handle.send(IncrementBy { amount: 5 }).await;
handle.send(IncrementBy { amount: 10 }).await;
tokio::time::sleep(Duration::from_millis(50)).await;
runtime.shutdown_all().await?;
assert_eq!(final_count.load(Ordering::SeqCst), 15);
Ok(())
}
#[acton_test]
async fn test_mutate_on_vs_act_on() -> anyhow::Result<()> {
#[acton_actor]
struct Counter {
count: i32,
}
#[acton_message]
struct Increment;
#[acton_message]
struct GetCount;
let final_count = Arc::new(AtomicI32::new(0));
let final_count_clone = final_count.clone();
let mut runtime = ActonApp::launch_async().await;
let mut counter = runtime.new_actor::<Counter>();
counter
.mutate_on::<Increment>(|actor, _envelope| {
actor.model.count += 1;
Reply::ready()
})
.act_on::<GetCount>(|actor, _envelope| {
std::hint::black_box(actor.model.count);
Reply::ready()
})
.after_stop(move |actor| {
final_count_clone.store(actor.model.count, Ordering::SeqCst);
Reply::ready()
});
let handle = counter.start().await;
handle.send(Increment).await;
handle.send(Increment).await;
handle.send(GetCount).await;
handle.send(Increment).await;
tokio::time::sleep(Duration::from_millis(50)).await;
runtime.shutdown_all().await?;
assert_eq!(final_count.load(Ordering::SeqCst), 3);
Ok(())
}