use std::sync::{
Arc,
atomic::{AtomicUsize, Ordering},
};
use kabel::{
ServiceCollection, ServiceProvider,
scope::{GlobalScopeProvider, ScopeDefault, ScopeProvider, ThreadLocalScope},
};
struct ScopedA(usize);
struct ScopedB(usize);
#[test]
fn test_global_refresh_scope() {
let mut sc = ServiceCollection::new();
let a_counter = Arc::new(AtomicUsize::new(0));
let a_factory_counter = a_counter.clone();
sc.add_scoped::<ScopedA, _>(move || ScopedA(a_factory_counter.fetch_add(1, Ordering::SeqCst)))
.unwrap();
let sp = ServiceProvider::new(sc);
GlobalScopeProvider::initialize(sp.create_scope());
let a1 = sp.dir::<ScopedA>().unwrap();
assert_eq!(a1.0, 0);
let b_factory_counter = Arc::new(AtomicUsize::new(0));
sp.mutate(move |sc| {
sc.add_scoped::<ScopedB, _>(move || {
ScopedB(b_factory_counter.fetch_add(1, Ordering::SeqCst))
})
.unwrap();
});
GlobalScopeProvider::refresh_scope_with(&sp).unwrap();
let b1 = sp.dir::<ScopedB>().unwrap();
let a2 = sp.dir::<ScopedA>().unwrap();
assert_eq!(b1.0, 0);
assert_eq!(a2.0, 0);
}
#[test]
fn test_thread_local_refresh_scope() {
let mut sc = ServiceCollection::new();
let a_counter = Arc::new(AtomicUsize::new(0));
let a_factory_counter = a_counter.clone();
sc.add_scoped::<ScopedA, _>(move || ScopedA(a_factory_counter.fetch_add(1, Ordering::SeqCst)))
.unwrap();
let sp = ServiceProvider::new(sc);
ThreadLocalScope::initialize(sp.create_scope());
let provider: Arc<dyn ScopeProvider> = Arc::new(ThreadLocalScope);
let a1 = sp.disr::<ScopedA>(provider.clone()).unwrap();
assert_eq!(a1.0, 0);
let b_factory_counter = Arc::new(AtomicUsize::new(0));
sp.mutate(move |sc| {
sc.add_scoped::<ScopedB, _>(move || {
ScopedB(b_factory_counter.fetch_add(1, Ordering::SeqCst))
})
.unwrap();
});
ThreadLocalScope::refresh_scope_with(&sp).unwrap();
let b1 = sp.disr::<ScopedB>(provider.clone()).unwrap();
let a2 = sp.disr::<ScopedA>(provider).unwrap();
assert_eq!(b1.0, 0);
assert_eq!(a2.0, 0);
}
#[cfg(feature = "tokio")]
#[test]
fn test_task_refresh_scope() {
use kabel::scope::tasks::TaskScopeProvider;
let mut sc = ServiceCollection::new();
let a_counter = Arc::new(AtomicUsize::new(0));
let a_factory_counter = a_counter.clone();
sc.add_scoped::<ScopedA, _>(move || ScopedA(a_factory_counter.fetch_add(1, Ordering::SeqCst)))
.unwrap();
let sp = ServiceProvider::new(sc);
let scope = (*sp.create_scope()).clone();
TaskScopeProvider::initialize_sync(scope, || {
let provider: Arc<dyn ScopeProvider> = Arc::new(TaskScopeProvider);
let a1 = sp.disr::<ScopedA>(provider.clone()).unwrap();
assert_eq!(a1.0, 0);
let b_factory_counter = Arc::new(AtomicUsize::new(0));
sp.mutate(move |sc| {
sc.add_scoped::<ScopedB, _>(move || {
ScopedB(b_factory_counter.fetch_add(1, Ordering::SeqCst))
})
.unwrap();
});
TaskScopeProvider::refresh_scope_with(&sp).unwrap();
let b1 = sp.disr::<ScopedB>(provider.clone()).unwrap();
let a2 = sp.disr::<ScopedA>(provider).unwrap();
assert_eq!(b1.0, 0);
assert_eq!(a2.0, 0);
});
}