use lazy_static::lazy_static; use std::time::{Duration, SystemTime}; use tearup::{tearup, Context, ContextCombinator, SharedContext}; use crate::helper::{assert_order, Checkpoint}; lazy_static! { static ref FIRST_SETUP_CHECKPOINT: Checkpoint = None.into(); static ref FIRST_TEARDOWN_CHECKPOINT: Checkpoint = None.into(); static ref SECOND_SETUP_CHECKPOINT: Checkpoint = None.into(); static ref SECOND_TEARDOWN_CHECKPOINT: Checkpoint = None.into(); } #[test] fn it_pass_through_setup_then_teardown_of_both_contexts_one_after_the_other() { sequential(); assert_order(&FIRST_SETUP_CHECKPOINT, &SECOND_SETUP_CHECKPOINT); assert_order(&SECOND_SETUP_CHECKPOINT, &FIRST_TEARDOWN_CHECKPOINT); assert_order(&FIRST_TEARDOWN_CHECKPOINT, &SECOND_TEARDOWN_CHECKPOINT); } type B = ContextCombinator; #[tearup(B)] fn sequential() {} pub struct FirstContext; impl Context for FirstContext { fn setup(_shared_context: &mut SharedContext) -> Self { let mut checkpoint = FIRST_SETUP_CHECKPOINT.lock().unwrap(); *checkpoint = Some(SystemTime::now()); std::thread::sleep(Duration::from_millis(50)); Self {} } fn teardown(self, _shared_context: &mut SharedContext) { let mut checkpoint = FIRST_TEARDOWN_CHECKPOINT.lock().unwrap(); *checkpoint = Some(SystemTime::now()); } } pub struct SecondContext; impl Context for SecondContext { fn setup(_shared_context: &mut SharedContext) -> Self { let mut checkpoint = SECOND_SETUP_CHECKPOINT.lock().unwrap(); *checkpoint = Some(SystemTime::now()); std::thread::sleep(Duration::from_millis(50)); Self {} } fn teardown(self, _shared_context: &mut SharedContext) { let mut checkpoint = SECOND_TEARDOWN_CHECKPOINT.lock().unwrap(); *checkpoint = Some(SystemTime::now()); } } mod asyncc { use lazy_static::lazy_static; use std::time::{Duration, SystemTime}; use tearup::{async_trait, tearup, AsyncContext, AsyncContextCombinator, AsyncSharedContext}; use tokio::time::sleep; use crate::helper::{assert_async_order, AsyncCheckpoint}; lazy_static! { static ref FIRST_SETUP_CHECKPOINT: AsyncCheckpoint = None.into(); static ref FIRST_TEARDOWN_CHECKPOINT: AsyncCheckpoint = None.into(); static ref SECOND_SETUP_CHECKPOINT: AsyncCheckpoint = None.into(); static ref SECOND_TEARDOWN_CHECKPOINT: AsyncCheckpoint = None.into(); } #[tokio::test] async fn it_pass_through_setup_then_teardown_of_both_contexts_one_after_the_other() { sequential().await; assert_async_order(&FIRST_SETUP_CHECKPOINT, &SECOND_SETUP_CHECKPOINT).await; assert_async_order(&SECOND_SETUP_CHECKPOINT, &FIRST_TEARDOWN_CHECKPOINT).await; assert_async_order(&FIRST_TEARDOWN_CHECKPOINT, &SECOND_TEARDOWN_CHECKPOINT).await; } type B = AsyncContextCombinator; #[tearup(B)] async fn sequential() {} pub struct FirstContext; #[async_trait] impl AsyncContext<'_> for FirstContext { async fn setup(_shared_context: AsyncSharedContext) -> Self { let mut checkpoint = FIRST_SETUP_CHECKPOINT.lock().await; *checkpoint = Some(SystemTime::now()); sleep(Duration::from_millis(50)).await; Self {} } async fn teardown(mut self, _shared_context: AsyncSharedContext) { let mut checkpoint = FIRST_TEARDOWN_CHECKPOINT.lock().await; *checkpoint = Some(SystemTime::now()); } } pub struct SecondContext; #[async_trait] impl AsyncContext<'_> for SecondContext { async fn setup(_shared_context: AsyncSharedContext) -> Self { let mut checkpoint = SECOND_SETUP_CHECKPOINT.lock().await; *checkpoint = Some(SystemTime::now()); sleep(Duration::from_millis(50)).await; Self {} } async fn teardown(mut self, _shared_context: AsyncSharedContext) { let mut checkpoint = SECOND_TEARDOWN_CHECKPOINT.lock().await; *checkpoint = Some(SystemTime::now()); } } }