#![cfg(test)]
use std::{
any::Any,
collections::HashMap,
ops::{Deref, DerefMut},
thread::spawn,
};
use hreads::set_current_thread_as_main;
use pretty_assertions::assert_eq;
use serial_test::serial;
use wasm_bindgen_test::wasm_bindgen_test;
use crate::{AsAny, Own, Weak};
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
#[serial]
#[wasm_bindgen_test(unsupported = test)]
fn weak_misc() {
set_current_thread_as_main();
let five = Own::new(5);
let ten = Own::new(10);
assert_ne!(five, ten);
let mut weak = five.weak();
let another_weak = weak.clone();
assert_eq!(weak.is_null(), false);
assert_eq!(weak.deref(), another_weak.deref());
let null = Weak::<i32>::default();
assert!(null.is_null());
assert_eq!(null.is_ok(), false);
assert_eq!(null.get(), None);
let five_ref = weak.get_mut().unwrap();
assert_eq!(five_ref, &5);
*five_ref = 10;
assert_eq!(weak.deref(), &10);
assert!(!weak.is_null());
assert_eq!(weak.is_ok(), true);
assert_eq!(weak.get(), Some(10).as_ref());
set_current_thread_as_main();
drop(five);
assert!(weak.is_null());
assert_eq!(weak.is_ok(), false);
assert_eq!(weak.get(), None);
}
#[serial]
#[wasm_bindgen_test(unsupported = test)]
fn leak_weak() {
set_current_thread_as_main();
let leaked = unsafe { Weak::leak(5) };
dbg!(leaked.deref());
}
#[serial]
#[wasm_bindgen_test(unsupported = test)]
#[should_panic(expected = "Invalid address. In could be a closure or empty type.")]
fn leak_weak_closure() {
let _leaked = unsafe { Weak::leak(|| {}) };
}
#[serial]
#[wasm_bindgen_test(unsupported = test)]
fn addr() {
set_current_thread_as_main();
let own = Own::new(5);
let weak = own.weak();
assert_eq!(own.addr(), weak.addr());
}
#[serial]
#[wasm_bindgen_test(unsupported = test)]
#[should_panic(expected = "Dereferencing never initialized weak pointer: i32")]
fn null_weak_panic() {
let default = Weak::<i32>::default();
assert_eq!(default.is_ok(), false);
let _ = default.deref();
}
#[serial]
#[wasm_bindgen_test(unsupported = test)]
#[should_panic(expected = "Dereferencing already freed weak pointer: i32")]
fn freed_unsized_weak_panic() {
set_current_thread_as_main();
let own = Own::new(5);
let weak: Weak<dyn Any> = own.weak();
drop(own);
assert_eq!(weak.type_name, "i32");
assert_eq!(weak.is_ok(), false);
let _ = weak.deref();
}
#[serial]
#[wasm_bindgen_test(unsupported = test)]
fn const_weak_default() {
const WEAK: Weak<bool> = Weak::const_default();
set_current_thread_as_main();
assert!(WEAK.is_null());
}
#[serial]
#[should_panic]
#[wasm_bindgen_test(unsupported = test)]
fn deref_null() {
set_current_thread_as_main();
let null = Weak::<u32>::default();
assert!(null.is_null());
assert_eq!(null.is_ok(), false);
let _ = null.deref();
}
#[serial]
#[should_panic]
#[wasm_bindgen_test(unsupported = test)]
fn deref_async() {
set_current_thread_as_main();
let num = Own::new(5);
let mut weak = num.weak();
spawn(move || {
assert_eq!(weak.deref(), &5);
assert_eq!(weak.deref_mut(), &5);
})
.join()
.unwrap();
}
#[serial]
#[wasm_bindgen_test(unsupported = test)]
fn default_weak() {
let weak = Weak::<i32>::default();
assert!(weak.is_null());
trait Trait {
fn _a(&self);
}
let weak = Weak::<dyn Trait>::default();
assert!(weak.is_null());
}
#[serial]
#[wasm_bindgen_test(unsupported = test)]
fn downcast_weak() {
set_current_thread_as_main();
trait Tr: AsAny {}
struct St {
_a: i32,
}
impl Tr for St {}
impl AsAny for St {
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
fn into_any_box(self: Box<Self>) -> Box<dyn Any> {
self
}
}
let own: Own<dyn Tr> = Own::new(St { _a: 50 });
let downcasted: Weak<St> = own.downcast_weak().unwrap();
assert_eq!(downcasted._a, 50);
}
#[serial]
#[wasm_bindgen_test(unsupported = test)]
fn downcast_own() {
set_current_thread_as_main();
trait Tr: AsAny {}
struct St {
a: i32,
}
impl Tr for St {}
impl AsAny for St {
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
fn into_any_box(self: Box<Self>) -> Box<dyn Any> {
self
}
}
let own: Own<dyn Tr> = Own::new(St { a: 100 });
let downcasted: Own<St> = own.downcast::<St>();
assert_eq!(downcasted.a, 100);
}
#[serial]
#[wasm_bindgen_test(unsupported = test)]
fn weak_map_key() {
set_current_thread_as_main();
struct NonHash {
_a: u8,
}
let own = Own::new(NonHash { _a: 0 });
let weak = own.weak();
let mut map: HashMap<Weak<NonHash>, u32> = HashMap::new();
map.entry(weak).or_insert(5);
assert_eq!(map.get(&weak).unwrap(), &5);
}
#[serial]
#[wasm_bindgen_test(unsupported = test)]
fn was_initialized() {
set_current_thread_as_main();
let a = Weak::<i32>::default();
let b = Own::new(5);
let b = b.weak();
assert!(!a.was_initialized());
assert!(b.was_initialized());
}
#[serial]
#[wasm_bindgen_test(unsupported = test)]
fn raw_and_dump() {
set_current_thread_as_main();
let a = Own::new(5);
let a = a.weak();
let erased = a.erase();
let raw = a.raw();
let from_raw: Weak<i32> = unsafe { Weak::from_raw(raw) };
let from_raw_unsized: Weak<dyn Any> = unsafe { Weak::from_raw(raw) };
assert_eq!(a.raw(), from_raw.raw());
assert_eq!(a.raw(), from_raw_unsized.raw());
assert_eq!(a.raw(), erased.raw());
}