use shadow_counted::{Commit, IntoShadowCounted, ShadowCountedIter};
use std::cell::Cell;
#[derive(Debug, Clone, Default, PartialEq)]
struct TestData {
value: u32,
}
impl Commit for TestData {
fn commit(&self, _from: Self) {}
}
#[derive(Debug, Clone, Default)]
struct AccumulatingData {
sum: Cell<i32>,
}
impl Commit for AccumulatingData {
fn commit(&self, from: Self) {
self.sum.set(self.sum.get() + from.sum.get());
}
}
#[test]
fn test_new_with_data() {
let data = TestData { value: 42 };
let iter = ShadowCountedIter::new_with(vec![1, 2, 3].into_iter(), data);
assert_eq!(iter.supplement().value, 42);
}
#[test]
fn test_supplement_access() {
let iter = ShadowCountedIter::new_with(vec![1, 2].into_iter(), TestData { value: 100 });
let data_ref = iter.supplement();
assert_eq!(data_ref.value, 100);
}
#[test]
fn test_supplement_mut_modification() {
let mut iter = ShadowCountedIter::new_with(vec![1, 2].into_iter(), TestData { value: 10 });
assert_eq!(iter.supplement().value, 10);
iter.supplement_mut().value = 20;
assert_eq!(iter.supplement().value, 20);
iter.supplement_mut().value += 5;
assert_eq!(iter.supplement().value, 25);
}
#[test]
fn test_data_cloned_to_nested() {
let mut parent = ShadowCountedIter::new_with(vec![1, 2].into_iter(), TestData { value: 99 });
let nested = vec![3, 4].into_iter().nested_shadow_counted(&mut parent);
assert_eq!(nested.supplement().value, 99);
}
#[test]
fn test_nested_data_isolation() {
let mut parent = ShadowCountedIter::new_with(vec![1].into_iter(), TestData { value: 50 });
let mut nested = vec![2].into_iter().nested_shadow_counted(&mut parent);
nested.supplement_mut().value = 75;
assert_eq!(nested.supplement().value, 75);
nested.commit().unwrap();
assert_eq!(parent.supplement().value, 50);
}
#[test]
fn test_commit_trait_accumulation() {
let mut parent =
ShadowCountedIter::new_with(vec![1].into_iter(), AccumulatingData { sum: Cell::new(10) });
let mut nested = vec![2, 3].into_iter().nested_shadow_counted(&mut parent);
nested.supplement_mut().sum.set(25);
nested.commit().unwrap();
assert_eq!(parent.supplement().sum.get(), 35);
}
#[test]
fn test_commit_trait_invoked() {
#[derive(Debug, Clone, Default)]
struct CallCounter {
commits: Cell<u32>,
}
impl Commit for CallCounter {
fn commit(&self, _from: Self) {
self.commits.set(self.commits.get() + 1);
}
}
let mut parent = ShadowCountedIter::new_with(vec![1].into_iter(), CallCounter::default());
let nested = vec![2].into_iter().nested_shadow_counted(&mut parent);
nested.commit().unwrap();
assert_eq!(parent.supplement().commits.get(), 1);
let nested2 = vec![3].into_iter().nested_shadow_counted(&mut parent);
nested2.commit().unwrap();
assert_eq!(parent.supplement().commits.get(), 2);
}
#[test]
fn test_unit_type_default() {
let mut iter = vec![1, 2, 3].into_iter().shadow_counted();
let _ = iter.supplement();
let _ = iter.supplement_mut();
for _ in iter.by_ref() {}
assert_eq!(iter.counter(), 3);
}
#[test]
fn test_rc_supplement() {
use std::rc::Rc;
let data = Rc::new(vec![1, 2, 3]);
let mut iter = ShadowCountedIter::new_with(vec![10, 20].into_iter(), data.clone());
assert_eq!(iter.supplement().len(), 3);
let nested = vec![30].into_iter().nested_shadow_counted(&mut iter);
assert_eq!(nested.supplement().len(), 3);
nested.commit().unwrap();
}
#[test]
fn test_arc_supplement() {
use std::sync::Arc;
let data = Arc::new(String::from("test"));
let mut iter = ShadowCountedIter::new_with(vec![1].into_iter(), data.clone());
assert_eq!(iter.supplement().as_str(), "test");
let nested = vec![2].into_iter().nested_shadow_counted(&mut iter);
assert_eq!(nested.supplement().as_str(), "test");
nested.commit().unwrap();
}
#[test]
fn test_data_persists_through_iteration() {
let mut iter =
ShadowCountedIter::new_with(vec![1, 2, 3, 4, 5].into_iter(), TestData { value: 123 });
for _ in 0..3 {
iter.next();
assert_eq!(iter.supplement().value, 123);
}
}
#[test]
fn test_multilevel_nesting_with_data() {
let mut level1 =
ShadowCountedIter::new_with(vec![1].into_iter(), AccumulatingData { sum: Cell::new(1) });
let mut level2 = vec![2].into_iter().nested_shadow_counted(&mut level1);
let current = level2.supplement().sum.get();
level2.supplement_mut().sum.set(current + 2);
let mut level3 = vec![3].into_iter().nested_shadow_counted(&mut level2);
let current = level3.supplement().sum.get();
level3.supplement_mut().sum.set(current + 3);
level3.commit().unwrap();
assert_eq!(level2.supplement().sum.get(), 9);
level2.commit().unwrap();
assert_eq!(level1.supplement().sum.get(), 10); }