use rong_test::*;
use std::string::String;
#[test]
fn test_convert() {
run(|ctx| {
let jsvalue = JSValue::from(ctx, false);
assert!(jsvalue.is_boolean());
assert!(!jsvalue.try_into::<bool>().unwrap());
let jsvalue = JSValue::from(ctx, i32::MIN);
assert!(jsvalue.is_number());
assert_eq!(i32::MIN, jsvalue.try_into::<i32>().unwrap());
let jsvalue = JSValue::from(ctx, u32::MAX);
assert_eq!(u32::MAX, jsvalue.try_into::<u32>().unwrap());
let small_i64: i64 = 42;
let jsvalue = JSValue::from(ctx, small_i64);
assert!(jsvalue.is_number(), "Small i64 should be a regular number");
assert_eq!(small_i64, jsvalue.try_into::<i64>().unwrap());
let jsvalue = JSValue::from(ctx, i64::MIN);
assert!(jsvalue.is_bigint(), "i64::MIN should be a BigInt");
assert_eq!(i64::MIN, jsvalue.try_into::<i64>().unwrap());
let small_u64: u64 = 42;
let jsvalue = JSValue::from(ctx, small_u64);
assert!(jsvalue.is_number(), "Small u64 should be a regular number");
assert_eq!(small_u64, jsvalue.try_into::<u64>().unwrap());
let jsvalue = JSValue::from(ctx, u64::MAX);
assert!(jsvalue.is_bigint(), "u64::MAX should be a BigInt");
assert_eq!(u64::MAX, jsvalue.try_into::<u64>().unwrap());
let safe_max: i64 = (1i64 << 53) - 1;
let jsvalue = JSValue::from(ctx, safe_max);
assert!(
jsvalue.is_number(),
"JS safe max should be a regular number"
);
assert_eq!(safe_max, jsvalue.try_into::<i64>().unwrap());
let unsafe_max: i64 = 1i64 << 53;
let jsvalue = JSValue::from(ctx, unsafe_max);
assert!(jsvalue.is_bigint(), "Beyond JS safe max should be a BigInt");
assert_eq!(unsafe_max, jsvalue.try_into::<i64>().unwrap());
let js_num: JSValue = ctx.eval(Source::from_bytes("42")).unwrap();
assert_eq!(42i64, js_num.try_into::<i64>().unwrap());
let js_bigint: JSValue = ctx.eval(Source::from_bytes("9007199254740992n")).unwrap();
assert_eq!(1i64 << 53, js_bigint.try_into::<i64>().unwrap());
let jsvalue = JSValue::from(ctx, f64::MIN);
assert_eq!(f64::MIN, jsvalue.try_into::<f64>().unwrap());
let hello = "Hello";
let jsvalue = JSValue::from(ctx, hello);
assert!(jsvalue.is_string());
let output: String = jsvalue.try_into().unwrap();
assert_eq!(String::from(hello), output);
let jsvalue = JSValue::undefined(ctx);
assert!(jsvalue.is_undefined());
let test_usize: usize = 42;
let jsvalue = JSValue::from(ctx, test_usize);
assert!(
jsvalue.is_number(),
"Small usize should be a regular number"
);
let output: usize = jsvalue.try_into().unwrap();
assert_eq!(test_usize, output);
let large_usize: usize = usize::MAX;
let jsvalue = JSValue::from(ctx, large_usize);
assert!(jsvalue.is_bigint(), "Large usize should be a BigInt");
let output: usize = jsvalue.try_into().unwrap();
assert_eq!(large_usize, output);
Ok(())
});
}
#[test]
fn test_convert_from_js() {
run(|ctx| {
let result: u64 = ctx.eval(Source::from_bytes(b"16"))?;
assert_eq!(16, result);
let result: u32 = ctx.eval(Source::from_bytes(b"16"))?;
assert_eq!(16, result);
let result: i32 = ctx.eval(Source::from_bytes(b"-16"))?;
assert_eq!(-16, result);
let result: i64 = ctx.eval(Source::from_bytes(b"-16"))?;
assert_eq!(-16, result);
let result: f64 = ctx.eval(Source::from_bytes(b"-0.89"))?;
assert_eq!(-0.89, result);
let result = ctx.eval::<i32>(Source::from_bytes(b"null"));
assert!(result.is_err());
let result = ctx.eval::<i64>(Source::from_bytes(b"null"));
assert!(result.is_err());
let result = ctx.eval::<u32>(Source::from_bytes(b"string"));
assert!(result.is_err());
let result = ctx.eval::<u64>(Source::from_bytes(b"undefined"));
assert!(result.is_err());
let result = ctx.eval::<f64>(Source::from_bytes(b"undefined"));
assert!(result.is_err());
Ok(())
});
}
#[cfg(feature = "jscore")]
#[test]
fn test_jscore_i32_u32_conversion_semantics() {
run(|ctx| {
let i32_over_max: i32 = ctx.eval(Source::from_bytes(b"2147483648"))?;
assert_eq!(i32::MIN, i32_over_max);
let i32_mod_zero: i32 = ctx.eval(Source::from_bytes(b"4294967296"))?;
assert_eq!(0, i32_mod_zero);
let i32_nan: i32 = ctx.eval(Source::from_bytes(b"NaN"))?;
assert_eq!(0, i32_nan);
let u32_neg_one: u32 = ctx.eval(Source::from_bytes(b"-1"))?;
assert_eq!(u32::MAX, u32_neg_one);
let u32_over_mod: u32 = ctx.eval(Source::from_bytes(b"4294967297"))?;
assert_eq!(1, u32_over_mod);
let u32_nan: u32 = ctx.eval(Source::from_bytes(b"NaN"))?;
assert_eq!(0, u32_nan);
Ok(())
});
}
#[test]
fn test_equal() {
run(|ctx| {
let boolean = JSValue::from(ctx, false);
let integer = JSValue::from(ctx, i32::MAX);
let integer2 = JSValue::from(ctx, i32::MAX);
assert!(boolean != integer);
assert!(integer == integer.clone());
assert!(integer == integer2);
Ok(())
});
}
#[test]
fn test_display() {
run(|ctx| {
let jsvalue = JSValue::undefined(ctx);
assert_eq!(format!("{}", jsvalue), "undefined");
let jsvalue = JSValue::from(ctx, true);
assert_eq!(format!("{}", jsvalue), "true");
let jsvalue = JSValue::from(ctx, 42);
assert_eq!(format!("{}", jsvalue), "42");
let jsvalue = JSValue::from(ctx, "hello");
assert_eq!(format!("{}", jsvalue), "hello");
let code = "({foo: 'bar'})";
let jsvalue: JSValue = ctx.eval(Source::from_bytes(code)).unwrap();
assert_eq!(format!("{}", jsvalue), "object");
let code = "[1, 2, 3]";
let jsvalue: JSValue = ctx.eval(Source::from_bytes(code)).unwrap();
assert_eq!(format!("{}", jsvalue), "array");
let code = "(function name() {})";
let jsvalue: JSValue = ctx.eval(Source::from_bytes(code)).unwrap();
assert_eq!(format!("{}", jsvalue), "function");
let code = "new Promise(() => {})";
let jsvalue: JSValue = ctx.eval(Source::from_bytes(code)).unwrap();
assert_eq!(format!("{}", jsvalue), "promise");
let code = "null";
let jsvalue: JSValue = ctx.eval(Source::from_bytes(code)).unwrap();
assert_eq!(format!("{}", jsvalue), "null");
Ok(())
});
}
#[test]
fn test_string_with_null() {
run(|ctx| {
let result: String = ctx
.eval(Source::from_bytes(
br#"
"before" + String.fromCharCode(0) + "after"
"#,
))
.unwrap();
assert_eq!(result.len(), 12, "String length should be 12 (6 + 1 + 5)");
assert!(
result.contains('\0'),
"String should contain null character"
);
let parts: Vec<&str> = result.split('\0').collect();
assert_eq!(parts[0], "before", "Content before null character");
assert_eq!(parts[1], "after", "Content after null character");
let result: String = ctx
.eval(Source::from_bytes(
br#"
String.fromCharCode(0)
"#,
))
.unwrap();
assert_eq!(
result.len(),
1,
"Single null character string length should be 1"
);
assert_eq!(result.as_bytes(), &[0], "Should be a single null byte");
let result: String = ctx
.eval(Source::from_bytes(
br#"
"a" + String.fromCharCode(0) + "b" + String.fromCharCode(0) + "c"
"#,
))
.unwrap();
assert_eq!(
result.len(),
5,
"String length should be 5 (a + \0 + b + \0 + c)"
);
let parts: Vec<&str> = result.split('\0').collect();
assert_eq!(parts, &["a", "b", "c"], "Should split into three parts");
Ok(())
});
}