Files
OxideJS-New/crates/oxide_vm/tests/value_tests.rs
T

242 lines
5.9 KiB
Rust

use oxide_vm::JsValue;
#[test]
fn int_roundtrip() {
for v in [0, 1, -1, 42, i32::MIN, i32::MAX] {
let val = JsValue::int(v);
assert!(val.is_int(), "int({v}) should be int");
assert_eq!(val.as_int(), v, "int({v}) roundtrip failed");
}
}
#[test]
fn float_roundtrip() {
for v in [0.0, -0.0, 1.0, -1.0, 42.5, f64::MIN, f64::MAX] {
let val = JsValue::float(v);
assert!(val.is_double(), "float({v}) should be double");
assert_eq!(val.as_double(), v, "float({v}) roundtrip failed");
}
}
#[test]
fn float_infinity() {
let val = JsValue::float(f64::INFINITY);
assert!(val.is_double());
assert!(val.as_double().is_infinite());
assert!(val.as_double().is_sign_positive());
let val = JsValue::float(f64::NEG_INFINITY);
assert!(val.is_double());
assert!(val.as_double().is_infinite());
assert!(val.as_double().is_sign_negative());
}
#[test]
fn float_nan_canonicalization() {
let val = JsValue::float(f64::NAN);
assert!(val.is_double(), "NaN should be classified as double");
let d = val.as_double();
assert!(d.is_nan(), "NaN value should still be NaN");
}
#[test]
fn bool_roundtrip() {
let t = JsValue::bool(true);
assert!(t.is_bool());
assert!(t.as_bool());
let f = JsValue::bool(false);
assert!(f.is_bool());
assert!(!f.as_bool());
}
#[test]
fn null_type_check() {
let val = JsValue::null();
assert!(val.is_null());
assert!(!val.is_int());
assert!(!val.is_double());
assert!(!val.is_bool());
assert!(!val.is_undefined());
assert!(!val.is_object());
}
#[test]
fn undefined_type_check() {
let val = JsValue::undefined();
assert!(val.is_undefined());
assert!(!val.is_int());
assert!(!val.is_double());
assert!(!val.is_bool());
assert!(!val.is_null());
assert!(!val.is_object());
}
#[test]
fn null_equals_null() {
assert_eq!(JsValue::null(), JsValue::null());
}
#[test]
fn null_not_equals_undefined() {
assert_ne!(JsValue::null(), JsValue::undefined());
}
#[test]
fn object_pointer_roundtrip() {
let x = 42u8;
let val = JsValue::object(&x as *const u8);
assert!(val.is_object());
let ptr = val.as_ptr();
assert_eq!(ptr, &x as *const u8);
}
#[test]
fn as_ptr_non_object_returns_null() {
assert!(JsValue::int(0).as_ptr().is_null());
assert!(JsValue::float(0.0).as_ptr().is_null());
assert!(JsValue::bool(true).as_ptr().is_null());
assert!(JsValue::null().as_ptr().is_null());
assert!(JsValue::undefined().as_ptr().is_null());
let x = 42u8;
assert!(!JsValue::object(&x as *const u8).as_ptr().is_null());
}
#[test]
fn as_object_ptr_non_object_returns_null() {
assert!(JsValue::int(0).as_object_ptr().is_null());
assert!(JsValue::float(0.0).as_object_ptr().is_null());
assert!(JsValue::bool(true).as_object_ptr().is_null());
assert!(JsValue::null().as_object_ptr().is_null());
assert!(JsValue::undefined().as_object_ptr().is_null());
let x = 42u8;
assert!(!JsValue::object(&x as *const u8).as_object_ptr().is_null());
}
#[test]
fn as_js_object_ptr_non_object_returns_null() {
assert!(JsValue::int(0).as_js_object_ptr().is_null());
assert!(JsValue::float(0.0).as_js_object_ptr().is_null());
assert!(JsValue::bool(true).as_js_object_ptr().is_null());
assert!(JsValue::null().as_js_object_ptr().is_null());
assert!(JsValue::undefined().as_js_object_ptr().is_null());
let x = 42u8;
assert!(!JsValue::object(&x as *const u8)
.as_js_object_ptr()
.is_null());
}
#[test]
fn display_int() {
assert_eq!(format!("{}", JsValue::int(42)), "42");
assert_eq!(format!("{}", JsValue::int(-1)), "-1");
}
#[test]
fn display_double() {
let val = JsValue::float(42.5);
assert!(format!("{}", val).contains("42.5"));
}
#[test]
fn display_bool() {
assert_eq!(format!("{}", JsValue::bool(true)), "true");
assert_eq!(format!("{}", JsValue::bool(false)), "false");
}
#[test]
fn display_null() {
assert_eq!(format!("{}", JsValue::null()), "null");
}
#[test]
fn display_undefined() {
assert_eq!(format!("{}", JsValue::undefined()), "undefined");
}
#[test]
fn display_nan() {
assert_eq!(format!("{}", JsValue::float(f64::NAN)), "NaN");
}
#[test]
fn display_infinity() {
assert_eq!(format!("{}", JsValue::float(f64::INFINITY)), "Infinity");
}
#[test]
fn debug_int() {
assert_eq!(format!("{:?}", JsValue::int(42)), "JsValue(Int(42))");
}
#[test]
fn debug_double() {
let val = JsValue::float(42.5);
assert!(format!("{:?}", val).starts_with("JsValue(Double("));
}
#[test]
fn debug_bool() {
assert_eq!(format!("{:?}", JsValue::bool(true)), "JsValue(Bool(true))");
}
#[test]
fn debug_null() {
assert_eq!(format!("{:?}", JsValue::null()), "JsValue(Null)");
}
#[test]
fn debug_undefined() {
assert_eq!(format!("{:?}", JsValue::undefined()), "JsValue(Undefined)");
}
#[test]
fn debug_object() {
let x = 0u8;
let val = JsValue::object(&x as *const u8);
assert!(format!("{:?}", val).starts_with("JsValue(Object("));
}
#[test]
fn copy_semantics() {
let a = JsValue::int(42);
let b = a;
assert_eq!(a, b);
assert_eq!(a.as_int(), 42);
assert_eq!(b.as_int(), 42);
}
#[test]
fn type_exclusivity_int() {
let val = JsValue::int(1);
assert!(val.is_int());
assert!(!val.is_double());
assert!(!val.is_bool());
assert!(!val.is_null());
assert!(!val.is_undefined());
assert!(!val.is_object());
}
#[test]
fn type_exclusivity_double() {
let val = JsValue::float(0.0);
assert!(val.is_double());
assert!(!val.is_int());
assert!(!val.is_bool());
assert!(!val.is_null());
assert!(!val.is_undefined());
assert!(!val.is_object());
}
#[test]
fn type_exclusivity_object() {
let x = 0u8;
let val = JsValue::object(&x as *const u8);
assert!(val.is_object());
assert!(!val.is_int());
assert!(!val.is_double());
assert!(!val.is_bool());
assert!(!val.is_null());
assert!(!val.is_undefined());
}