//! Integration tests for the `object_pool` module. use sarasacw_omrf::object_pool::{ObjectPool, INVALID_TOKEN}; /// Coverage: the `INVALID_TOKEN` constant is `0`, the value the counter never produces. #[test] fn invalid_token_is_zero() { assert_eq!(INVALID_TOKEN, 0); } /// Coverage: `allocate` returns distinct, non-zero tokens across successive calls. #[test] fn allocate_yields_distinct_nonzero_tokens() { let pool: ObjectPool = ObjectPool::new(); let t1 = pool.allocate(10); let t2 = pool.allocate(20); let t3 = pool.allocate(30); assert_ne!(t1, 0); assert_ne!(t2, 0); assert_ne!(t3, 0); assert_ne!(t1, t2); assert_ne!(t2, t3); assert_ne!(t1, t3); } /// Coverage: the guard-style `get` reads and `get_mut` writes an entry, with changes observable /// by a subsequent `get`. #[test] fn get_and_get_mut_round_trip() { let pool: ObjectPool = ObjectPool::new(); let t = pool.allocate(7); assert_eq!(*pool.get(t).unwrap(), 7); *pool.get_mut(t).unwrap() = 99; assert_eq!(*pool.get(t).unwrap(), 99); } /// Coverage: the deadlock-safe closure-based `get_with`/`get_mut_with` read and write an entry. #[test] fn get_with_and_get_mut_with_round_trip() { let pool: ObjectPool = ObjectPool::new(); let t = pool.allocate(1); assert_eq!(pool.get_with(t, |v| *v).unwrap(), 1); pool.get_mut_with(t, |v| *v = 42).unwrap(); assert_eq!(pool.get_with(t, |v| *v).unwrap(), 42); } /// Coverage: `pop` returns the owned value and invalidates the token for any further access. #[test] fn pop_returns_owned_value_and_invalidates_token() { let pool: ObjectPool = ObjectPool::new(); let t = pool.allocate("hello".to_string()); let owned = pool.pop(t).unwrap(); assert_eq!(owned, "hello"); assert!(pool.get(t).is_err()); } /// Coverage: `free` removes the entry; subsequent `get`/`get_mut` on the same token fail. #[test] fn free_invalidates_token() { let pool: ObjectPool = ObjectPool::new(); let t = pool.allocate(5); pool.free(t).unwrap(); assert!(pool.get(t).is_err()); assert!(pool.get_mut(t).is_err()); } /// Coverage: every access/mutation/removal method rejects `INVALID_TOKEN` (and any absent token). #[test] fn invalid_token_errors_on_all_methods() { let pool: ObjectPool = ObjectPool::new(); let bad = INVALID_TOKEN; assert!(pool.get(bad).is_err()); assert!(pool.get_mut(bad).is_err()); assert!(pool.get_with(bad, |_| ()).is_err()); assert!(pool.get_mut_with(bad, |_| ()).is_err()); assert!(pool.free(bad).is_err()); assert!(pool.pop(bad).is_err()); } /// Coverage: `clear` empties the pool; all previously-issued tokens become invalid. #[test] fn clear_removes_all_objects() { let pool: ObjectPool = ObjectPool::new(); let t1 = pool.allocate(1); let t2 = pool.allocate(2); pool.clear(); assert!(pool.get(t1).is_err()); assert!(pool.get(t2).is_err()); } /// Coverage: two distinct tokens can be mutated independently via sequential closure access, which /// never holds two guards at once (the deadlock-safe pattern). #[test] fn two_tokens_modified_independently_via_closure() { let pool: ObjectPool = ObjectPool::new(); let t1 = pool.allocate(0); let t2 = pool.allocate(0); pool.get_mut_with(t1, |v| *v = 11).unwrap(); pool.get_mut_with(t2, |v| *v = 22).unwrap(); assert_eq!(pool.get_with(t1, |v| *v).unwrap(), 11); assert_eq!(pool.get_with(t2, |v| *v).unwrap(), 22); }