use generational_box::{GenerationalBox, Storage, SyncStorage, UnsyncStorage}; /// # Example /// /// ```compile_fail /// let data = String::from("hello world"); /// let owner = UnsyncStorage::owner(); /// let key = owner.insert(&data); /// drop(data); /// assert_eq!(*key.read(), "hello world"); /// ``` #[allow(unused)] fn compile_fail() {} #[test] fn leaking_is_ok() { fn leaking_is_ok_test>() { let data = String::from("hello world"); let key; { // create an owner let owner = S::owner(); // insert data into the store key = owner.insert(data); // don't drop the owner std::mem::forget(owner); } assert_eq!( key.try_read().as_deref().unwrap(), &"hello world".to_string() ); } leaking_is_ok_test::(); leaking_is_ok_test::(); } #[test] fn drops() { fn drops_test>() { let data = String::from("hello world"); let key; { // create an owner let owner = S::owner(); // insert data into the store key = owner.insert(data); // drop the owner } assert!(key.try_read().is_err()); } drops_test::(); drops_test::(); } #[test] fn works() { fn works_test>() { let owner = S::owner(); let key = owner.insert(1); assert_eq!(*key.read(), 1); } works_test::(); works_test::(); } #[test] fn insert_while_reading() { fn insert_while_reading_test + Storage<&'static i32>>() { let owner = S::owner(); let key; { let data: String = "hello world".to_string(); key = owner.insert(data); } let value = key.read(); owner.insert(&1); assert_eq!(*value, "hello world"); } insert_while_reading_test::(); insert_while_reading_test::(); } #[test] #[should_panic] fn panics() { fn panics_test>() { let owner = S::owner(); let key = owner.insert(1); drop(owner); assert_eq!(*key.read(), 1); } panics_test::(); panics_test::(); } #[test] fn fuzz() { fn maybe_owner_scope>( valid_keys: &mut Vec>, invalid_keys: &mut Vec>, path: &mut Vec, ) { let branch_cutoff = 5; let children = if path.len() < branch_cutoff { rand::random::() % 4 } else { rand::random::() % 2 }; for i in 0..children { let owner = S::owner(); let value = format!("hello world {path:?}"); let key = owner.insert(value.clone()); println!("created new box {key:?}"); valid_keys.push(key); path.push(i); // read all keys println!("{:?}", path); for key in valid_keys.iter() { println!("reading {key:?}"); let value = key.read(); println!("{:?}", &*value); assert!(value.starts_with("hello world")); } for key in invalid_keys.iter() { println!("reading invalid {key:?}"); assert!(key.try_read().is_err()); } maybe_owner_scope(valid_keys, invalid_keys, path); // After all the children run, we should still have our data let key_value = &*key.read(); println!("{:?}", key_value); assert_eq!(key_value, &value); let invalid = valid_keys.pop().unwrap(); println!("popping {invalid:?}"); invalid_keys.push(invalid); path.pop(); } } for _ in 0..10 { maybe_owner_scope::(&mut Vec::new(), &mut Vec::new(), &mut Vec::new()); } for _ in 0..10 { maybe_owner_scope::(&mut Vec::new(), &mut Vec::new(), &mut Vec::new()); } } #[test] fn fuzz_rc() { fn maybe_owner_scope>( valid_keys: &mut Vec>>, invalid_keys: &mut Vec>, path: &mut Vec, ) { let branch_cutoff = 5; let children = if path.len() < branch_cutoff { rand::random::() % 4 } else { rand::random::() % 2 }; for i in 0..children { let owner = S::owner(); let value = format!("hello world {path:?}"); let key = owner.insert_rc(value.clone()); println!("created new box {key:?}"); let mut keys = vec![key]; for _ in 0..rand::random::() % 10 { if rand::random::() % 2 == 0 { let owner = S::owner(); let key = owner.insert_reference(key).unwrap(); println!("created new reference {key:?}"); invalid_keys.push(key); } let key = owner.insert_reference(key).unwrap(); println!("created new reference {key:?}"); keys.push(key); } valid_keys.push(keys.clone()); path.push(i); // read all keys println!("{:?}", path); for keys in valid_keys.iter() { for key in keys { println!("reading {key:?}"); let value = key.read(); println!("{:?}", &*value); assert!(value.starts_with("hello world")); } } for key in invalid_keys.iter() { println!("reading invalid {key:?}"); assert!(key.try_read().is_err()); } maybe_owner_scope(valid_keys, invalid_keys, path); // After all the children run, we should still have our data for key in keys { let key_value = &*key.read(); println!("{:?}", key_value); assert_eq!(key_value, &value); } let invalid = valid_keys.pop().unwrap(); println!("popping {invalid:?}"); invalid_keys.extend(invalid); path.pop(); } } for _ in 0..10 { maybe_owner_scope::(&mut Vec::new(), &mut Vec::new(), &mut Vec::new()); } for _ in 0..10 { maybe_owner_scope::(&mut Vec::new(), &mut Vec::new(), &mut Vec::new()); } }