use rong_test::*;
#[test]
fn basic() {
run(|ctx| {
let v = 3;
let key = "key";
let obj = JSObject::new(ctx);
assert!(obj.is_object());
assert!(obj.set(key, v).is_ok());
assert!(obj.has(key));
obj.del(key);
assert!(!obj.has(key));
let value = JSValue::from(ctx, v);
assert!(obj.set(key, value.clone()).is_ok());
assert_eq!(obj.get::<&str, i32>(key).unwrap(), v);
assert!(obj.set(9, value.clone()).is_ok());
assert_eq!(obj.get::<i32, i32>(9).unwrap(), v);
let objv = JSObject::new(ctx);
assert!(obj.set("obj", objv).is_ok());
assert!(obj.has("obj"));
Ok(())
});
}
#[test]
fn from_javascript() {
run(|ctx| {
let obj: JSObject = ctx
.eval(Source::from_bytes(
br#"
let a3 = [];
a3[1] = "foo";
({
a1: [0,,2,,5],
a2: [0,"michael",{},undefined,5],
a3: a3,
func1: () => 1,
func2: function(){ return "bar"},
obj1: {
a: 1,
b: "foo",
},
})
"#,
))
.unwrap();
assert!(obj.get::<_, JSObject>("a1").unwrap().is_array());
assert!(obj.get::<_, JSObject>("a2").unwrap().is_array());
assert!(obj.get::<_, JSObject>("a3").unwrap().is_array());
assert!(obj.get::<_, JSObject>("func1").unwrap().is_function());
assert!(obj.get::<_, JSObject>("func2").unwrap().is_function());
assert!(!obj.get::<_, JSObject>("obj1").unwrap().is_function());
assert!(!obj.get::<_, JSObject>("obj1").unwrap().is_array());
assert!(obj.get::<_, JSObject>("obj1").unwrap().is_object());
assert_eq!(
obj.get::<_, JSObject>("obj1")
.unwrap()
.get::<_, i32>("a")
.unwrap(),
1
);
let result: Result<String, RongJSError> = obj.get("None");
assert!(result.is_err());
match result {
Err(e) if e.is_property_not_found() => (),
_ => panic!("Expected PropertyNotFound error"),
}
Ok(())
})
}
#[test]
fn test_object_display() {
run(|ctx| {
let code = "({foo: 'bar', num: 42})";
let obj: JSObject = ctx.eval(Source::from_bytes(code)).unwrap();
assert_eq!(format!("{}", obj), "object");
assert_eq!(format!("{:?}", obj), "JSObject(object)");
let code = "[1, 2, 3]";
let obj: JSObject = ctx.eval(Source::from_bytes(code)).unwrap();
assert_eq!(format!("{}", obj), "array");
assert_eq!(format!("{:?}", obj), "JSObject(array)");
Ok(())
});
}
#[test]
fn test_object_properties() {
run(|ctx| {
let source = Source::from_bytes(
r#"
let obj = {
name: "test",
age: 42,
greet: function() { return "Hello"; }
};
obj;
"#,
);
let obj: JSObject = ctx.eval(source).unwrap();
assert_eq!(obj.get::<_, String>("name").unwrap(), "test");
assert_eq!(obj.get::<_, i32>("age").unwrap(), 42);
assert!(obj.has("greet"));
let entries = obj.entries().unwrap();
assert_eq!(entries.len(), 3);
let entries: Vec<(String, JSValue)> = obj.entries_as().unwrap();
assert!(entries.iter().any(|(k, _)| k == "name"));
let keys: Vec<String> = obj.keys_as().unwrap();
assert_eq!(keys.len(), 3);
assert!(keys.contains(&"name".to_string()));
assert!(keys.contains(&"age".to_string()));
assert!(keys.contains(&"greet".to_string()));
let values = obj.values().unwrap();
assert_eq!(values.count(), 3);
assert!(obj.set("name", "updated").is_ok());
assert_eq!(obj.get::<_, String>("name").unwrap(), "updated");
assert!(obj.del("age"));
assert!(!obj.has("age"));
assert!(obj.get::<_, String>("nonexistent").is_err());
Ok(())
});
}
#[test]
fn test_object_property_attributes() {
run(|ctx| {
let source = Source::from_bytes(
r#"
let obj = {};
Object.defineProperty(obj, 'readOnly', {
value: 'constant',
writable: false,
enumerable: true
});
Object.defineProperty(obj, 'hidden', {
value: 'secret',
enumerable: false
});
obj;
"#,
);
let obj: JSObject = ctx.eval(source).unwrap();
assert_eq!(obj.get::<_, String>("readOnly").unwrap(), "constant");
let keys: Vec<String> = obj.keys_as().unwrap();
assert!(keys.contains(&"readOnly".to_string()));
assert!(!keys.contains(&"hidden".to_string()));
assert!(obj.has("hidden"));
assert!(obj.has("readOnly"));
Ok(())
});
}
#[test]
fn test_object_prototype() {
run(|ctx| {
let source = Source::from_bytes(
r#"
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
return this.name + " makes a sound";
};
let dog = new Animal("Dog");
dog;
"#,
);
let obj: JSObject = ctx.eval(source).unwrap();
assert_eq!(obj.get::<_, String>("name").unwrap(), "Dog");
let result: String = ctx
.eval(Source::from_bytes(
r#"
dog.speak();
"#,
))
.unwrap();
assert_eq!(result, "Dog makes a sound");
let own_keys: Vec<String> = obj.keys_as().unwrap();
assert!(own_keys.contains(&"name".to_string()));
assert!(!own_keys.contains(&"speak".to_string())); Ok(())
});
}