use super::Asc;
use alloc::collections::BTreeMap;
use alloc::format;
use alloc::string::String;
use alloc::vec::Vec;
#[test]
fn clone_and_drop() {
let a = Asc::new(String::from("hello"));
let a1 = a.shallow_clone();
let a2 = Asc::clone(&a);
assert_eq!(&*a, "hello");
drop(a1);
drop(a);
drop(a2);
}
#[test]
fn strong_count_basic() {
let a = Asc::new(42i32);
assert_eq!(Asc::strong_count(&a), 1);
let b = a.clone();
assert_eq!(Asc::strong_count(&a), 2);
assert_eq!(Asc::strong_count(&b), 2);
drop(b);
assert_eq!(Asc::strong_count(&a), 1);
}
#[test]
fn ptr_eq_same() {
let a = Asc::new(1);
let b = a.clone();
assert!(Asc::ptr_eq(&a, &b));
let c = Asc::new(1);
assert!(!Asc::ptr_eq(&a, &c));
}
#[test]
fn try_unwrap_success() {
let a = Asc::new(42);
let val = Asc::try_unwrap(a).unwrap();
assert_eq!(val, 42);
}
#[test]
fn try_unwrap_failure() {
let a = Asc::new(42);
let _b = a.clone();
let result = Asc::try_unwrap(a);
assert!(result.is_err());
let a = result.unwrap_err();
assert_eq!(*a, 42);
}
#[test]
fn into_inner_unique() {
let a = Asc::new("data");
assert_eq!(Asc::into_inner(a), Some("data"));
}
#[test]
fn into_inner_shared() {
let a = Asc::new("data");
let _b = a.clone();
assert_eq!(Asc::into_inner(a), None);
}
#[test]
fn unwrap_or_clone_unique() {
let a = Asc::new(String::from("hello"));
let s = Asc::unwrap_or_clone(a);
assert_eq!(s, "hello");
}
#[test]
fn unwrap_or_clone_shared() {
let a = Asc::new(String::from("hello"));
let _b = a.clone();
let s = Asc::unwrap_or_clone(a);
assert_eq!(s, "hello");
}
#[test]
#[cfg_attr(miri, ignore)]
fn into_raw_from_raw_roundtrip() {
let a = Asc::new(42i32);
let ptr = Asc::into_raw(a);
let a = unsafe { Asc::from_raw(ptr) };
assert_eq!(*a, 42);
}
#[test]
fn as_ptr_borrowed() {
let a = Asc::new(7u32);
let ptr = Asc::as_ptr(&a);
assert_eq!(unsafe { *ptr }, 7);
assert_eq!(*a, 7);
}
#[test]
#[cfg_attr(miri, ignore)]
fn from_raw_high_alignment() {
#[repr(align(64))]
struct Aligned(u8);
let a = Asc::new(Aligned(42));
let ptr = Asc::into_raw(a);
let a = unsafe { Asc::from_raw(ptr) };
assert_eq!(a.0, 42);
}
#[test]
#[cfg_attr(miri, ignore)]
fn increment_decrement_strong_count() {
let a = Asc::new(42i32);
let ptr = Asc::into_raw(a);
unsafe { Asc::increment_strong_count(ptr) };
let a = unsafe { Asc::from_raw(ptr) };
assert_eq!(Asc::strong_count(&a), 2);
assert_eq!(*a, 42);
unsafe { Asc::decrement_strong_count(Asc::as_ptr(&a)) };
assert_eq!(Asc::strong_count(&a), 1);
let ptr = Asc::into_raw(a);
unsafe { Asc::decrement_strong_count(ptr) };
}
#[test]
#[cfg_attr(miri, ignore)]
fn increment_strong_count_via_as_ptr() {
let a = Asc::new(7u32);
let ptr = Asc::as_ptr(&a);
unsafe { Asc::increment_strong_count(ptr) };
assert_eq!(Asc::strong_count(&a), 2);
unsafe { Asc::decrement_strong_count(ptr) };
assert_eq!(Asc::strong_count(&a), 1);
}
#[test]
fn is_unique_basic() {
let a = Asc::new(1);
assert!(Asc::is_unique(&a));
let b = a.clone();
assert!(!Asc::is_unique(&a));
assert!(!Asc::is_unique(&b));
drop(b);
assert!(Asc::is_unique(&a));
}
#[test]
fn get_mut_unique() {
let mut a = Asc::new(10i32);
{
let val = Asc::get_mut(&mut a).unwrap();
*val = 20;
}
assert_eq!(*a, 20);
}
#[test]
fn get_mut_shared() {
let mut a = Asc::new(10i32);
let _b = a.clone();
assert!(Asc::get_mut(&mut a).is_none());
}
#[test]
fn make_mut_unique() {
let mut a = Asc::new(5i32);
*Asc::make_mut(&mut a) = 10;
assert_eq!(*a, 10);
assert_eq!(Asc::strong_count(&a), 1);
}
#[test]
fn make_mut_shared_clones() {
let mut a = Asc::new(5i32);
let _b = a.clone();
assert_eq!(Asc::strong_count(&a), 2);
*Asc::make_mut(&mut a) = 10;
assert_eq!(*a, 10);
assert_eq!(Asc::strong_count(&a), 1);
}
#[test]
fn pin_basic() {
let pinned = Asc::pin(42i32);
assert_eq!(*pinned, 42);
let _clone = pinned.clone();
}
#[test]
fn deref() {
let a = Asc::new(100);
assert_eq!(*a, 100);
}
#[test]
fn partial_eq() {
let a = Asc::new(1);
let b = Asc::new(1);
let c = Asc::new(2);
assert_eq!(a, b);
assert_ne!(a, c);
}
#[test]
fn eq_trait() {
fn assert_eq_trait<T: core::cmp::Eq>(_t: &T) {}
let a = Asc::new(1);
assert_eq_trait(&a);
}
#[test]
fn hash() {
use core::hash::{BuildHasher, Hasher};
#[derive(Default)]
struct SimpleHasher(u64);
impl Hasher for SimpleHasher {
fn finish(&self) -> u64 {
self.0
}
fn write(&mut self, bytes: &[u8]) {
for &b in bytes {
self.0 = self.0.wrapping_mul(31).wrapping_add(u64::from(b));
}
}
}
#[derive(Default)]
struct SimpleBuildHasher;
impl BuildHasher for SimpleBuildHasher {
type Hasher = SimpleHasher;
fn build_hasher(&self) -> SimpleHasher {
SimpleHasher::default()
}
}
let bh = SimpleBuildHasher;
let a = Asc::new(1);
let b = Asc::new(1);
let c = Asc::new(2);
assert_eq!(bh.hash_one(&a), bh.hash_one(&b));
assert_ne!(bh.hash_one(&a), bh.hash_one(&c));
}
#[test]
fn ord_as_map_key() {
let mut map = BTreeMap::new();
map.insert(Asc::new(1), "one");
map.insert(Asc::new(2), "two");
assert_eq!(map.get(&Asc::new(1)), Some(&"one"));
assert_eq!(map.get(&Asc::new(2)), Some(&"two"));
}
#[test]
fn partial_ord_and_ord() {
let a = Asc::new(1);
let b = Asc::new(2);
assert!(a < b);
assert!(b > a);
assert_eq!(a.cmp(&b), core::cmp::Ordering::Less);
}
#[test]
fn display() {
let a = Asc::new(42);
assert_eq!(format!("{a}"), "42");
}
#[test]
fn pointer_fmt() {
let a = Asc::new(1);
let s = format!("{a:p}");
let expected = format!("{:p}", Asc::as_ptr(&a));
assert_eq!(s, expected);
}
#[test]
fn from_trait() {
let a: Asc<i32> = 42.into();
assert_eq!(*a, 42);
}
#[test]
fn default_trait() {
let a: Asc<i32> = Asc::default();
assert_eq!(*a, 0);
}
#[test]
fn debug() {
let a = Asc::new(7);
assert_eq!(format!("{a:?}"), "7");
}
#[test]
fn send_sync() {
fn assert_send<T: Send>(_t: &T) {}
fn assert_sync<T: Sync>(_t: &T) {}
let a = Asc::new(1);
assert_send(&a);
assert_sync(&a);
}
#[test]
fn try_unwrap_after_make_mut() {
let mut a = Asc::new(String::from("hello"));
let _b = a.clone();
Asc::make_mut(&mut a).push_str(" world");
let s = Asc::try_unwrap(a).unwrap();
assert_eq!(s, "hello world");
}
#[test]
fn test_vec_of_asc() {
let items: Vec<Asc<i32>> = (0..5).map(Asc::new).collect();
let clones: Vec<Asc<i32>> = items.iter().map(Asc::clone).collect();
assert_eq!(items.len(), clones.len());
for (a, b) in items.iter().zip(&clones) {
assert!(Asc::ptr_eq(a, b));
}
}
#[test]
fn drop_behavior() {
let a = Asc::new(());
let b = a.clone();
let c = a.clone();
assert_eq!(Asc::strong_count(&a), 3);
drop(b);
assert_eq!(Asc::strong_count(&a), 2);
drop(c);
assert_eq!(Asc::strong_count(&a), 1);
}
#[test]
fn zero_sized_type() {
let a = Asc::new(());
let b = a.clone();
assert_eq!(Asc::strong_count(&a), 2);
assert!(Asc::ptr_eq(&a, &b));
drop(b);
Asc::try_unwrap(a).unwrap();
}
#[test]
fn get_mut_unchecked_direct() {
let mut a = Asc::new(5i32);
unsafe {
*Asc::get_mut_unchecked(&mut a) = 15;
}
assert_eq!(*a, 15);
assert_eq!(Asc::strong_count(&a), 1);
}
#[test]
fn make_mut_zero_sized() {
let mut a = Asc::new(());
let _b = a.clone();
assert_eq!(Asc::strong_count(&a), 2);
let _val = Asc::make_mut(&mut a);
assert_eq!(Asc::strong_count(&a), 1);
}
#[test]
fn try_unwrap_zero_sized_shared() {
let a = Asc::new(());
let _b = a.clone();
let result = Asc::try_unwrap(a);
assert!(result.is_err());
let a = result.unwrap_err();
assert_eq!(*a, ());
drop(a);
}
#[test]
fn make_mut_preserves_value() {
let mut a = Asc::new(String::from("original"));
let b = a.clone();
Asc::make_mut(&mut a).push_str(" modified");
assert_eq!(&*b, "original");
assert_eq!(&*a, "original modified");
}
#[cfg(feature = "serde")]
mod serde_tests {
use super::Asc;
use alloc::string::String;
use alloc::vec;
use alloc::vec::Vec;
#[test]
fn serialize_basic() {
let a = Asc::new(42i32);
let json = serde_json::to_string(&a).unwrap();
assert_eq!(json, "42");
}
#[test]
fn deserialize_basic() {
let a: Asc<i32> = serde_json::from_str("42").unwrap();
assert_eq!(*a, 42);
}
#[test]
fn roundtrip_json() {
let a = Asc::new(String::from("hello"));
let json = serde_json::to_string(&a).unwrap();
let b: Asc<String> = serde_json::from_str(&json).unwrap();
assert_eq!(*a, *b);
}
#[test]
fn serialize_complex() {
let a = Asc::new(vec![1, 2, 3]);
let json = serde_json::to_string(&a).unwrap();
assert_eq!(json, "[1,2,3]");
}
#[test]
fn deserialize_complex() {
let a: Asc<Vec<i32>> = serde_json::from_str("[4,5,6]").unwrap();
assert_eq!(*a, vec![4, 5, 6]);
}
#[test]
fn serialize_shared() {
let a = Asc::new(10);
let _b = a.clone();
let json = serde_json::to_string(&a).unwrap();
assert_eq!(json, "10");
}
#[test]
fn serialize_zero_sized() {
let a = Asc::new(());
let json = serde_json::to_string(&a).unwrap();
assert_eq!(json, "null");
}
}
#[cfg(feature = "unstable")]
mod dst_tests {
use super::Asc;
use alloc::format;
use alloc::string::String;
use core::fmt::Debug;
use core::mem::MaybeUninit;
#[test]
fn slice_deref_clone_drop() {
let a: Asc<[i32]> = Asc::new([1, 2, 3]);
assert_eq!(&*a, &[1, 2, 3]);
let b = a.clone();
assert_eq!(Asc::strong_count(&a), 2);
assert!(Asc::ptr_eq(&a, &b));
drop(b);
assert_eq!(Asc::strong_count(&a), 1);
}
#[test]
fn slice_debug() {
let a: Asc<[i32]> = Asc::new([10, 20]);
assert_eq!(format!("{a:?}"), "[10, 20]");
}
#[test]
fn slice_partial_eq() {
let a: Asc<[i32]> = Asc::new([1, 2]);
let b: Asc<[i32]> = Asc::new([1, 2]);
let c: Asc<[i32]> = Asc::new([3, 4]);
assert_eq!(a, b);
assert_ne!(a, c);
}
#[test]
#[cfg_attr(miri, ignore)]
fn slice_as_ptr_into_raw() {
let a: Asc<[i32]> = Asc::new([7, 8, 9]);
let ptr = Asc::as_ptr(&a);
assert_eq!(unsafe { &*ptr }, &[7, 8, 9]);
let ptr2 = Asc::into_raw(a);
assert_eq!(unsafe { &*ptr2 }, &[7, 8, 9]);
}
#[test]
fn trait_object_deref_clone_drop() {
let a: Asc<dyn Debug> = Asc::new(String::from("hello"));
assert_eq!(format!("{a:?}"), "\"hello\"");
let b = a.clone();
assert_eq!(Asc::strong_count(&a), 2);
drop(b);
assert_eq!(Asc::strong_count(&a), 1);
}
#[test]
fn trait_object_pointer_fmt() {
let a: Asc<dyn Debug> = Asc::new(42i32);
let s = format!("{a:p}");
let expected = format!("{:p}", Asc::as_ptr(&a));
assert_eq!(s, expected);
}
#[test]
#[cfg_attr(miri, ignore)]
fn new_uninit_slice_assume_init() {
let mut uninit: Asc<[MaybeUninit<i32>]> = Asc::new_uninit_slice(3);
assert_eq!(Asc::strong_count(&uninit), 1);
let mu = Asc::get_mut(&mut uninit).unwrap();
mu[0].write(10);
mu[1].write(20);
mu[2].write(30);
let init: Asc<[i32]> = unsafe { uninit.assume_init() };
assert_eq!(&*init, &[10, 20, 30]);
}
#[test]
#[cfg_attr(miri, ignore)]
fn new_zeroed_slice_assume_init() {
let zeroed: Asc<[MaybeUninit<u64>]> = Asc::new_zeroed_slice(4);
let init: Asc<[u64]> = unsafe { zeroed.assume_init() };
assert_eq!(&*init, &[0u64, 0, 0, 0]);
}
#[test]
#[cfg_attr(miri, ignore)]
fn new_uninit_slice_zst() {
let mut uninit: Asc<[MaybeUninit<()>]> = Asc::new_uninit_slice(5);
Asc::get_mut(&mut uninit).unwrap()[2].write(());
let init: Asc<[()]> = unsafe { uninit.assume_init() };
assert_eq!(init.len(), 5);
}
#[test]
#[cfg_attr(miri, ignore)]
fn new_uninit_slice_zero_len() {
let uninit: Asc<[MaybeUninit<i32>]> = Asc::new_uninit_slice(0);
assert_eq!(Asc::strong_count(&uninit), 1);
drop(uninit);
}
}
#[cfg(feature = "std")]
mod thread_tests {
use super::Asc;
use alloc::vec::Vec;
use std::thread;
#[test]
fn send_to_another_thread() {
let a = Asc::new(42i32);
let handle = thread::spawn(move || {
assert_eq!(*a, 42);
Asc::strong_count(&a)
});
let count = handle.join().unwrap();
assert_eq!(count, 1);
}
#[test]
fn clone_across_threads() {
let a = Asc::new(0i32);
let b = a.clone();
let handle = thread::spawn(move || {
assert_eq!(*b, 0);
});
handle.join().unwrap();
assert_eq!(*a, 0);
assert_eq!(Asc::strong_count(&a), 1);
}
#[test]
fn concurrent_clone_drop() {
let a = Asc::new(());
let n = 8;
let mut handles = Vec::new();
for _ in 0..n {
let a = a.clone();
handles.push(thread::spawn(move || {
let _a = a;
}));
}
for h in handles {
h.join().unwrap();
}
assert_eq!(Asc::strong_count(&a), 1);
}
}
#[test]
fn new_uninit_assume_init() {
let mut five = Asc::<i32>::new_uninit();
Asc::get_mut(&mut five).unwrap().write(5);
let five = unsafe { five.assume_init() };
assert_eq!(*five, 5);
}
#[test]
fn new_zeroed_assume_init() {
let zeroed = Asc::<u64>::new_zeroed();
let zeroed = unsafe { zeroed.assume_init() };
assert_eq!(*zeroed, 0u64);
}
#[test]
fn new_uninit_zst() {
let mut zst = Asc::<()>::new_uninit();
Asc::get_mut(&mut zst).unwrap().write(());
let zst = unsafe { zst.assume_init() };
assert_eq!(*zst, ());
}
#[test]
fn new_zeroed_drop_behavior() {
let a = Asc::<i32>::new_zeroed();
let b = a.clone();
assert_eq!(Asc::strong_count(&a), 2);
drop(b);
assert_eq!(Asc::strong_count(&a), 1);
}
#[test]
fn new_uninit_drop_without_init() {
let _a = Asc::<i32>::new_uninit();
let _b = Asc::<String>::new_uninit();
}