use crate::SwmrCell;
use std::prelude::v1::*;
use std::thread;
use std::thread::JoinHandle;
use std::format;
use std::string::ToString;
use std::vec;
#[test]
fn test_create_swmr_cell_and_basic_usage() {
let cell = SwmrCell::new(42i32);
let local = cell.local_reader();
let guard = local.pin();
assert_eq!(*guard, 42);
}
#[test]
fn test_reader_pin_drop_cycle() {
let cell = SwmrCell::new(42i32);
let local = cell.local_reader();
{
let _guard = local.pin();
}
{
let _guard = local.pin();
}
}
#[test]
fn test_writer_store() {
let mut cell = SwmrCell::new(10i32);
let local = cell.local_reader();
{
let guard = local.pin();
assert_eq!(*guard, 10);
}
cell.store(20);
{
let guard = local.pin();
assert_eq!(*guard, 20);
}
}
#[test]
fn test_writer_collect() {
let mut cell = SwmrCell::builder()
.auto_reclaim_threshold(Some(1000))
.build(0i32);
cell.store(100);
cell.store(200);
cell.collect();
}
#[test]
fn test_nested_pins() {
let cell = SwmrCell::new(42i32);
let local = cell.local_reader();
let guard1 = local.pin();
let guard2 = local.pin();
let guard3 = local.pin();
assert_eq!(*guard1, 42);
assert_eq!(*guard2, 42);
assert_eq!(*guard3, 42);
drop(guard3);
drop(guard2);
drop(guard1);
}
#[test]
fn test_multiple_locals() {
let cell = SwmrCell::new(42i32);
let reader1 = cell.local_reader();
let reader2 = cell.local_reader();
let guard1 = reader1.pin();
let guard2 = reader2.pin();
assert_eq!(*guard1, 42);
assert_eq!(*guard2, 42);
}
#[test]
fn test_swmr_with_string() {
let cell = SwmrCell::new(String::from("hello"));
let local = cell.local_reader();
{
let guard = local.pin();
assert_eq!(*guard, "hello");
}
}
#[test]
fn test_swmr_with_struct() {
#[derive(Debug, PartialEq)]
struct Point {
x: i32,
y: i32,
}
let cell = SwmrCell::new(Point { x: 10, y: 20 });
let local = cell.local_reader();
{
let guard = local.pin();
assert_eq!(guard.x, 10);
assert_eq!(guard.y, 20);
}
}
#[test]
fn test_swmr_drop() {
let cell = SwmrCell::new(42i32);
let local = cell.local_reader();
drop(local);
drop(cell);
}
#[test]
fn test_multiple_swmr_instances() {
let c1 = SwmrCell::new(10i32);
let c2 = SwmrCell::new(20i32);
let c3 = SwmrCell::new(30i32);
let r1 = c1.local_reader();
let r2 = c2.local_reader();
let r3 = c3.local_reader();
{
let g1 = r1.pin();
let g2 = r2.pin();
let g3 = r3.pin();
assert_eq!(*g1, 10);
assert_eq!(*g2, 20);
assert_eq!(*g3, 30);
}
}
#[test]
fn test_thread_safety() {
let cell = SwmrCell::new(0i32);
let mut handles = vec![];
for _ in 0..5 {
let local = cell.local_reader();
handles.push(thread::spawn(move || {
let guard = local.pin();
*guard }));
}
let results: Vec<i32> = handles
.into_iter()
.map(|h: JoinHandle<i32>| h.join().unwrap())
.collect();
assert_eq!(results.len(), 5);
for &result in &results {
assert_eq!(result, 0);
}
}
#[test]
fn test_previous_none_initially() {
let cell = SwmrCell::new(42i32);
assert!(cell.previous().is_none());
}
#[test]
fn test_previous_after_store() {
let mut cell = SwmrCell::new(1i32);
assert!(cell.previous().is_none());
cell.store(2);
assert_eq!(cell.previous(), Some(&1));
cell.store(3);
assert_eq!(cell.previous(), Some(&2));
cell.store(4);
assert_eq!(cell.previous(), Some(&3));
}
#[test]
fn test_previous_survives_gc() {
let mut cell = SwmrCell::builder()
.auto_reclaim_threshold(None) .build(0i32);
for i in 1..=10 {
cell.store(i);
}
cell.collect();
assert_eq!(cell.previous(), Some(&9));
}
#[test]
fn test_previous_with_struct() {
#[derive(Debug, PartialEq)]
struct Data {
value: i32,
name: String,
}
let mut cell = SwmrCell::new(Data {
value: 1,
name: "first".to_string(),
});
assert!(cell.previous().is_none());
cell.store(Data {
value: 2,
name: "second".to_string(),
});
let prev = cell.previous().unwrap();
assert_eq!(prev.value, 1);
assert_eq!(prev.name, "first");
}
#[test]
fn test_get_returns_current_value() {
let mut cell = SwmrCell::new(42i32);
assert_eq!(*cell.get(), 42);
cell.store(100);
assert_eq!(*cell.get(), 100);
}
#[test]
fn test_update_with_closure() {
let mut cell = SwmrCell::new(10i32);
cell.update(|v| v + 5);
assert_eq!(*cell.get(), 15);
cell.update(|v| v * 2);
assert_eq!(*cell.get(), 30);
}
#[test]
fn test_garbage_count_tracks_retired_objects() {
let mut cell = SwmrCell::builder()
.auto_reclaim_threshold(None) .build(0i32);
assert_eq!(cell.garbage_count(), 0);
cell.store(1);
assert_eq!(cell.garbage_count(), 1);
cell.store(2);
assert_eq!(cell.garbage_count(), 2);
cell.store(3);
assert_eq!(cell.garbage_count(), 3);
}
#[test]
fn test_local_reader_is_pinned() {
let cell = SwmrCell::new(42i32);
let local = cell.local_reader();
assert!(!local.is_pinned());
let guard = local.pin();
assert!(local.is_pinned());
drop(guard);
assert!(!local.is_pinned());
}
#[test]
fn test_local_reader_version() {
let mut cell = SwmrCell::new(0i32);
let local = cell.local_reader();
assert_eq!(local.version(), 0);
cell.store(1);
assert_eq!(local.version(), 1);
cell.store(2);
assert_eq!(local.version(), 2);
}
#[test]
fn test_pin_guard_version() {
let mut cell = SwmrCell::new(0i32);
let local = cell.local_reader();
let guard = local.pin();
assert_eq!(guard.version(), 0);
drop(guard);
cell.store(1);
let guard = local.pin();
assert_eq!(guard.version(), 1);
}
#[test]
fn test_pin_guard_as_ref() {
let cell = SwmrCell::new(42i32);
let local = cell.local_reader();
let guard = local.pin();
let value: &i32 = guard.as_ref();
assert_eq!(*value, 42);
}
#[test]
fn test_default_trait() {
let cell: SwmrCell<i32> = SwmrCell::default();
assert_eq!(*cell.get(), 0);
let cell: SwmrCell<String> = SwmrCell::default();
assert_eq!(*cell.get(), "");
let cell: SwmrCell<Vec<i32>> = SwmrCell::default();
assert!(cell.get().is_empty());
}
#[test]
fn test_from_trait() {
let cell: SwmrCell<i32> = SwmrCell::from(42);
assert_eq!(*cell.get(), 42);
let cell: SwmrCell<String> = SwmrCell::from(String::from("hello"));
assert_eq!(*cell.get(), "hello");
}
#[test]
fn test_debug_trait_swmr_cell() {
let cell = SwmrCell::new(42i32);
let debug_str = format!("{:?}", cell);
assert!(debug_str.contains("SwmrCell"));
assert!(debug_str.contains("42"));
}
#[test]
fn test_debug_trait_local_reader() {
let cell = SwmrCell::new(42i32);
let local = cell.local_reader();
let debug_str = format!("{:?}", local);
assert!(debug_str.contains("LocalReader"));
}
#[test]
fn test_debug_trait_pin_guard() {
let cell = SwmrCell::new(42i32);
let local = cell.local_reader();
let guard = local.pin();
let debug_str = format!("{:?}", guard);
assert!(debug_str.contains("PinGuard"));
assert!(debug_str.contains("42"));
}