use super::*;
use crate::internal::error::Result;
use crate::internal::object::{Object, Ptr};
use crate::internal::vm::global::Global;
use crate::util::JoinIter;
struct Bar {
value: u64,
}
impl Object for Bar {
fn type_name(_: Ptr<Self>) -> &'static str {
"Bar"
}
fn instance_of(_: Ptr<Self>, _: Value) -> Result<bool> {
unimplemented!()
}
}
declare_object_type!(Bar);
impl Debug for Bar {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Bar").field("value", &self.value).finish()
}
}
impl Display for Bar {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Debug::fmt(self, f)
}
}
#[test]
fn create_value() {
let global = Global::default();
let values = [
Value::float(std::f64::consts::PI),
Value::int(-1_000_000),
Value::bool(true),
Value::none(),
Value::object(global.alloc(Bar { value: 100 })),
];
let snapshot = format!("[{}]", values.iter().join(", "));
assert_snapshot!(snapshot);
}
#[test]
fn drop_object_value() {
let global = Global::default();
Value::object(global.alloc(Bar { value: 100 }));
}
#[test]
fn clone_and_drop_values() {
let values = [
Value::float(std::f64::consts::PI),
Value::int(-1_000_000),
Value::bool(true),
Value::none(),
];
for value in values.iter() {
std::hint::black_box(value.clone());
}
}
#[test]
fn clone_and_drop_object_value() {
let global = Global::default();
let ptr = global.alloc(Bar { value: 100 }).into_any();
assert_eq!(ptr.refs(), 1);
let a = Value::object(ptr.clone());
assert_eq!(ptr.refs(), 2);
let b = a.clone();
assert_eq!(ptr.refs(), 3);
let ptr_a = a.to_any().unwrap();
assert_eq!(ptr_a.refs(), 3);
let ptr_b = b.to_any().unwrap();
assert_eq!(ptr_b.refs(), 3);
drop(Value::object(ptr_a));
assert_eq!(ptr.refs(), 2);
drop(Value::object(ptr_b));
assert_eq!(ptr.refs(), 1);
}
#[test]
#[should_panic]
fn create_value_from_qnan() {
Value::float(f64::from_bits(
0b01111111_11111100_00000000_00000000_00000000_00000000_00000000_00000000,
));
}