Browse Source

[builtins - object] Object.create (#543)

pull/554/head
croraf 4 years ago committed by GitHub
parent
commit
0fe591b5c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 32
      boa/src/builtins/object/mod.rs
  2. 70
      boa/src/builtins/object/tests.rs

32
boa/src/builtins/object/mod.rs

@ -410,6 +410,36 @@ pub fn make_object(_: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultVa
Ok(object)
}
/// `Object.create( proto, [propertiesObject] )`
///
/// Creates a new object from the provided prototype.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#sec-object.create
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create
pub fn create(_: &Value, args: &[Value], interpreter: &mut Interpreter) -> ResultValue {
let prototype = args.get(0).cloned().unwrap_or_else(Value::undefined);
let properties = args.get(1).cloned().unwrap_or_else(Value::undefined);
if properties != Value::Undefined {
unimplemented!("propertiesObject argument of Object.create")
}
match prototype {
Value::Object(_) | Value::Null => Ok(Value::new_object_from_prototype(
prototype,
ObjectData::Ordinary,
)),
_ => interpreter.throw_type_error(format!(
"Object prototype may only be an Object or null: {}",
prototype
)),
}
}
/// Uses the SameValue algorithm to check equality of objects
pub fn is(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
let x = args.get(0).cloned().unwrap_or_else(Value::undefined);
@ -520,6 +550,8 @@ pub fn init(global: &Value) -> (&str, Value) {
let object = make_constructor_fn("Object", 1, make_object, global, prototype, true);
// static methods of the builtin Object
make_builtin_fn(create, "create", &object, 2);
make_builtin_fn(set_prototype_of, "setPrototypeOf", &object, 2);
make_builtin_fn(get_prototype_of, "getPrototypeOf", &object, 1);
make_builtin_fn(define_property, "defineProperty", &object, 3);

70
boa/src/builtins/object/tests.rs

@ -1,5 +1,75 @@
use crate::{exec::Interpreter, forward, realm::Realm};
#[test]
fn object_create_with_regular_object() {
let realm = Realm::create();
let mut engine = Interpreter::new(realm);
let init = r#"
const foo = { a: 5 };
const bar = Object.create(foo);
"#;
forward(&mut engine, init);
assert_eq!(forward(&mut engine, "bar.a"), "5");
assert_eq!(forward(&mut engine, "Object.create.length"), "2");
}
#[test]
fn object_create_with_undefined() {
let realm = Realm::create();
let mut engine = Interpreter::new(realm);
let init = r#"
try {
const bar = Object.create();
} catch (err) {
err.message
}
"#;
let result = forward(&mut engine, init);
assert_eq!(
result,
"Object prototype may only be an Object or null: undefined"
);
}
#[test]
fn object_create_with_number() {
let realm = Realm::create();
let mut engine = Interpreter::new(realm);
let init = r#"
try {
const bar = Object.create(5);
} catch (err) {
err.message
}
"#;
let result = forward(&mut engine, init);
assert_eq!(result, "Object prototype may only be an Object or null: 5");
}
#[test]
#[ignore]
// to test on __proto__ somehow. __proto__ getter is not working as expected currently
fn object_create_with_function() {
let realm = Realm::create();
let mut engine = Interpreter::new(realm);
let init = r#"
const x = function (){};
const bar = Object.create(5);
bar.__proto__
"#;
let result = forward(&mut engine, init);
assert_eq!(result, "...something on __proto__...");
}
#[test]
fn object_is() {
let realm = Realm::create();

Loading…
Cancel
Save